1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5cr.define('cr.ui', function() {
6
7  /**
8   * The class name to set on the document element.
9   */
10  const CLASS_NAME = 'focus-outline-visible';
11
12  /**
13   * This class sets a CSS class name on the HTML element of |doc| when the user
14   * presses the tab key. It removes the class name when the user clicks
15   * anywhere.
16   *
17   * This allows you to write CSS like this:
18   *
19   * html.focus-outline-visible my-element:focus {
20   *   outline: 5px auto -webkit-focus-ring-color;
21   * }
22   *
23   * And the outline will only be shown if the user uses the keyboard to get to
24   * it.
25   *
26   * @param {Document} doc The document to attach the focus outline manager to.
27   * @constructor
28   */
29  function FocusOutlineManager(doc) {
30    this.classList_ = doc.documentElement.classList;
31    var self = this;
32    doc.addEventListener('keydown', function(e) {
33      if (e.keyCode == 9)  // Tab
34        self.visible = true;
35    }, true);
36
37    doc.addEventListener('mousedown', function(e) {
38      self.visible = false;
39    }, true);
40  }
41
42  FocusOutlineManager.prototype = {
43    /**
44     * Whether the focus outline should be visible.
45     * @type {boolean}
46     */
47    set visible(visible) {
48      if (visible)
49        this.classList_.add(CLASS_NAME);
50      else
51        this.classList_.remove(CLASS_NAME);
52    },
53    get visible() {
54      this.classList_.contains(CLASS_NAME);
55    }
56  }
57
58  /**
59   * Array of Document and FocusOutlineManager pairs.
60   * @type {Array}
61   */
62  var docsToManager = [];
63
64  /**
65   * Gets a per document sigleton focus outline manager.
66   * @param {Document} doc The document to get the |FocusOutlineManager| for.
67   * @return {FocusOutlineManager} The per document singleton focus outline
68   *     manager.
69   */
70  FocusOutlineManager.forDocument = function(doc) {
71    for (var i = 0; i < docsToManager.length; i++) {
72      if (doc == docsToManager[i][0])
73        return docsToManager[i][1];
74    }
75    var manager = new FocusOutlineManager(doc);
76    docsToManager.push([doc, manager]);
77    return manager;
78  };
79
80  return {
81    FocusOutlineManager: FocusOutlineManager
82  };
83});
84