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 /** | 5 /** |
6 * @fileoverview A collection of utility methods for UberPage and its contained | 6 * @fileoverview A collection of utility methods for UberPage and its contained |
7 * pages. | 7 * pages. |
8 */ | 8 */ |
9 | 9 |
10 cr.define('uber', function() { | 10 cr.define('uber', function() { |
11 | 11 |
12 /** | 12 /** |
13 * Fixed position header elements on the page to be shifted by handleScroll. | 13 * Fixed position header elements on the page to be shifted by handleScroll. |
14 * @type {NodeList} | 14 * @type {NodeList} |
15 */ | 15 */ |
16 var headerElements; | 16 var headerElements; |
17 | 17 |
18 /** | 18 /** |
19 * This should be called by uber content pages when DOM content has loaded. | 19 * This should be called by uber content pages when DOM content has loaded. |
20 */ | 20 */ |
21 function onContentFrameLoaded() { | 21 function onContentFrameLoaded() { |
22 headerElements = document.getElementsByTagName('header'); | 22 headerElements = document.getElementsByTagName('header'); |
23 document.addEventListener('scroll', handleScroll); | 23 document.addEventListener('scroll', handleScroll); |
24 | 24 |
25 invokeMethodOnParent('ready'); | |
26 | |
25 // Prevent the navigation from being stuck in a disabled state when a | 27 // Prevent the navigation from being stuck in a disabled state when a |
26 // content page is reloaded while an overlay is visible (crbug.com/246939). | 28 // content page is reloaded while an overlay is visible (crbug.com/246939). |
27 invokeMethodOnParent('stopInterceptingEvents'); | 29 invokeMethodOnParent('stopInterceptingEvents'); |
28 | 30 |
29 // Trigger the scroll handler to tell the navigation if our page started | 31 // Trigger the scroll handler to tell the navigation if our page started |
30 // with some scroll (happens when you use tab restore). | 32 // with some scroll (happens when you use tab restore). |
31 handleScroll(); | 33 handleScroll(); |
32 | 34 |
33 window.addEventListener('message', handleWindowMessage); | 35 window.addEventListener('message', handleWindowMessage); |
34 } | 36 } |
(...skipping 18 matching lines...) Expand all Loading... | |
53 | 55 |
54 /** | 56 /** |
55 * Handles 'message' events on window. | 57 * Handles 'message' events on window. |
56 * @param {Event} e The message event. | 58 * @param {Event} e The message event. |
57 */ | 59 */ |
58 function handleWindowMessage(e) { | 60 function handleWindowMessage(e) { |
59 if (e.data.method === 'frameSelected') | 61 if (e.data.method === 'frameSelected') |
60 handleFrameSelected(); | 62 handleFrameSelected(); |
61 else if (e.data.method === 'mouseWheel') | 63 else if (e.data.method === 'mouseWheel') |
62 handleMouseWheel(e.data.params); | 64 handleMouseWheel(e.data.params); |
65 else if (e.data.method === 'popState') | |
66 handlePopState(e.data.params.state, e.data.params.path); | |
63 } | 67 } |
64 | 68 |
65 /** | 69 /** |
66 * This is called when a user selects this frame via the navigation bar | 70 * This is called when a user selects this frame via the navigation bar |
67 * frame (and is triggered via postMessage() from the uber page). | 71 * frame (and is triggered via postMessage() from the uber page). |
68 * @private | 72 * @private |
69 */ | 73 */ |
70 function handleFrameSelected() { | 74 function handleFrameSelected() { |
71 setScrollTopForDocument(document, 0); | 75 setScrollTopForDocument(document, 0); |
72 } | 76 } |
73 | 77 |
74 /** | 78 /** |
75 * Called when a user mouse wheels (or trackpad scrolls) over the nav frame. | 79 * Called when a user mouse wheels (or trackpad scrolls) over the nav frame. |
76 * The wheel event is forwarded here and we scroll the body. | 80 * The wheel event is forwarded here and we scroll the body. |
77 * There's no way to figure out the actual scroll amount for a given delta. | 81 * There's no way to figure out the actual scroll amount for a given delta. |
78 * It differs for every platform and even initWebKitWheelEvent takes a | 82 * It differs for every platform and even initWebKitWheelEvent takes a |
79 * pixel amount instead of a wheel delta. So we just choose something | 83 * pixel amount instead of a wheel delta. So we just choose something |
80 * reasonable and hope no one notices the difference. | 84 * reasonable and hope no one notices the difference. |
81 * @param {Object} params A structure that holds wheel deltas in X and Y. | 85 * @param {Object} params A structure that holds wheel deltas in X and Y. |
82 */ | 86 */ |
83 function handleMouseWheel(params) { | 87 function handleMouseWheel(params) { |
84 window.scrollBy(-params.deltaX * 49 / 120, -params.deltaY * 49 / 120); | 88 window.scrollBy(-params.deltaX * 49 / 120, -params.deltaY * 49 / 120); |
85 } | 89 } |
86 | 90 |
87 /** | 91 /** |
92 * Called when the parent window restores some state saved by uber.pushState | |
93 * or uber.replaceState. Simulates a popstate event. | |
94 */ | |
95 function handlePopState(state, path) { | |
96 history.replaceState(state, '', path); | |
97 window.dispatchEvent(new PopStateEvent('popstate', {state: state})); | |
98 } | |
99 | |
100 /** | |
101 * Returns true if this frame has a parent. | |
Dan Beam
2014/05/19 23:49:10
^ and then remove this (seems duplicative)
davidben
2014/05/20 00:12:55
Done.
| |
102 * @return {boolean} Whether this frame has a parent. | |
103 */ | |
104 function hasParent() { | |
105 return window != window.parent; | |
106 } | |
107 | |
108 /** | |
88 * Invokes a method on the parent window (UberPage). This is a convenience | 109 * Invokes a method on the parent window (UberPage). This is a convenience |
89 * method for API calls into the uber page. | 110 * method for API calls into the uber page. |
90 * @param {string} method The name of the method to invoke. | 111 * @param {string} method The name of the method to invoke. |
91 * @param {Object=} opt_params Optional property bag of parameters to pass to | 112 * @param {Object=} opt_params Optional property bag of parameters to pass to |
92 * the invoked method. | 113 * the invoked method. |
93 * @private | 114 * @private |
94 */ | 115 */ |
95 function invokeMethodOnParent(method, opt_params) { | 116 function invokeMethodOnParent(method, opt_params) { |
96 if (window.location == window.parent.location) | 117 if (!hasParent()) |
97 return; | 118 return; |
98 | 119 |
99 invokeMethodOnWindow(window.parent, method, opt_params, 'chrome://chrome'); | 120 invokeMethodOnWindow(window.parent, method, opt_params, 'chrome://chrome'); |
100 } | 121 } |
101 | 122 |
102 /** | 123 /** |
103 * Invokes a method on the target window. | 124 * Invokes a method on the target window. |
104 * @param {string} method The name of the method to invoke. | 125 * @param {string} method The name of the method to invoke. |
105 * @param {Object=} opt_params Optional property bag of parameters to pass to | 126 * @param {Object=} opt_params Optional property bag of parameters to pass to |
106 * the invoked method. | 127 * the invoked method. |
107 * @param {string=} opt_url The origin of the target window. | 128 * @param {string=} opt_url The origin of the target window. |
108 * @private | 129 * @private |
109 */ | 130 */ |
110 function invokeMethodOnWindow(targetWindow, method, opt_params, opt_url) { | 131 function invokeMethodOnWindow(targetWindow, method, opt_params, opt_url) { |
111 var data = {method: method, params: opt_params}; | 132 var data = {method: method, params: opt_params}; |
112 targetWindow.postMessage(data, opt_url ? opt_url : '*'); | 133 targetWindow.postMessage(data, opt_url ? opt_url : '*'); |
113 } | 134 } |
114 | 135 |
136 /** | |
137 * Updates the page's history state. If the page is embedded in a child, | |
138 * forward the information to the parent for it to manage history for us. This | |
139 * is a replacement of history.replaceState and history.pushState. | |
140 * @param {Object} state A state object for replaceState and pushState. | |
141 * @param {string} title The title of the page to replace. | |
142 * @param {string} path The path the page navigated to. | |
143 * @param {boolean} replace If true, navigate with replacement. | |
144 * @private | |
145 */ | |
146 function updateHistory(state, path, replace) { | |
147 var historyFunction = replace ? | |
148 window.history.replaceState : | |
149 window.history.pushState; | |
150 | |
151 if (hasParent()) { | |
152 // If there's a parent, always replaceState. The parent will do the actual | |
153 // pushState. | |
154 historyFunction = window.history.replaceState; | |
155 invokeMethodOnParent('updateHistory', { | |
156 state: state, path: path, replace: replace}); | |
157 } | |
158 historyFunction.call(window.history, state, '', '/' + path); | |
159 } | |
160 | |
161 /** | |
162 * Sets the current title for the page. If the page is embedded in a child, | |
163 * forward the information to the parent. This is a replacement for setting | |
164 * document.title. | |
165 * @param {string} title The new title for the page. | |
166 */ | |
167 function setTitle(title) { | |
168 document.title = title; | |
169 invokeMethodOnParent('setTitle', {title: title}); | |
170 } | |
171 | |
172 /** | |
173 * Pushes new history state for the page. If the page is embedded in a child, | |
174 * forward the information to the parent; when embedded, all history entries | |
175 * are attached to the parent. This is a replacement of history.pushState. | |
176 * @param {Object} state A state object for replaceState and pushState. | |
177 * @param {string} path The path the page navigated to. | |
178 */ | |
179 function pushState(state, path) { | |
180 updateHistory(state, path, false); | |
181 } | |
182 | |
183 /** | |
184 * Replaces the page's history state. If the page is embedded in a child, | |
185 * forward the information to the parent; when embedded, all history entries | |
186 * are attached to the parent. This is a replacement of history.replaceState. | |
187 * @param {Object} state A state object for replaceState and pushState. | |
188 * @param {string} path The path the page navigated to. | |
189 */ | |
190 function replaceState(state, path) { | |
191 updateHistory(state, path, true); | |
192 } | |
193 | |
115 return { | 194 return { |
116 invokeMethodOnParent: invokeMethodOnParent, | 195 invokeMethodOnParent: invokeMethodOnParent, |
117 invokeMethodOnWindow: invokeMethodOnWindow, | 196 invokeMethodOnWindow: invokeMethodOnWindow, |
118 onContentFrameLoaded: onContentFrameLoaded, | 197 onContentFrameLoaded: onContentFrameLoaded, |
198 pushState: pushState, | |
199 replaceState: replaceState, | |
200 setTitle: setTitle, | |
119 }; | 201 }; |
120 }); | 202 }); |
OLD | NEW |