OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 cr.define('options', function() { | 5 cr.define('options', function() { |
6 ///////////////////////////////////////////////////////////////////////////// | 6 ///////////////////////////////////////////////////////////////////////////// |
7 // OptionsPage class: | 7 // OptionsPage class: |
8 | 8 |
9 /** | 9 /** |
10 * Base class for options page. | 10 * Base class for options page. |
11 * @constructor | 11 * @constructor |
12 * @param {string} name Options page name, also defines id of the div element | 12 * @param {string} name Options page name, also defines id of the div element |
13 * containing the options view and the name of options page navigation bar | 13 * containing the options view and the name of options page navigation bar |
14 * item as name+'PageNav'. | 14 * item as name+'PageNav'. |
15 * @param {string} title Options page title, used for navigation bar | 15 * @param {string} title Options page title, used for navigation bar |
16 * @extends {EventTarget} | 16 * @extends {EventTarget} |
17 */ | 17 */ |
18 function OptionsPage(name, title, pageDivName) { | 18 function OptionsPage(name, title, pageDivName) { |
19 this.name = name; | 19 this.name = name; |
20 this.title = title; | 20 this.title = title; |
21 this.pageDivName = pageDivName; | 21 this.pageDivName = pageDivName; |
22 this.pageDiv = $(this.pageDivName); | 22 this.pageDiv = $(this.pageDivName); |
23 this.tab = null; | 23 this.tab = null; |
24 this.managed = false; | 24 this.managed = false; |
25 } | 25 } |
26 | 26 |
27 OptionsPage.registeredPages_ = {}; | 27 /** |
28 * Main level option pages. | |
29 * @protected | |
30 */ | |
31 OptionsPage.registeredPages = {}; | |
28 | 32 |
29 /** | 33 /** |
30 * Pages which are nested under a main page. | 34 * Pages which are nested under a main level page. |
35 * @protected | |
31 */ | 36 */ |
32 OptionsPage.registeredSubPages_ = {}; | 37 OptionsPage.registeredSubPages = {}; |
33 | 38 |
34 /** | 39 /** |
35 * Pages which are meant to behave like modal dialogs. | 40 * Pages which are meant to behave like modal dialogs. |
41 * @protected | |
36 */ | 42 */ |
37 OptionsPage.registeredOverlayPages_ = {}; | 43 OptionsPage.registeredOverlayPages = {}; |
38 | 44 |
39 /** | 45 /** |
40 * Whether or not |initialize| has been called. | 46 * Whether or not |initialize| has been called. |
47 * @private | |
41 */ | 48 */ |
42 OptionsPage.initialized_ = false; | 49 OptionsPage.initialized_ = false; |
43 | 50 |
44 /** | 51 /** |
45 * Shows a registered page. This handles both top-level pages and sub-pages. | 52 * Shows a registered page. This handles both top-level pages and sub-pages. |
46 * @param {string} pageName Page name. | 53 * @param {string} pageName Page name. |
47 */ | 54 */ |
48 OptionsPage.showPageByName = function(pageName) { | 55 OptionsPage.showPageByName = function(pageName) { |
49 for (var name in OptionsPage.registeredPages_) { | 56 // Notify main pages that they will be shown or hidden. |
50 var page = OptionsPage.registeredPages_[name]; | 57 for (var name in this.registeredPages) { |
58 var page = this.registeredPages[name]; | |
59 if (name == pageName) { | |
60 if (page.willShowPage) | |
61 page.willShowPage(); | |
62 } else { | |
63 if (page.willHidePage) | |
64 page.willHidePage(); | |
65 } | |
66 } | |
67 | |
68 // Update the visibility attribute for main pages. | |
69 for (var name in this.registeredPages) { | |
70 var page = this.registeredPages[name]; | |
51 page.visible = name == pageName; | 71 page.visible = name == pageName; |
James Hawkins
2010/12/02 23:11:44
Can you just move this to the above for loop that
csilv
2010/12/02 23:40:21
No. The reason is that the 'willShowPage' and 'wi
James Hawkins
2010/12/03 00:02:09
Can you elucidate the problem? I'm not understand
| |
52 } | 72 } |
53 for (var name in OptionsPage.registeredSubPages_) { | 73 |
54 var pageInfo = OptionsPage.registeredSubPages_[name]; | 74 // Update the visibility attribute for sub-pages. |
75 for (var name in this.registeredSubPages) { | |
76 var pageInfo = this.registeredSubPages[name]; | |
55 var match = name == pageName; | 77 var match = name == pageName; |
56 if (match) | 78 if (match) |
57 pageInfo.parentPage.visible = true; | 79 pageInfo.parentPage.visible = true; |
58 pageInfo.page.visible = match; | 80 pageInfo.page.visible = match; |
59 } | 81 } |
82 | |
83 // Notify main pages that they were shown or hidden. | |
84 for (var name in this.registeredPages) { | |
85 var page = this.registeredPages[name]; | |
86 if (name == pageName) { | |
87 if (page.didShowPage) | |
James Hawkins
2010/12/02 23:11:44
Is there a way for a page to listen to class chang
csilv
2010/12/02 23:40:21
Yes, there is a mechanism for this in cr, but that
| |
88 page.didShowPage(); | |
89 } else { | |
90 if (page.didHidePage) | |
91 page.didHidePage(); | |
92 } | |
93 } | |
60 }; | 94 }; |
61 | 95 |
62 /** | 96 /** |
63 * Called on load. Dispatch the URL hash to the given page's handleHash | 97 * Called on load. Dispatch the URL hash to the given page's handleHash |
64 * function. | 98 * function. |
65 * @param {string} pageName The string name of the (registered) options page. | 99 * @param {string} pageName The string name of the (registered) options page. |
66 * @param {string} hash The value of the hash component of the URL. | 100 * @param {string} hash The value of the hash component of the URL. |
67 */ | 101 */ |
68 OptionsPage.handleHashForPage = function(pageName, hash) { | 102 OptionsPage.handleHashForPage = function(pageName, hash) { |
69 var page = OptionsPage.registeredPages_[pageName]; | 103 var page = this.registeredPages[pageName]; |
70 if (!page) { | 104 if (!page) { |
71 page = OptionsPage.registeredSubPages_[pageName].page; | 105 page = this.registeredSubPages[pageName].page; |
72 } | 106 } |
73 page.handleHash(hash); | 107 page.handleHash(hash); |
74 }; | 108 }; |
75 | 109 |
76 /** | 110 /** |
77 * Shows a registered Overlay page. | 111 * Shows a registered Overlay page. |
78 * @param {string} overlayName Page name. | 112 * @param {string} overlayName Page name. |
79 */ | 113 */ |
80 OptionsPage.showOverlay = function(overlayName) { | 114 OptionsPage.showOverlay = function(overlayName) { |
81 if (OptionsPage.registeredOverlayPages_[overlayName]) { | 115 if (this.registeredOverlayPages[overlayName]) { |
82 OptionsPage.registeredOverlayPages_[overlayName].visible = true; | 116 this.registeredOverlayPages[overlayName].visible = true; |
83 } | 117 } |
84 }; | 118 }; |
85 | 119 |
86 /** | 120 /** |
87 * Clears overlays (i.e. hide all overlays). | 121 * Clears overlays (i.e. hide all overlays). |
88 */ | 122 */ |
89 OptionsPage.clearOverlays = function() { | 123 OptionsPage.clearOverlays = function() { |
90 for (var name in OptionsPage.registeredOverlayPages_) { | 124 for (var name in this.registeredOverlayPages) { |
91 var page = OptionsPage.registeredOverlayPages_[name]; | 125 var page = this.registeredOverlayPages[name]; |
92 page.visible = false; | 126 page.visible = false; |
93 } | 127 } |
94 }; | 128 }; |
95 | 129 |
96 /** | 130 /** |
97 * Clears overlays if the key event is ESC. | 131 * Handle 'keydown' events. |
98 * @param {Event} e Key event. | 132 * @param {Event} e Key event. |
99 * @private | 133 * @private |
100 */ | 134 */ |
101 OptionsPage.clearOverlaysOnEsc_ = function(e) { | 135 OptionsPage.handleKeyDown_ = function(e) { |
James Hawkins
2010/12/02 23:11:44
s/handleKeyDown_/onKeyDown_/
csilv
2010/12/02 23:40:21
Done.
| |
102 if (e.keyCode == 27) { // Esc | 136 if (e.keyCode == 27) { // Esc |
103 OptionsPage.clearOverlays(); | 137 this.clearOverlays(); |
104 } | 138 } |
105 }; | 139 }; |
106 | 140 |
107 /** | 141 /** |
108 * Closes any currently-open subpage. | 142 * Closes any currently-open subpage. |
109 */ | 143 */ |
110 OptionsPage.closeSubPage = function() { | 144 OptionsPage.closeSubPage = function() { |
111 for (var name in OptionsPage.registeredSubPages_) { | 145 for (var name in this.registeredSubPages) { |
112 var pageInfo = OptionsPage.registeredSubPages_[name]; | 146 var pageInfo = this.registeredSubPages[name]; |
113 if (pageInfo.page.visible) { | 147 if (pageInfo.page.visible) { |
114 pageInfo.page.visible = false; | 148 pageInfo.page.visible = false; |
115 // Since the managed pref banner lives outside the overlay, and the | 149 // Since the managed pref banner lives outside the overlay, and the |
116 // parent is not changing visibility, update the banner explicitly. | 150 // parent is not changing visibility, update the banner explicitly. |
117 pageInfo.parentPage.updateManagedBannerVisibility(); | 151 pageInfo.parentPage.updateManagedBannerVisibility(); |
118 } | 152 } |
119 } | 153 } |
120 }; | 154 }; |
121 | 155 |
122 /** | 156 /** |
(...skipping 19 matching lines...) Expand all Loading... | |
142 tab.classList.add('active-tab'); | 176 tab.classList.add('active-tab'); |
143 $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); | 177 $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); |
144 this.activeNavTab = tab; | 178 this.activeNavTab = tab; |
145 }; | 179 }; |
146 | 180 |
147 /** | 181 /** |
148 * Registers new options page. | 182 * Registers new options page. |
149 * @param {OptionsPage} page Page to register. | 183 * @param {OptionsPage} page Page to register. |
150 */ | 184 */ |
151 OptionsPage.register = function(page) { | 185 OptionsPage.register = function(page) { |
152 OptionsPage.registeredPages_[page.name] = page; | 186 this.registeredPages[page.name] = page; |
153 // Create and add new page <li> element to navbar. | 187 // Create and add new page <li> element to navbar. |
154 var pageNav = document.createElement('li'); | 188 var pageNav = document.createElement('li'); |
155 pageNav.id = page.name + 'PageNav'; | 189 pageNav.id = page.name + 'PageNav'; |
156 pageNav.className = 'navbar-item'; | 190 pageNav.className = 'navbar-item'; |
157 pageNav.setAttribute('pageName', page.name); | 191 pageNav.setAttribute('pageName', page.name); |
158 pageNav.textContent = page.title; | 192 pageNav.textContent = page.title; |
159 pageNav.tabIndex = 0; | 193 pageNav.tabIndex = 0; |
160 pageNav.onclick = function(event) { | 194 pageNav.onclick = function(event) { |
161 OptionsPage.showPageByName(this.getAttribute('pageName')); | 195 OptionsPage.showPageByName(this.getAttribute('pageName')); |
162 }; | 196 }; |
163 pageNav.onkeypress = function(event) { | 197 pageNav.onkeypress = function(event) { |
164 // Enter or space | 198 // Enter or space |
165 if (event.keyCode == 13 || event.keyCode == 32) { | 199 if (event.keyCode == 13 || event.keyCode == 32) { |
166 OptionsPage.showPageByName(this.getAttribute('pageName')); | 200 OptionsPage.showPageByName(this.getAttribute('pageName')); |
167 } | 201 } |
168 }; | 202 }; |
169 var navbar = $('navbar'); | 203 var navbar = $('navbar'); |
170 navbar.appendChild(pageNav); | 204 navbar.appendChild(pageNav); |
171 page.tab = pageNav; | 205 page.tab = pageNav; |
172 page.initializePage(); | 206 page.initializePage(); |
173 }; | 207 }; |
174 | 208 |
175 /** | 209 /** |
176 * Registers a new Sub tab page. | 210 * Registers a new Sub tab page. |
177 * @param {OptionsPage} page Page to register. | 211 * @param {OptionsPage} page Page to register. |
178 */ | 212 */ |
179 OptionsPage.registerSubPage = function(subPage, parentPage) { | 213 OptionsPage.registerSubPage = function(subPage, parentPage) { |
180 OptionsPage.registeredSubPages_[subPage.name] = { | 214 this.registeredSubPages[subPage.name] = { |
181 page: subPage, parentPage: parentPage }; | 215 page: subPage, parentPage: parentPage }; |
182 subPage.tab = undefined; | 216 subPage.tab = undefined; |
183 subPage.isSubPageSheet = true; | 217 subPage.isSubPageSheet = true; |
184 subPage.initializePage(); | 218 subPage.initializePage(); |
185 }; | 219 }; |
186 | 220 |
187 /** | 221 /** |
188 * Registers a new Overlay page. | 222 * Registers a new Overlay page. |
189 * @param {OptionsPage} page Page to register, must be a class derived from | 223 * @param {OptionsPage} page Page to register, must be a class derived from |
190 * OptionsPage. | 224 * OptionsPage. |
191 */ | 225 */ |
192 OptionsPage.registerOverlay = function(page) { | 226 OptionsPage.registerOverlay = function(page) { |
193 OptionsPage.registeredOverlayPages_[page.name] = page; | 227 this.registeredOverlayPages[page.name] = page; |
194 page.tab = undefined; | 228 page.tab = undefined; |
195 page.isOverlay = true; | 229 page.isOverlay = true; |
196 page.initializePage(); | 230 page.initializePage(); |
197 }; | 231 }; |
198 | 232 |
199 /** | 233 /** |
200 * Callback for window.onpopstate. | 234 * Callback for window.onpopstate. |
201 * @param {Object} data State data pushed into history. | 235 * @param {Object} data State data pushed into history. |
202 */ | 236 */ |
203 OptionsPage.setState = function(data) { | 237 OptionsPage.setState = function(data) { |
204 if (data && data.pageName) { | 238 if (data && data.pageName) { |
205 OptionsPage.showPageByName(data.pageName); | 239 this.showPageByName(data.pageName); |
206 } | 240 } |
207 }; | 241 }; |
208 | 242 |
209 /** | 243 /** |
210 * Initializes the complete options page. This will cause | 244 * Initializes the complete options page. This will cause |
211 * all C++ handlers to be invoked to do final setup. | 245 * all C++ handlers to be invoked to do final setup. |
212 */ | 246 */ |
213 OptionsPage.initialize = function() { | 247 OptionsPage.initialize = function() { |
214 chrome.send('coreOptionsInitialize'); | 248 chrome.send('coreOptionsInitialize'); |
215 this.initialized_ = true; | 249 this.initialized_ = true; |
216 | 250 |
217 // Set up the overlay sheet. Clicks on the visible part of the parent page | 251 // Set up the overlay sheet. Clicks on the visible part of the parent page |
218 // should close the overlay, not fall through to the parent page. | 252 // should close the overlay, not fall through to the parent page. |
219 $('subpage-sheet-container').onclick = function(event) { | 253 $('subpage-sheet-container').onclick = function(event) { |
220 if (!$('subpage-sheet').contains(event.target)) | 254 if (!$('subpage-sheet').contains(event.target)) |
221 OptionsPage.closeSubPage(); | 255 this.closeSubPage(); |
222 event.stopPropagation(); | 256 event.stopPropagation(); |
223 } | 257 } |
224 }; | 258 }; |
225 | 259 |
226 /** | 260 /** |
227 * Re-initializes the C++ handlers if necessary. This is called if the | 261 * Re-initializes the C++ handlers if necessary. This is called if the |
228 * handlers are torn down and recreated but the DOM may not have been (in | 262 * handlers are torn down and recreated but the DOM may not have been (in |
229 * which case |initialize| won't be called again). If |initialize| hasn't been | 263 * which case |initialize| won't be called again). If |initialize| hasn't been |
230 * called, this does nothing (since it will be later, once the DOM has | 264 * called, this does nothing (since it will be later, once the DOM has |
231 * finished loading). | 265 * finished loading). |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 * Sets page visibility. | 311 * Sets page visibility. |
278 */ | 312 */ |
279 set visible(visible) { | 313 set visible(visible) { |
280 if ((this.visible && visible) || (!this.visible && !visible)) | 314 if ((this.visible && visible) || (!this.visible && !visible)) |
281 return; | 315 return; |
282 | 316 |
283 if (visible) { | 317 if (visible) { |
284 this.pageDiv.classList.remove('hidden'); | 318 this.pageDiv.classList.remove('hidden'); |
285 if (this.isOverlay) { | 319 if (this.isOverlay) { |
286 $('overlay').classList.remove('hidden'); | 320 $('overlay').classList.remove('hidden'); |
287 document.addEventListener('keydown', | 321 document.addEventListener('keydown', OptionsPage.handleKeyDown_); |
288 OptionsPage.clearOverlaysOnEsc_); | |
289 } else { | 322 } else { |
290 if (this.isSubPageSheet) | 323 if (this.isSubPageSheet) |
291 $('subpage-sheet-container').classList.remove('hidden'); | 324 $('subpage-sheet-container').classList.remove('hidden'); |
292 | 325 |
293 this.updateManagedBannerVisibility(); | 326 this.updateManagedBannerVisibility(); |
294 | 327 |
295 // Recent webkit change no longer allows url change from "chrome://". | 328 // Recent webkit change no longer allows url change from "chrome://". |
296 window.history.pushState({pageName: this.name}, this.title); | 329 window.history.pushState({pageName: this.name}, this.title); |
297 } | 330 } |
298 if (this.tab) { | 331 if (this.tab) { |
299 this.tab.classList.add('navbar-item-selected'); | 332 this.tab.classList.add('navbar-item-selected'); |
300 } | 333 } |
301 } else { | 334 } else { |
302 this.pageDiv.classList.add('hidden'); | 335 this.pageDiv.classList.add('hidden'); |
303 if (this.isOverlay) { | 336 if (this.isOverlay) { |
304 $('overlay').classList.add('hidden'); | 337 $('overlay').classList.add('hidden'); |
305 document.removeEventListener('keydown', | 338 document.removeEventListener('keydown', OptionsPage.handleKeyDown_); |
306 OptionsPage.clearOverlaysOnEsc_); | |
307 } else if (this.isSubPageSheet) { | 339 } else if (this.isSubPageSheet) { |
308 $('subpage-sheet-container').classList.add('hidden'); | 340 $('subpage-sheet-container').classList.add('hidden'); |
309 } | 341 } |
310 if (this.tab) { | 342 if (this.tab) { |
311 this.tab.classList.remove('navbar-item-selected'); | 343 this.tab.classList.remove('navbar-item-selected'); |
312 } | 344 } |
313 } | 345 } |
314 | 346 |
315 cr.dispatchPropertyChange(this, 'visible', visible, !visible); | 347 cr.dispatchPropertyChange(this, 'visible', visible, !visible); |
316 }, | 348 }, |
317 | 349 |
318 /** | 350 /** |
319 * Handles a hash value in the URL (such as bar in | 351 * Handles a hash value in the URL (such as bar in |
320 * chrome://options/foo#bar). Called on page load. By default, this shows | 352 * chrome://options/foo#bar). Called on page load. By default, this shows |
321 * an overlay that matches the hash name, but can be overriden by individual | 353 * an overlay that matches the hash name, but can be overriden by individual |
322 * OptionsPage subclasses to get other behavior. | 354 * OptionsPage subclasses to get other behavior. |
323 * @param {string} hash The hash value. | 355 * @param {string} hash The hash value. |
324 */ | 356 */ |
325 handleHash: function(hash) { | 357 handleHash: function(hash) { |
326 OptionsPage.showOverlay(hash); | 358 OptionsPage.showOverlay(hash); |
327 }, | 359 }, |
328 }; | 360 }; |
329 | 361 |
330 // Export | 362 // Export |
331 return { | 363 return { |
332 OptionsPage: OptionsPage | 364 OptionsPage: OptionsPage |
333 }; | 365 }; |
334 | 366 |
335 }); | 367 }); |
OLD | NEW |