2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
8 YUI.add('dd-scroll', function(Y) {
12 * Base scroller class used to create the Plugin.DDNodeScroll and Plugin.DDWinScroll.
13 * This class should not be called on it's own, it's designed to be a plugin.
15 * @submodule dd-scroll
18 * Base scroller class used to create the Plugin.DDNodeScroll and Plugin.DDWinScroll.
19 * This class should not be called on it's own, it's designed to be a plugin.
27 S.superclass.constructor.apply(this, arguments);
33 PARENT_SCROLL = 'parentScroll',
34 WINDOW_SCROLL = 'windowScroll',
35 SCROLL_TOP = 'scrollTop',
36 SCROLL_LEFT = 'scrollLeft',
37 OFFSET_WIDTH = 'offsetWidth',
38 OFFSET_HEIGHT = 'offsetHeight';
43 * @attribute parentScroll
44 * @description Internal config option to hold the node that we are scrolling. Should not be set by the developer.
49 setter: function(node) {
58 * @description The number of pixels from the edge of the screen to turn on scrolling. Default: 30
63 validator: Y.Lang.isNumber
66 * @attribute scrollDelay
67 * @description The number of milliseconds delay to pass to the auto scroller. Default: 235
72 validator: Y.Lang.isNumber
76 * @description The host we are plugged into.
83 * @attribute windowScroll
84 * @description Turn on window scroll support, default: false
89 validator: Y.Lang.isBoolean
93 * @description Allow vertical scrolling, default: true.
98 validator: Y.Lang.isBoolean
101 * @attribute horizontal
102 * @description Allow horizontal scrolling, default: true.
107 validator: Y.Lang.isBoolean
111 Y.extend(S, Y.Base, {
114 * @property _scrolling
115 * @description Tells if we are actively scrolling or not.
121 * @property _vpRegionCache
122 * @description Cache of the Viewport dims.
125 _vpRegionCache: null,
128 * @property _dimCache
129 * @description Cache of the dragNode dims.
135 * @property _scrollTimer
136 * @description Holder for the Timer object returned from Y.later.
142 * @method _getVPRegion
143 * @description Sets the _vpRegionCache property with an Object containing the dims from the viewport.
145 _getVPRegion: function() {
147 n = this.get(PARENT_SCROLL),
148 b = this.get(BUFFER),
149 ws = this.get(WINDOW_SCROLL),
150 xy = ((ws) ? [] : n.getXY()),
151 w = ((ws) ? 'winWidth' : OFFSET_WIDTH),
152 h = ((ws) ? 'winHeight' : OFFSET_HEIGHT),
153 t = ((ws) ? n.get(SCROLL_TOP) : xy[1]),
154 l = ((ws) ? n.get(SCROLL_LEFT) : xy[0]);
158 right: (n.get(w) + l) - b,
159 bottom: (n.get(h) + t) - b,
162 this._vpRegionCache = r;
165 initializer: function() {
166 var h = this.get(HOST);
167 h.after('drag:start', Y.bind(this.start, this));
168 h.after('drag:end', Y.bind(this.end, this));
169 h.on('drag:align', Y.bind(this.align, this));
171 //TODO - This doesn't work yet??
172 Y.one('win').on('scroll', Y.bind(function() {
173 this._vpRegionCache = null;
178 * @method _checkWinScroll
179 * @description Check to see if we need to fire the scroll timer. If scroll timer is running this will scroll the window.
180 * @param {Boolean} move Should we move the window. From Y.later
182 _checkWinScroll: function(move) {
183 var r = this._getVPRegion(),
185 ws = this.get(WINDOW_SCROLL),
188 b = this.get(BUFFER),
189 win = this.get(PARENT_SCROLL),
190 sTop = win.get(SCROLL_TOP),
191 sLeft = win.get(SCROLL_LEFT),
192 w = this._dimCache.w,
193 h = this._dimCache.h,
203 if (this.get('horizontal')) {
204 if (left <= r.left) {
206 nl = xy[0] - ((ws) ? b : 0);
209 if (right >= r.right) {
211 nl = xy[0] + ((ws) ? b : 0);
215 if (this.get('vertical')) {
216 if (bottom >= r.bottom) {
218 nt = xy[1] + ((ws) ? b : 0);
224 nt = xy[1] - ((ws) ? b : 0);
247 ho._moveNode({ node: win, top: st, left: sl});
249 this._cancelScroll();
255 this._cancelScroll();
261 * @method _initScroll
262 * @description Cancel a previous scroll timer and init a new one.
264 _initScroll: function() {
265 this._cancelScroll();
266 this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
271 * @method _cancelScroll
272 * @description Cancel a currently running scroll timer.
274 _cancelScroll: function() {
275 this._scrolling = false;
276 if (this._scrollTimer) {
277 this._scrollTimer.cancel();
278 delete this._scrollTimer;
283 * @description Called from the drag:align event to determine if we need to scroll.
286 if (this._scrolling) {
287 this._cancelScroll();
290 if (!this._scrolling) {
291 this._checkWinScroll();
296 * @method _setDimCache
297 * @description Set the cache of the dragNode dims.
299 _setDimCache: function() {
300 var node = this.get(HOST).get('dragNode');
302 h: node.get(OFFSET_HEIGHT),
303 w: node.get(OFFSET_WIDTH)
308 * @description Called from the drag:start event
315 * @description Called from the drag:end event
318 this._dimCache = null;
319 this._cancelScroll();
323 * @description General toString method for logging
324 * @return String name for the object
326 toString: function() {
327 return S.NAME + ' #' + this.get('node').get('id');
331 Y.namespace('Plugin');
335 * Extends the Scroll class to make the window scroll while dragging.
336 * @class DDWindowScroll
342 WS.superclass.constructor.apply(this, arguments);
344 WS.ATTRS = Y.merge(S.ATTRS, {
346 * @attribute windowScroll
347 * @description Turn on window scroll support, default: true
352 setter: function(scroll) {
354 this.set(PARENT_SCROLL, Y.one('win'));
361 //Shouldn't have to do this..
362 initializer: function() {
363 this.set('windowScroll', this.get('windowScroll'));
372 * @description The Scroll instance will be placed on the Drag instance under the winscroll namespace.
375 WS.NAME = WS.NS = 'winscroll';
376 Y.Plugin.DDWinScroll = WS;
380 * Extends the Scroll class to make a parent node scroll while dragging.
381 * @class DDNodeScroll
387 NS.superclass.constructor.apply(this, arguments);
390 NS.ATTRS = Y.merge(S.ATTRS, {
393 * @description The node we want to scroll. Used to set the internal parentScroll attribute.
398 setter: function(node) {
401 if (node !== false) {
402 Y.error('DDNodeScroll: Invalid Node Given: ' + node);
405 this.set(PARENT_SCROLL, n);
412 //Shouldn't have to do this..
413 initializer: function() {
414 this.set('node', this.get('node'));
419 * @default nodescroll
423 * @description The NodeScroll instance will be placed on the Drag instance under the nodescroll namespace.
426 NS.NAME = NS.NS = 'nodescroll';
427 Y.Plugin.DDNodeScroll = NS;
433 }, '3.3.0' ,{requires:['dd-drag'], skinnable:false, optional:['dd-proxy']});