check.jcarr.wit.com/chrome/focus_outline_manager.js

107 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('cr.ui', function() {
/**
* The class name to set on the document element.
* @const
*/
var CLASS_NAME = 'focus-outline-visible';
/**
* This class sets a CSS class name on the HTML element of |doc| when the user
* presses the tab key. It removes the class name when the user clicks
* anywhere.
*
* This allows you to write CSS like this:
*
* html.focus-outline-visible my-element:focus {
* outline: 5px auto -webkit-focus-ring-color;
* }
*
* And the outline will only be shown if the user uses the keyboard to get to
* it.
*
* @param {Document} doc The document to attach the focus outline manager to.
* @constructor
*/
function FocusOutlineManager(doc) {
this.classList_ = doc.documentElement.classList;
var self = this;
doc.addEventListener('keydown', function(e) {
self.focusByKeyboard_ = true;
}, true);
doc.addEventListener('mousedown', function(e) {
self.focusByKeyboard_ = false;
}, true);
doc.addEventListener('focus', function(event) {
// Update visibility only when focus is actually changed.
self.updateVisibility();
}, true);
doc.addEventListener('focusout', function(event) {
window.setTimeout(function() {
if (!doc.hasFocus()) {
self.focusByKeyboard_ = true;
self.updateVisibility();
}
}, 0);
});
this.updateVisibility();
}
FocusOutlineManager.prototype = {
/**
* Whether focus change is triggered by TAB key.
* @type {boolean}
* @private
*/
focusByKeyboard_: true,
updateVisibility: function() {
this.visible = this.focusByKeyboard_;
},
/**
* Whether the focus outline should be visible.
* @type {boolean}
*/
set visible(visible) {
this.classList_.toggle(CLASS_NAME, visible);
},
get visible() {
return this.classList_.contains(CLASS_NAME);
}
};
/**
* Array of Document and FocusOutlineManager pairs.
* @type {Array}
*/
var docsToManager = [];
/**
* Gets a per document singleton focus outline manager.
* @param {Document} doc The document to get the |FocusOutlineManager| for.
* @return {cr.ui.FocusOutlineManager} The per document singleton focus
* outline manager.
*/
FocusOutlineManager.forDocument = function(doc) {
for (var i = 0; i < docsToManager.length; i++) {
if (doc == docsToManager[i][0])
return docsToManager[i][1];
}
var manager = new FocusOutlineManager(doc);
docsToManager.push([doc, manager]);
return manager;
};
return {FocusOutlineManager: FocusOutlineManager};
});