Skip to content
This repository has been archived by the owner on May 22, 2018. It is now read-only.

Commit

Permalink
JasonLeyba, on behalf of KenKania: Creating a chromedriver specific l…
Browse files Browse the repository at this point in the history
…ocation in view atom.

Added an option for centering objects in a scrollable viewport.
Refactored for better testability and added some tests.

r12676
  • Loading branch information
jleyba committed Jul 1, 2011
1 parent 749aac6 commit f535cc3
Show file tree
Hide file tree
Showing 6 changed files with 545 additions and 129 deletions.
5 changes: 4 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,10 @@ file "cpp/IEDriver/sizzle.h" => [ "//third_party/js/sizzle:sizzle:header" ] do
end
task :sizzle_header => [ "cpp/IEDriver/sizzle.h" ]

file "javascript/deps.js" => FileList["third_party/closure/goog/**/*.js", "javascript/*-atom*/*.js"] do
file "javascript/deps.js" => FileList[
"third_party/closure/goog/**/*.js",
"javascript/*-atom*/*.js",
"javascript/chrome-driver/*.js" ] do
our_cmd = "java -jar third_party/py/jython.jar third_party/closure/bin/calcdeps.py "
our_cmd << "--output_mode=deps --path=javascript "
our_cmd << "--dep=third_party/closure/goog"
Expand Down
185 changes: 185 additions & 0 deletions javascript/chrome-driver/atoms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @fileoverview Chrome specific atoms.
*
*/

goog.provide('webdriver.chrome');

goog.require('goog.dom');
goog.require('goog.math.Coordinate');
goog.require('goog.math.Rect');
goog.require('goog.math.Size');
goog.require('goog.style');


/**
* Returns the minimum required offsets to scroll a given region into view.
* If the region is larger than the scrollable view, the region will be
* centered or aligned with the top-left of the scrollable view, depending
* on the value of "center".
*
* @param {!goog.math.Size} size The size of the scrollable view.
* @param {!goog.math.Rect} region The region of the scrollable to bring into
* view.
* @param {boolean} center If true, when the region is too big to view,
* center it instead of aligning with the top-left.
* @return {!goog.math.Coordinate} Offset by which to scroll.
* @private
*/
webdriver.chrome.computeScrollOffsets_ = function(size, region,
center) {
var scroll = [0, 0];
var scrollableSize = [size.width, size.height];
var regionLoc = [region.left, region.top];
var regionSize = [region.width, region.height];

for (var i = 0; i < 2; i++) {
if (regionSize[i] > scrollableSize[i]) {
if (center)
scroll[i] = regionLoc[i] + regionSize[i] / 2 - scrollableSize[i] / 2;
else
scroll[i] = regionLoc[i];
} else {
var alignRight = regionLoc[i] - scrollableSize[i] + regionSize[i];
if (alignRight > 0)
scroll[i] = alignRight;
else if (regionLoc[i] < 0)
scroll[i] = regionLoc[i];
}
}

return new goog.math.Coordinate(scroll[0], scroll[1]);
};


/**
* Return the offset of the given element from its container.
*
* @param {!Element} container The container.
* @param {!Element} elem The element.
* @return {!goog.math.Coordinate} The offset.
* @private
*/
webdriver.chrome.computeOffsetInContainer_ = function(container, elem) {
var offset = goog.math.Coordinate.difference(
goog.style.getPageOffset(elem), goog.style.getPageOffset(container));
var containerBorder = goog.style.getBorderBox(container);
offset.x -= containerBorder.left;
offset.y -= containerBorder.top;
return offset;
};


/**
* Scrolls the region of an element into view. If the region will not fit,
* it will be aligned at the top-left or centered, depending on
* "center".
*
* @param {!Element} elem The element with the region to scroll into view.
* @param {!goog.math.Rect} region The region, relative to the element's
* border box, to scroll into view.
* @param {boolean} center If true, when the region is too big to view,
* center it instead of aligning with the top-left.
* @private
*/
webdriver.chrome.scrollIntoView_ = function(elem, region, center) {
function scrollHelper(scrollable, size, offset, region, center) {
region = new goog.math.Rect(
offset.x + region.left, offset.y + region.top,
region.width, region.height);

scroll = webdriver.chrome.computeScrollOffsets_(size, region, center);
scrollable.scrollLeft += scroll.x;
scrollable.scrollTop += scroll.y;
}

var doc = goog.dom.getOwnerDocument(elem);
var container = elem.parentNode;
var offset;
while (container &&
container != doc.documentElement &&
container != doc.body) {
offset = webdriver.chrome.computeOffsetInContainer_(container, elem);
var containerSize = new goog.math.Size(container.clientWidth,
container.clientHeight);
scrollHelper(container, containerSize, offset, region, center);
container = container.parentNode;
}

offset = goog.style.getClientPosition(elem);
var windowSize = goog.dom.getDomHelper(elem).getViewportSize();
scrollHelper(doc.body, windowSize, offset, region, center);
};


