3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
7 YUI.add('dd-scroll', function (Y, NAME) {
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);
245 if (!ho.con.inRegion([nl + sl, nt + st])) {
251 ho._alignNode([nl, nt], true); //We are srolling..
254 ho._moveNode({ node: win, top: st, left: sl});
256 this._cancelScroll();
262 this._cancelScroll();
268 * @method _initScroll
269 * @description Cancel a previous scroll timer and init a new one.
271 _initScroll: function() {
272 this._cancelScroll();
273 this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
278 * @method _cancelScroll
279 * @description Cancel a currently running scroll timer.
281 _cancelScroll: function() {
282 this._scrolling = false;
283 if (this._scrollTimer) {
284 this._scrollTimer.cancel();
285 delete this._scrollTimer;
290 * @description Called from the drag:align event to determine if we need to scroll.
293 if (this._scrolling) {
294 this._cancelScroll();
297 if (!this._scrolling) {
298 this._checkWinScroll();
303 * @method _setDimCache
304 * @description Set the cache of the dragNode dims.
306 _setDimCache: function() {
307 var node = this.get(HOST).get('dragNode');
309 h: node.get(OFFSET_HEIGHT),
310 w: node.get(OFFSET_WIDTH)
315 * @description Called from the drag:start event
322 * @description Called from the drag:end event
325 this._dimCache = null;
326 this._cancelScroll();
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.7.2', {"requires": ["dd-drag"]});