// Copyright 2013 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.

// This file provides common functionality for synthetic gesture actions.
'use strict';

(function() {

  function getBoundingVisibleRect(el) {
    var bound = el.getBoundingClientRect();
    var rect = { top: bound.top,
                 left: bound.left,
                 width: bound.width,
                 height: bound.height };
    if (rect.top < 0) {
      rect.height += rect.top;
      rect.top = 0;
    }
    if (rect.left < 0) {
      rect.width += rect.left;
      rect.left = 0;
    }

    var outsideHeight = (rect.top + rect.height) - window.innerHeight;
    var outsideWidth = (rect.left + rect.width) - window.innerWidth;

    if (outsideHeight > 0) {
      rect.height -= outsideHeight;
    }
    if (outsideWidth > 0) {
      rect.width -= outsideWidth;
    }
    return rect;
  };

  window.__GestureCommon_GetBoundingVisibleRect = getBoundingVisibleRect;
})();

// Copyright 2013 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.

// This file provides common functionality for synthetic gesture actions.
'use strict';

(function() {

  // Returns the bounding rectangle wrt to the top-most document.
  function getBoundingRect(el) {
    var client_rect = el.getBoundingClientRect();
    var bound = { left: client_rect.left,
                  top: client_rect.top,
                  width: client_rect.width,
                  height: client_rect.height };

    var frame = el.ownerDocument.defaultView.frameElement;
    while (frame) {
      var frame_bound = frame.getBoundingClientRect();
      // This computation doesn't account for more complex CSS transforms on the
      // frame (e.g. scaling or rotations).
      bound.left += frame_bound.left;
      bound.top += frame_bound.top;

      frame = frame.ownerDocument.frameElement;
    }
    return bound;
  }

  function getBoundingVisibleRect(el) {
    var rect = getBoundingRect(el);
    if (rect.top < 0) {
      rect.height += rect.top;
      rect.top = 0;
    }
    if (rect.left < 0) {
      rect.width += rect.left;
      rect.left = 0;
    }

    var outsideHeight = (rect.top + rect.height) - window.innerHeight;
    var outsideWidth = (rect.left + rect.width) - window.innerWidth;

    if (outsideHeight > 0) {
      rect.height -= outsideHeight;
    }
    if (outsideWidth > 0) {
      rect.width -= outsideWidth;
    }
    return rect;
  };

  window.__GestureCommon_GetBoundingVisibleRect = getBoundingVisibleRect;
})();

Fix calculation of bounding rects for elements in iframes.
Telemetry: Fix calculation of bounding rects for elements in iframes.

We currently use getBoundingClientRect() to compute the bounds of an element in
the page. That method returns the coordinates wrt to its viewport (which could
be an iframe). For synthetic gestures however, we require coordinates wrt to the
top-most window.

This patch fixes the computation by walking up the tree of frames and updating
the bounds for the element by the coordinates of the frames.

Tested on http://www.polymer-project.org/components/paper-elements/demo.html

BUG=391406

Review URL: https://codereview.chromium.org/365113004

git-svn-id: de016e52bd170d2d4f2344f9bf92d50478b649e0@281418 0039d316-1c4b-4281-b951-d872f2087c98
