1 // Copyright 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.
5 // This file provides the ScrollAction object, which scrolls a page
6 // to the bottom or for a specified distance:
7 // 1. var action = new __ScrollAction(callback, opt_distance_func)
8 // 2. action.start(scroll_options)
12 var MAX_SCROLL_LENGTH_TIME_MS = 6250;
14 function ScrollGestureOptions(opt_options) {
16 this.element_ = opt_options.element;
17 this.left_start_ratio_ = opt_options.left_start_ratio;
18 this.top_start_ratio_ = opt_options.top_start_ratio;
19 this.direction_ = opt_options.direction;
20 this.speed_ = opt_options.speed;
21 this.gesture_source_type_ = opt_options.gesture_source_type;
23 this.element_ = document.scrollingElement || document.body;
24 this.left_start_ratio_ = 0.5;
25 this.top_start_ratio_ = 0.5;
26 this.direction_ = 'down';
28 this.gesture_source_type_ = chrome.gpuBenchmarking.DEFAULT_INPUT;
32 function supportedByBrowser() {
33 return !!(window.chrome &&
34 chrome.gpuBenchmarking &&
35 chrome.gpuBenchmarking.smoothScrollBy &&
36 chrome.gpuBenchmarking.visualViewportHeight &&
37 chrome.gpuBenchmarking.visualViewportWidth);
40 // This class scrolls a page from the top to the bottom once.
42 // The page is scrolled down by a single scroll gesture.
43 function ScrollAction(opt_callback, opt_distance_func) {
46 this.beginMeasuringHook = function() {};
47 this.endMeasuringHook = function() {};
49 this.callback_ = opt_callback;
50 this.distance_func_ = opt_distance_func;
53 ScrollAction.prototype.getScrollDistanceDown_ = function() {
55 // clientHeight is "special" for the body element.
56 if (this.element_ == document.body)
57 clientHeight = __GestureCommon_GetWindowHeight();
59 clientHeight = this.element_.clientHeight;
61 return this.element_.scrollHeight -
62 this.element_.scrollTop -
66 ScrollAction.prototype.getScrollDistanceUp_ = function() {
67 return this.element_.scrollTop;
70 ScrollAction.prototype.getScrollDistanceRight_ = function() {
72 // clientWidth is "special" for the body element.
73 if (this.element_ == document.body)
74 clientWidth = __GestureCommon_GetWindowWidth();
76 clientWidth = this.element_.clientWidth;
78 return this.element_.scrollWidth - this.element_.scrollLeft - clientWidth;
81 ScrollAction.prototype.getScrollDistanceLeft_ = function() {
82 return this.element_.scrollLeft;
85 ScrollAction.prototype.getScrollDistance_ = function() {
86 if (this.distance_func_)
87 return this.distance_func_();
89 if (this.options_.direction_ == 'down') {
90 return this.getScrollDistanceDown_();
91 } else if (this.options_.direction_ == 'up') {
92 return this.getScrollDistanceUp_();
93 } else if (this.options_.direction_ == 'right') {
94 return this.getScrollDistanceRight_();
95 } else if (this.options_.direction_ == 'left') {
96 return this.getScrollDistanceLeft_();
97 } else if (this.options_.direction_ == 'upleft') {
98 return Math.min(this.getScrollDistanceUp_(),
99 this.getScrollDistanceLeft_());
100 } else if (this.options_.direction_ == 'upright') {
101 return Math.min(this.getScrollDistanceUp_(),
102 this.getScrollDistanceRight_());
103 } else if (this.options_.direction_ == 'downleft') {
104 return Math.min(this.getScrollDistanceDown_(),
105 this.getScrollDistanceLeft_());
106 } else if (this.options_.direction_ == 'downright') {
107 return Math.min(this.getScrollDistanceDown_(),
108 this.getScrollDistanceRight_());
112 ScrollAction.prototype.start = function(opt_options) {
113 this.options_ = new ScrollGestureOptions(opt_options);
114 // Assign this.element_ here instead of constructor, because the constructor
115 // ensures this method will be called after the document is loaded.
116 this.element_ = this.options_.element_;
117 requestAnimationFrame(this.startGesture_.bind(this));
120 ScrollAction.prototype.startGesture_ = function() {
121 this.beginMeasuringHook();
123 var max_scroll_length_pixels = (MAX_SCROLL_LENGTH_TIME_MS / 1000) *
124 this.options_.speed_;
125 var distance = Math.min(max_scroll_length_pixels,
126 this.getScrollDistance_());
128 var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
130 rect.left + rect.width * this.options_.left_start_ratio_;
132 rect.top + rect.height * this.options_.top_start_ratio_;
133 chrome.gpuBenchmarking.smoothScrollBy(
134 distance, this.onGestureComplete_.bind(this), start_left, start_top,
135 this.options_.gesture_source_type_, this.options_.direction_,
136 this.options_.speed_);
139 ScrollAction.prototype.onGestureComplete_ = function() {
140 this.endMeasuringHook();
147 window.__ScrollAction = ScrollAction;
148 window.__ScrollAction_SupportedByBrowser = supportedByBrowser;