// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @fileoverview A collection of utility methods for UberPage and its contained * pages. */ cr.define('uber', function() { /** * Fixed position header elements on the page to be shifted by handleScroll. * @type {NodeList} */ var headerElements; /** * This should be called by uber content pages when DOM content has loaded. */ function onContentFrameLoaded() { headerElements = document.getElementsByTagName('header'); document.addEventListener('scroll', handleScroll); // Prevent the navigation from being stuck in a disabled state when a // content page is reloaded while an overlay is visible (crbug.com/246939). invokeMethodOnParent('stopInterceptingEvents'); // Trigger the scroll handler to tell the navigation if our page started // with some scroll (happens when you use tab restore). handleScroll(); window.addEventListener('message', handleWindowMessage); } /** * Handles scroll events on the document. This adjusts the position of all * headers and updates the parent frame when the page is scrolled. * @private */ function handleScroll() { var scrollLeft = scrollLeftForDocument(document); var offset = scrollLeft * -1; for (var i = 0; i < headerElements.length; i++) { // As a workaround for http://crbug.com/231830, set the transform to // 'none' rather than 0px. headerElements[i].style.webkitTransform = offset ? 'translateX(' + offset + 'px)' : 'none'; } invokeMethodOnParent('adjustToScroll', scrollLeft); }; /** * Handles 'message' events on window. * @param {Event} e The message event. */ function handleWindowMessage(e) { if (e.data.method === 'frameSelected') handleFrameSelected(); else if (e.data.method === 'mouseWheel') handleMouseWheel(e.data.params); } /** * This is called when a user selects this frame via the navigation bar * frame (and is triggered via postMessage() from the uber page). * @private */ function handleFrameSelected() { setScrollTopForDocument(document, 0); } /** * Called when a user mouse wheels (or trackpad scrolls) over the nav frame. * The wheel event is forwarded here and we scroll the body. * There's no way to figure out the actual scroll amount for a given delta. * It differs for every platform and even initWebKitWheelEvent takes a * pixel amount instead of a wheel delta. So we just choose something * reasonable and hope no one notices the difference. * @param {Object} params A structure that holds wheel deltas in X and Y. */ function handleMouseWheel(params) { window.scrollBy(-params.deltaX * 49 / 120, -params.deltaY * 49 / 120); } /** * Invokes a method on the parent window (UberPage). This is a convenience * method for API calls into the uber page. * @param {string} method The name of the method to invoke. * @param {Object=} opt_params Optional property bag of parameters to pass to * the invoked method. * @private */ function invokeMethodOnParent(method, opt_params) { if (window.location == window.parent.location) return; invokeMethodOnWindow(window.parent, method, opt_params, 'chrome://chrome'); } /** * Invokes a method on the target window. * @param {string} method The name of the method to invoke. * @param {Object=} opt_params Optional property bag of parameters to pass to * the invoked method. * @param {string=} opt_url The origin of the target window. * @private */ function invokeMethodOnWindow(targetWindow, method, opt_params, opt_url) { var data = {method: method, params: opt_params}; targetWindow.postMessage(data, opt_url ? opt_url : '*'); } return { invokeMethodOnParent: invokeMethodOnParent, invokeMethodOnWindow: invokeMethodOnWindow, onContentFrameLoaded: onContentFrameLoaded, }; });