| 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 if they will be hidden. |
| 50 var page = OptionsPage.registeredPages_[name]; | 57 for (var name in this.registeredPages) { |
| 58 var page = this.registeredPages[name]; |
| 59 if (name != pageName && page.willHidePage) |
| 60 page.willHidePage(); |
| 61 } |
| 62 |
| 63 // Update the visibility attribute for main pages. |
| 64 for (var name in this.registeredPages) { |
| 65 var page = this.registeredPages[name]; |
| 51 page.visible = name == pageName; | 66 page.visible = name == pageName; |
| 52 } | 67 } |
| 53 for (var name in OptionsPage.registeredSubPages_) { | 68 |
| 54 var pageInfo = OptionsPage.registeredSubPages_[name]; | 69 // Update the visibility attribute for sub-pages. |
| 70 for (var name in this.registeredSubPages) { |
| 71 var pageInfo = this.registeredSubPages[name]; |
| 55 var match = name == pageName; | 72 var match = name == pageName; |
| 56 if (match) | 73 if (match) |
| 57 pageInfo.parentPage.visible = true; | 74 pageInfo.parentPage.visible = true; |
| 58 pageInfo.page.visible = match; | 75 pageInfo.page.visible = match; |
| 59 } | 76 } |
| 77 |
| 78 // Notify main pages if they were shown. |
| 79 for (var name in this.registeredPages) { |
| 80 var page = this.registeredPages[name]; |
| 81 if (name == pageName && page.didShowPage) |
| 82 page.didShowPage(); |
| 83 } |
| 60 }; | 84 }; |
| 61 | 85 |
| 62 /** | 86 /** |
| 63 * Called on load. Dispatch the URL hash to the given page's handleHash | 87 * Called on load. Dispatch the URL hash to the given page's handleHash |
| 64 * function. | 88 * function. |
| 65 * @param {string} pageName The string name of the (registered) options page. | 89 * @param {string} pageName The string name of the (registered) options page. |
| 66 * @param {string} hash The value of the hash component of the URL. | 90 * @param {string} hash The value of the hash component of the URL. |
| 67 */ | 91 */ |
| 68 OptionsPage.handleHashForPage = function(pageName, hash) { | 92 OptionsPage.handleHashForPage = function(pageName, hash) { |
| 69 var page = OptionsPage.registeredPages_[pageName]; | 93 var page = this.registeredPages[pageName]; |
| 70 if (!page) { | 94 if (!page) { |
| 71 page = OptionsPage.registeredSubPages_[pageName].page; | 95 page = this.registeredSubPages[pageName].page; |
| 72 } | 96 } |
| 73 page.handleHash(hash); | 97 page.handleHash(hash); |
| 74 }; | 98 }; |
| 75 | 99 |
| 76 /** | 100 /** |
| 77 * Shows a registered Overlay page. | 101 * Shows a registered Overlay page. |
| 78 * @param {string} overlayName Page name. | 102 * @param {string} overlayName Page name. |
| 79 */ | 103 */ |
| 80 OptionsPage.showOverlay = function(overlayName) { | 104 OptionsPage.showOverlay = function(overlayName) { |
| 81 if (OptionsPage.registeredOverlayPages_[overlayName]) { | 105 if (this.registeredOverlayPages[overlayName]) { |
| 82 OptionsPage.registeredOverlayPages_[overlayName].visible = true; | 106 this.registeredOverlayPages[overlayName].visible = true; |
| 83 } | 107 } |
| 84 }; | 108 }; |
| 85 | 109 |
| 86 /** | 110 /** |
| 87 * Clears overlays (i.e. hide all overlays). | 111 * Clears overlays (i.e. hide all overlays). |
| 88 */ | 112 */ |
| 89 OptionsPage.clearOverlays = function() { | 113 OptionsPage.clearOverlays = function() { |
| 90 for (var name in OptionsPage.registeredOverlayPages_) { | 114 for (var name in this.registeredOverlayPages) { |
| 91 var page = OptionsPage.registeredOverlayPages_[name]; | 115 var page = this.registeredOverlayPages[name]; |
| 92 page.visible = false; | 116 page.visible = false; |
| 93 } | 117 } |
| 94 }; | 118 }; |
| 95 | 119 |
| 96 /** | 120 /** |
| 97 * Clears overlays if the key event is ESC. | 121 * Handle 'keydown' events. |
| 98 * @param {Event} e Key event. | 122 * @param {Event} e Key event. |
| 99 * @private | 123 * @private |
| 100 */ | 124 */ |
| 101 OptionsPage.clearOverlaysOnEsc_ = function(e) { | 125 OptionsPage.onKeyDown_ = function(e) { |
| 102 if (e.keyCode == 27) { // Esc | 126 if (e.keyCode == 27) { // Esc |
| 103 OptionsPage.clearOverlays(); | 127 this.clearOverlays(); |
| 104 } | 128 } |
| 105 }; | 129 }; |
| 106 | 130 |
| 107 /** | 131 /** |
| 108 * Closes any currently-open subpage. | 132 * Closes any currently-open subpage. |
| 109 */ | 133 */ |
| 110 OptionsPage.closeSubPage = function() { | 134 OptionsPage.closeSubPage = function() { |
| 111 for (var name in OptionsPage.registeredSubPages_) { | 135 for (var name in this.registeredSubPages) { |
| 112 var pageInfo = OptionsPage.registeredSubPages_[name]; | 136 var pageInfo = this.registeredSubPages[name]; |
| 113 if (pageInfo.page.visible) { | 137 if (pageInfo.page.visible) { |
| 114 pageInfo.page.visible = false; | 138 pageInfo.page.visible = false; |
| 115 // Since the managed pref banner lives outside the overlay, and the | 139 // Since the managed pref banner lives outside the overlay, and the |
| 116 // parent is not changing visibility, update the banner explicitly. | 140 // parent is not changing visibility, update the banner explicitly. |
| 117 pageInfo.parentPage.updateManagedBannerVisibility(); | 141 pageInfo.parentPage.updateManagedBannerVisibility(); |
| 118 } | 142 } |
| 119 } | 143 } |
| 120 }; | 144 }; |
| 121 | 145 |
| 122 /** | 146 /** |
| (...skipping 19 matching lines...) Expand all Loading... |
| 142 tab.classList.add('active-tab'); | 166 tab.classList.add('active-tab'); |
| 143 $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); | 167 $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); |
| 144 this.activeNavTab = tab; | 168 this.activeNavTab = tab; |
| 145 }; | 169 }; |
| 146 | 170 |
| 147 /** | 171 /** |
| 148 * Registers new options page. | 172 * Registers new options page. |
| 149 * @param {OptionsPage} page Page to register. | 173 * @param {OptionsPage} page Page to register. |
| 150 */ | 174 */ |
| 151 OptionsPage.register = function(page) { | 175 OptionsPage.register = function(page) { |
| 152 OptionsPage.registeredPages_[page.name] = page; | 176 this.registeredPages[page.name] = page; |
| 153 // Create and add new page <li> element to navbar. | 177 // Create and add new page <li> element to navbar. |
| 154 var pageNav = document.createElement('li'); | 178 var pageNav = document.createElement('li'); |
| 155 pageNav.id = page.name + 'PageNav'; | 179 pageNav.id = page.name + 'PageNav'; |
| 156 pageNav.className = 'navbar-item'; | 180 pageNav.className = 'navbar-item'; |
| 157 pageNav.setAttribute('pageName', page.name); | 181 pageNav.setAttribute('pageName', page.name); |
| 158 pageNav.textContent = page.title; | 182 pageNav.textContent = page.title; |
| 159 pageNav.tabIndex = 0; | 183 pageNav.tabIndex = 0; |
| 160 pageNav.onclick = function(event) { | 184 pageNav.onclick = function(event) { |
| 161 OptionsPage.showPageByName(this.getAttribute('pageName')); | 185 OptionsPage.showPageByName(this.getAttribute('pageName')); |
| 162 }; | 186 }; |
| 163 pageNav.onkeypress = function(event) { | 187 pageNav.onkeypress = function(event) { |
| 164 // Enter or space | 188 // Enter or space |
| 165 if (event.keyCode == 13 || event.keyCode == 32) { | 189 if (event.keyCode == 13 || event.keyCode == 32) { |
| 166 OptionsPage.showPageByName(this.getAttribute('pageName')); | 190 OptionsPage.showPageByName(this.getAttribute('pageName')); |
| 167 } | 191 } |
| 168 }; | 192 }; |
| 169 var navbar = $('navbar'); | 193 var navbar = $('navbar'); |
| 170 navbar.appendChild(pageNav); | 194 navbar.appendChild(pageNav); |
| 171 page.tab = pageNav; | 195 page.tab = pageNav; |
| 172 page.initializePage(); | 196 page.initializePage(); |
| 173 }; | 197 }; |
| 174 | 198 |
| 175 /** | 199 /** |
| 176 * Registers a new Sub tab page. | 200 * Registers a new Sub tab page. |
| 177 * @param {OptionsPage} page Page to register. | 201 * @param {OptionsPage} page Page to register. |
| 178 */ | 202 */ |
| 179 OptionsPage.registerSubPage = function(subPage, parentPage) { | 203 OptionsPage.registerSubPage = function(subPage, parentPage) { |
| 180 OptionsPage.registeredSubPages_[subPage.name] = { | 204 this.registeredSubPages[subPage.name] = { |
| 181 page: subPage, parentPage: parentPage }; | 205 page: subPage, parentPage: parentPage }; |
| 182 subPage.tab = undefined; | 206 subPage.tab = undefined; |
| 183 subPage.isSubPageSheet = true; | 207 subPage.isSubPageSheet = true; |
| 184 subPage.initializePage(); | 208 subPage.initializePage(); |
| 185 }; | 209 }; |
| 186 | 210 |
| 187 /** | 211 /** |
| 188 * Registers a new Overlay page. | 212 * Registers a new Overlay page. |
| 189 * @param {OptionsPage} page Page to register, must be a class derived from | 213 * @param {OptionsPage} page Page to register, must be a class derived from |
| 190 * OptionsPage. | 214 * OptionsPage. |
| 191 */ | 215 */ |
| 192 OptionsPage.registerOverlay = function(page) { | 216 OptionsPage.registerOverlay = function(page) { |
| 193 OptionsPage.registeredOverlayPages_[page.name] = page; | 217 this.registeredOverlayPages[page.name] = page; |
| 194 page.tab = undefined; | 218 page.tab = undefined; |
| 195 page.isOverlay = true; | 219 page.isOverlay = true; |
| 196 page.initializePage(); | 220 page.initializePage(); |
| 197 }; | 221 }; |
| 198 | 222 |
| 199 /** | 223 /** |
| 200 * Callback for window.onpopstate. | 224 * Callback for window.onpopstate. |
| 201 * @param {Object} data State data pushed into history. | 225 * @param {Object} data State data pushed into history. |
| 202 */ | 226 */ |
| 203 OptionsPage.setState = function(data) { | 227 OptionsPage.setState = function(data) { |
| 204 if (data && data.pageName) { | 228 if (data && data.pageName) { |
| 205 OptionsPage.showPageByName(data.pageName); | 229 this.showPageByName(data.pageName); |
| 206 } | 230 } |
| 207 }; | 231 }; |
| 208 | 232 |
| 209 /** | 233 /** |
| 210 * Initializes the complete options page. This will cause | 234 * Initializes the complete options page. This will cause |
| 211 * all C++ handlers to be invoked to do final setup. | 235 * all C++ handlers to be invoked to do final setup. |
| 212 */ | 236 */ |
| 213 OptionsPage.initialize = function() { | 237 OptionsPage.initialize = function() { |
| 214 chrome.send('coreOptionsInitialize'); | 238 chrome.send('coreOptionsInitialize'); |
| 215 this.initialized_ = true; | 239 this.initialized_ = true; |
| 216 | 240 |
| 217 // Set up the overlay sheet. Clicks on the visible part of the parent page | 241 // 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. | 242 // should close the overlay, not fall through to the parent page. |
| 219 $('subpage-sheet-container').onclick = function(event) { | 243 $('subpage-sheet-container').onclick = function(event) { |
| 220 if (!$('subpage-sheet').contains(event.target)) | 244 if (!$('subpage-sheet').contains(event.target)) |
| 221 OptionsPage.closeSubPage(); | 245 this.closeSubPage(); |
| 222 event.stopPropagation(); | 246 event.stopPropagation(); |
| 223 } | 247 } |
| 224 }; | 248 }; |
| 225 | 249 |
| 226 /** | 250 /** |
| 227 * Re-initializes the C++ handlers if necessary. This is called if the | 251 * 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 | 252 * 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 | 253 * 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 | 254 * called, this does nothing (since it will be later, once the DOM has |
| 231 * finished loading). | 255 * finished loading). |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 * Sets page visibility. | 301 * Sets page visibility. |
| 278 */ | 302 */ |
| 279 set visible(visible) { | 303 set visible(visible) { |
| 280 if ((this.visible && visible) || (!this.visible && !visible)) | 304 if ((this.visible && visible) || (!this.visible && !visible)) |
| 281 return; | 305 return; |
| 282 | 306 |
| 283 if (visible) { | 307 if (visible) { |
| 284 this.pageDiv.classList.remove('hidden'); | 308 this.pageDiv.classList.remove('hidden'); |
| 285 if (this.isOverlay) { | 309 if (this.isOverlay) { |
| 286 $('overlay').classList.remove('hidden'); | 310 $('overlay').classList.remove('hidden'); |
| 287 document.addEventListener('keydown', | 311 document.addEventListener('keydown', OptionsPage.onKeyDown_); |
| 288 OptionsPage.clearOverlaysOnEsc_); | |
| 289 } else { | 312 } else { |
| 290 if (this.isSubPageSheet) | 313 if (this.isSubPageSheet) |
| 291 $('subpage-sheet-container').classList.remove('hidden'); | 314 $('subpage-sheet-container').classList.remove('hidden'); |
| 292 | 315 |
| 293 this.updateManagedBannerVisibility(); | 316 this.updateManagedBannerVisibility(); |
| 294 | 317 |
| 295 // Recent webkit change no longer allows url change from "chrome://". | 318 // Recent webkit change no longer allows url change from "chrome://". |
| 296 window.history.pushState({pageName: this.name}, this.title); | 319 window.history.pushState({pageName: this.name}, this.title); |
| 297 } | 320 } |
| 298 if (this.tab) { | 321 if (this.tab) { |
| 299 this.tab.classList.add('navbar-item-selected'); | 322 this.tab.classList.add('navbar-item-selected'); |
| 300 } | 323 } |
| 301 } else { | 324 } else { |
| 302 this.pageDiv.classList.add('hidden'); | 325 this.pageDiv.classList.add('hidden'); |
| 303 if (this.isOverlay) { | 326 if (this.isOverlay) { |
| 304 $('overlay').classList.add('hidden'); | 327 $('overlay').classList.add('hidden'); |
| 305 document.removeEventListener('keydown', | 328 document.removeEventListener('keydown', OptionsPage.onKeyDown_); |
| 306 OptionsPage.clearOverlaysOnEsc_); | |
| 307 } else if (this.isSubPageSheet) { | 329 } else if (this.isSubPageSheet) { |
| 308 $('subpage-sheet-container').classList.add('hidden'); | 330 $('subpage-sheet-container').classList.add('hidden'); |
| 309 } | 331 } |
| 310 if (this.tab) { | 332 if (this.tab) { |
| 311 this.tab.classList.remove('navbar-item-selected'); | 333 this.tab.classList.remove('navbar-item-selected'); |
| 312 } | 334 } |
| 313 } | 335 } |
| 314 | 336 |
| 315 cr.dispatchPropertyChange(this, 'visible', visible, !visible); | 337 cr.dispatchPropertyChange(this, 'visible', visible, !visible); |
| 316 }, | 338 }, |
| 317 | 339 |
| 318 /** | 340 /** |
| 319 * Handles a hash value in the URL (such as bar in | 341 * Handles a hash value in the URL (such as bar in |
| 320 * chrome://options/foo#bar). Called on page load. By default, this shows | 342 * 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 | 343 * an overlay that matches the hash name, but can be overriden by individual |
| 322 * OptionsPage subclasses to get other behavior. | 344 * OptionsPage subclasses to get other behavior. |
| 323 * @param {string} hash The hash value. | 345 * @param {string} hash The hash value. |
| 324 */ | 346 */ |
| 325 handleHash: function(hash) { | 347 handleHash: function(hash) { |
| 326 OptionsPage.showOverlay(hash); | 348 OptionsPage.showOverlay(hash); |
| 327 }, | 349 }, |
| 328 }; | 350 }; |
| 329 | 351 |
| 330 // Export | 352 // Export |
| 331 return { | 353 return { |
| 332 OptionsPage: OptionsPage | 354 OptionsPage: OptionsPage |
| 333 }; | 355 }; |
| 334 | 356 |
| 335 }); | 357 }); |
| OLD | NEW |