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 |