Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(749)

Side by Side Diff: chrome/browser/resources/options/options_page.js

Issue 298553002: Options: maintain history entries on the parent frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Unnecessary diff. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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,
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
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
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);
davidben 2014/05/19 22:38:33 This is replaced by an explicit updateTitle_ call.
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.
davidben 2014/05/19 22:38:33 This special-case is replaced with the new replace
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);
davidben 2014/05/19 22:38:33 This is replaced by the updateTitle_ call later. I
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
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
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 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698