| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; | 6 /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; |
| 7 | 7 |
| 8 ///////////////////////////////////////////////////////////////////////////// | 8 ///////////////////////////////////////////////////////////////////////////// |
| 9 // OptionsPage class: | 9 // OptionsPage class: |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 64 |
| 65 /** | 65 /** |
| 66 * Gets the default page (to be shown on initial load). | 66 * Gets the default page (to be shown on initial load). |
| 67 */ | 67 */ |
| 68 OptionsPage.getDefaultPage = function() { | 68 OptionsPage.getDefaultPage = function() { |
| 69 return BrowserOptions.getInstance(); | 69 return BrowserOptions.getInstance(); |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 /** | 72 /** |
| 73 * Shows the default page. | 73 * Shows the default page. |
| 74 * @param {Object=} opt_propertyBag An optional bag of properties including |
| 75 * replaceState (if history state should be replaced instead of pushed). |
| 74 */ | 76 */ |
| 75 OptionsPage.showDefaultPage = function() { | 77 OptionsPage.showDefaultPage = function(opt_propertyBag) { |
| 76 this.navigateToPage(this.getDefaultPage().name); | 78 this.navigateToPage(this.getDefaultPage().name, opt_propertyBag); |
| 77 }; | 79 }; |
| 78 | 80 |
| 79 /** | 81 /** |
| 80 * "Navigates" to a page, meaning that the page will be shown and the | 82 * "Navigates" to a page, meaning that the page will be shown and the |
| 81 * appropriate entry is placed in the history. | 83 * appropriate entry is placed in the history. |
| 82 * @param {string} pageName Page name. | 84 * @param {string} pageName Page name. |
| 85 * @param {Object=} opt_propertyBag An optional bag of properties including |
| 86 * replaceState (if history state should be replaced instead of pushed). |
| 83 */ | 87 */ |
| 84 OptionsPage.navigateToPage = function(pageName) { | 88 OptionsPage.navigateToPage = function(pageName, opt_propertyBag) { |
| 85 this.showPageByName(pageName, true); | 89 this.showPageByName(pageName, true, opt_propertyBag); |
| 86 }; | 90 }; |
| 87 | 91 |
| 88 /** | 92 /** |
| 89 * Shows a registered page. This handles both top-level and overlay pages. | 93 * Shows a registered page. This handles both top-level and overlay pages. |
| 90 * @param {string} pageName Page name. | 94 * @param {string} pageName Page name. |
| 91 * @param {boolean} updateHistory True if we should update the history after | 95 * @param {boolean} updateHistory True if we should update the history after |
| 92 * showing the page. | 96 * showing the page. |
| 93 * @param {Object=} opt_propertyBag An optional bag of properties including | 97 * @param {Object=} opt_propertyBag An optional bag of properties including |
| 94 * replaceState (if history state should be replaced instead of pushed). | 98 * replaceState (if history state should be replaced instead of pushed). |
| 95 * @private | 99 * @private |
| (...skipping 17 matching lines...) Expand all Loading... |
| 113 } | 117 } |
| 114 } | 118 } |
| 115 | 119 |
| 116 // Find the target page. | 120 // Find the target page. |
| 117 var targetPage = this.registeredPages[pageName.toLowerCase()]; | 121 var targetPage = this.registeredPages[pageName.toLowerCase()]; |
| 118 if (!targetPage || !targetPage.canShowPage()) { | 122 if (!targetPage || !targetPage.canShowPage()) { |
| 119 // If it's not a page, try it as an overlay. | 123 // If it's not a page, try it as an overlay. |
| 120 if (!targetPage && this.showOverlay_(pageName, rootPage)) { | 124 if (!targetPage && this.showOverlay_(pageName, rootPage)) { |
| 121 if (updateHistory) | 125 if (updateHistory) |
| 122 this.updateHistoryState_(!!opt_propertyBag.replaceState); | 126 this.updateHistoryState_(!!opt_propertyBag.replaceState); |
| 127 this.updateTitle_(); |
| 123 return; | 128 return; |
| 124 } else { | 129 } else { |
| 125 targetPage = this.getDefaultPage(); | 130 targetPage = this.getDefaultPage(); |
| 126 } | 131 } |
| 127 } | 132 } |
| 128 | 133 |
| 129 pageName = targetPage.name.toLowerCase(); | 134 pageName = targetPage.name.toLowerCase(); |
| 130 var targetPageWasVisible = targetPage.visible; | 135 var targetPageWasVisible = targetPage.visible; |
| 131 | 136 |
| 132 // Determine if the root page is 'sticky', meaning that it | 137 // Determine if the root page is 'sticky', meaning that it |
| (...skipping 26 matching lines...) Expand all Loading... |
| 159 this.registeredOverlayPages[name]; | 164 this.registeredOverlayPages[name]; |
| 160 if (!page.parentPage && isRootPageLocked) | 165 if (!page.parentPage && isRootPageLocked) |
| 161 continue; | 166 continue; |
| 162 page.visible = name == pageName || page.isAncestorOfPage(targetPage); | 167 page.visible = name == pageName || page.isAncestorOfPage(targetPage); |
| 163 } | 168 } |
| 164 | 169 |
| 165 // Update the history and current location. | 170 // Update the history and current location. |
| 166 if (updateHistory) | 171 if (updateHistory) |
| 167 this.updateHistoryState_(!!opt_propertyBag.replaceState); | 172 this.updateHistoryState_(!!opt_propertyBag.replaceState); |
| 168 | 173 |
| 169 // Update tab title. | |
| 170 this.setTitle_(targetPage.title); | |
| 171 | |
| 172 // Update focus if any other control was focused on the previous page, | 174 // Update focus if any other control was focused on the previous page, |
| 173 // or the previous page is not known. | 175 // or the previous page is not known. |
| 174 if (document.activeElement != document.body && | 176 if (document.activeElement != document.body && |
| 175 (!rootPage || rootPage.pageDiv.contains(document.activeElement))) { | 177 (!rootPage || rootPage.pageDiv.contains(document.activeElement))) { |
| 176 targetPage.focus(); | 178 targetPage.focus(); |
| 177 } | 179 } |
| 178 | 180 |
| 179 // Notify pages if they were shown. | 181 // Notify pages if they were shown. |
| 180 for (var i = 0; i < allPageNames.length; ++i) { | 182 for (var i = 0; i < allPageNames.length; ++i) { |
| 181 var name = allPageNames[i]; | 183 var name = allPageNames[i]; |
| 182 var page = this.registeredPages[name] || | 184 var page = this.registeredPages[name] || |
| 183 this.registeredOverlayPages[name]; | 185 this.registeredOverlayPages[name]; |
| 184 if (!page.parentPage && isRootPageLocked) | 186 if (!page.parentPage && isRootPageLocked) |
| 185 continue; | 187 continue; |
| 186 if (!targetPageWasVisible && page.didShowPage && | 188 if (!targetPageWasVisible && page.didShowPage && |
| 187 (name == pageName || page.isAncestorOfPage(targetPage))) { | 189 (name == pageName || page.isAncestorOfPage(targetPage))) { |
| 188 page.didShowPage(); | 190 page.didShowPage(); |
| 189 } | 191 } |
| 190 } | 192 } |
| 193 |
| 194 // Update the document title. Do this after didShowPage was called, in case |
| 195 // a page decides to change its title. |
| 196 this.updateTitle_(); |
| 191 }; | 197 }; |
| 192 | 198 |
| 193 /** | 199 /** |
| 194 * Sets the title of the page. This is accomplished by calling into the | |
| 195 * parent page API. | |
| 196 * @param {string} title The title string. | |
| 197 * @private | |
| 198 */ | |
| 199 OptionsPage.setTitle_ = function(title) { | |
| 200 uber.invokeMethodOnParent('setTitle', {title: title}); | |
| 201 }; | |
| 202 | |
| 203 /** | |
| 204 * Scrolls the page to the correct position (the top when opening an overlay, | 200 * Scrolls the page to the correct position (the top when opening an overlay, |
| 205 * or the old scroll position a previously hidden overlay becomes visible). | 201 * or the old scroll position a previously hidden overlay becomes visible). |
| 206 * @private | 202 * @private |
| 207 */ | 203 */ |
| 208 OptionsPage.updateScrollPosition_ = function() { | 204 OptionsPage.updateScrollPosition_ = function() { |
| 209 var container = $('page-container'); | 205 var container = $('page-container'); |
| 210 var scrollTop = container.oldScrollTop || 0; | 206 var scrollTop = container.oldScrollTop || 0; |
| 211 container.oldScrollTop = undefined; | 207 container.oldScrollTop = undefined; |
| 212 window.scroll(scrollLeftForDocument(document), scrollTop); | 208 window.scroll(scrollLeftForDocument(document), scrollTop); |
| 213 }; | 209 }; |
| 214 | 210 |
| 215 /** | 211 /** |
| 216 * Pushes the current page onto the history stack, overriding the last page | 212 * Updates the title to title of the current page. |
| 217 * if it is the generic chrome://settings/. | 213 * @private |
| 214 */ |
| 215 OptionsPage.updateTitle_ = function() { |
| 216 var page = this.getTopmostVisiblePage(); |
| 217 uber.setTitle(page.title); |
| 218 }; |
| 219 |
| 220 /** |
| 221 * Pushes the current page onto the history stack, replacing the current entry |
| 222 * if appropriate. |
| 218 * @param {boolean} replace If true, allow no history events to be created. | 223 * @param {boolean} replace If true, allow no history events to be created. |
| 219 * @param {object=} opt_params A bag of optional params, including: | 224 * @param {object=} opt_params A bag of optional params, including: |
| 220 * {boolean} ignoreHash Whether to include the hash or not. | 225 * {boolean} ignoreHash Whether to include the hash or not. |
| 221 * @private | 226 * @private |
| 222 */ | 227 */ |
| 223 OptionsPage.updateHistoryState_ = function(replace, opt_params) { | 228 OptionsPage.updateHistoryState_ = function(replace, opt_params) { |
| 224 if (OptionsPage.isDialog) | 229 if (OptionsPage.isDialog) |
| 225 return; | 230 return; |
| 226 | 231 |
| 227 var page = this.getTopmostVisiblePage(); | 232 var page = this.getTopmostVisiblePage(); |
| 228 var path = window.location.pathname + window.location.hash; | 233 var path = window.location.pathname + window.location.hash; |
| 229 if (path) | 234 if (path) |
| 230 path = path.slice(1).replace(/\/(?:#|$)/, ''); // Remove trailing slash. | 235 path = path.slice(1).replace(/\/(?:#|$)/, ''); // Remove trailing slash. |
| 231 | 236 |
| 232 // Update tab title. | |
| 233 this.setTitle_(page.title); | |
| 234 | |
| 235 // The page is already in history (the user may have clicked the same link | 237 // The page is already in history (the user may have clicked the same link |
| 236 // twice). Do nothing. | 238 // twice). Do nothing. |
| 237 if (path == page.name && !OptionsPage.isLoading()) | 239 if (path == page.name && !OptionsPage.isLoading()) |
| 238 return; | 240 return; |
| 239 | 241 |
| 240 var hash = opt_params && opt_params.ignoreHash ? '' : window.location.hash; | 242 var hash = opt_params && opt_params.ignoreHash ? '' : window.location.hash; |
| 241 | 243 |
| 242 // If settings are embedded, tell the outer page to set its "path" to the | 244 var newPath = (page == this.getDefaultPage() ? '' : page.name) + hash; |
| 243 // inner frame's path. | 245 var historyFunction = replace ? uber.replaceState : uber.pushState; |
| 244 var outerPath = (page == this.getDefaultPage() ? '' : page.name) + hash; | 246 historyFunction.call(uber, {pageName: page.name}, newPath); |
| 245 uber.invokeMethodOnParent('setPath', {path: outerPath}); | |
| 246 | |
| 247 // If there is no path, the current location is chrome://settings/. | |
| 248 // Override this with the new page. | |
| 249 var historyFunction = path && !replace ? window.history.pushState : | |
| 250 window.history.replaceState; | |
| 251 historyFunction.call(window.history, | |
| 252 {pageName: page.name}, | |
| 253 page.title, | |
| 254 '/' + page.name + hash); | |
| 255 }; | 247 }; |
| 256 | 248 |
| 257 /** | 249 /** |
| 258 * Shows a registered Overlay page. Does not update history. | 250 * Shows a registered Overlay page. Does not update history. |
| 259 * @param {string} overlayName Page name. | 251 * @param {string} overlayName Page name. |
| 260 * @param {OptionPage} rootPage The currently visible root-level page. | 252 * @param {OptionPage} rootPage The currently visible root-level page. |
| 261 * @return {boolean} whether we showed an overlay. | 253 * @return {boolean} whether we showed an overlay. |
| 262 */ | 254 */ |
| 263 OptionsPage.showOverlay_ = function(overlayName, rootPage) { | 255 OptionsPage.showOverlay_ = function(overlayName, rootPage) { |
| 264 var overlay = this.registeredOverlayPages[overlayName.toLowerCase()]; | 256 var overlay = this.registeredOverlayPages[overlayName.toLowerCase()]; |
| 265 if (!overlay || !overlay.canShowPage()) | 257 if (!overlay || !overlay.canShowPage()) |
| 266 return false; | 258 return false; |
| 267 | 259 |
| 268 // Save the currently focused element in the page for restoration later. | 260 // Save the currently focused element in the page for restoration later. |
| 269 var currentPage = this.getTopmostVisiblePage(); | 261 var currentPage = this.getTopmostVisiblePage(); |
| 270 if (currentPage) | 262 if (currentPage) |
| 271 currentPage.lastFocusedElement = document.activeElement; | 263 currentPage.lastFocusedElement = document.activeElement; |
| 272 | 264 |
| 273 if ((!rootPage || !rootPage.sticky) && | 265 if ((!rootPage || !rootPage.sticky) && |
| 274 overlay.parentPage && | 266 overlay.parentPage && |
| 275 !overlay.parentPage.visible) { | 267 !overlay.parentPage.visible) { |
| 276 this.showPageByName(overlay.parentPage.name, false); | 268 this.showPageByName(overlay.parentPage.name, false); |
| 277 } | 269 } |
| 278 | 270 |
| 279 if (!overlay.visible) { | 271 if (!overlay.visible) { |
| 280 overlay.visible = true; | 272 overlay.visible = true; |
| 281 if (overlay.didShowPage) overlay.didShowPage(); | 273 if (overlay.didShowPage) overlay.didShowPage(); |
| 282 } | 274 } |
| 283 | 275 |
| 284 // Update tab title. | |
| 285 this.setTitle_(overlay.title); | |
| 286 | |
| 287 // Change focus to the overlay if any other control was focused by keyboard | 276 // Change focus to the overlay if any other control was focused by keyboard |
| 288 // before. Otherwise, no one should have focus. | 277 // before. Otherwise, no one should have focus. |
| 289 if (document.activeElement != document.body) { | 278 if (document.activeElement != document.body) { |
| 290 if (FocusOutlineManager.forDocument(document).visible) { | 279 if (FocusOutlineManager.forDocument(document).visible) { |
| 291 overlay.focus(); | 280 overlay.focus(); |
| 292 } else if (!overlay.pageDiv.contains(document.activeElement)) { | 281 } else if (!overlay.pageDiv.contains(document.activeElement)) { |
| 293 document.activeElement.blur(); | 282 document.activeElement.blur(); |
| 294 } | 283 } |
| 295 } | 284 } |
| 296 | 285 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 */ | 332 */ |
| 344 OptionsPage.closeOverlay = function() { | 333 OptionsPage.closeOverlay = function() { |
| 345 var overlay = this.getVisibleOverlay_(); | 334 var overlay = this.getVisibleOverlay_(); |
| 346 if (!overlay) | 335 if (!overlay) |
| 347 return; | 336 return; |
| 348 | 337 |
| 349 overlay.visible = false; | 338 overlay.visible = false; |
| 350 | 339 |
| 351 if (overlay.didClosePage) overlay.didClosePage(); | 340 if (overlay.didClosePage) overlay.didClosePage(); |
| 352 this.updateHistoryState_(false, {ignoreHash: true}); | 341 this.updateHistoryState_(false, {ignoreHash: true}); |
| 342 this.updateTitle_(); |
| 353 | 343 |
| 354 this.restoreLastFocusedElement_(); | 344 this.restoreLastFocusedElement_(); |
| 355 }; | 345 }; |
| 356 | 346 |
| 357 /** | 347 /** |
| 358 * Closes all overlays and updates the history after each closed overlay. | 348 * Closes all overlays and updates the history after each closed overlay. |
| 359 */ | 349 */ |
| 360 OptionsPage.closeAllOverlays = function() { | 350 OptionsPage.closeAllOverlays = function() { |
| 361 while (this.isOverlayVisible_()) { | 351 while (this.isOverlayVisible_()) { |
| 362 this.closeOverlay(); | 352 this.closeOverlay(); |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 canShowPage: function() { | 1009 canShowPage: function() { |
| 1020 return true; | 1010 return true; |
| 1021 }, | 1011 }, |
| 1022 }; | 1012 }; |
| 1023 | 1013 |
| 1024 // Export | 1014 // Export |
| 1025 return { | 1015 return { |
| 1026 OptionsPage: OptionsPage | 1016 OptionsPage: OptionsPage |
| 1027 }; | 1017 }; |
| 1028 }); | 1018 }); |
| OLD | NEW |