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