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

Side by Side Diff: chrome/browser/resources/uber/uber.js

Issue 300033009: Settings: load iframes anew when switching to a non-current one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: dbeam comments Created 6 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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('uber', function() { 5 cr.define('uber', function() {
6 /** 6 /**
7 * Options for how web history should be handled. 7 * Options for how web history should be handled.
8 */ 8 */
9 var HISTORY_STATE_OPTION = { 9 var HISTORY_STATE_OPTION = {
10 PUSH: 1, // Push a new history state. 10 PUSH: 1, // Push a new history state.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 98
99 /** 99 /**
100 * Handler for window.onpopstate. 100 * Handler for window.onpopstate.
101 * @param {Event} e The history event. 101 * @param {Event} e The history event.
102 */ 102 */
103 function onPopHistoryState(e) { 103 function onPopHistoryState(e) {
104 if (e.state && e.state.pageId) { 104 if (e.state && e.state.pageId) {
105 var params = resolvePageInfo(); 105 var params = resolvePageInfo();
106 assert(params.id === e.state.pageId); 106 assert(params.id === e.state.pageId);
107 107
108 // If the page doesn't exist, create it. Otherwise, swap it in. 108 // If the page isn't the current page, load it fresh. Even if the page is
109 var frame = $(params.id).querySelector('iframe'); 109 // already loaded, it may have state not reflected in the URL, such as the
110 if (!frame) 110 // history page's "Remove selected items" overlay. http://crbug.com/377386
111 if (getRequiredElement(params.id) !== getSelectedIframe())
111 showPage(params.id, HISTORY_STATE_OPTION.NONE, params.path); 112 showPage(params.id, HISTORY_STATE_OPTION.NONE, params.path);
112 else
113 selectPage(params.id);
114 113
115 // Either way, send the state down to it. 114 // Either way, send the state down to it.
116 // 115 //
117 // Note: This assumes that the state and path parameters for every page 116 // Note: This assumes that the state and path parameters for every page
118 // under this origin are compatible. All of the downstream pages which 117 // under this origin are compatible. All of the downstream pages which
119 // navigate use pushState and replaceState. 118 // navigate use pushState and replaceState.
120 invokeMethodOnPage(e.state.pageId, 'popState', 119 invokeMethodOnPage(e.state.pageId, 'popState',
121 {state: e.state.pageState, path: params.path}); 120 {state: e.state.pageState, path: params.path});
122 } 121 }
123 } 122 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 * @return {!HTMLElement} The frame associated to |origin| or null. 216 * @return {!HTMLElement} The frame associated to |origin| or null.
218 */ 217 */
219 function getIframeFromOrigin(origin) { 218 function getIframeFromOrigin(origin) {
220 assert(origin.substr(-1) != '/', 'invalid origin given'); 219 assert(origin.substr(-1) != '/', 'invalid origin given');
221 var query = '.iframe-container > iframe[src^="' + origin + '/"]'; 220 var query = '.iframe-container > iframe[src^="' + origin + '/"]';
222 return document.querySelector(query); 221 return document.querySelector(query);
223 } 222 }
224 223
225 /** 224 /**
226 * Changes the path past the page title (i.e. chrome://chrome/settings/(.*)). 225 * Changes the path past the page title (i.e. chrome://chrome/settings/(.*)).
227 * @param {string} pageId Should match an id of one of the iframe containers.
228 * @param {Object} state The page's state object for the navigation. 226 * @param {Object} state The page's state object for the navigation.
229 * @param {string} path The new /path/ to be set after the page name. 227 * @param {string} path The new /path/ to be set after the page name.
230 * @param {number} historyOption The type of history modification to make. 228 * @param {number} historyOption The type of history modification to make.
231 */ 229 */
232 function changePathTo(pageId, state, path, historyOption) { 230 function changePathTo(state, path, historyOption) {
233 assert(!path || path.substr(-1) != '/', 'invalid path given'); 231 assert(!path || path.substr(-1) != '/', 'invalid path given');
234 232
235 var histFunc; 233 var histFunc;
236 if (historyOption == HISTORY_STATE_OPTION.PUSH) 234 if (historyOption == HISTORY_STATE_OPTION.PUSH)
237 histFunc = window.history.pushState; 235 histFunc = window.history.pushState;
238 else if (historyOption == HISTORY_STATE_OPTION.REPLACE) 236 else if (historyOption == HISTORY_STATE_OPTION.REPLACE)
239 histFunc = window.history.replaceState; 237 histFunc = window.history.replaceState;
240 238
241 assert(histFunc, 'invalid historyOption given ' + historyOption); 239 assert(histFunc, 'invalid historyOption given ' + historyOption);
242 240
241 var pageId = getSelectedIframe().id;
243 var args = [{pageId: pageId, pageState: state}, 242 var args = [{pageId: pageId, pageState: state},
244 '', 243 '',
245 '/' + pageId + '/' + (path || '')]; 244 '/' + pageId + '/' + (path || '')];
246 histFunc.apply(window.history, args); 245 histFunc.apply(window.history, args);
247 } 246 }
248 247
249 /** 248 /**
250 * Adds or replaces the current history entry based on a navigation from the 249 * Adds or replaces the current history entry based on a navigation from the
251 * source iframe. 250 * source iframe.
252 * @param {string} origin The origin of the source iframe. 251 * @param {string} origin The origin of the source iframe.
253 * @param {Object} state The source iframe's state object. 252 * @param {Object} state The source iframe's state object.
254 * @param {string} path The new "path" (e.g. "/createProfile"). 253 * @param {string} path The new "path" (e.g. "/createProfile").
255 * @param {boolean} replace Whether to replace the current history entry. 254 * @param {boolean} replace Whether to replace the current history entry.
256 */ 255 */
257 function updateHistory(origin, state, path, replace) { 256 function updateHistory(origin, state, path, replace) {
258 assert(!path || path[0] != '/', 'invalid path sent from ' + origin); 257 assert(!path || path[0] != '/', 'invalid path sent from ' + origin);
259 var historyOption = 258 var historyOption =
260 replace ? HISTORY_STATE_OPTION.REPLACE : HISTORY_STATE_OPTION.PUSH; 259 replace ? HISTORY_STATE_OPTION.REPLACE : HISTORY_STATE_OPTION.PUSH;
261 // Only update the currently displayed path if this is the visible frame. 260 // Only update the currently displayed path if this is the visible frame.
262 var container = getIframeFromOrigin(origin).parentNode; 261 var container = getIframeFromOrigin(origin).parentNode;
263 if (container == getSelectedIframe()) 262 if (container == getSelectedIframe())
264 changePathTo(container.id, state, path, historyOption); 263 changePathTo(state, path, historyOption);
265 } 264 }
266 265
267 /** 266 /**
268 * Sets the title of the page. 267 * Sets the title of the page.
269 * @param {string} origin The origin of the source iframe. 268 * @param {string} origin The origin of the source iframe.
270 * @param {string} title The title of the page. 269 * @param {string} title The title of the page.
271 */ 270 */
272 function setTitle(origin, title) { 271 function setTitle(origin, title) {
273 // Cache the title for the client iframe, i.e., the iframe setting the 272 // Cache the title for the client iframe, i.e., the iframe setting the
274 // title. querySelector returns the actual iframe element, so use parentNode 273 // title. querySelector returns the actual iframe element, so use parentNode
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 container.appendChild(frame); 333 container.appendChild(frame);
335 frame.src = sourceUrl; 334 frame.src = sourceUrl;
336 } else { 335 } else {
337 // There's no particularly good way to know what the current URL of the 336 // There's no particularly good way to know what the current URL of the
338 // content frame is as we don't have access to its contentWindow's 337 // content frame is as we don't have access to its contentWindow's
339 // location, so just replace every time until necessary to do otherwise. 338 // location, so just replace every time until necessary to do otherwise.
340 frame.contentWindow.location.replace(sourceUrl); 339 frame.contentWindow.location.replace(sourceUrl);
341 frame.dataset.ready = false; 340 frame.dataset.ready = false;
342 } 341 }
343 342
344 // This must be called before selectPage so that the title change applies to 343 // If the last selected container is already showing, ignore the rest.
345 // the new history entry.
346 if (historyOption != HISTORY_STATE_OPTION.NONE)
347 changePathTo(pageId, {}, path, historyOption);
348
349 selectPage(pageId);
350 }
351
352 /**
353 * Switches to a subpage. The subpage must already exist.
354 * @param {string} pageId Should match an id of one of the iframe containers.
355 */
356 function selectPage(pageId) {
357 var container = getRequiredElement(pageId);
358 var lastSelected = document.querySelector('.iframe-container.selected'); 344 var lastSelected = document.querySelector('.iframe-container.selected');
359
360 // If the last selected container is already showing, ignore the rest.
361 if (lastSelected === container) 345 if (lastSelected === container)
362 return; 346 return;
363 347
364 if (lastSelected) { 348 if (lastSelected) {
365 lastSelected.classList.remove('selected'); 349 lastSelected.classList.remove('selected');
366 // Setting aria-hidden hides the container from assistive technology 350 // Setting aria-hidden hides the container from assistive technology
367 // immediately. The 'hidden' attribute is set after the transition 351 // immediately. The 'hidden' attribute is set after the transition
368 // finishes - that ensures it's not possible to accidentally focus 352 // finishes - that ensures it's not possible to accidentally focus
369 // an element in an unselected container. 353 // an element in an unselected container.
370 lastSelected.setAttribute('aria-hidden', 'true'); 354 lastSelected.setAttribute('aria-hidden', 'true');
371 } 355 }
372 356
373 // Containers that aren't selected have to be hidden so that their 357 // Containers that aren't selected have to be hidden so that their
374 // content isn't focusable. 358 // content isn't focusable.
375 container.hidden = false; 359 container.hidden = false;
376 container.setAttribute('aria-hidden', 'false'); 360 container.setAttribute('aria-hidden', 'false');
377 361
378 // Trigger a layout after making it visible and before setting 362 // Trigger a layout after making it visible and before setting
379 // the class to 'selected', so that it animates in. 363 // the class to 'selected', so that it animates in.
380 container.offsetTop; 364 container.offsetTop;
381 container.classList.add('selected'); 365 container.classList.add('selected');
382 366
383 setContentChanging(true); 367 setContentChanging(true);
384 adjustToScroll(0); 368 adjustToScroll(0);
385 369
386 var selectedFrame = getSelectedIframe().querySelector('iframe'); 370 var selectedFrame = getSelectedIframe().querySelector('iframe');
387 uber.invokeMethodOnWindow(selectedFrame.contentWindow, 'frameSelected'); 371 uber.invokeMethodOnWindow(selectedFrame.contentWindow, 'frameSelected');
388 372
373 if (historyOption != HISTORY_STATE_OPTION.NONE)
374 changePathTo({}, path, historyOption);
375
389 if (container.dataset.title) 376 if (container.dataset.title)
390 document.title = container.dataset.title; 377 document.title = container.dataset.title;
391 $('favicon').href = 'chrome://theme/' + container.dataset.favicon; 378 $('favicon').href = 'chrome://theme/' + container.dataset.favicon;
392 $('favicon2x').href = 'chrome://theme/' + container.dataset.favicon + '@2x'; 379 $('favicon2x').href = 'chrome://theme/' + container.dataset.favicon + '@2x';
393 380
394 updateNavigationControls(); 381 updateNavigationControls();
395 } 382 }
396 383
397 function onNavigationControlsLoaded() { 384 function onNavigationControlsLoaded() {
398 updateNavigationControls(); 385 updateNavigationControls();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 } 450 }
464 451
465 return { 452 return {
466 onLoad: onLoad, 453 onLoad: onLoad,
467 onPopHistoryState: onPopHistoryState 454 onPopHistoryState: onPopHistoryState
468 }; 455 };
469 }); 456 });
470 457
471 window.addEventListener('popstate', uber.onPopHistoryState); 458 window.addEventListener('popstate', uber.onPopHistoryState);
472 document.addEventListener('DOMContentLoaded', uber.onLoad); 459 document.addEventListener('DOMContentLoaded', uber.onLoad);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698