Chromium Code Reviews| 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 Oobe network screen implementation. | 6 * @fileoverview Oobe network screen implementation. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 cr.define('oobe', function() { | 9 cr.define('oobe', function() { |
| 10 /** | 10 /** |
| 11 * Creates a new DropDown div. | 11 * Creates a new DropDown div. |
| 12 * @constructor | 12 * @constructor |
| 13 * @extends {HTMLDivElement} | 13 * @extends {HTMLDivElement} |
| 14 */ | 14 */ |
| 15 var DropDown = cr.ui.define('div'); | 15 var DropDown = cr.ui.define('div'); |
| 16 | 16 |
| 17 DropDown.ITEM_DIVIDER_ID = -2; | 17 DropDown.ITEM_DIVIDER_ID = -2; |
| 18 | 18 |
| 19 DropDown.prototype = { | 19 DropDown.prototype = { |
| 20 __proto__: HTMLDivElement.prototype, | 20 __proto__: HTMLDivElement.prototype, |
| 21 | 21 |
| 22 /** @inheritDoc */ | 22 /** @inheritDoc */ |
| 23 decorate: function() { | 23 decorate: function() { |
| 24 // Create overlay to catch outside clicks. | |
| 25 var overlay = this.ownerDocument.createElement('div'); | |
| 26 overlay.classList.add('dropdown-overlay'); | |
| 27 overlay.addEventListener('click', function() { | |
| 28 this.parentNode.childNodes[1].focus(); | |
|
xiyuan
2011/08/08 20:07:43
Let's add two getters for title buttone and dropdo
altimofeev
2011/08/09 10:32:30
Done.
| |
| 29 this.parentNode.isShown = false; | |
| 30 }); | |
| 31 this.appendChild(overlay); | |
| 32 | |
| 24 this.appendChild(this.createTitle_()); | 33 this.appendChild(this.createTitle_()); |
| 25 | 34 |
| 26 // Create menu items container. | 35 // Create menu items container. |
| 27 var container = this.ownerDocument.createElement('div') | 36 var container = this.ownerDocument.createElement('div'); |
|
xiyuan
2011/08/08 20:07:43
recommend to wrap the container into a class.
altimofeev
2011/08/09 10:32:30
Done.
| |
| 28 container.classList.add('dropdown-container'); | 37 container.classList.add('dropdown-container'); |
| 38 | |
| 39 // Selected item in the menu list. | |
| 40 container.selectedItem = null; | |
| 41 | |
| 42 container.selectItem = function (selectedItem) { | |
| 43 if (container.selectedItem) | |
| 44 container.selectedItem.classList.remove('hover'); | |
| 45 selectedItem.classList.add('hover'); | |
| 46 container.selectedItem = selectedItem; | |
| 47 }; | |
| 48 | |
| 29 this.appendChild(container); | 49 this.appendChild(container); |
| 30 this.isShown = false; | 50 this.isShown = false; |
| 51 | |
| 52 // Handle pressing of the up/down keys. | |
| 53 this.addEventListener('keydown', function (e) { | |
|
xiyuan
2011/08/08 20:07:43
Could we put the logic into its own function since
altimofeev
2011/08/09 10:32:30
Done.
| |
| 54 if (!this.isShown) | |
| 55 return; | |
| 56 var container = this.lastChild; | |
| 57 var selected = container.selectedItem; | |
| 58 switch(e.keyCode) { | |
|
xiyuan
2011/08/08 20:07:43
do we need to handle "enter" key as well?
altimofeev
2011/08/09 10:32:30
tl;dr. Done.
Enter is handled by JS directly, sin
| |
| 59 case 38: { // Key up. | |
| 60 do { | |
| 61 selected = selected.previousSibling; | |
| 62 if (!selected) | |
| 63 selected = container.lastChild; | |
| 64 } while (selected.iid < 0); | |
| 65 container.selectItem(selected); | |
| 66 break; | |
| 67 } | |
| 68 case 40: { // Key down. | |
| 69 do { | |
| 70 selected = selected.nextSibling; | |
| 71 if (!selected) | |
| 72 selected = container.firstItem; | |
| 73 } while (selected.iid < 0); | |
| 74 container.selectItem(selected); | |
| 75 break; | |
| 76 } | |
| 77 case 27: { // Esc. | |
| 78 this.isShown = false; | |
| 79 break; | |
| 80 } | |
| 81 case 9: { // Tab. | |
| 82 this.isShown = false; | |
| 83 break; | |
| 84 } | |
| 85 } | |
| 86 }); | |
| 31 }, | 87 }, |
| 32 | 88 |
| 33 /** | 89 /** |
| 34 * Returns true if dropdown menu is shown. | 90 * Returns true if dropdown menu is shown. |
| 35 * @type {bool} Whether menu element is shown. | 91 * @type {bool} Whether menu element is shown. |
| 36 */ | 92 */ |
| 37 get isShown() { | 93 get isShown() { |
| 38 return !this.lastElementChild.hidden; | 94 return !this.lastElementChild.hidden; |
| 39 }, | 95 }, |
| 40 | 96 |
| 41 /** | 97 /** |
| 42 * Sets dropdown menu visibility. | 98 * Sets dropdown menu visibility. |
| 43 * @param {bool} show New visibility state for dropdown menu. | 99 * @param {bool} show New visibility state for dropdown menu. |
| 44 */ | 100 */ |
| 45 set isShown(show) { | 101 set isShown(show) { |
| 102 if (show) { | |
| 103 this.lastElementChild.selectItem(this.lastElementChild.firstItem); | |
| 104 } | |
|
xiyuan
2011/08/08 20:07:43
nit: no need for enclosing {} for one line branch.
altimofeev
2011/08/09 10:32:30
Done.
| |
| 46 this.lastElementChild.hidden = !show; | 105 this.lastElementChild.hidden = !show; |
| 106 this.firstElementChild.hidden = !show; | |
| 47 }, | 107 }, |
| 48 | 108 |
| 49 /** | 109 /** |
| 50 * Sets title and icon. | 110 * Sets title and icon. |
| 51 * @param {string} title Text on dropdown. | 111 * @param {string} title Text on dropdown. |
| 52 * @param {string} icon Icon in dataURL format. | 112 * @param {string} icon Icon in dataURL format. |
| 53 */ | 113 */ |
| 54 setTitle: function(title, icon) { | 114 setTitle: function(title, icon) { |
| 55 // TODO(nkostylev): Icon support for dropdown title. | 115 // TODO(nkostylev): Icon support for dropdown title. |
| 56 this.firstElementChild.textContent = title; | 116 this.childNodes[1].textContent = title; |
| 57 }, | 117 }, |
| 58 | 118 |
| 59 /** | 119 /** |
| 60 * Sets dropdown items. | 120 * Sets dropdown items. |
| 61 * @param {Array} items Dropdown items array. | 121 * @param {Array} items Dropdown items array. |
| 62 */ | 122 */ |
| 63 setItems: function(items) { | 123 setItems: function(items) { |
| 64 var container = this.lastElementChild; | 124 var container = this.lastElementChild; |
| 65 container.innerHTML = ''; | 125 container.innerHTML = ''; |
| 126 // First item in the menu list. | |
| 127 container.firstItem = null; | |
|
xiyuan
2011/08/08 20:07:43
clear container.selectedItem as well?
altimofeev
2011/08/09 10:32:30
Good point, this is useful for the case, when the
| |
| 66 for (var i = 0; i < items.length; ++i) { | 128 for (var i = 0; i < items.length; ++i) { |
| 67 var item = items[i]; | 129 var item = items[i]; |
| 68 if ('sub' in item) { | 130 if ('sub' in item) { |
| 69 // Workaround for submenus, add items on top level. | 131 // Workaround for submenus, add items on top level. |
| 70 // TODO(altimofeev): support submenus. | 132 // TODO(altimofeev): support submenus. |
| 71 for (var j = 0; j < item.sub.length; ++j) | 133 for (var j = 0; j < item.sub.length; ++j) |
| 72 this.createItem_(container, item.sub[j]); | 134 this.createItem_(container, item.sub[j]); |
| 73 continue; | 135 continue; |
| 74 } | 136 } |
| 75 this.createItem_(container, item); | 137 this.createItem_(container, item); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 wrapperDiv.classList.add('dropdown-item-container'); | 175 wrapperDiv.classList.add('dropdown-item-container'); |
| 114 var imageDiv = this.ownerDocument.createElement('div'); | 176 var imageDiv = this.ownerDocument.createElement('div'); |
| 115 imageDiv.classList.add('dropdown-image'); | 177 imageDiv.classList.add('dropdown-image'); |
| 116 imageDiv.appendChild(image); | 178 imageDiv.appendChild(image); |
| 117 wrapperDiv.appendChild(imageDiv); | 179 wrapperDiv.appendChild(imageDiv); |
| 118 wrapperDiv.appendChild(itemElement); | 180 wrapperDiv.appendChild(itemElement); |
| 119 wrapperDiv.addEventListener('click', function f(e) { | 181 wrapperDiv.addEventListener('click', function f(e) { |
| 120 var item = this.lastElementChild; | 182 var item = this.lastElementChild; |
| 121 if (item.iid < -1 || item.classList.contains('disabled-item')) | 183 if (item.iid < -1 || item.classList.contains('disabled-item')) |
| 122 return; | 184 return; |
| 123 item.controller.isShown = !item.controller.isShown; | 185 item.controller.isShown = false; |
| 124 if (item.iid >= 0) | 186 if (item.iid >= 0) |
| 125 chrome.send('networkItemChosen', [item.iid]); | 187 chrome.send('networkItemChosen', [item.iid]); |
| 126 }); | 188 }); |
| 189 wrapperDiv.addEventListener('mouseover', function f(e) { | |
| 190 this.parentNode.selectItem(this); | |
| 191 }); | |
| 127 itemElement = wrapperDiv; | 192 itemElement = wrapperDiv; |
| 128 } | 193 } |
| 129 container.appendChild(itemElement); | 194 container.appendChild(itemElement); |
| 195 if (!container.firstItem && item.id >= 0) { | |
| 196 container.firstItem = itemElement; | |
| 197 } | |
| 130 }, | 198 }, |
| 131 | 199 |
| 132 /** | 200 /** |
| 133 * Creates dropdown title element. | 201 * Creates dropdown title element. |
| 134 * @type {HTMLElement} | 202 * @type {HTMLElement} |
| 135 * @private | 203 * @private |
| 136 */ | 204 */ |
| 137 createTitle_: function() { | 205 createTitle_: function() { |
| 138 var el = this.ownerDocument.createElement('button'); | 206 var el = this.ownerDocument.createElement('button'); |
| 139 el.classList.add('dropdown-title'); | 207 el.classList.add('dropdown-title'); |
| 208 el.id = 'dropdown-title-button'; | |
| 140 el.iid = -1; | 209 el.iid = -1; |
| 141 el.controller = this; | 210 el.controller = this; |
| 211 el.mouseDown = false; | |
| 212 | |
| 213 // Only occurs with mouse click. | |
| 214 el.addEventListener('mousedown', function f(e) { | |
| 215 this.controller.isShown = !this.controller.isShown; | |
| 216 this.mouseDown = true; | |
| 217 // TODO(altimofeev): avoid this hack. | |
| 218 setTimeout("$('dropdown-title-button').focus();", 1); | |
| 219 }); | |
| 220 | |
| 142 el.addEventListener('click', function f(e) { | 221 el.addEventListener('click', function f(e) { |
| 222 if (this.mouseDown) { | |
| 223 this.mouseDown = false; | |
| 224 return; | |
| 225 } | |
| 143 this.controller.isShown = !this.controller.isShown; | 226 this.controller.isShown = !this.controller.isShown; |
| 227 | |
| 228 if (!this.controller.isShown) { | |
| 229 var item = this.controller.lastChild.selectedItem.lastChild; | |
| 230 if (item.iid >= 0 && !item.classList.contains('disabled-item')) | |
| 231 chrome.send('networkItemChosen', [item.iid]); | |
| 232 } | |
| 144 }); | 233 }); |
| 145 return el; | 234 return el; |
| 146 } | 235 } |
| 147 }; | 236 }; |
| 148 | 237 |
| 149 /** | 238 /** |
| 150 * Creates a new oobe screen div. | 239 * Creates a new oobe screen div. |
| 151 * @constructor | 240 * @constructor |
| 152 * @extends {HTMLDivElement} | 241 * @extends {HTMLDivElement} |
| 153 */ | 242 */ |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 233 }; | 322 }; |
| 234 | 323 |
| 235 NetworkScreen.updateNetworkTitle = function(title, icon) { | 324 NetworkScreen.updateNetworkTitle = function(title, icon) { |
| 236 $('connect').updateNetworkTitle(title, icon); | 325 $('connect').updateNetworkTitle(title, icon); |
| 237 }; | 326 }; |
| 238 | 327 |
| 239 return { | 328 return { |
| 240 NetworkScreen: NetworkScreen | 329 NetworkScreen: NetworkScreen |
| 241 }; | 330 }; |
| 242 }); | 331 }); |
| OLD | NEW |