| 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('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. |
| 11 REPLACE: 2, // Replace the current history state. | 11 REPLACE: 2, // Replace the current history state. |
| 12 NONE: 3, // Ignore this history state change. | 12 NONE: 3, // Ignore this history state change. |
| 13 }; | 13 }; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * We cache a reference to the #navigation frame here so we don't need to grab | 16 * We cache a reference to the #navigation frame here so we don't need to grab |
| 17 * it from the DOM on each scroll. | 17 * it from the DOM on each scroll. |
| 18 * @type {Node} | 18 * @type {Node} |
| 19 * @private | 19 * @private |
| 20 */ | 20 */ |
| 21 var navFrame; | 21 var navFrame; |
| 22 | 22 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 if (index != -1) { | 74 if (index != -1) { |
| 75 params.id = path.slice(0, index); | 75 params.id = path.slice(0, index); |
| 76 params.path = path.slice(index + 1); | 76 params.path = path.slice(index + 1); |
| 77 } else { | 77 } else { |
| 78 params.id = path; | 78 params.id = path; |
| 79 } | 79 } |
| 80 | 80 |
| 81 var container = $(params.id); | 81 var container = $(params.id); |
| 82 if (container) { | 82 if (container) { |
| 83 // The id is valid. Add the hash and search parts of the URL to path. | 83 // The id is valid. Add the hash and search parts of the URL to path. |
| 84 params.path = (params.path || '') + window.location.search + | 84 params.path = |
| 85 window.location.hash; | 85 (params.path || '') + window.location.search + window.location.hash; |
| 86 } else { | 86 } else { |
| 87 // The target sub-page does not exist, discard the params we generated. | 87 // The target sub-page does not exist, discard the params we generated. |
| 88 params.id = undefined; | 88 params.id = undefined; |
| 89 params.path = undefined; | 89 params.path = undefined; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 // If we don't have a valid page, get a default. | 92 // If we don't have a valid page, get a default. |
| 93 if (!params.id) | 93 if (!params.id) |
| 94 params.id = getDefaultIframe().id; | 94 params.id = getDefaultIframe().id; |
| 95 | 95 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 108 // already loaded, it may have state not reflected in the URL, such as the | 108 // already loaded, it may have state not reflected in the URL, such as the |
| 109 // history page's "Remove selected items" overlay. http://crbug.com/377386 | 109 // history page's "Remove selected items" overlay. http://crbug.com/377386 |
| 110 if (getRequiredElement(params.id) !== getSelectedIframeContainer()) | 110 if (getRequiredElement(params.id) !== getSelectedIframeContainer()) |
| 111 showPage(params.id, HISTORY_STATE_OPTION.NONE, params.path); | 111 showPage(params.id, HISTORY_STATE_OPTION.NONE, params.path); |
| 112 | 112 |
| 113 // Either way, send the state down to it. | 113 // Either way, send the state down to it. |
| 114 // | 114 // |
| 115 // Note: This assumes that the state and path parameters for every page | 115 // Note: This assumes that the state and path parameters for every page |
| 116 // under this origin are compatible. All of the downstream pages which | 116 // under this origin are compatible. All of the downstream pages which |
| 117 // navigate use pushState and replaceState. | 117 // navigate use pushState and replaceState. |
| 118 invokeMethodOnPage(params.id, 'popState', | 118 invokeMethodOnPage( |
| 119 {state: e.state, path: '/' + params.path}); | 119 params.id, 'popState', {state: e.state, path: '/' + params.path}); |
| 120 } | 120 } |
| 121 | 121 |
| 122 /** | 122 /** |
| 123 * @return {Object} The default iframe container. | 123 * @return {Object} The default iframe container. |
| 124 */ | 124 */ |
| 125 function getDefaultIframe() { | 125 function getDefaultIframe() { |
| 126 return $(loadTimeData.getString('helpHost')); | 126 return $(loadTimeData.getString('helpHost')); |
| 127 } | 127 } |
| 128 | 128 |
| 129 /** | 129 /** |
| (...skipping 19 matching lines...) Expand all Loading... |
| 149 * { method : "methodToInvoke", | 149 * { method : "methodToInvoke", |
| 150 * params : {...} | 150 * params : {...} |
| 151 * } | 151 * } |
| 152 * | 152 * |
| 153 * |method| is required, while |params| is optional. Extra parameters required | 153 * |method| is required, while |params| is optional. Extra parameters required |
| 154 * by a method must be specified by that method's documentation. | 154 * by a method must be specified by that method's documentation. |
| 155 * | 155 * |
| 156 * @param {Event} e The posted object. | 156 * @param {Event} e The posted object. |
| 157 */ | 157 */ |
| 158 function handleWindowMessage(e) { | 158 function handleWindowMessage(e) { |
| 159 e = /** @type {!MessageEvent<!{method: string, params: *}>} */(e); | 159 e = /** @type {!MessageEvent<!{method: string, params: *}>} */ (e); |
| 160 if (e.data.method === 'beginInterceptingEvents') { | 160 if (e.data.method === 'beginInterceptingEvents') { |
| 161 backgroundNavigation(); | 161 backgroundNavigation(); |
| 162 } else if (e.data.method === 'stopInterceptingEvents') { | 162 } else if (e.data.method === 'stopInterceptingEvents') { |
| 163 foregroundNavigation(); | 163 foregroundNavigation(); |
| 164 } else if (e.data.method === 'ready') { | 164 } else if (e.data.method === 'ready') { |
| 165 pageReady(e.origin); | 165 pageReady(e.origin); |
| 166 } else if (e.data.method === 'updateHistory') { | 166 } else if (e.data.method === 'updateHistory') { |
| 167 updateHistory(e.origin, e.data.params.state, e.data.params.path, | 167 updateHistory( |
| 168 e.data.params.replace); | 168 e.origin, e.data.params.state, e.data.params.path, |
| 169 e.data.params.replace); |
| 169 } else if (e.data.method === 'setTitle') { | 170 } else if (e.data.method === 'setTitle') { |
| 170 setTitle(e.origin, e.data.params.title); | 171 setTitle(e.origin, e.data.params.title); |
| 171 } else if (e.data.method === 'showPage') { | 172 } else if (e.data.method === 'showPage') { |
| 172 showPage(e.data.params.pageId, | 173 showPage( |
| 173 HISTORY_STATE_OPTION.PUSH, | 174 e.data.params.pageId, HISTORY_STATE_OPTION.PUSH, e.data.params.path); |
| 174 e.data.params.path); | |
| 175 } else if (e.data.method === 'navigationControlsLoaded') { | 175 } else if (e.data.method === 'navigationControlsLoaded') { |
| 176 onNavigationControlsLoaded(); | 176 onNavigationControlsLoaded(); |
| 177 } else if (e.data.method === 'adjustToScroll') { | 177 } else if (e.data.method === 'adjustToScroll') { |
| 178 adjustToScroll(/** @type {number} */(e.data.params)); | 178 adjustToScroll(/** @type {number} */ (e.data.params)); |
| 179 } else if (e.data.method === 'mouseWheel') { | 179 } else if (e.data.method === 'mouseWheel') { |
| 180 forwardMouseWheel(/** @type {Object} */(e.data.params)); | 180 forwardMouseWheel(/** @type {Object} */ (e.data.params)); |
| 181 } else if (e.data.method === 'mouseDown') { | 181 } else if (e.data.method === 'mouseDown') { |
| 182 forwardMouseDown(); | 182 forwardMouseDown(); |
| 183 } else { | 183 } else { |
| 184 console.error('Received unexpected message', e.data); | 184 console.error('Received unexpected message', e.data); |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 | 187 |
| 188 /** | 188 /** |
| 189 * Sends the navigation iframe to the background. | 189 * Sends the navigation iframe to the background. |
| 190 */ | 190 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 205 | 205 |
| 206 /** | 206 /** |
| 207 * Enables or disables animated transitions when changing content while | 207 * Enables or disables animated transitions when changing content while |
| 208 * horizontally scrolled. | 208 * horizontally scrolled. |
| 209 * @param {boolean} enabled True if enabled, else false to disable. | 209 * @param {boolean} enabled True if enabled, else false to disable. |
| 210 */ | 210 */ |
| 211 function setContentChanging(enabled) { | 211 function setContentChanging(enabled) { |
| 212 navFrame.classList[enabled ? 'add' : 'remove']('changing-content'); | 212 navFrame.classList[enabled ? 'add' : 'remove']('changing-content'); |
| 213 | 213 |
| 214 if (isRTL()) { | 214 if (isRTL()) { |
| 215 uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow, | 215 uber.invokeMethodOnWindow( |
| 216 'setContentChanging', enabled); | 216 navFrame.firstChild.contentWindow, 'setContentChanging', enabled); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 /** | 220 /** |
| 221 * Get an iframe based on the origin of a received post message. | 221 * Get an iframe based on the origin of a received post message. |
| 222 * @param {string} origin The origin of a post message. | 222 * @param {string} origin The origin of a post message. |
| 223 * @return {!Element} The frame associated to |origin| or null. | 223 * @return {!Element} The frame associated to |origin| or null. |
| 224 */ | 224 */ |
| 225 function getIframeFromOrigin(origin) { | 225 function getIframeFromOrigin(origin) { |
| 226 assert(origin.substr(-1) != '/', 'invalid origin given'); | 226 assert(origin.substr(-1) != '/', 'invalid origin given'); |
| 227 var query = '.iframe-container > iframe[src^="' + origin + '/"]'; | 227 var query = '.iframe-container > iframe[src^="' + origin + '/"]'; |
| 228 var element = document.querySelector(query); | 228 var element = document.querySelector(query); |
| 229 assert(element); | 229 assert(element); |
| 230 return /** @type {!Element} */(element); | 230 return /** @type {!Element} */ (element); |
| 231 } | 231 } |
| 232 | 232 |
| 233 /** | 233 /** |
| 234 * Changes the path past the page title (i.e. chrome://chrome/settings/(.*)). | 234 * Changes the path past the page title (i.e. chrome://chrome/settings/(.*)). |
| 235 * @param {Object} state The page's state object for the navigation. | 235 * @param {Object} state The page's state object for the navigation. |
| 236 * @param {string} path The new /path/ to be set after the page name. | 236 * @param {string} path The new /path/ to be set after the page name. |
| 237 * @param {number} historyOption The type of history modification to make. | 237 * @param {number} historyOption The type of history modification to make. |
| 238 */ | 238 */ |
| 239 function changePathTo(state, path, historyOption) { | 239 function changePathTo(state, path, historyOption) { |
| 240 assert(!path || path.substr(-1) != '/', 'invalid path given'); | 240 assert(!path || path.substr(-1) != '/', 'invalid path given'); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 uber.invokeMethodOnWindow(selectedWindow, 'frameSelected'); | 380 uber.invokeMethodOnWindow(selectedWindow, 'frameSelected'); |
| 381 selectedWindow.focus(); | 381 selectedWindow.focus(); |
| 382 | 382 |
| 383 if (historyOption != HISTORY_STATE_OPTION.NONE) | 383 if (historyOption != HISTORY_STATE_OPTION.NONE) |
| 384 changePathTo({}, path, historyOption); | 384 changePathTo({}, path, historyOption); |
| 385 | 385 |
| 386 if (container.dataset.title) | 386 if (container.dataset.title) |
| 387 document.title = container.dataset.title; | 387 document.title = container.dataset.title; |
| 388 assert('favicon' in container.dataset); | 388 assert('favicon' in container.dataset); |
| 389 | 389 |
| 390 var dataset = /** @type {{favicon: string}} */(container.dataset); | 390 var dataset = /** @type {{favicon: string}} */ (container.dataset); |
| 391 $('favicon').href = 'chrome://theme/' + dataset.favicon; | 391 $('favicon').href = 'chrome://theme/' + dataset.favicon; |
| 392 $('favicon2x').href = 'chrome://theme/' + dataset.favicon + '@2x'; | 392 $('favicon2x').href = 'chrome://theme/' + dataset.favicon + '@2x'; |
| 393 | 393 |
| 394 updateNavigationControls(); | 394 updateNavigationControls(); |
| 395 } | 395 } |
| 396 | 396 |
| 397 function onNavigationControlsLoaded() { | 397 function onNavigationControlsLoaded() { |
| 398 updateNavigationControls(); | 398 updateNavigationControls(); |
| 399 } | 399 } |
| 400 | 400 |
| 401 /** | 401 /** |
| 402 * Sends a message to uber-frame to update the appearance of the nav controls. | 402 * Sends a message to uber-frame to update the appearance of the nav controls. |
| 403 * It should be called whenever the selected iframe changes. | 403 * It should be called whenever the selected iframe changes. |
| 404 */ | 404 */ |
| 405 function updateNavigationControls() { | 405 function updateNavigationControls() { |
| 406 var container = getSelectedIframeContainer(); | 406 var container = getSelectedIframeContainer(); |
| 407 uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow, | 407 uber.invokeMethodOnWindow( |
| 408 'changeSelection', {pageId: container.id}); | 408 navFrame.firstChild.contentWindow, 'changeSelection', |
| 409 {pageId: container.id}); |
| 409 } | 410 } |
| 410 | 411 |
| 411 /** | 412 /** |
| 412 * Forwarded scroll offset from a content frame's scroll handler. | 413 * Forwarded scroll offset from a content frame's scroll handler. |
| 413 * @param {number} scrollOffset The scroll offset from the content frame. | 414 * @param {number} scrollOffset The scroll offset from the content frame. |
| 414 */ | 415 */ |
| 415 function adjustToScroll(scrollOffset) { | 416 function adjustToScroll(scrollOffset) { |
| 416 // NOTE: The scroll is reset to 0 and easing turned on every time a user | 417 // NOTE: The scroll is reset to 0 and easing turned on every time a user |
| 417 // switches frames. If we receive a non-zero value it has to have come from | 418 // switches frames. If we receive a non-zero value it has to have come from |
| 418 // a real user scroll, so we disable easing when this happens. | 419 // a real user scroll, so we disable easing when this happens. |
| 419 if (scrollOffset != 0) | 420 if (scrollOffset != 0) |
| 420 setContentChanging(false); | 421 setContentChanging(false); |
| 421 | 422 |
| 422 if (isRTL()) { | 423 if (isRTL()) { |
| 423 uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow, | 424 uber.invokeMethodOnWindow( |
| 424 'adjustToScroll', | 425 navFrame.firstChild.contentWindow, 'adjustToScroll', scrollOffset); |
| 425 scrollOffset); | |
| 426 var navWidth = Math.max(0, +navFrame.dataset.width + scrollOffset); | 426 var navWidth = Math.max(0, +navFrame.dataset.width + scrollOffset); |
| 427 navFrame.style.width = navWidth + 'px'; | 427 navFrame.style.width = navWidth + 'px'; |
| 428 } else { | 428 } else { |
| 429 navFrame.style.webkitTransform = 'translateX(' + -scrollOffset + 'px)'; | 429 navFrame.style.webkitTransform = 'translateX(' + -scrollOffset + 'px)'; |
| 430 } | 430 } |
| 431 } | 431 } |
| 432 | 432 |
| 433 /** | 433 /** |
| 434 * Forward scroll wheel events to subpages. | 434 * Forward scroll wheel events to subpages. |
| 435 * @param {Object} params Relevant parameters of wheel event. | 435 * @param {Object} params Relevant parameters of wheel event. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 459 container.hidden = true; | 459 container.hidden = true; |
| 460 container.setAttribute('aria-hidden', 'true'); | 460 container.setAttribute('aria-hidden', 'true'); |
| 461 } | 461 } |
| 462 container.addEventListener('webkitTransitionEnd', function(event) { | 462 container.addEventListener('webkitTransitionEnd', function(event) { |
| 463 if (!event.target.classList.contains('selected')) | 463 if (!event.target.classList.contains('selected')) |
| 464 event.target.hidden = true; | 464 event.target.hidden = true; |
| 465 }); | 465 }); |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 | 468 |
| 469 return { | 469 return {onLoad: onLoad, onPopHistoryState: onPopHistoryState}; |
| 470 onLoad: onLoad, | |
| 471 onPopHistoryState: onPopHistoryState | |
| 472 }; | |
| 473 }); | 470 }); |
| 474 | 471 |
| 475 window.addEventListener('popstate', uber.onPopHistoryState); | 472 window.addEventListener('popstate', uber.onPopHistoryState); |
| 476 document.addEventListener('DOMContentLoaded', uber.onLoad); | 473 document.addEventListener('DOMContentLoaded', uber.onLoad); |
| OLD | NEW |