3
Copyright 2011 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
7
YUI.add('dd-scroll', function(Y) {
11
* Base scroller class used to create the Plugin.DDNodeScroll and Plugin.DDWinScroll.
12
* This class should not be called on it's own, it's designed to be a plugin.
14
* @submodule dd-scroll
17
* Base scroller class used to create the Plugin.DDNodeScroll and Plugin.DDWinScroll.
18
* This class should not be called on it's own, it's designed to be a plugin.
26
S.superclass.constructor.apply(this, arguments);
32
PARENT_SCROLL = 'parentScroll',
33
WINDOW_SCROLL = 'windowScroll',
34
SCROLL_TOP = 'scrollTop',
35
SCROLL_LEFT = 'scrollLeft',
36
OFFSET_WIDTH = 'offsetWidth',
37
OFFSET_HEIGHT = 'offsetHeight';
42
* @attribute parentScroll
43
* @description Internal config option to hold the node that we are scrolling. Should not be set by the developer.
48
setter: function(node) {
57
* @description The number of pixels from the edge of the screen to turn on scrolling. Default: 30
62
validator: Y.Lang.isNumber
65
* @attribute scrollDelay
66
* @description The number of milliseconds delay to pass to the auto scroller. Default: 235
71
validator: Y.Lang.isNumber
75
* @description The host we are plugged into.
82
* @attribute windowScroll
83
* @description Turn on window scroll support, default: false
88
validator: Y.Lang.isBoolean
92
* @description Allow vertical scrolling, default: true.
97
validator: Y.Lang.isBoolean
100
* @attribute horizontal
101
* @description Allow horizontal scrolling, default: true.
106
validator: Y.Lang.isBoolean
110
Y.extend(S, Y.Base, {
113
* @property _scrolling
114
* @description Tells if we are actively scrolling or not.
120
* @property _vpRegionCache
121
* @description Cache of the Viewport dims.
124
_vpRegionCache: null,
127
* @property _dimCache
128
* @description Cache of the dragNode dims.
134
* @property _scrollTimer
135
* @description Holder for the Timer object returned from Y.later.
141
* @method _getVPRegion
142
* @description Sets the _vpRegionCache property with an Object containing the dims from the viewport.
144
_getVPRegion: function() {
146
n = this.get(PARENT_SCROLL),
147
b = this.get(BUFFER),
148
ws = this.get(WINDOW_SCROLL),
149
xy = ((ws) ? [] : n.getXY()),
150
w = ((ws) ? 'winWidth' : OFFSET_WIDTH),
151
h = ((ws) ? 'winHeight' : OFFSET_HEIGHT),
152
t = ((ws) ? n.get(SCROLL_TOP) : xy[1]),
153
l = ((ws) ? n.get(SCROLL_LEFT) : xy[0]);
157
right: (n.get(w) + l) - b,
158
bottom: (n.get(h) + t) - b,
161
this._vpRegionCache = r;
164
initializer: function() {
165
var h = this.get(HOST);
166
h.after('drag:start', Y.bind(this.start, this));
167
h.after('drag:end', Y.bind(this.end, this));
168
h.on('drag:align', Y.bind(this.align, this));
170
//TODO - This doesn't work yet??
171
Y.one('win').on('scroll', Y.bind(function() {
172
this._vpRegionCache = null;
177
* @method _checkWinScroll
178
* @description Check to see if we need to fire the scroll timer. If scroll timer is running this will scroll the window.
179
* @param {Boolean} move Should we move the window. From Y.later
181
_checkWinScroll: function(move) {
182
var r = this._getVPRegion(),
184
ws = this.get(WINDOW_SCROLL),
187
b = this.get(BUFFER),
188
win = this.get(PARENT_SCROLL),
189
sTop = win.get(SCROLL_TOP),
190
sLeft = win.get(SCROLL_LEFT),
191
w = this._dimCache.w,
192
h = this._dimCache.h,
202
if (this.get('horizontal')) {
203
if (left <= r.left) {
205
nl = xy[0] - ((ws) ? b : 0);
208
if (right >= r.right) {
210
nl = xy[0] + ((ws) ? b : 0);
214
if (this.get('vertical')) {
215
if (bottom >= r.bottom) {
217
nt = xy[1] + ((ws) ? b : 0);
223
nt = xy[1] - ((ws) ? b : 0);
246
ho._moveNode({ node: win, top: st, left: sl});
248
this._cancelScroll();
254
this._cancelScroll();
260
* @method _initScroll
261
* @description Cancel a previous scroll timer and init a new one.
263
_initScroll: function() {
264
this._cancelScroll();
265
this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
270
* @method _cancelScroll
271
* @description Cancel a currently running scroll timer.
273
_cancelScroll: function() {
274
this._scrolling = false;
275
if (this._scrollTimer) {
276
this._scrollTimer.cancel();
277
delete this._scrollTimer;
282
* @description Called from the drag:align event to determine if we need to scroll.
285
if (this._scrolling) {
286
this._cancelScroll();
289
if (!this._scrolling) {
290
this._checkWinScroll();
295
* @method _setDimCache
296
* @description Set the cache of the dragNode dims.
298
_setDimCache: function() {
299
var node = this.get(HOST).get('dragNode');
301
h: node.get(OFFSET_HEIGHT),
302
w: node.get(OFFSET_WIDTH)
307
* @description Called from the drag:start event
314
* @description Called from the drag:end event
317
this._dimCache = null;
318
this._cancelScroll();
322
* @description General toString method for logging
323
* @return String name for the object
325
toString: function() {
326
return S.NAME + ' #' + this.get('node').get('id');
330
Y.namespace('Plugin');
334
* Extends the Scroll class to make the window scroll while dragging.
335
* @class DDWindowScroll
341
WS.superclass.constructor.apply(this, arguments);
343
WS.ATTRS = Y.merge(S.ATTRS, {
345
* @attribute windowScroll
346
* @description Turn on window scroll support, default: true
351
setter: function(scroll) {
353
this.set(PARENT_SCROLL, Y.one('win'));
360
//Shouldn't have to do this..
361
initializer: function() {
362
this.set('windowScroll', this.get('windowScroll'));
371
* @description The Scroll instance will be placed on the Drag instance under the winscroll namespace.
374
WS.NAME = WS.NS = 'winscroll';
375
Y.Plugin.DDWinScroll = WS;
379
* Extends the Scroll class to make a parent node scroll while dragging.
380
* @class DDNodeScroll
386
NS.superclass.constructor.apply(this, arguments);
389
NS.ATTRS = Y.merge(S.ATTRS, {
392
* @description The node we want to scroll. Used to set the internal parentScroll attribute.
397
setter: function(node) {
400
if (node !== false) {
401
Y.error('DDNodeScroll: Invalid Node Given: ' + node);
404
this.set(PARENT_SCROLL, n);
411
//Shouldn't have to do this..
412
initializer: function() {
413
this.set('node', this.get('node'));
418
* @default nodescroll
422
* @description The NodeScroll instance will be placed on the Drag instance under the nodescroll namespace.
425
NS.NAME = NS.NS = 'nodescroll';
426
Y.Plugin.DDNodeScroll = NS;
433
}, '3.4.1' ,{optional:['dd-proxy'], requires:['dd-drag'], skinnable:false});