- add sources.
[platform/framework/web/crosswalk.git] / src / ui / webui / resources / js / cr / ui / focus_outline_manager.js
1 // Copyright (c) 2012 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
5 cr.define('cr.ui', function() {
6
7   /**
8    * The class name to set on the document element.
9    * @const
10    */
11   var CLASS_NAME = 'focus-outline-visible';
12
13   /**
14    * This class sets a CSS class name on the HTML element of |doc| when the user
15    * presses the tab key. It removes the class name when the user clicks
16    * anywhere.
17    *
18    * This allows you to write CSS like this:
19    *
20    * html.focus-outline-visible my-element:focus {
21    *   outline: 5px auto -webkit-focus-ring-color;
22    * }
23    *
24    * And the outline will only be shown if the user uses the keyboard to get to
25    * it.
26    *
27    * @param {Document} doc The document to attach the focus outline manager to.
28    * @constructor
29    */
30   function FocusOutlineManager(doc) {
31     this.classList_ = doc.documentElement.classList;
32     var self = this;
33     doc.addEventListener('keydown', function(e) {
34       if (e.keyCode == 9)  // Tab
35         self.focusByKeyboard_ = true;
36     }, true);
37
38     doc.addEventListener('mousedown', function(e) {
39       self.focusByKeyboard_ = false;
40     }, true);
41
42     doc.addEventListener('focus', function(event) {
43       // Update visibility only when focus is actually changed.
44       self.visible = self.focusByKeyboard_;
45     }, true);
46   }
47
48   FocusOutlineManager.prototype = {
49     /**
50      * Whether focus change is triggered by TAB key.
51      * @type {boolean}
52      * @private
53      */
54     focusByKeyboard_: true,
55
56     /**
57      * Whether the focus outline should be visible.
58      * @type {boolean}
59      */
60     set visible(visible) {
61       if (visible)
62         this.classList_.add(CLASS_NAME);
63       else
64         this.classList_.remove(CLASS_NAME);
65     },
66     get visible() {
67       return this.classList_.contains(CLASS_NAME);
68     }
69   };
70
71   /**
72    * Array of Document and FocusOutlineManager pairs.
73    * @type {Array}
74    */
75   var docsToManager = [];
76
77   /**
78    * Gets a per document sigleton focus outline manager.
79    * @param {Document} doc The document to get the |FocusOutlineManager| for.
80    * @return {FocusOutlineManager} The per document singleton focus outline
81    *     manager.
82    */
83   FocusOutlineManager.forDocument = function(doc) {
84     for (var i = 0; i < docsToManager.length; i++) {
85       if (doc == docsToManager[i][0])
86         return docsToManager[i][1];
87     }
88     var manager = new FocusOutlineManager(doc);
89     docsToManager.push([doc, manager]);
90     return manager;
91   };
92
93   return {
94     FocusOutlineManager: FocusOutlineManager
95   };
96 });