• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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