/**
* Scrolls a region of the given element into the client's view and returns
* its position relative to the client viewport. If the element or region is too
* large to fit in the view, it will be centered or aligned to the top-left,
* depending on the value of "center".
*
* scrollIntoView is not used because it does not work correctly in Chrome:
* http://crbug.com/73953.
*
* The element should be attached to the current document.
*
* @param {!Element} elem The element to use.
* @param {boolean} center If true, center the region when it is too big
* to fit in the view
* @param {!goog.math.Rect} opt_region The region relative to the element's
* border box to be scrolled into view. If null, the border box will be
* used.
* @return {!goog.math.Coordinate} The top-left coordinate of the element's
* region in client space
*/
webdriver.chrome.getLocationInView = function(elem, center, opt_region) {
var region = opt_region;
if (!region)
region = new goog.math.Rect(0, 0, elem.offsetWidth, elem.offsetHeight);

webdriver.chrome.scrollIntoView_(elem, region, center);

var elemClientPos = goog.style.getClientPosition(elem);
var coord = new goog.math.Coordinate(
elemClientPos.x + region.left, elemClientPos.y + region.top);
coord.x = parseInt(coord.x);
coord.y = parseInt(coord.y);
return coord;
};


/**
* Returns the first client rect of the given element, relative to the
* element's border box. If the element does not have any client rects,
* throws an error.
*
* @param {!Element} elem The element to use.
* @return {!goog.math.Rect} The first client rect of the given element,
* relative to the element's border box.
*/
webdriver.chrome.getFirstClientRect = function(elem) {
var clientRects = elem.getClientRects();
if (clientRects.length == 0)
throw new Error('Element does not have any client rects');
var clientRect = clientRects[0];
var clientPos = goog.style.getClientPosition(elem);
return new goog.math.Rect(
clientRect.left - clientPos.x, clientRect.top - clientPos.y,
clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
};

30 changes: 29 additions & 1 deletion javascript/chrome-driver/build.desc
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
# Used for http://src.chromium.org/svn/trunk/third_party/webdriver/atoms.h

js_deps(name = "deps",
srcs = [ "*.js" ],
deps = [ "//javascript/atoms:deps" ])

js_fragment(name = "get_location_in_view",
module = "webdriver.chrome",
function = "webdriver.chrome.getLocationInView",
deps = [ ":deps" ])

js_fragment(name = "get_first_client_rect",
module = "webdriver.chrome",
function = "webdriver.chrome.getFirstClientRect",
deps = [ ":deps" ])

js_test(name = "test",
srcs = [ "test/*_test.html" ],
path = "/javascript/chrome-driver/test",
sysproperties = [
{ "selenium.browser" : "org.openqa.selenium.chrome.ChromeDriver" },
],
deps = [
":deps",
"//java/client/src/org/openqa/selenium/chrome",
"//java/client/test/org/openqa/selenium/javascript",
])

js_fragment_header(name = "atoms",
deps = [
"//javascript/chrome-driver:get_first_client_rect:chrome",
"//javascript/chrome-driver:get_location_in_view:chrome",
"//javascript/webdriver-atoms:clear:chrome",
"//javascript/webdriver-atoms:execute_script:chrome",
"//javascript/webdriver-atoms:execute_async_script:chrome",
Expand All @@ -9,7 +38,6 @@ js_fragment_header(name = "atoms",
"//javascript/webdriver-atoms:get_attribute:chrome",
"//javascript/webdriver-atoms:get_effective_style:chrome",
"//javascript/webdriver-atoms:get_location:chrome",
"//javascript/webdriver-atoms:get_location_in_view:chrome",
"//javascript/webdriver-atoms:get_size:chrome",
"//javascript/webdriver-atoms:get_text:chrome",
"//javascript/webdriver-atoms:is_displayed:chrome",
Expand Down
Loading

0 comments on commit f535cc3

Please sign in to comment.