src/cm/media/js/lib/yui/yui_3.10.3/build/scrollview-scrollbars/scrollview-scrollbars-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 Yahoo! Inc. All rights reserved.
       
     4 Licensed under the BSD License.
       
     5 http://yuilibrary.com/license/
       
     6 */
       
     7 
       
     8 YUI.add('scrollview-scrollbars', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11  * Provides a plugin, which adds support for a scroll indicator to ScrollView instances
       
    12  *
       
    13  * @module scrollview
       
    14  * @submodule scrollview-scrollbars
       
    15  */
       
    16 
       
    17 var getClassName = Y.ClassNameManager.getClassName,
       
    18     _classNames,
       
    19 
       
    20     Transition = Y.Transition,
       
    21     NATIVE_TRANSITIONS = Transition.useNative,
       
    22     SCROLLBAR = 'scrollbar',
       
    23     SCROLLVIEW = 'scrollview',
       
    24 
       
    25     VERTICAL_NODE = "verticalNode",
       
    26     HORIZONTAL_NODE = "horizontalNode",
       
    27 
       
    28     CHILD_CACHE = "childCache",
       
    29 
       
    30     TOP = "top",
       
    31     LEFT = "left",
       
    32     WIDTH = "width",
       
    33     HEIGHT = "height",
       
    34 
       
    35     HORIZ_CACHE = "_sbh",
       
    36     VERT_CACHE = "_sbv",
       
    37 
       
    38     TRANSITION_PROPERTY = Y.ScrollView._TRANSITION.PROPERTY,
       
    39     TRANSFORM = "transform",
       
    40 
       
    41     TRANSLATE_X = "translateX(",
       
    42     TRANSLATE_Y = "translateY(",
       
    43 
       
    44     SCALE_X = "scaleX(",
       
    45     SCALE_Y = "scaleY(",
       
    46     
       
    47     SCROLL_X = "scrollX",
       
    48     SCROLL_Y = "scrollY",
       
    49 
       
    50     PX = "px",
       
    51     CLOSE = ")",
       
    52     PX_CLOSE = PX + CLOSE;
       
    53 
       
    54 /**
       
    55  * ScrollView plugin that adds scroll indicators to ScrollView instances
       
    56  *
       
    57  * @class ScrollViewScrollbars
       
    58  * @namespace Plugin
       
    59  * @extends Plugin.Base
       
    60  * @constructor
       
    61  */
       
    62 function ScrollbarsPlugin() {
       
    63     ScrollbarsPlugin.superclass.constructor.apply(this, arguments);
       
    64 }
       
    65 
       
    66 ScrollbarsPlugin.CLASS_NAMES = {
       
    67     showing: getClassName(SCROLLVIEW, SCROLLBAR, 'showing'),
       
    68     scrollbar: getClassName(SCROLLVIEW, SCROLLBAR),
       
    69     scrollbarV: getClassName(SCROLLVIEW, SCROLLBAR, 'vert'),
       
    70     scrollbarH: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz'),
       
    71     scrollbarVB: getClassName(SCROLLVIEW, SCROLLBAR, 'vert', 'basic'),
       
    72     scrollbarHB: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz', 'basic'),
       
    73     child: getClassName(SCROLLVIEW, 'child'),
       
    74     first: getClassName(SCROLLVIEW, 'first'),
       
    75     middle: getClassName(SCROLLVIEW, 'middle'),
       
    76     last: getClassName(SCROLLVIEW, 'last')
       
    77 };
       
    78 
       
    79 _classNames = ScrollbarsPlugin.CLASS_NAMES;
       
    80 
       
    81 /**
       
    82  * The identity of the plugin
       
    83  *
       
    84  * @property NAME
       
    85  * @type String
       
    86  * @default 'pluginScrollViewScrollbars'
       
    87  * @static
       
    88  */
       
    89 ScrollbarsPlugin.NAME = 'pluginScrollViewScrollbars';
       
    90     
       
    91 /**
       
    92  * The namespace on which the plugin will reside.
       
    93  *
       
    94  * @property NS
       
    95  * @type String
       
    96  * @default 'scrollbars'
       
    97  * @static
       
    98  */
       
    99 ScrollbarsPlugin.NS = 'scrollbars';
       
   100 
       
   101 /**
       
   102  * HTML template for the scrollbar
       
   103  *
       
   104  * @property SCROLLBAR_TEMPLATE
       
   105  * @type Object
       
   106  * @static
       
   107  */
       
   108 ScrollbarsPlugin.SCROLLBAR_TEMPLATE = [
       
   109     '<div>',
       
   110     '<span class="' + _classNames.child + ' ' + _classNames.first + '"></span>',
       
   111     '<span class="' + _classNames.child + ' ' + _classNames.middle + '"></span>',
       
   112     '<span class="' + _classNames.child + ' ' + _classNames.last + '"></span>',
       
   113     '</div>'
       
   114 ].join('');
       
   115 
       
   116 /**
       
   117  * The default attribute configuration for the plugin
       
   118  *
       
   119  * @property ATTRS
       
   120  * @type Object
       
   121  * @static
       
   122  */
       
   123 ScrollbarsPlugin.ATTRS = {
       
   124     
       
   125     /**
       
   126      * Vertical scrollbar node
       
   127      *
       
   128      * @attribute verticalNode
       
   129      * @type Y.Node
       
   130      */
       
   131     verticalNode: {
       
   132         setter: '_setNode',
       
   133         valueFn: '_defaultNode'
       
   134     },
       
   135 
       
   136     /**
       
   137      * Horizontal scrollbar node
       
   138      *
       
   139      * @attribute horizontalNode
       
   140      * @type Y.Node
       
   141      */
       
   142     horizontalNode: {
       
   143         setter: '_setNode',
       
   144         valueFn: '_defaultNode'
       
   145     }
       
   146 };
       
   147 
       
   148 Y.namespace("Plugin").ScrollViewScrollbars = Y.extend(ScrollbarsPlugin, Y.Plugin.Base, {
       
   149 
       
   150     /**
       
   151      * Designated initializer
       
   152      *
       
   153      * @method initializer
       
   154      */
       
   155     initializer: function() {
       
   156         this._host = this.get("host");
       
   157 
       
   158         this.afterHostEvent('scrollEnd', this._hostScrollEnd);
       
   159         this.afterHostMethod('scrollTo', this._update);
       
   160         this.afterHostMethod('_uiDimensionsChange', this._hostDimensionsChange);
       
   161     },
       
   162 
       
   163     /**
       
   164      * Set up the DOM nodes for the scrollbars. This method is invoked whenever the
       
   165      * host's _uiDimensionsChange fires, giving us the opportunity to remove un-needed
       
   166      * scrollbars, as well as add one if necessary.
       
   167      *
       
   168      * @method _hostDimensionsChange
       
   169      * @protected
       
   170      */
       
   171     _hostDimensionsChange: function() {
       
   172         var host = this._host,
       
   173             axis = host._cAxis,
       
   174             scrollX = host.get(SCROLL_X),
       
   175             scrollY = host.get(SCROLL_Y);
       
   176 
       
   177         this._dims = host._getScrollDims();
       
   178 
       
   179         if (axis && axis.y) {
       
   180             this._renderBar(this.get(VERTICAL_NODE), true, 'vert');
       
   181         }
       
   182 
       
   183         if (axis && axis.x) {
       
   184             this._renderBar(this.get(HORIZONTAL_NODE), true, 'horiz');
       
   185         }
       
   186 
       
   187         this._update(scrollX, scrollY);
       
   188 
       
   189         Y.later(500, this, 'flash', true);
       
   190     },
       
   191 
       
   192     /**
       
   193      * Handler for the scrollEnd event fired by the host. Default implementation flashes the scrollbar
       
   194      *
       
   195      * @method _hostScrollEnd
       
   196      * @param {Event.Facade} e The event facade.
       
   197      * @protected
       
   198      */
       
   199     _hostScrollEnd : function() {
       
   200         var host = this._host,
       
   201             scrollX = host.get(SCROLL_X),
       
   202             scrollY = host.get(SCROLL_Y);
       
   203 
       
   204         this.flash();
       
   205 
       
   206         this._update(scrollX, scrollY);
       
   207     },
       
   208 
       
   209     /**
       
   210      * Adds or removes a scrollbar node from the document.
       
   211      *
       
   212      * @method _renderBar
       
   213      * @private
       
   214      * @param {Node} bar The scrollbar node
       
   215      * @param {boolean} add true, to add the node, false to remove it
       
   216      */
       
   217     _renderBar: function(bar, add) {
       
   218         var inDoc = bar.inDoc(),
       
   219             bb = this._host._bb,
       
   220             className = bar.getData("isHoriz") ? _classNames.scrollbarHB : _classNames.scrollbarVB;
       
   221 
       
   222         if (add && !inDoc) {
       
   223             bb.append(bar);
       
   224             bar.toggleClass(className, this._basic);
       
   225             this._setChildCache(bar);
       
   226         } else if(!add && inDoc) {
       
   227             bar.remove();
       
   228             this._clearChildCache(bar);
       
   229         }
       
   230     },
       
   231 
       
   232     /**
       
   233      * Caches scrollbar child element information,
       
   234      * to optimize _update implementation
       
   235      *
       
   236      * @method _setChildCache
       
   237      * @private
       
   238      * @param {Node} node
       
   239      */
       
   240     _setChildCache : function(node) {
       
   241         var c = node.get("children"),
       
   242             fc = c.item(0),
       
   243             mc = c.item(1),
       
   244             lc = c.item(2),
       
   245             size = node.getData("isHoriz") ? "offsetWidth" : "offsetHeight";
       
   246 
       
   247         node.setStyle(TRANSITION_PROPERTY, TRANSFORM);
       
   248         mc.setStyle(TRANSITION_PROPERTY, TRANSFORM);
       
   249         lc.setStyle(TRANSITION_PROPERTY, TRANSFORM);
       
   250 
       
   251         node.setData(CHILD_CACHE, {
       
   252             fc : fc,
       
   253             lc : lc,
       
   254             mc : mc,
       
   255             fcSize : fc && fc.get(size),
       
   256             lcSize : lc && lc.get(size)
       
   257         });
       
   258     },
       
   259 
       
   260     /**
       
   261      * Clears child cache
       
   262      *
       
   263      * @method _clearChildCache
       
   264      * @private
       
   265      * @param {Node} node
       
   266      */
       
   267     _clearChildCache : function(node) {
       
   268         node.clearData(CHILD_CACHE);
       
   269     },
       
   270 
       
   271     /**
       
   272      * Utility method, to move/resize either vertical or horizontal scrollbars
       
   273      *
       
   274      * @method _updateBar
       
   275      * @private
       
   276      *
       
   277      * @param {Node} scrollbar The scrollbar node.
       
   278      * @param {Number} current The current scroll position.
       
   279      * @param {Number} duration The transition duration.
       
   280      * @param {boolean} horiz true if horizontal, false if vertical.
       
   281      */
       
   282     _updateBar : function(scrollbar, current, duration, horiz) {
       
   283 
       
   284         var host = this._host,
       
   285             basic = this._basic,
       
   286 
       
   287             scrollbarSize = 0,
       
   288             scrollbarPos = 1,
       
   289 
       
   290             childCache = scrollbar.getData(CHILD_CACHE),
       
   291             lastChild = childCache.lc,
       
   292             middleChild = childCache.mc,
       
   293             firstChildSize = childCache.fcSize,
       
   294             lastChildSize = childCache.lcSize,
       
   295             middleChildSize,
       
   296             lastChildPosition,
       
   297 
       
   298             transition,
       
   299             translate,
       
   300             scale,
       
   301 
       
   302             dim,
       
   303             dimOffset,
       
   304             dimCache,
       
   305             widgetSize,
       
   306             contentSize;
       
   307 
       
   308         if (horiz) {
       
   309             dim = WIDTH;
       
   310             dimOffset = LEFT;
       
   311             dimCache = HORIZ_CACHE;
       
   312             widgetSize = this._dims.offsetWidth;
       
   313             contentSize = this._dims.scrollWidth;
       
   314             translate = TRANSLATE_X;
       
   315             scale = SCALE_X;
       
   316             current = (current !== undefined) ? current : host.get(SCROLL_X);
       
   317         } else {
       
   318             dim = HEIGHT;
       
   319             dimOffset = TOP;
       
   320             dimCache = VERT_CACHE;
       
   321             widgetSize = this._dims.offsetHeight;
       
   322             contentSize = this._dims.scrollHeight;
       
   323             translate = TRANSLATE_Y;
       
   324             scale = SCALE_Y;
       
   325             current = (current !== undefined) ? current : host.get(SCROLL_Y);
       
   326         }
       
   327 
       
   328         scrollbarSize = Math.floor(widgetSize * (widgetSize/contentSize));
       
   329         scrollbarPos = Math.floor((current/(contentSize - widgetSize)) * (widgetSize - scrollbarSize));
       
   330         if (scrollbarSize > widgetSize) {
       
   331             scrollbarSize = 1;
       
   332         }
       
   333 
       
   334         if (scrollbarPos > (widgetSize - scrollbarSize)) {
       
   335             scrollbarSize = scrollbarSize - (scrollbarPos - (widgetSize - scrollbarSize));
       
   336         } else if (scrollbarPos < 0) {
       
   337             scrollbarSize = scrollbarPos + scrollbarSize;
       
   338             scrollbarPos = 0;
       
   339         } else if (isNaN(scrollbarPos)) {
       
   340             scrollbarPos = 0;
       
   341         }
       
   342 
       
   343         middleChildSize = (scrollbarSize - (firstChildSize + lastChildSize));
       
   344 
       
   345         if (middleChildSize < 0) {
       
   346             middleChildSize = 0;
       
   347         }
       
   348 
       
   349         if (middleChildSize === 0 && scrollbarPos !== 0) {
       
   350             scrollbarPos = widgetSize - (firstChildSize + lastChildSize) - 1;
       
   351         }
       
   352 
       
   353         if (duration !== 0) {
       
   354             // Position Scrollbar
       
   355             transition = {
       
   356                 duration : duration
       
   357             };
       
   358 
       
   359             if (NATIVE_TRANSITIONS) {
       
   360                 transition.transform = translate + scrollbarPos + PX_CLOSE;
       
   361             } else {
       
   362                 transition[dimOffset] = scrollbarPos + PX;
       
   363             }
       
   364 
       
   365             scrollbar.transition(transition);
       
   366 
       
   367         } else {
       
   368             if (NATIVE_TRANSITIONS) {
       
   369                 scrollbar.setStyle(TRANSFORM, translate + scrollbarPos + PX_CLOSE);
       
   370             } else {
       
   371                 scrollbar.setStyle(dimOffset, scrollbarPos + PX);
       
   372             }
       
   373         }
       
   374 
       
   375         // Resize Scrollbar Middle Child
       
   376         if (this[dimCache] !== middleChildSize) {
       
   377             this[dimCache] = middleChildSize;
       
   378 
       
   379             if (middleChildSize > 0) {
       
   380 
       
   381                 if (duration !== 0) {
       
   382                     transition = {
       
   383                         duration : duration
       
   384                     };
       
   385 
       
   386                     if(NATIVE_TRANSITIONS) {
       
   387                         transition.transform = scale + middleChildSize + CLOSE;
       
   388                     } else {
       
   389                         transition[dim] = middleChildSize + PX;
       
   390                     }
       
   391 
       
   392                     middleChild.transition(transition);
       
   393                 } else {
       
   394                     if (NATIVE_TRANSITIONS) {
       
   395                         middleChild.setStyle(TRANSFORM, scale + middleChildSize + CLOSE);
       
   396                     } else {
       
   397                         middleChild.setStyle(dim, middleChildSize + PX);
       
   398                     }
       
   399                 }
       
   400     
       
   401                 // Position Last Child
       
   402                 if (!horiz || !basic) {
       
   403 
       
   404                     lastChildPosition = scrollbarSize - lastChildSize;
       
   405     
       
   406                     if(duration !== 0) {
       
   407                         transition = {
       
   408                             duration : duration
       
   409                         };
       
   410                 
       
   411                         if (NATIVE_TRANSITIONS) {
       
   412                             transition.transform = translate + lastChildPosition + PX_CLOSE;
       
   413                         } else {
       
   414                             transition[dimOffset] = lastChildPosition;
       
   415                         }
       
   416 
       
   417                         lastChild.transition(transition);
       
   418                     } else {
       
   419                         if (NATIVE_TRANSITIONS) {
       
   420                             lastChild.setStyle(TRANSFORM, translate + lastChildPosition + PX_CLOSE);
       
   421                         } else {
       
   422                             lastChild.setStyle(dimOffset, lastChildPosition + PX);
       
   423                         }
       
   424                     }
       
   425                 }
       
   426             }
       
   427         }
       
   428     },
       
   429 
       
   430     /**
       
   431      * AOP method, invoked after the host's _uiScrollTo method,
       
   432      *  to position and resize the scroll bars
       
   433      *
       
   434      * @method _update
       
   435      * @param x {Number} The current scrollX value
       
   436      * @param y {Number} The current scrollY value
       
   437      * @param duration {Number} Number of ms of animation (optional) - used when snapping to bounds
       
   438      * @param easing {String} Optional easing equation to use during the animation, if duration is set
       
   439      * @protected
       
   440      */
       
   441     _update: function(x, y, duration) {
       
   442         var vNode = this.get(VERTICAL_NODE),
       
   443             hNode = this.get(HORIZONTAL_NODE),
       
   444             host = this._host,
       
   445             axis = host._cAxis;
       
   446 
       
   447         duration = (duration || 0)/1000;
       
   448 
       
   449         if (!this._showing) {
       
   450             this.show();
       
   451         }
       
   452 
       
   453         if (axis && axis.y && vNode && y !== null) {
       
   454             this._updateBar(vNode, y, duration, false);
       
   455         }
       
   456 
       
   457         if (axis && axis.x && hNode && x !== null) {
       
   458             this._updateBar(hNode, x, duration, true);
       
   459         }
       
   460     },
       
   461 
       
   462     /**
       
   463      * Show the scroll bar indicators
       
   464      *
       
   465      * @method show
       
   466      * @param animated {Boolean} Whether or not to animate the showing
       
   467      */
       
   468     show: function(animated) {
       
   469         this._show(true, animated);
       
   470     },
       
   471 
       
   472     /**
       
   473      * Hide the scroll bar indicators
       
   474      *
       
   475      * @method hide
       
   476      * @param animated {Boolean} Whether or not to animate the hiding
       
   477      */
       
   478     hide: function(animated) {
       
   479         this._show(false, animated);
       
   480     },
       
   481 
       
   482     /**
       
   483      * Internal hide/show implementation utility method
       
   484      *
       
   485      * @method _show
       
   486      * @param {boolean} show Whether to show or hide the scrollbar
       
   487      * @param {bolean} animated Whether or not to animate while showing/hide
       
   488      * @protected
       
   489      */
       
   490     _show : function(show, animated) {
       
   491 
       
   492         var verticalNode = this.get(VERTICAL_NODE),
       
   493             horizontalNode = this.get(HORIZONTAL_NODE),
       
   494 
       
   495             duration = (animated) ? 0.6 : 0,
       
   496             opacity = (show) ? 1 : 0,
       
   497 
       
   498             transition;
       
   499 
       
   500         this._showing = show;
       
   501 
       
   502         if (this._flashTimer) {
       
   503             this._flashTimer.cancel();
       
   504         }
       
   505 
       
   506         transition = {
       
   507             duration : duration,
       
   508             opacity : opacity
       
   509         };
       
   510 
       
   511         if (verticalNode && verticalNode._node) {
       
   512             verticalNode.transition(transition);
       
   513         }
       
   514 
       
   515         if (horizontalNode && horizontalNode._node) {
       
   516             horizontalNode.transition(transition);
       
   517         }
       
   518     },
       
   519 
       
   520     /**
       
   521      * Momentarily flash the scroll bars to indicate current scroll position
       
   522      *
       
   523      * @method flash
       
   524      */
       
   525     flash: function() {
       
   526         this.show(true);
       
   527         this._flashTimer = Y.later(800, this, 'hide', true);
       
   528     },
       
   529 
       
   530     /**
       
   531      * Setter for the verticalNode and horizontalNode attributes
       
   532      *
       
   533      * @method _setNode
       
   534      * @param node {Node} The Y.Node instance for the scrollbar
       
   535      * @param name {String} The attribute name
       
   536      * @return {Node} The Y.Node instance for the scrollbar
       
   537      *
       
   538      * @protected
       
   539      */
       
   540     _setNode: function(node, name) {
       
   541         var horiz = (name === HORIZONTAL_NODE);
       
   542             node = Y.one(node);
       
   543 
       
   544         if (node) {
       
   545             node.addClass(_classNames.scrollbar);
       
   546             node.addClass( (horiz) ? _classNames.scrollbarH : _classNames.scrollbarV );
       
   547             node.setData("isHoriz", horiz);
       
   548         }
       
   549 
       
   550         return node;
       
   551     },
       
   552 
       
   553     /**
       
   554      * Creates default node instances for scrollbars
       
   555      *
       
   556      * @method _defaultNode
       
   557      * @return {Node} The Y.Node instance for the scrollbar
       
   558      *
       
   559      * @protected
       
   560      */
       
   561     _defaultNode: function() {
       
   562         return Y.Node.create(ScrollbarsPlugin.SCROLLBAR_TEMPLATE);
       
   563     },
       
   564 
       
   565     _basic: Y.UA.ie && Y.UA.ie <= 8
       
   566 
       
   567 });
       
   568 
       
   569 
       
   570 }, '3.10.3', {"requires": ["classnamemanager", "transition", "plugin"], "skinnable": true});