2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('dd-scroll', function (Y, NAME) {
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 * Internal config option to hold the node that we are scrolling. Should not be set by the developer.
44 * @attribute parentScroll
50 setter: function(node) {
58 * The number of pixels from the edge of the screen to turn on scrolling. Default: 30
64 validator: Y.Lang.isNumber
67 * The number of milliseconds delay to pass to the auto scroller. Default: 235
68 * @attribute scrollDelay
73 validator: Y.Lang.isNumber
76 * The host we are plugged into.
84 * Turn on window scroll support, default: false
85 * @attribute windowScroll
90 validator: Y.Lang.isBoolean
93 * Allow vertical scrolling, default: true.
99 validator: Y.Lang.isBoolean
102 * Allow horizontal scrolling, default: true.
103 * @attribute horizontal
108 validator: Y.Lang.isBoolean
112 Y.extend(S, Y.Base, {
114 * Tells if we are actively scrolling or not.
116 * @property _scrolling
121 * Cache of the Viewport dims.
123 * @property _vpRegionCache
126 _vpRegionCache: null,
128 * Cache of the dragNode dims.
130 * @property _dimCache
135 * Holder for the Timer object returned from Y.later.
137 * @property _scrollTimer
142 * Sets the _vpRegionCache property with an Object containing the dims from the viewport.
144 * @method _getVPRegion
146 _getVPRegion: function() {
148 n = this.get(PARENT_SCROLL),
149 b = this.get(BUFFER),
150 ws = this.get(WINDOW_SCROLL),
151 xy = ((ws) ? [] : n.getXY()),
152 w = ((ws) ? 'winWidth' : OFFSET_WIDTH),
153 h = ((ws) ? 'winHeight' : OFFSET_HEIGHT),
154 t = ((ws) ? n.get(SCROLL_TOP) : xy[1]),
155 l = ((ws) ? n.get(SCROLL_LEFT) : xy[0]);
159 right: (n.get(w) + l) - b,
160 bottom: (n.get(h) + t) - b,
163 this._vpRegionCache = r;
166 initializer: function() {
167 var h = this.get(HOST);
168 h.after('drag:start', Y.bind(this.start, this));
169 h.after('drag:end', Y.bind(this.end, this));
170 h.on('drag:align', Y.bind(this.align, this));
172 //TODO - This doesn't work yet??
173 Y.one('win').on('scroll', Y.bind(function() {
174 this._vpRegionCache = null;
178 * Check to see if we need to fire the scroll timer. If scroll timer is running this will scroll the window.
180 * @method _checkWinScroll
181 * @param {Boolean} move Should we move the window. From Y.later
183 _checkWinScroll: function(move) {
184 var r = this._getVPRegion(),
186 ws = this.get(WINDOW_SCROLL),
189 b = this.get(BUFFER),
190 win = this.get(PARENT_SCROLL),
191 sTop = win.get(SCROLL_TOP),
192 sLeft = win.get(SCROLL_LEFT),
193 w = this._dimCache.w,
194 h = this._dimCache.h,
204 if (this.get('horizontal')) {
205 if (left <= r.left) {
207 nl = xy[0] - ((ws) ? b : 0);
210 if (right >= r.right) {
212 nl = xy[0] + ((ws) ? b : 0);
216 if (this.get('vertical')) {
217 if (bottom >= r.bottom) {
219 nt = xy[1] + ((ws) ? b : 0);
225 nt = xy[1] - ((ws) ? b : 0);
248 ho._alignNode([nl, nt], true); //We are srolling..
251 ho._moveNode({ node: win, top: st, left: sl});
253 this._cancelScroll();
259 this._cancelScroll();
264 * Cancel a previous scroll timer and init a new one.
266 * @method _initScroll
268 _initScroll: function() {
269 this._cancelScroll();
270 this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
274 * Cancel a currently running scroll timer.
276 * @method _cancelScroll
278 _cancelScroll: function() {
279 this._scrolling = false;
280 if (this._scrollTimer) {
281 this._scrollTimer.cancel();
282 delete this._scrollTimer;
286 * Called from the drag:align event to determine if we need to scroll.
290 if (this._scrolling) {
291 this._cancelScroll();
294 if (!this._scrolling) {
295 this._checkWinScroll();
299 * Set the cache of the dragNode dims.
301 * @method _setDimCache
303 _setDimCache: function() {
304 var node = this.get(HOST).get('dragNode');
306 h: node.get(OFFSET_HEIGHT),
307 w: node.get(OFFSET_WIDTH)
311 * Called from the drag:start event
318 * Called from the drag:end event
322 this._dimCache = null;
323 this._cancelScroll();
327 Y.namespace('Plugin');
331 * Extends the Scroll class to make the window scroll while dragging.
332 * @class DDWindowScroll
338 WS.superclass.constructor.apply(this, arguments);
340 WS.ATTRS = Y.merge(S.ATTRS, {
342 * Turn on window scroll support, default: true
343 * @attribute windowScroll
348 setter: function(scroll) {
350 this.set(PARENT_SCROLL, Y.one('win'));
357 //Shouldn't have to do this..
358 initializer: function() {
359 this.set('windowScroll', this.get('windowScroll'));
363 * The Scroll instance will be placed on the Drag instance under the winscroll namespace.
371 WS.NAME = WS.NS = 'winscroll';
372 Y.Plugin.DDWinScroll = WS;
376 * Extends the Scroll class to make a parent node scroll while dragging.
377 * @class DDNodeScroll
383 NS.superclass.constructor.apply(this, arguments);
386 NS.ATTRS = Y.merge(S.ATTRS, {
388 * The node we want to scroll. Used to set the internal parentScroll attribute.
394 setter: function(node) {
397 if (node !== false) {
398 Y.error('DDNodeScroll: Invalid Node Given: ' + node);
401 this.set(PARENT_SCROLL, n);
408 //Shouldn't have to do this..
409 initializer: function() {
410 this.set('node', this.get('node'));
414 * The NodeScroll instance will be placed on the Drag instance under the nodescroll namespace.
416 * @default nodescroll
422 NS.NAME = NS.NS = 'nodescroll';
423 Y.Plugin.DDNodeScroll = NS;
430 }, '3.13.0', {"requires": ["dd-drag"]});