| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Network drop-down implementation. | 6 * @fileoverview Network drop-down implementation. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 cr.define('cr.ui', function() { | 9 cr.define('cr.ui', function() { |
| 10 /** | 10 /** |
| 11 * Creates a new container for the drop down menu items. | 11 * Creates a new container for the drop down menu items. |
| 12 * @constructor | 12 * @constructor |
| 13 * @extends {HTMLDivElement} | 13 * @extends {HTMLDivElement} |
| 14 */ | 14 */ |
| 15 var DropDownContainer = cr.ui.define('div'); | 15 var DropDownContainer = cr.ui.define('div'); |
| 16 | 16 |
| 17 DropDownContainer.prototype = { | 17 DropDownContainer.prototype = { |
| 18 __proto__: HTMLDivElement.prototype, | 18 __proto__: HTMLDivElement.prototype, |
| 19 | 19 |
| 20 /** @inheritDoc */ | 20 /** @inheritDoc */ |
| 21 decorate: function() { | 21 decorate: function() { |
| 22 this.classList.add('dropdown-container'); | 22 this.classList.add('dropdown-container'); |
| 23 // Selected item in the menu list. | 23 // Selected item in the menu list. |
| 24 this.selectedItem = null; | 24 this.selectedItem = null; |
| 25 // First item which could be selected. | 25 // First item which could be selected. |
| 26 this.firstItem = null; | 26 this.firstItem = null; |
| 27 this.setAttribute('role', 'menu'); |
| 27 // Whether scroll has just happened. | 28 // Whether scroll has just happened. |
| 28 this.scrollJustHappened = false; | 29 this.scrollJustHappened = false; |
| 29 }, | 30 }, |
| 30 | 31 |
| 31 /** | 32 /** |
| 32 * Gets scroll action to be done for the item. | 33 * Gets scroll action to be done for the item. |
| 33 * @param {!Object} item Menu item. | 34 * @param {!Object} item Menu item. |
| 34 * @return {integer} -1 for scroll up; 0 for no action; 1 for scroll down. | 35 * @return {integer} -1 for scroll up; 0 for no action; 1 for scroll down. |
| 35 */ | 36 */ |
| 36 scrollAction: function(item) { | 37 scrollAction: function(item) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 50 */ | 51 */ |
| 51 selectItem: function(selectedItem, mouseOver) { | 52 selectItem: function(selectedItem, mouseOver) { |
| 52 if (mouseOver && this.scrollJustHappened) { | 53 if (mouseOver && this.scrollJustHappened) { |
| 53 this.scrollJustHappened = false; | 54 this.scrollJustHappened = false; |
| 54 return; | 55 return; |
| 55 } | 56 } |
| 56 if (this.selectedItem) | 57 if (this.selectedItem) |
| 57 this.selectedItem.classList.remove('hover'); | 58 this.selectedItem.classList.remove('hover'); |
| 58 selectedItem.classList.add('hover'); | 59 selectedItem.classList.add('hover'); |
| 59 this.selectedItem = selectedItem; | 60 this.selectedItem = selectedItem; |
| 61 if (!this.hidden) { |
| 62 this.previousSibling.setAttribute( |
| 63 'aria-activedescendant', selectedItem.id); |
| 64 } |
| 60 var action = this.scrollAction(selectedItem); | 65 var action = this.scrollAction(selectedItem); |
| 61 if (action != 0) { | 66 if (action != 0) { |
| 62 selectedItem.scrollIntoView(action < 0); | 67 selectedItem.scrollIntoView(action < 0); |
| 63 this.scrollJustHappened = true; | 68 this.scrollJustHappened = true; |
| 64 } | 69 } |
| 65 } | 70 } |
| 66 }; | 71 }; |
| 67 | 72 |
| 68 /** | 73 /** |
| 69 * Creates a new DropDown div. | 74 * Creates a new DropDown div. |
| 70 * @constructor | 75 * @constructor |
| 71 * @extends {HTMLDivElement} | 76 * @extends {HTMLDivElement} |
| 72 */ | 77 */ |
| 73 var DropDown = cr.ui.define('div'); | 78 var DropDown = cr.ui.define('div'); |
| 74 | 79 |
| 75 DropDown.ITEM_DIVIDER_ID = -2; | 80 DropDown.ITEM_DIVIDER_ID = -2; |
| 76 | 81 |
| 77 DropDown.prototype = { | 82 DropDown.prototype = { |
| 78 __proto__: HTMLDivElement.prototype, | 83 __proto__: HTMLDivElement.prototype, |
| 79 | 84 |
| 80 /** @inheritDoc */ | 85 /** @inheritDoc */ |
| 81 decorate: function() { | 86 decorate: function() { |
| 82 this.appendChild(this.createOverlay_()); | 87 this.appendChild(this.createOverlay_()); |
| 83 this.appendChild(this.createTitle_()); | 88 this.appendChild(this.title_ = this.createTitle_()); |
| 84 this.appendChild(new DropDownContainer()); | 89 this.appendChild(new DropDownContainer()); |
| 85 | 90 |
| 86 this.isShown = false; | 91 this.isShown = false; |
| 87 this.addEventListener('keydown', this.keyDownHandler_); | 92 this.addEventListener('keydown', this.keyDownHandler_); |
| 93 |
| 94 this.title_.id = this.id + '-dropdown'; |
| 95 this.title_.setAttribute('role', 'button'); |
| 96 this.title_.setAttribute('aria-haspopup', 'true'); |
| 88 }, | 97 }, |
| 89 | 98 |
| 90 /** | 99 /** |
| 91 * Returns true if dropdown menu is shown. | 100 * Returns true if dropdown menu is shown. |
| 92 * @type {bool} Whether menu element is shown. | 101 * @type {bool} Whether menu element is shown. |
| 93 */ | 102 */ |
| 94 get isShown() { | 103 get isShown() { |
| 95 return !this.container.hidden; | 104 return !this.container.hidden; |
| 96 }, | 105 }, |
| 97 | 106 |
| 98 /** | 107 /** |
| 99 * Sets dropdown menu visibility. | 108 * Sets dropdown menu visibility. |
| 100 * @param {bool} show New visibility state for dropdown menu. | 109 * @param {bool} show New visibility state for dropdown menu. |
| 101 */ | 110 */ |
| 102 set isShown(show) { | 111 set isShown(show) { |
| 103 this.firstElementChild.hidden = !show; | 112 this.firstElementChild.hidden = !show; |
| 104 this.container.hidden = !show; | 113 this.container.hidden = !show; |
| 105 if (show) | 114 if (show) { |
| 106 this.container.selectItem(this.container.firstItem, false); | 115 this.container.selectItem(this.container.firstItem, false); |
| 116 this.title_.setAttribute('aria-pressed', 'true'); |
| 117 } else { |
| 118 this.title_.setAttribute('aria-pressed', 'false'); |
| 119 this.title_.removeAttribute('aria-activedescendant'); |
| 120 } |
| 107 }, | 121 }, |
| 108 | 122 |
| 109 /** | 123 /** |
| 110 * Returns title button. | 124 * Returns title button. |
| 111 */ | 125 */ |
| 112 get titleButton() { | 126 get titleButton() { |
| 113 return this.children[1]; | 127 return this.children[1]; |
| 114 }, | 128 }, |
| 115 | 129 |
| 116 /** | 130 /** |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 if (item.id == DropDown.ITEM_DIVIDER_ID) { | 184 if (item.id == DropDown.ITEM_DIVIDER_ID) { |
| 171 className = 'dropdown-divider'; | 185 className = 'dropdown-divider'; |
| 172 itemContentElement = this.ownerDocument.createElement('hr'); | 186 itemContentElement = this.ownerDocument.createElement('hr'); |
| 173 } else { | 187 } else { |
| 174 var span = this.ownerDocument.createElement('span'); | 188 var span = this.ownerDocument.createElement('span'); |
| 175 itemContentElement = span; | 189 itemContentElement = span; |
| 176 span.textContent = item.label; | 190 span.textContent = item.label; |
| 177 if ('bold' in item && item.bold) | 191 if ('bold' in item && item.bold) |
| 178 span.classList.add('bold'); | 192 span.classList.add('bold'); |
| 179 var image = this.ownerDocument.createElement('img'); | 193 var image = this.ownerDocument.createElement('img'); |
| 194 image.alt = ''; |
| 180 if (item.icon) | 195 if (item.icon) |
| 181 image.src = item.icon; | 196 image.src = item.icon; |
| 182 } | 197 } |
| 183 | 198 |
| 184 var itemElement = this.ownerDocument.createElement('div'); | 199 var itemElement = this.ownerDocument.createElement('div'); |
| 185 itemElement.classList.add(className); | 200 itemElement.classList.add(className); |
| 186 itemElement.appendChild(itemContentElement); | 201 itemElement.appendChild(itemContentElement); |
| 187 itemElement.iid = item.id; | 202 itemElement.iid = item.id; |
| 188 itemElement.controller = this; | 203 itemElement.controller = this; |
| 189 var enabled = 'enabled' in item && item.enabled; | 204 var enabled = 'enabled' in item && item.enabled; |
| 190 if (!enabled) | 205 if (!enabled) |
| 191 itemElement.classList.add('disabled-item'); | 206 itemElement.classList.add('disabled-item'); |
| 192 | 207 |
| 193 if (item.id > 0) { | 208 if (item.id > 0) { |
| 194 var wrapperDiv = this.ownerDocument.createElement('div'); | 209 var wrapperDiv = this.ownerDocument.createElement('div'); |
| 210 wrapperDiv.setAttribute('role', 'menuitem'); |
| 211 wrapperDiv.id = this.id + item.id; |
| 212 if (!enabled) |
| 213 wrapperDiv.setAttribute('aria-disabled', 'true'); |
| 195 wrapperDiv.classList.add('dropdown-item-container'); | 214 wrapperDiv.classList.add('dropdown-item-container'); |
| 196 var imageDiv = this.ownerDocument.createElement('div'); | 215 var imageDiv = this.ownerDocument.createElement('div'); |
| 197 imageDiv.classList.add('dropdown-image'); | 216 imageDiv.classList.add('dropdown-image'); |
| 198 imageDiv.appendChild(image); | 217 imageDiv.appendChild(image); |
| 199 wrapperDiv.appendChild(imageDiv); | 218 wrapperDiv.appendChild(imageDiv); |
| 200 wrapperDiv.appendChild(itemElement); | 219 wrapperDiv.appendChild(itemElement); |
| 201 wrapperDiv.addEventListener('click', function f(e) { | 220 wrapperDiv.addEventListener('click', function f(e) { |
| 202 var item = this.lastElementChild; | 221 var item = this.lastElementChild; |
| 203 if (item.iid < -1 || item.classList.contains('disabled-item')) | 222 if (item.iid < -1 || item.classList.contains('disabled-item')) |
| 204 return; | 223 return; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 233 return overlay; | 252 return overlay; |
| 234 }, | 253 }, |
| 235 | 254 |
| 236 /** | 255 /** |
| 237 * Creates dropdown title element. | 256 * Creates dropdown title element. |
| 238 * @type {HTMLElement} | 257 * @type {HTMLElement} |
| 239 * @private | 258 * @private |
| 240 */ | 259 */ |
| 241 createTitle_: function() { | 260 createTitle_: function() { |
| 242 var image = this.ownerDocument.createElement('img'); | 261 var image = this.ownerDocument.createElement('img'); |
| 262 image.alt = ''; |
| 243 var text = this.ownerDocument.createElement('div'); | 263 var text = this.ownerDocument.createElement('div'); |
| 244 | 264 |
| 245 var el = this.ownerDocument.createElement('div'); | 265 var el = this.ownerDocument.createElement('div'); |
| 246 el.appendChild(image); | 266 el.appendChild(image); |
| 247 el.appendChild(text); | 267 el.appendChild(text); |
| 248 | 268 |
| 249 el.tabIndex = 0; | 269 el.tabIndex = 0; |
| 250 el.classList.add('dropdown-title'); | 270 el.classList.add('dropdown-title'); |
| 251 el.iid = -1; | 271 el.iid = -1; |
| 252 el.controller = this; | 272 el.controller = this; |
| 253 el.inFocus = false; | 273 el.inFocus = false; |
| 254 el.opening = false; | 274 el.opening = false; |
| 255 | 275 |
| 256 el.addEventListener('click', function f(e) { | 276 el.addEventListener('click', function f(e) { |
| 257 this.controller.isShown = !this.controller.isShown; | 277 this.controller.isShown = !this.controller.isShown; |
| 258 }); | 278 }); |
| 259 | 279 |
| 260 el.addEventListener('focus', function(e) { | 280 el.addEventListener('focus', function(e) { |
| 261 this.inFocus = true; | 281 this.inFocus = true; |
| 262 }); | 282 }); |
| 263 | 283 |
| 264 el.addEventListener('blur', function(e) { | 284 el.addEventListener('blur', function(e) { |
| 265 this.inFocus = false; | 285 this.inFocus = false; |
| 266 }); | 286 }); |
| 267 | 287 |
| 268 el.addEventListener('keydown', function f(e) { | 288 el.addEventListener('keydown', function f(e) { |
| 269 if (this.inFocus && !this.controller.isShown && e.keyCode == 13) { | 289 if (this.inFocus && !this.controller.isShown && |
| 270 // Enter has been pressed. | 290 (e.keyCode == 13 || e.keyCode == 32)) { |
| 291 // Enter or space has been pressed. |
| 271 this.opening = true; | 292 this.opening = true; |
| 272 this.controller.isShown = true; | 293 this.controller.isShown = true; |
| 273 } | 294 } |
| 274 }); | 295 }); |
| 275 return el; | 296 return el; |
| 276 }, | 297 }, |
| 277 | 298 |
| 278 /** | 299 /** |
| 279 * Handles keydown event from the keyboard. | 300 * Handles keydown event from the keyboard. |
| 280 * @private | 301 * @private |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 * Refreshes network drop-down. Should be called on language change. | 392 * Refreshes network drop-down. Should be called on language change. |
| 372 */ | 393 */ |
| 373 DropDown.refresh = function() { | 394 DropDown.refresh = function() { |
| 374 chrome.send('networkDropdownRefresh', []); | 395 chrome.send('networkDropdownRefresh', []); |
| 375 }; | 396 }; |
| 376 | 397 |
| 377 return { | 398 return { |
| 378 DropDown: DropDown | 399 DropDown: DropDown |
| 379 }; | 400 }; |
| 380 }); | 401 }); |
| OLD | NEW |