summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraltimofeev@chromium.org <altimofeev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-10 07:59:55 +0000
committeraltimofeev@chromium.org <altimofeev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-10 07:59:55 +0000
commite2036c519b4685b13a82a1860d2c6c7326983abb (patch)
treee344da8c0ba8f96c32d766a3a647b5bb407b522a
parent6cd8666d0f2f30f20841e50e6323053ab99129bc (diff)
downloadchromium_src-e2036c519b4685b13a82a1860d2c6c7326983abb.zip
chromium_src-e2036c519b4685b13a82a1860d2c6c7326983abb.tar.gz
chromium_src-e2036c519b4685b13a82a1860d2c6c7326983abb.tar.bz2
Makes the network dropdown keyboard accessible (focus friendly).
Also: * fixes drop-down buttons layout. * overlay for catching outside the menu clicks is implemented (mimics standard select control behavior). BUG=chromium-os:18826 TEST=manual Review URL: http://codereview.chromium.org/7550070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96147 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/chromeos/login/oobe.css27
-rw-r--r--chrome/browser/resources/chromeos/login/oobe_screen_network.html12
-rw-r--r--chrome/browser/resources/chromeos/login/oobe_screen_network.js149
3 files changed, 160 insertions, 28 deletions
diff --git a/chrome/browser/resources/chromeos/login/oobe.css b/chrome/browser/resources/chromeos/login/oobe.css
index 89bd4134..771a574 100644
--- a/chrome/browser/resources/chromeos/login/oobe.css
+++ b/chrome/browser/resources/chromeos/login/oobe.css
@@ -164,12 +164,7 @@ hr.bottom {
.control-with-label {
margin: 10px 0 10px 0;
display: -webkit-box;
-}
-
-.label {
- margin: 5px 5px 5px 0;
- padding: 5px 5px 5px 0;
- width: 170px;
+ -webkit-box-align: start;
}
.menu-area {
@@ -180,6 +175,12 @@ hr.bottom {
width: 250px;
}
+.label {
+ margin: 5px 5px 5px 0;
+ padding: 5px 5px 5px 0;
+ width: 170px;
+}
+
#connect {
box-sizing: border-box;
padding: 60px 0 0 145px;
@@ -564,6 +565,7 @@ body.login-display #progress {
text-indent: 4px;
white-space: nowrap;
width: 250px;
+ z-index: 10;
}
.dropdown-title:hover {
@@ -590,7 +592,7 @@ body.login-display #progress {
position: relative;
top: 100%;
width: 248px;
- z-index: 1;
+ z-index: 10;
}
.dropdown-item-container {
@@ -599,7 +601,7 @@ body.login-display #progress {
padding-left: 5px;
}
-.dropdown-item-container:hover {
+.dropdown-item-container.hover {
background: #dce4fa;
}
@@ -659,3 +661,12 @@ html[dir=rtl] .error-message {
position: absolute;
text-shadow: 0 1px 1px #fff;
}
+
+.dropdown-overlay {
+ bottom: 0;
+ left: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 5;
+}
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.html b/chrome/browser/resources/chromeos/login/oobe_screen_network.html
index 2ee05bc..ea116f9 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_network.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_network.html
@@ -1,24 +1,20 @@
<div class="step hidden" id="connect">
<div class="control-with-label">
- <label for="language-select" i18n-content="selectLanguage"
- class="label menu-control"></label>
+ <div i18n-content="selectLanguage" class="label menu-control"></div>
<div class="menu-area">
<select id="language-select" class="menu-control"></select>
</div>
</div>
<div class="control-with-label">
- <label for="keyboard-select" i18n-content="selectKeyboard"
- class="label menu-control"></label>
+ <div i18n-content="selectKeyboard" class="label menu-control"></div>
<div class="menu-area">
<select id="keyboard-select" class="menu-control"></select>
</div>
</div>
<div class="control-with-label">
- <label for="networks-list" i18n-content="selectNetwork"
- class="label menu-control"></label>
+ <div i18n-content="selectNetwork" class="label menu-control"></div>
<div class="menu-area">
- <div id="networks-list" class="menu-control"
- tabindex="0" role="button" aria-haspopup="true"></div>
+ <div id="networks-list" class="menu-control" aria-haspopup="true"></div>
</div>
</div>
</div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.js b/chrome/browser/resources/chromeos/login/oobe_screen_network.js
index 9321f49..4fe3bbc 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_network.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_network.js
@@ -8,6 +8,37 @@
cr.define('oobe', function() {
/**
+ * Creates a new container for the drop down menu items.
+ * @constructor
+ * @extends{HTMLDivElement}
+ */
+ var DropDownContainer = cr.ui.define('div');
+
+ DropDownContainer.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ /** @inheritDoc */
+ decorate: function() {
+ this.classList.add('dropdown-container');
+ // Selected item in the menu list.
+ this.selectedItem = null;
+ // First item which could be selected.
+ this.firstItem = null;
+ },
+
+ /**
+ * Selects new item.
+ * @param {!Object} selectedItem Item to be selected.
+ */
+ selectItem: function(selectedItem) {
+ if (this.selectedItem)
+ this.selectedItem.classList.remove('hover');
+ selectedItem.classList.add('hover');
+ this.selectedItem = selectedItem;
+ }
+ };
+
+ /**
* Creates a new DropDown div.
* @constructor
* @extends {HTMLDivElement}
@@ -21,13 +52,12 @@ cr.define('oobe', function() {
/** @inheritDoc */
decorate: function() {
+ this.appendChild(this.createOverlay_());
this.appendChild(this.createTitle_());
+ this.appendChild(new DropDownContainer());
- // Create menu items container.
- var container = this.ownerDocument.createElement('div')
- container.classList.add('dropdown-container');
- this.appendChild(container);
this.isShown = false;
+ this.addEventListener('keydown', this.keyDownHandler_);
},
/**
@@ -35,7 +65,7 @@ cr.define('oobe', function() {
* @type {bool} Whether menu element is shown.
*/
get isShown() {
- return !this.lastElementChild.hidden;
+ return !this.container.hidden;
},
/**
@@ -43,7 +73,24 @@ cr.define('oobe', function() {
* @param {bool} show New visibility state for dropdown menu.
*/
set isShown(show) {
- this.lastElementChild.hidden = !show;
+ this.firstElementChild.hidden = !show;
+ this.container.hidden = !show;
+ if (show)
+ this.container.selectItem(this.container.firstItem);
+ },
+
+ /**
+ * Returns title button.
+ */
+ get titleButton() {
+ return this.childNodes[1];
+ },
+
+ /**
+ * Returns container of the menu items.
+ */
+ get container() {
+ return this.lastElementChild;
},
/**
@@ -53,7 +100,7 @@ cr.define('oobe', function() {
*/
setTitle: function(title, icon) {
// TODO(nkostylev): Icon support for dropdown title.
- this.firstElementChild.textContent = title;
+ this.titleButton.textContent = title;
},
/**
@@ -61,19 +108,21 @@ cr.define('oobe', function() {
* @param {Array} items Dropdown items array.
*/
setItems: function(items) {
- var container = this.lastElementChild;
- container.innerHTML = '';
+ this.container.innerHTML = '';
+ this.container.firstItem = null;
+ this.container.selectedItem = null;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if ('sub' in item) {
// Workaround for submenus, add items on top level.
// TODO(altimofeev): support submenus.
for (var j = 0; j < item.sub.length; ++j)
- this.createItem_(container, item.sub[j]);
+ this.createItem_(this.container, item.sub[j]);
continue;
}
- this.createItem_(container, item);
+ this.createItem_(this.container, item);
}
+ this.container.selectItem(this.container.firstItem);
},
/**
@@ -120,13 +169,34 @@ cr.define('oobe', function() {
var item = this.lastElementChild;
if (item.iid < -1 || item.classList.contains('disabled-item'))
return;
- item.controller.isShown = !item.controller.isShown;
+ item.controller.isShown = false;
if (item.iid >= 0)
chrome.send('networkItemChosen', [item.iid]);
});
+ wrapperDiv.addEventListener('mouseover', function f(e) {
+ this.parentNode.selectItem(this);
+ });
itemElement = wrapperDiv;
}
container.appendChild(itemElement);
+ if (!container.firstItem && item.id >= 0) {
+ container.firstItem = itemElement;
+ }
+ },
+
+ /**
+ * Creates dropdown overlay element, which catches outside clicks.
+ * @type {HTMLElement}
+ * @private
+ */
+ createOverlay_: function() {
+ var overlay = this.ownerDocument.createElement('div');
+ overlay.classList.add('dropdown-overlay');
+ overlay.addEventListener('click', function() {
+ this.parentNode.titleButton.focus();
+ this.parentNode.isShown = false;
+ });
+ return overlay;
},
/**
@@ -139,10 +209,65 @@ cr.define('oobe', function() {
el.classList.add('dropdown-title');
el.iid = -1;
el.controller = this;
+ el.enterPressed = false;
+
el.addEventListener('click', function f(e) {
+ this.focus();
this.controller.isShown = !this.controller.isShown;
+
+ if (this.enterPressed) {
+ this.enterPressed = false;
+ if (!this.controller.isShown) {
+ var item = this.controller.container.selectedItem.lastElementChild;
+ if (item.iid >= 0 && !item.classList.contains('disabled-item'))
+ chrome.send('networkItemChosen', [item.iid]);
+ }
+ }
});
return el;
+ },
+
+ /**
+ * Handles keydown event from the keyboard.
+ * @private
+ * @param {!Event} e Keydown event.
+ */
+ keyDownHandler_: function(e) {
+ if (!this.isShown)
+ return;
+ var selected = this.container.selectedItem;
+ switch(e.keyCode) {
+ case 38: { // Key up.
+ do {
+ selected = selected.previousSibling;
+ if (!selected)
+ selected = this.container.lastElementChild;
+ } while (selected.iid < 0);
+ this.container.selectItem(selected);
+ break;
+ }
+ case 40: { // Key down.
+ do {
+ selected = selected.nextSibling;
+ if (!selected)
+ selected = this.container.firstItem;
+ } while (selected.iid < 0);
+ this.container.selectItem(selected);
+ break;
+ }
+ case 27: { // Esc.
+ this.isShown = false;
+ break;
+ }
+ case 9: { // Tab.
+ this.isShown = false;
+ break;
+ }
+ case 13: { // Enter.
+ this.titleButton.enterPressed = true;
+ break;
+ }
+ };
}
};