// found in the LICENSE file.
// This file provides the ScrollAction object, which scrolls a page
-// from top to bottom:
-// 1. var action = new __ScrollAction(callback)
+// to the bottom or for a specified distance:
+// 1. var action = new __ScrollAction(callback, opt_distance_func)
// 2. action.start(scroll_options)
'use strict';
function ScrollGestureOptions(opt_options) {
if (opt_options) {
this.element_ = opt_options.element;
- this.left_start_percentage_ = opt_options.left_start_percentage;
- this.top_start_percentage_ = opt_options.top_start_percentage;
+ this.left_start_ratio_ = opt_options.left_start_ratio;
+ this.top_start_ratio_ = opt_options.top_start_ratio;
+ this.direction_ = opt_options.direction;
+ this.speed_ = opt_options.speed;
+ this.gesture_source_type_ = opt_options.gesture_source_type;
} else {
this.element_ = document.body;
- this.left_start_percentage_ = 0.5;
- this.top_start_percentage_ = 0.5;
+ this.left_start_ratio_ = 0.5;
+ this.top_start_ratio_ = 0.5;
+ this.direction_ = 'down';
+ this.speed_ = 800;
+ this.gesture_source_type_ = chrome.gpuBenchmarking.DEFAULT_INPUT;
}
}
chrome.gpuBenchmarking.smoothScrollBy);
}
- /**
- * Scrolls a given element down a certain amount to emulate user scroll.
- * Uses smooth scroll capabilities provided by the platform, if available.
- * @constructor
- */
- function SmoothScrollDownGesture(options) {
- this.options_ = options;
- };
-
- function min(a, b) {
- if (a > b) {
- return b;
- }
- return a;
- };
-
- function getBoundingVisibleRect(el) {
- var bound = el.getBoundingClientRect();
- var rect = { top: bound.top,
- left: bound.left,
- width: bound.width,
- height: bound.height };
- 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;
- };
-
- SmoothScrollDownGesture.prototype.start = function(distance, callback) {
- this.callback_ = callback;
-
- var rect = getBoundingVisibleRect(this.options_.element_);
- var start_left =
- rect.left + rect.width * this.options_.left_start_percentage_;
- var start_top =
- rect.top + rect.height * this.options_.top_start_percentage_;
- chrome.gpuBenchmarking.smoothScrollBy(distance, function() {
- callback();
- }, start_left, start_top);
- };
-
// This class scrolls a page from the top to the bottom once.
//
// The page is scrolled down by a single scroll gesture.
- function ScrollAction(opt_callback, opt_remaining_distance_func) {
+ function ScrollAction(opt_callback, opt_distance_func) {
var self = this;
this.beginMeasuringHook = function() {}
this.endMeasuringHook = function() {}
this.callback_ = opt_callback;
- this.remaining_distance_func_ = opt_remaining_distance_func;
+ this.distance_func_ = opt_distance_func;
}
- ScrollAction.prototype.getRemainingScrollDistance_ = function() {
- if (this.remaining_distance_func_)
- return this.remaining_distance_func_();
-
- var clientHeight;
- // clientHeight is "special" for the body element.
- if (this.element_ == document.body)
- clientHeight = window.innerHeight;
- else
- clientHeight = this.element_.clientHeight;
-
- return this.scrollHeight_ - this.element_.scrollTop - clientHeight;
+ ScrollAction.prototype.getScrollDistance_ = function() {
+ if (this.distance_func_)
+ return this.distance_func_();
+
+ if (this.options_.direction_ == 'down') {
+ var clientHeight;
+ // clientHeight is "special" for the body element.
+ if (this.element_ == document.body)
+ clientHeight = window.innerHeight;
+ else
+ clientHeight = this.element_.clientHeight;
+
+ return this.element_.scrollHeight -
+ this.element_.scrollTop -
+ clientHeight;
+ } else if (this.options_.direction_ == 'up') {
+ return this.element_.scrollTop;
+ } else if (this.options_.direction_ == 'right') {
+ var clientWidth;
+ // clientWidth is "special" for the body element.
+ if (this.element_ == document.body)
+ clientWidth = window.innerWidth;
+ else
+ clientWidth = this.element_.clientWidth;
+
+ return this.element_.scrollWidth - this.element_.scrollLeft - clientWidth;
+ } else if (this.options_.direction_ == 'left') {
+ return this.element_.scrollLeft;
+ }
}
ScrollAction.prototype.start = function(opt_options) {
// Assign this.element_ here instead of constructor, because the constructor
// ensures this method will be called after the document is loaded.
this.element_ = this.options_.element_;
- // Some pages load more content when you scroll to the bottom. Record
- // the original element height here and only scroll to that point.
- // -1 to allow for rounding errors on scaled viewports (like mobile).
- this.scrollHeight_ = Math.min(MAX_SCROLL_LENGTH_PIXELS,
- this.element_.scrollHeight - 1);
- requestAnimationFrame(this.startPass_.bind(this));
+ requestAnimationFrame(this.startGesture_.bind(this));
};
- ScrollAction.prototype.startPass_ = function() {
- this.element_.scrollTop = 0;
-
+ ScrollAction.prototype.startGesture_ = function() {
this.beginMeasuringHook();
- this.gesture_ = new SmoothScrollDownGesture(this.options_);
- this.gesture_.start(this.getRemainingScrollDistance_(),
- this.onGestureComplete_.bind(this));
+ var distance = Math.min(MAX_SCROLL_LENGTH_PIXELS,
+ this.getScrollDistance_());
+
+ var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
+ var start_left =
+ rect.left + rect.width * this.options_.left_start_ratio_;
+ var start_top =
+ rect.top + rect.height * this.options_.top_start_ratio_;
+ chrome.gpuBenchmarking.smoothScrollBy(
+ distance, this.onGestureComplete_.bind(this), start_left, start_top,
+ this.options_.gesture_source_type_, this.options_.direction_,
+ this.options_.speed_);
};
ScrollAction.prototype.onGestureComplete_ = function() {
};
window.__ScrollAction = ScrollAction;
- window.__ScrollAction_GetBoundingVisibleRect = getBoundingVisibleRect;
window.__ScrollAction_SupportedByBrowser = supportedByBrowser;
})();