Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Unified Diff: chrome/browser/resources/options/options_page.js

Issue 6315012: DOMUI Prefs: Keep focus within the topmost page/overlay (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address last review comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/options/options_page.js
diff --git a/chrome/browser/resources/options/options_page.js b/chrome/browser/resources/options/options_page.js
index 715de30257100d1aecf729b0d29372c53c47718b..429ee08f4e3936fa7643ab313728f5b2768df9bd 100644
--- a/chrome/browser/resources/options/options_page.js
+++ b/chrome/browser/resources/options/options_page.js
@@ -129,11 +129,20 @@ cr.define('options', function() {
* @private
*/
OptionsPage.isOverlayVisible_ = function() {
+ return this.getVisibleOverlay_() != null;
+ };
+
+ /**
+ * Returns the currently visible overlay, or null if no page is visible.
+ * @return {OptionPage} The visible overlay.
+ */
+ OptionsPage.getVisibleOverlay_ = function() {
for (var name in this.registeredOverlayPages) {
- if (this.registeredOverlayPages[name].visible)
- return true;
+ var page = this.registeredOverlayPages[name];
+ if (page.visible)
+ return page;
}
- return false;
+ return null;
};
/**
@@ -159,7 +168,7 @@ cr.define('options', function() {
topPage = page;
}
return topPage;
- }
+ };
/**
* Closes the topmost open subpage, if any.
@@ -349,6 +358,9 @@ cr.define('options', function() {
// Install handler for key presses.
document.addEventListener('keydown', this.keyDownEventHandler_.bind(this));
+
+ document.addEventListener('focus', this.manageFocusChange_.bind(this),
+ true);
};
/**
@@ -373,6 +385,30 @@ cr.define('options', function() {
};
/**
+ * Called when focus changes; ensures that focus doesn't move outside
+ * the topmost subpage/overlay.
+ * @param {Event} e The focus change event.
+ * @private
+ */
+ OptionsPage.manageFocusChange_ = function(e) {
+ var focusableItemsRoot;
+ // If an overlay is visible, that defines the tab loop.
+ var topPage = this.getVisibleOverlay_();
+ if (topPage)
+ focusableItemsRoot = topPage.pageDiv;
+ // If a subpage is visible, use its parent as the tab loop constraint.
+ // (The parent is used because it contains the close button.)
+ if (!topPage) {
+ var topPage = this.getTopmostVisiblePage();
+ if (topPage && topPage.nestingLevel > 0)
+ focusableItemsRoot = topPage.pageDiv.parentNode;
+ }
+
+ if (focusableItemsRoot && !focusableItemsRoot.contains(e.target))
+ topPage.focusFirstElement();
+ };
+
+ /**
* A function to handle mouse events (mousedown or click) on the html body by
* closing subpages and/or stopping event propagation.
* @return {Event} a mousedown or click event.
@@ -542,6 +578,17 @@ cr.define('options', function() {
},
/**
+ * Focuses the first control on the page.
+ */
+ focusFirstElement: function() {
+ // Sets focus on the first interactive element in the page.
+ var focusElement =
+ this.pageDiv.querySelector('button, input, list, select');
+ if (focusElement)
+ focusElement.focus();
+ },
+
+ /**
* The nesting level of this page.
* @type {number} The nesting level of this page (0 for top-level page)
*/
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698