Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/events/mousewheelhandler.js
2868 views
1
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview This event wrapper will dispatch an event when the user uses
17
* the mouse wheel to scroll an element. You can get the direction by checking
18
* the deltaX and deltaY properties of the event.
19
*
20
* This class aims to smooth out inconsistencies between browser platforms with
21
* regards to mousewheel events, but we do not cover every possible
22
* software/hardware combination out there, some of which occasionally produce
23
* very large deltas in mousewheel events. If your application wants to guard
24
* against extremely large deltas, use the setMaxDeltaX and setMaxDeltaY APIs
25
* to set maximum values that make sense for your application.
26
*
27
* @author [email protected] (Erik Arvidsson)
28
* @see ../demos/mousewheelhandler.html
29
*/
30
31
goog.provide('goog.events.MouseWheelEvent');
32
goog.provide('goog.events.MouseWheelHandler');
33
goog.provide('goog.events.MouseWheelHandler.EventType');
34
35
goog.require('goog.dom');
36
goog.require('goog.events');
37
goog.require('goog.events.BrowserEvent');
38
goog.require('goog.events.EventTarget');
39
goog.require('goog.math');
40
goog.require('goog.style');
41
goog.require('goog.userAgent');
42
43
44
45
/**
46
* This event handler allows you to catch mouse wheel events in a consistent
47
* manner.
48
* @param {Element|Document} element The element to listen to the mouse wheel
49
* event on.
50
* @param {boolean=} opt_capture Whether to handle the mouse wheel event in
51
* capture phase.
52
* @constructor
53
* @extends {goog.events.EventTarget}
54
*/
55
goog.events.MouseWheelHandler = function(element, opt_capture) {
56
goog.events.EventTarget.call(this);
57
58
/**
59
* This is the element that we will listen to the real mouse wheel events on.
60
* @type {Element|Document}
61
* @private
62
*/
63
this.element_ = element;
64
65
var rtlElement = goog.dom.isElement(this.element_) ?
66
/** @type {Element} */ (this.element_) :
67
(this.element_ ?
68
/** @type {Document} */ (this.element_).body :
69
null);
70
71
/**
72
* True if the element exists and is RTL, false otherwise.
73
* @type {boolean}
74
* @private
75
*/
76
this.isRtl_ = !!rtlElement && goog.style.isRightToLeft(rtlElement);
77
78
var type = goog.userAgent.GECKO ? 'DOMMouseScroll' : 'mousewheel';
79
80
/**
81
* The key returned from the goog.events.listen.
82
* @type {goog.events.Key}
83
* @private
84
*/
85
this.listenKey_ = goog.events.listen(this.element_, type, this, opt_capture);
86
};
87
goog.inherits(goog.events.MouseWheelHandler, goog.events.EventTarget);
88
89
90
/**
91
* Enum type for the events fired by the mouse wheel handler.
92
* @enum {string}
93
*/
94
goog.events.MouseWheelHandler.EventType = {
95
MOUSEWHEEL: 'mousewheel'
96
};
97
98
99
/**
100
* Optional maximum magnitude for x delta on each mousewheel event.
101
* @type {number|undefined}
102
* @private
103
*/
104
goog.events.MouseWheelHandler.prototype.maxDeltaX_;
105
106
107
/**
108
* Optional maximum magnitude for y delta on each mousewheel event.
109
* @type {number|undefined}
110
* @private
111
*/
112
goog.events.MouseWheelHandler.prototype.maxDeltaY_;
113
114
115
/**
116
* @param {number} maxDeltaX Maximum magnitude for x delta on each mousewheel
117
* event. Should be non-negative.
118
*/
119
goog.events.MouseWheelHandler.prototype.setMaxDeltaX = function(maxDeltaX) {
120
this.maxDeltaX_ = maxDeltaX;
121
};
122
123
124
/**
125
* @param {number} maxDeltaY Maximum magnitude for y delta on each mousewheel
126
* event. Should be non-negative.
127
*/
128
goog.events.MouseWheelHandler.prototype.setMaxDeltaY = function(maxDeltaY) {
129
this.maxDeltaY_ = maxDeltaY;
130
};
131
132
133
/**
134
* Handles the events on the element.
135
* @param {goog.events.BrowserEvent} e The underlying browser event.
136
*/
137
goog.events.MouseWheelHandler.prototype.handleEvent = function(e) {
138
var deltaX = 0;
139
var deltaY = 0;
140
var detail = 0;
141
var be = e.getBrowserEvent();
142
if (be.type == 'mousewheel') {
143
// In IE we get a multiple of 120; we adjust to a multiple of 3 to
144
// represent number of lines scrolled (like Gecko).
145
// Newer versions of Webkit match IE behavior, and WebKit on
146
// Windows also matches IE behavior.
147
// See bug https://bugs.webkit.org/show_bug.cgi?id=24368
148
var wheelDeltaScaleFactor = 40;
149
150
detail = goog.events.MouseWheelHandler.smartScale_(
151
-be.wheelDelta, wheelDeltaScaleFactor);
152
if (goog.isDef(be.wheelDeltaX)) {
153
// Webkit has two properties to indicate directional scroll, and
154
// can scroll both directions at once.
155
deltaX = goog.events.MouseWheelHandler.smartScale_(
156
-be.wheelDeltaX, wheelDeltaScaleFactor);
157
deltaY = goog.events.MouseWheelHandler.smartScale_(
158
-be.wheelDeltaY, wheelDeltaScaleFactor);
159
} else {
160
deltaY = detail;
161
}
162
163
// Historical note: Opera (pre 9.5) used to negate the detail value.
164
} else { // Gecko
165
// Gecko returns multiple of 3 (representing the number of lines scrolled)
166
detail = be.detail;
167
168
// Gecko sometimes returns really big values if the user changes settings to
169
// scroll a whole page per scroll
170
if (detail > 100) {
171
detail = 3;
172
} else if (detail < -100) {
173
detail = -3;
174
}
175
176
// Firefox 3.1 adds an axis field to the event to indicate direction of
177
// scroll. See https://developer.mozilla.org/en/Gecko-Specific_DOM_Events
178
if (goog.isDef(be.axis) && be.axis === be.HORIZONTAL_AXIS) {
179
deltaX = detail;
180
} else {
181
deltaY = detail;
182
}
183
}
184
185
if (goog.isNumber(this.maxDeltaX_)) {
186
deltaX = goog.math.clamp(deltaX, -this.maxDeltaX_, this.maxDeltaX_);
187
}
188
if (goog.isNumber(this.maxDeltaY_)) {
189
deltaY = goog.math.clamp(deltaY, -this.maxDeltaY_, this.maxDeltaY_);
190
}
191
// Don't clamp 'detail', since it could be ambiguous which axis it refers to
192
// and because it's informally deprecated anyways.
193
194
// For horizontal scrolling we need to flip the value for RTL grids.
195
if (this.isRtl_) {
196
deltaX = -deltaX;
197
}
198
var newEvent = new goog.events.MouseWheelEvent(detail, be, deltaX, deltaY);
199
this.dispatchEvent(newEvent);
200
};
201
202
203
/**
204
* Helper for scaling down a mousewheel delta by a scale factor, if appropriate.
205
* @param {number} mouseWheelDelta Delta from a mouse wheel event. Expected to
206
* be an integer.
207
* @param {number} scaleFactor Factor to scale the delta down by. Expected to
208
* be an integer.
209
* @return {number} Scaled-down delta value, or the original delta if the
210
* scaleFactor does not appear to be applicable.
211
* @private
212
*/
213
goog.events.MouseWheelHandler.smartScale_ = function(
214
mouseWheelDelta, scaleFactor) {
215
// The basic problem here is that in Webkit on Mac and Linux, we can get two
216
// very different types of mousewheel events: from continuous devices
217
// (touchpads, Mighty Mouse) or non-continuous devices (normal wheel mice).
218
//
219
// Non-continuous devices in Webkit get their wheel deltas scaled up to
220
// behave like IE. Continuous devices return much smaller unscaled values
221
// (which most of the time will not be cleanly divisible by the IE scale
222
// factor), so we should not try to normalize them down.
223
//
224
// Detailed discussion:
225
// https://bugs.webkit.org/show_bug.cgi?id=29601
226
// http://trac.webkit.org/browser/trunk/WebKit/chromium/src/mac/WebInputEventFactory.mm#L1063
227
if (goog.userAgent.WEBKIT && (goog.userAgent.MAC || goog.userAgent.LINUX) &&
228
(mouseWheelDelta % scaleFactor) != 0) {
229
return mouseWheelDelta;
230
} else {
231
return mouseWheelDelta / scaleFactor;
232
}
233
};
234
235
236
/** @override */
237
goog.events.MouseWheelHandler.prototype.disposeInternal = function() {
238
goog.events.MouseWheelHandler.superClass_.disposeInternal.call(this);
239
goog.events.unlistenByKey(this.listenKey_);
240
this.listenKey_ = null;
241
};
242
243
244
245
/**
246
* A base class for mouse wheel events. This is used with the
247
* MouseWheelHandler.
248
*
249
* @param {number} detail The number of rows the user scrolled.
250
* @param {Event} browserEvent Browser event object.
251
* @param {number} deltaX The number of rows the user scrolled in the X
252
* direction.
253
* @param {number} deltaY The number of rows the user scrolled in the Y
254
* direction.
255
* @constructor
256
* @extends {goog.events.BrowserEvent}
257
* @final
258
*/
259
goog.events.MouseWheelEvent = function(detail, browserEvent, deltaX, deltaY) {
260
goog.events.BrowserEvent.call(this, browserEvent);
261
262
this.type = goog.events.MouseWheelHandler.EventType.MOUSEWHEEL;
263
264
/**
265
* The number of lines the user scrolled
266
* @type {number}
267
* NOTE: Informally deprecated. Use deltaX and deltaY instead, they provide
268
* more information.
269
*/
270
this.detail = detail;
271
272
/**
273
* The number of "lines" scrolled in the X direction.
274
*
275
* Note that not all browsers provide enough information to distinguish
276
* horizontal and vertical scroll events, so for these unsupported browsers,
277
* we will always have a deltaX of 0, even if the user scrolled their mouse
278
* wheel or trackpad sideways.
279
*
280
* Currently supported browsers are Webkit and Firefox 3.1 or later.
281
*
282
* @type {number}
283
*/
284
this.deltaX = deltaX;
285
286
/**
287
* The number of lines scrolled in the Y direction.
288
* @type {number}
289
*/
290
this.deltaY = deltaY;
291
};
292
goog.inherits(goog.events.MouseWheelEvent, goog.events.BrowserEvent);
293
294