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

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: dbeam comments 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 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
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
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
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
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 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698