src/cm/media/js/lib/yui/yui_3.0.0b1/build/dd/dd-scroll.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0b1
       
     6 build: 1163
       
     7 */
       
     8 YUI.add('dd-scroll', function(Y) {
       
     9 
       
    10 
       
    11     /**
       
    12      * The Drag & Drop Utility allows you to create a draggable interface efficiently, buffering you from browser-level abnormalities and enabling you to focus on the interesting logic surrounding your particular implementation. This component enables you to create a variety of standard draggable objects with just a few lines of code and then, using its extensive API, add your own specific implementation logic.
       
    13      * @module dd
       
    14      * @submodule dd-scroll
       
    15      */
       
    16     /**
       
    17      * This class is the 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.
       
    19      * @class Scroll
       
    20      * @extends Base
       
    21      * @namespace DD
       
    22      * @constructor
       
    23      */
       
    24 
       
    25     var S = function() {
       
    26         S.superclass.constructor.apply(this, arguments);
       
    27 
       
    28     },
       
    29     HOST = 'host',
       
    30     BUFFER = 'buffer',
       
    31     PARENT_SCROLL = 'parentScroll',
       
    32     WINDOW_SCROLL = 'windowScroll',
       
    33     SCROLL_TOP = 'scrollTop',
       
    34     SCROLL_LEFT = 'scrollLeft',
       
    35     OFFSET_WIDTH = 'offsetWidth',
       
    36     OFFSET_HEIGHT = 'offsetHeight';
       
    37 
       
    38 
       
    39     S.ATTRS = {
       
    40         /**
       
    41         * @attribute parentScroll
       
    42         * @description Internal config option to hold the node that we are scrolling. Should not be set by the developer.
       
    43         * @type Node
       
    44         */
       
    45         parentScroll: {
       
    46             value: false,
       
    47             setter: function(node) {
       
    48                 if (node) {
       
    49                     return node;
       
    50                 }
       
    51                 return false;
       
    52             }
       
    53         },
       
    54         /**
       
    55         * @attribute buffer
       
    56         * @description The number of pixels from the edge of the screen to turn on scrolling. Default: 30
       
    57         * @type Number
       
    58         */
       
    59         buffer: {
       
    60             value: 30
       
    61         },
       
    62         /**
       
    63         * @attribute scrollDelay
       
    64         * @description The number of milliseconds delay to pass to the auto scroller. Default: 235
       
    65         * @type Number
       
    66         */
       
    67         scrollDelay: {
       
    68             value: 235
       
    69         },
       
    70         /**
       
    71         * @attribute host
       
    72         * @description The host we are plugged into.
       
    73         * @type Object
       
    74         */
       
    75         host: {
       
    76             value: null
       
    77         },
       
    78         /**
       
    79         * @attribute windowScroll
       
    80         * @description Turn on window scroll support, default: false
       
    81         * @type Boolean
       
    82         */
       
    83         windowScroll: {
       
    84             value: false
       
    85         },
       
    86         /**
       
    87         * @attribute vertical
       
    88         * @description Allow vertical scrolling, default: true.
       
    89         * @type Boolean
       
    90         */
       
    91         vertical: {
       
    92             value: true
       
    93         },
       
    94         /**
       
    95         * @attribute horizontal
       
    96         * @description Allow horizontal scrolling, default: true.
       
    97         * @type Boolean
       
    98         */
       
    99         horizontal: {
       
   100             value: true
       
   101         }
       
   102     };
       
   103 
       
   104     Y.extend(S, Y.Base, {
       
   105         /**
       
   106         * @private
       
   107         * @property _scrolling
       
   108         * @description Tells if we are actively scrolling or not.
       
   109         * @type Boolean
       
   110         */
       
   111         _scrolling: null,
       
   112         /**
       
   113         * @private
       
   114         * @property _vpRegionCache
       
   115         * @description Cache of the Viewport dims.
       
   116         * @type Object
       
   117         */
       
   118         _vpRegionCache: null,
       
   119         /**
       
   120         * @private
       
   121         * @property _dimCache
       
   122         * @description Cache of the dragNode dims.
       
   123         * @type Object
       
   124         */
       
   125         _dimCache: null,
       
   126         /**
       
   127         * @private
       
   128         * @property _scrollTimer
       
   129         * @description Holder for the Timer object returned from Y.later.
       
   130         * @type {Y.later}
       
   131         */
       
   132         _scrollTimer: null,
       
   133         /**
       
   134         * @private
       
   135         * @method _getVPRegion
       
   136         * @description Sets the _vpRegionCache property with an Object containing the dims from the viewport.
       
   137         */        
       
   138         _getVPRegion: function() {
       
   139             var r = {};
       
   140             //if (!this._vpRegionCache) {
       
   141                 var n = this.get(PARENT_SCROLL),
       
   142                 b = this.get(BUFFER),
       
   143                 ws = this.get(WINDOW_SCROLL),
       
   144                 xy = ((ws) ? [] : n.getXY()),
       
   145                 w = ((ws) ? 'winWidth' : OFFSET_WIDTH),
       
   146                 h = ((ws) ? 'winHeight' : OFFSET_HEIGHT),
       
   147                 t = ((ws) ? n.get(SCROLL_TOP) : xy[1]),
       
   148                 l = ((ws) ? n.get(SCROLL_LEFT) : xy[0]);
       
   149 
       
   150                 r = {
       
   151                     top: t + b,
       
   152                     right: (n.get(w) + l) - b,
       
   153                     bottom: (n.get(h) + t) - b,
       
   154                     left: l + b
       
   155                 };
       
   156                 this._vpRegionCache = r;
       
   157             //} else {
       
   158             //    r = this._vpRegionCache;
       
   159             //}
       
   160             return r;
       
   161         },
       
   162         initializer: function() {
       
   163             var h = this.get(HOST);
       
   164             h.after('drag:start', Y.bind(this.start, this));
       
   165             h.after('drag:end', Y.bind(this.end, this));
       
   166             h.on('drag:align', Y.bind(this.align, this));
       
   167 
       
   168             //TODO - This doesn't work yet??
       
   169             Y.get(window).on('scroll', Y.bind(function() {
       
   170                 this._vpRegionCache = null;
       
   171             }, this));
       
   172         },
       
   173         /**
       
   174         * @private
       
   175         * @method _checkWinScroll
       
   176         * @description Check to see if we need to fire the scroll timer. If scroll timer is running this will scroll the window.
       
   177         * @param {Boolean} move Should we move the window. From Y.later
       
   178         */        
       
   179         _checkWinScroll: function(move) {
       
   180             var r = this._getVPRegion(),
       
   181                 ho = this.get(HOST),
       
   182                 ws = this.get(WINDOW_SCROLL),
       
   183                 xy = ho.lastXY,
       
   184                 scroll = false,
       
   185                 b = this.get(BUFFER),
       
   186                 win = this.get(PARENT_SCROLL),
       
   187                 sTop = win.get(SCROLL_TOP),
       
   188                 sLeft = win.get(SCROLL_LEFT),
       
   189                 w = this._dimCache.w,
       
   190                 h = this._dimCache.h,
       
   191                 bottom = xy[1] + h,
       
   192                 top = xy[1],
       
   193                 right = xy[0] + w,
       
   194                 left = xy[0],
       
   195                 nt = top,
       
   196                 nl = left,
       
   197                 st = sTop,
       
   198                 sl = sLeft;
       
   199             
       
   200             if (this.get('horizontal')) {
       
   201                 if (left <= r.left) {
       
   202                     scroll = true;
       
   203                     nl = xy[0] - ((ws) ? b : 0);
       
   204                     sl = sLeft - b;
       
   205                 }
       
   206                 if (right >= r.right) {
       
   207                     scroll = true;
       
   208                     nl = xy[0] + ((ws) ? b : 0);
       
   209                     sl = sLeft + b;
       
   210                 }
       
   211             }
       
   212             if (this.get('vertical')) {
       
   213                 if (bottom >= r.bottom) {
       
   214                     scroll = true;
       
   215                     nt = xy[1] + ((ws) ? b : 0);
       
   216                     st = sTop + b;
       
   217 
       
   218                 }
       
   219                 if (top <= r.top) {
       
   220                     scroll = true;
       
   221                     nt = xy[1] - ((ws) ? b : 0);
       
   222                     st = sTop - b;
       
   223                 }
       
   224             }
       
   225 
       
   226             if (st < 0) {
       
   227                 st = 0;
       
   228                 nt = xy[1];
       
   229             }
       
   230 
       
   231             if (sl < 0) {
       
   232                 sl = 0;
       
   233                 nl = xy[0];
       
   234             }
       
   235 
       
   236             if (nt < 0) {
       
   237                 nt = xy[1];
       
   238             }
       
   239             if (nl < 0) {
       
   240                 nl = xy[0];
       
   241             }
       
   242             if (move) {
       
   243                 ho.actXY = [nl, nt];
       
   244                 ho._moveNode({ node: win, top: st, left: sl});
       
   245                 if (!st && !sl) {
       
   246                     this._cancelScroll();
       
   247                 }
       
   248             } else {
       
   249                 if (scroll) {
       
   250                     this._initScroll();
       
   251                 } else {
       
   252                     this._cancelScroll();
       
   253                 }
       
   254             }
       
   255         },
       
   256         /**
       
   257         * @private
       
   258         * @method _initScroll
       
   259         * @description Cancel a previous scroll timer and init a new one.
       
   260         */        
       
   261         _initScroll: function() {
       
   262             this._cancelScroll();
       
   263             this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
       
   264 
       
   265         },
       
   266         /**
       
   267         * @private
       
   268         * @method _cancelScroll
       
   269         * @description Cancel a currently running scroll timer.
       
   270         */        
       
   271         _cancelScroll: function() {
       
   272             this._scrolling = false;
       
   273             if (this._scrollTimer) {
       
   274                 this._scrollTimer.cancel();
       
   275                 delete this._scrollTimer;
       
   276             }
       
   277         },
       
   278         /**
       
   279         * @method align
       
   280         * @description Called from the drag:align event to determine if we need to scroll.
       
   281         */        
       
   282         align: function(e) {
       
   283             if (this._scrolling) {
       
   284                 this._cancelScroll();
       
   285                 e.preventDefault();
       
   286             }
       
   287             if (!this._scrolling) {
       
   288                 this._checkWinScroll();
       
   289             }
       
   290         },
       
   291         /**
       
   292         * @private
       
   293         * @method _setDimCache
       
   294         * @description Set the cache of the dragNode dims.
       
   295         */        
       
   296         _setDimCache: function() {
       
   297             var node = this.get(HOST).get('dragNode');
       
   298             this._dimCache = {
       
   299                 h: node.get(OFFSET_HEIGHT),
       
   300                 w: node.get(OFFSET_WIDTH)
       
   301             };
       
   302         },
       
   303         /**
       
   304         * @method start
       
   305         * @description Called from the drag:start event
       
   306         */
       
   307         start: function() {
       
   308             this._setDimCache();
       
   309         },
       
   310         /**
       
   311         * @method end
       
   312         * @description Called from the drag:end event
       
   313         */
       
   314         end: function(xy) {
       
   315             this._dimCache = null;
       
   316             this._cancelScroll();
       
   317         },
       
   318         /**
       
   319         * @method toString
       
   320         * @description General toString method for logging
       
   321         * @return String name for the object
       
   322         */
       
   323         toString: function() {
       
   324             return S.NAME + ' #' + this.get('node').get('id');
       
   325         }
       
   326     });
       
   327 
       
   328     Y.namespace('Plugin');
       
   329 
       
   330     
       
   331     /**
       
   332      * Extends the Scroll class to make the window scroll while dragging.
       
   333      * @class DDWindowScroll
       
   334      * @extends DD.Scroll
       
   335      * @namespace Plugin
       
   336      * @constructor
       
   337      */
       
   338     var WS = function() {
       
   339         WS.superclass.constructor.apply(this, arguments);
       
   340     };
       
   341     WS.ATTRS = Y.merge(S.ATTRS, {
       
   342         /**
       
   343         * @attribute windowScroll
       
   344         * @description Turn on window scroll support, default: true
       
   345         * @type Boolean
       
   346         */
       
   347         windowScroll: {
       
   348             value: true,
       
   349             setter: function(scroll) {
       
   350                 if (scroll) {
       
   351                     this.set(PARENT_SCROLL, Y.get(window));
       
   352                 }
       
   353                 return scroll;
       
   354             }
       
   355         }
       
   356     });
       
   357     Y.extend(WS, S, {
       
   358         //Shouldn't have to do this..
       
   359         initializer: function() {
       
   360             this.set('windowScroll', this.get('windowScroll'));
       
   361         }
       
   362     });
       
   363     WS.NAME = WS.NS = 'winscroll';
       
   364     Y.Plugin.DDWinScroll = WS;
       
   365     
       
   366 
       
   367     /**
       
   368      * Extends the Scroll class to make a parent node scroll while dragging.
       
   369      * @class DDNodeScroll
       
   370      * @extends DD.Scroll
       
   371      * @namespace Plugin
       
   372      * @constructor
       
   373      */
       
   374     var NS = function() {
       
   375         NS.superclass.constructor.apply(this, arguments);
       
   376 
       
   377     };
       
   378     NS.ATTRS = Y.merge(S.ATTRS, {
       
   379         /**
       
   380         * @attribute node
       
   381         * @description The node we want to scroll. Used to set the internal parentScroll attribute.
       
   382         * @type Node
       
   383         */
       
   384         node: {
       
   385             value: false,
       
   386             setter: function(node) {
       
   387                 var n = Y.get(node);
       
   388                 if (!n) {
       
   389                     if (node !== false) {
       
   390                         Y.error('DDNodeScroll: Invalid Node Given: ' + node);
       
   391                     }
       
   392                 } else {
       
   393                     n = n.item(0);
       
   394                     this.set(PARENT_SCROLL, n);
       
   395                 }
       
   396                 return n;
       
   397             }
       
   398         }
       
   399     });
       
   400     Y.extend(NS, S, {
       
   401         //Shouldn't have to do this..
       
   402         initializer: function() {
       
   403             this.set('node', this.get('node'));
       
   404         }
       
   405     });
       
   406     NS.NAME = NS.NS = 'nodescroll';
       
   407     Y.Plugin.DDNodeScroll = NS;
       
   408 
       
   409     Y.DD.Scroll = S;    
       
   410 
       
   411 
       
   412 
       
   413 }, '3.0.0b1' ,{skinnable:false, requires:['dd-drag'], optional:['dd-proxy']});