Home | History | Annotate | Download | only in uber
      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 
     10 cr.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