1cef7893435aa41160dd1255c43cb8498279738ccChris Craik// Copyright 2013 The Chromium Authors. All rights reserved.
2cef7893435aa41160dd1255c43cb8498279738ccChris Craik// Use of this source code is governed by a BSD-style license that can be
3cef7893435aa41160dd1255c43cb8498279738ccChris Craik// found in the LICENSE file.
4cef7893435aa41160dd1255c43cb8498279738ccChris Craik
5cef7893435aa41160dd1255c43cb8498279738ccChris Craik// This file provides common functionality for synthetic gesture actions.
6cef7893435aa41160dd1255c43cb8498279738ccChris Craik'use strict';
7cef7893435aa41160dd1255c43cb8498279738ccChris Craik
8cef7893435aa41160dd1255c43cb8498279738ccChris Craik(function() {
9cef7893435aa41160dd1255c43cb8498279738ccChris Craik
10cef7893435aa41160dd1255c43cb8498279738ccChris Craik  // Returns the bounding rectangle wrt to the top-most document.
11cef7893435aa41160dd1255c43cb8498279738ccChris Craik  function getBoundingRect(el) {
12cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var client_rect = el.getBoundingClientRect();
13cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var bound = { left: client_rect.left,
14cef7893435aa41160dd1255c43cb8498279738ccChris Craik                  top: client_rect.top,
15cef7893435aa41160dd1255c43cb8498279738ccChris Craik                  width: client_rect.width,
16cef7893435aa41160dd1255c43cb8498279738ccChris Craik                  height: client_rect.height };
17cef7893435aa41160dd1255c43cb8498279738ccChris Craik
18cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var frame = el.ownerDocument.defaultView.frameElement;
19cef7893435aa41160dd1255c43cb8498279738ccChris Craik    while (frame) {
20cef7893435aa41160dd1255c43cb8498279738ccChris Craik      var frame_bound = frame.getBoundingClientRect();
21cef7893435aa41160dd1255c43cb8498279738ccChris Craik      // This computation doesn't account for more complex CSS transforms on the
22cef7893435aa41160dd1255c43cb8498279738ccChris Craik      // frame (e.g. scaling or rotations).
23cef7893435aa41160dd1255c43cb8498279738ccChris Craik      bound.left += frame_bound.left;
24cef7893435aa41160dd1255c43cb8498279738ccChris Craik      bound.top += frame_bound.top;
25cef7893435aa41160dd1255c43cb8498279738ccChris Craik
26cef7893435aa41160dd1255c43cb8498279738ccChris Craik      frame = frame.ownerDocument.frameElement;
27cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
28cef7893435aa41160dd1255c43cb8498279738ccChris Craik    return bound;
29cef7893435aa41160dd1255c43cb8498279738ccChris Craik  }
30cef7893435aa41160dd1255c43cb8498279738ccChris Craik
31cef7893435aa41160dd1255c43cb8498279738ccChris Craik  function getBoundingVisibleRect(el) {
32cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var rect = getBoundingRect(el);
33cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (rect.top < 0) {
34cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.height += rect.top;
35cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.top = 0;
36cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
37cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (rect.left < 0) {
38cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.width += rect.left;
39cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.left = 0;
40cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
41cef7893435aa41160dd1255c43cb8498279738ccChris Craik
42cef7893435aa41160dd1255c43cb8498279738ccChris Craik    // TODO(ymalik): Remove the fallback path once the visualViewportHeight and
43cef7893435aa41160dd1255c43cb8498279738ccChris Craik    // visualViewportWidth properties roll into stable.
44cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var visualViewportHeight = window.innerHeight;
45cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var visualViewportWidth = window.innerWidth;
46cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (chrome.gpuBenchmarking.visualViewportHeight) {
47cef7893435aa41160dd1255c43cb8498279738ccChris Craik      visualViewportHeight = chrome.gpuBenchmarking.visualViewportHeight();
48cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
49cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (chrome.gpuBenchmarking.visualViewportWidth) {
50cef7893435aa41160dd1255c43cb8498279738ccChris Craik      visualViewportWidth = chrome.gpuBenchmarking.visualViewportWidth();
51cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
52cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var outsideHeight = (rect.top + rect.height) - visualViewportHeight;
53cef7893435aa41160dd1255c43cb8498279738ccChris Craik    var outsideWidth = (rect.left + rect.width) - visualViewportWidth;
54cef7893435aa41160dd1255c43cb8498279738ccChris Craik
55cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (outsideHeight > 0) {
56cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.height -= outsideHeight;
57cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
58cef7893435aa41160dd1255c43cb8498279738ccChris Craik    if (outsideWidth > 0) {
59cef7893435aa41160dd1255c43cb8498279738ccChris Craik      rect.width -= outsideWidth;
60cef7893435aa41160dd1255c43cb8498279738ccChris Craik    }
61cef7893435aa41160dd1255c43cb8498279738ccChris Craik    return rect;
62cef7893435aa41160dd1255c43cb8498279738ccChris Craik  };
63cef7893435aa41160dd1255c43cb8498279738ccChris Craik
64cef7893435aa41160dd1255c43cb8498279738ccChris Craik  window.__GestureCommon_GetBoundingVisibleRect = getBoundingVisibleRect;
65cef7893435aa41160dd1255c43cb8498279738ccChris Craik})();
66