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 3// found in the LICENSE file. 4 5/** 6 * @fileoverview A collection of utility methods for UberPage and its contained 7 * pages. 8 */ 9 10cr.define('uber', function() { 11 12 /** 13 * Fixed position header elements on the page to be shifted by handleScroll. 14 * @type {NodeList} 15 */ 16 var headerElements; 17 18 /** 19 * This should be called by uber content pages when DOM content has loaded. 20 */ 21 function onContentFrameLoaded() { 22 headerElements = document.getElementsByTagName('header'); 23 document.addEventListener('scroll', handleScroll); 24 25 // 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). 27 invokeMethodOnParent('stopInterceptingEvents'); 28 29 // Trigger the scroll handler to tell the navigation if our page started 30 // with some scroll (happens when you use tab restore). 31 handleScroll(); 32 33 window.addEventListener('message', handleWindowMessage); 34 } 35 36 /** 37 * Handles scroll events on the document. This adjusts the position of all 38 * headers and updates the parent frame when the page is scrolled. 39 * @private 40 */ 41 function handleScroll() { 42 var scrollLeft = scrollLeftForDocument(document); 43 var offset = scrollLeft * -1; 44 for (var i = 0; i < headerElements.length; i++) { 45 // As a workaround for http://crbug.com/231830, set the transform to 46 // 'none' rather than 0px. 47 headerElements[i].style.webkitTransform = offset ? 48 'translateX(' + offset + 'px)' : 'none'; 49 } 50 51 invokeMethodOnParent('adjustToScroll', scrollLeft); 52 }; 53 54 /** 55 * Handles 'message' events on window. 56 * @param {Event} e The message event. 57 */ 58 function handleWindowMessage(e) { 59 if (e.data.method === 'frameSelected') 60 handleFrameSelected(); 61 else if (e.data.method === 'mouseWheel') 62 handleMouseWheel(e.data.params); 63 } 64 65 /** 66 * This is called when a user selects this frame via the navigation bar 67 * frame (and is triggered via postMessage() from the uber page). 68 * @private 69 */ 70 function handleFrameSelected() { 71 setScrollTopForDocument(document, 0); 72 } 73 74 /** 75 * 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. 77 * 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 79 * pixel amount instead of a wheel delta. So we just choose something 80 * reasonable and hope no one notices the difference. 81 * @param {Object} params A structure that holds wheel deltas in X and Y. 82 */ 83 function handleMouseWheel(params) { 84 window.scrollBy(-params.deltaX * 49 / 120, -params.deltaY * 49 / 120); 85 } 86 87 /** 88 * Invokes a method on the parent window (UberPage). This is a convenience 89 * method for API calls into the uber page. 90 * @param {string} method The name of the method to invoke. 91 * @param {Object=} opt_params Optional property bag of parameters to pass to 92 * the invoked method. 93 * @private 94 */ 95 function invokeMethodOnParent(method, opt_params) { 96 if (window.location == window.parent.location) 97 return; 98 99 invokeMethodOnWindow(window.parent, method, opt_params, 'chrome://chrome'); 100 } 101 102 /** 103 * Invokes a method on the target window. 104 * @param {string} method The name of the method to invoke. 105 * @param {Object=} opt_params Optional property bag of parameters to pass to 106 * the invoked method. 107 * @param {string=} opt_url The origin of the target window. 108 * @private 109 */ 110 function invokeMethodOnWindow(targetWindow, method, opt_params, opt_url) { 111 var data = {method: method, params: opt_params}; 112 targetWindow.postMessage(data, opt_url ? opt_url : '*'); 113 } 114 115 return { 116 invokeMethodOnParent: invokeMethodOnParent, 117 invokeMethodOnWindow: invokeMethodOnWindow, 118 onContentFrameLoaded: onContentFrameLoaded, 119 }; 120}); 121