src/cm/media/js/lib/yui/yui_3.10.3/build/widget-stack/widget-stack-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('widget-stack', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11  * Provides stackable (z-index) support for Widgets through an extension.
       
    12  *
       
    13  * @module widget-stack
       
    14  */
       
    15     var L = Y.Lang,
       
    16         UA = Y.UA,
       
    17         Node = Y.Node,
       
    18         Widget = Y.Widget,
       
    19 
       
    20         ZINDEX = "zIndex",
       
    21         SHIM = "shim",
       
    22         VISIBLE = "visible",
       
    23 
       
    24         BOUNDING_BOX = "boundingBox",
       
    25 
       
    26         RENDER_UI = "renderUI",
       
    27         BIND_UI = "bindUI",
       
    28         SYNC_UI = "syncUI",
       
    29 
       
    30         OFFSET_WIDTH = "offsetWidth",
       
    31         OFFSET_HEIGHT = "offsetHeight",
       
    32         PARENT_NODE = "parentNode",
       
    33         FIRST_CHILD = "firstChild",
       
    34         OWNER_DOCUMENT = "ownerDocument",
       
    35 
       
    36         WIDTH = "width",
       
    37         HEIGHT = "height",
       
    38         PX = "px",
       
    39 
       
    40         // HANDLE KEYS
       
    41         SHIM_DEFERRED = "shimdeferred",
       
    42         SHIM_RESIZE = "shimresize",
       
    43 
       
    44         // Events
       
    45         VisibleChange = "visibleChange",
       
    46         WidthChange = "widthChange",
       
    47         HeightChange = "heightChange",
       
    48         ShimChange = "shimChange",
       
    49         ZIndexChange = "zIndexChange",
       
    50         ContentUpdate = "contentUpdate",
       
    51 
       
    52         // CSS
       
    53         STACKED = "stacked";
       
    54 
       
    55     /**
       
    56      * Widget extension, which can be used to add stackable (z-index) support to the
       
    57      * base Widget class along with a shimming solution, through the
       
    58      * <a href="Base.html#method_build">Base.build</a> method.
       
    59      *
       
    60      * @class WidgetStack
       
    61      * @param {Object} User configuration object
       
    62      */
       
    63     function Stack(config) {
       
    64         this._stackNode = this.get(BOUNDING_BOX);
       
    65         this._stackHandles = {};
       
    66 
       
    67         // WIDGET METHOD OVERLAP
       
    68         Y.after(this._renderUIStack, this, RENDER_UI);
       
    69         Y.after(this._syncUIStack, this, SYNC_UI);
       
    70         Y.after(this._bindUIStack, this, BIND_UI);
       
    71     }
       
    72 
       
    73     // Static Properties
       
    74     /**
       
    75      * Static property used to define the default attribute
       
    76      * configuration introduced by WidgetStack.
       
    77      *
       
    78      * @property ATTRS
       
    79      * @type Object
       
    80      * @static
       
    81      */
       
    82     Stack.ATTRS = {
       
    83         /**
       
    84          * @attribute shim
       
    85          * @type boolean
       
    86          * @default false, for all browsers other than IE6, for which a shim is enabled by default.
       
    87          *
       
    88          * @description Boolean flag to indicate whether or not a shim should be added to the Widgets
       
    89          * boundingBox, to protect it from select box bleedthrough.
       
    90          */
       
    91         shim: {
       
    92             value: (UA.ie == 6)
       
    93         },
       
    94 
       
    95         /**
       
    96          * @attribute zIndex
       
    97          * @type number
       
    98          * @default 0
       
    99          * @description The z-index to apply to the Widgets boundingBox. Non-numerical values for
       
   100          * zIndex will be converted to 0
       
   101          */
       
   102         zIndex: {
       
   103             value : 0,
       
   104             setter: '_setZIndex'
       
   105         }
       
   106     };
       
   107 
       
   108     /**
       
   109      * The HTML parsing rules for the WidgetStack class.
       
   110      *
       
   111      * @property HTML_PARSER
       
   112      * @static
       
   113      * @type Object
       
   114      */
       
   115     Stack.HTML_PARSER = {
       
   116         zIndex: function (srcNode) {
       
   117             return this._parseZIndex(srcNode);
       
   118         }
       
   119     };
       
   120 
       
   121     /**
       
   122      * Default class used to mark the shim element
       
   123      *
       
   124      * @property SHIM_CLASS_NAME
       
   125      * @type String
       
   126      * @static
       
   127      * @default "yui3-widget-shim"
       
   128      */
       
   129     Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM);
       
   130 
       
   131     /**
       
   132      * Default class used to mark the boundingBox of a stacked widget.
       
   133      *
       
   134      * @property STACKED_CLASS_NAME
       
   135      * @type String
       
   136      * @static
       
   137      * @default "yui3-widget-stacked"
       
   138      */
       
   139     Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED);
       
   140 
       
   141     /**
       
   142      * Default markup template used to generate the shim element.
       
   143      *
       
   144      * @property SHIM_TEMPLATE
       
   145      * @type String
       
   146      * @static
       
   147      */
       
   148     Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>';
       
   149 
       
   150     Stack.prototype = {
       
   151 
       
   152         /**
       
   153          * Synchronizes the UI to match the Widgets stack state. This method in
       
   154          * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure.
       
   155          *
       
   156          * @method _syncUIStack
       
   157          * @protected
       
   158          */
       
   159         _syncUIStack: function() {
       
   160             this._uiSetShim(this.get(SHIM));
       
   161             this._uiSetZIndex(this.get(ZINDEX));
       
   162         },
       
   163 
       
   164         /**
       
   165          * Binds event listeners responsible for updating the UI state in response to
       
   166          * Widget stack related state changes.
       
   167          * <p>
       
   168          * This method is invoked after bindUI is invoked for the Widget class
       
   169          * using YUI's aop infrastructure.
       
   170          * </p>
       
   171          * @method _bindUIStack
       
   172          * @protected
       
   173          */
       
   174         _bindUIStack: function() {
       
   175             this.after(ShimChange, this._afterShimChange);
       
   176             this.after(ZIndexChange, this._afterZIndexChange);
       
   177         },
       
   178 
       
   179         /**
       
   180          * Creates/Initializes the DOM to support stackability.
       
   181          * <p>
       
   182          * This method in invoked after renderUI is invoked for the Widget class
       
   183          * using YUI's aop infrastructure.
       
   184          * </p>
       
   185          * @method _renderUIStack
       
   186          * @protected
       
   187          */
       
   188         _renderUIStack: function() {
       
   189             this._stackNode.addClass(Stack.STACKED_CLASS_NAME);
       
   190         },
       
   191 
       
   192         /**
       
   193         Parses a `zIndex` attribute value from this widget's `srcNode`.
       
   194 
       
   195         @method _parseZIndex
       
   196         @param {Node} srcNode The node to parse a `zIndex` value from.
       
   197         @return {Mixed} The parsed `zIndex` value.
       
   198         @protected
       
   199         **/
       
   200         _parseZIndex: function (srcNode) {
       
   201             var zIndex;
       
   202 
       
   203             // Prefers how WebKit handles `z-index` which better matches the
       
   204             // spec:
       
   205             //
       
   206             // * http://www.w3.org/TR/CSS2/visuren.html#z-index
       
   207             // * https://bugs.webkit.org/show_bug.cgi?id=15562
       
   208             //
       
   209             // When a node isn't rendered in the document, and/or when a
       
   210             // node is not positioned, then it doesn't have a context to derive
       
   211             // a valid `z-index` value from.
       
   212             if (!srcNode.inDoc() || srcNode.getStyle('position') === 'static') {
       
   213                 zIndex = 'auto';
       
   214             } else {
       
   215                 // Uses `getComputedStyle()` because it has greater accuracy in
       
   216                 // more browsers than `getStyle()` does for `z-index`.
       
   217                 zIndex = srcNode.getComputedStyle('zIndex');
       
   218             }
       
   219 
       
   220             // This extension adds a stacking context to widgets, therefore a
       
   221             // `srcNode` witout a stacking context (i.e. "auto") will return
       
   222             // `null` from this DOM parser. This way the widget's default or
       
   223             // user provided value for `zIndex` will be used.
       
   224             return zIndex === 'auto' ? null : zIndex;
       
   225         },
       
   226 
       
   227         /**
       
   228          * Default setter for zIndex attribute changes. Normalizes zIndex values to
       
   229          * numbers, converting non-numerical values to 0.
       
   230          *
       
   231          * @method _setZIndex
       
   232          * @protected
       
   233          * @param {String | Number} zIndex
       
   234          * @return {Number} Normalized zIndex
       
   235          */
       
   236         _setZIndex: function(zIndex) {
       
   237             if (L.isString(zIndex)) {
       
   238                 zIndex = parseInt(zIndex, 10);
       
   239             }
       
   240             if (!L.isNumber(zIndex)) {
       
   241                 zIndex = 0;
       
   242             }
       
   243             return zIndex;
       
   244         },
       
   245 
       
   246         /**
       
   247          * Default attribute change listener for the shim attribute, responsible
       
   248          * for updating the UI, in response to attribute changes.
       
   249          *
       
   250          * @method _afterShimChange
       
   251          * @protected
       
   252          * @param {EventFacade} e The event facade for the attribute change
       
   253          */
       
   254         _afterShimChange : function(e) {
       
   255             this._uiSetShim(e.newVal);
       
   256         },
       
   257 
       
   258         /**
       
   259          * Default attribute change listener for the zIndex attribute, responsible
       
   260          * for updating the UI, in response to attribute changes.
       
   261          *
       
   262          * @method _afterZIndexChange
       
   263          * @protected
       
   264          * @param {EventFacade} e The event facade for the attribute change
       
   265          */
       
   266         _afterZIndexChange : function(e) {
       
   267             this._uiSetZIndex(e.newVal);
       
   268         },
       
   269 
       
   270         /**
       
   271          * Updates the UI to reflect the zIndex value passed in.
       
   272          *
       
   273          * @method _uiSetZIndex
       
   274          * @protected
       
   275          * @param {number} zIndex The zindex to be reflected in the UI
       
   276          */
       
   277         _uiSetZIndex: function (zIndex) {
       
   278             this._stackNode.setStyle(ZINDEX, zIndex);
       
   279         },
       
   280 
       
   281         /**
       
   282          * Updates the UI to enable/disable the shim. If the widget is not currently visible,
       
   283          * creation of the shim is deferred until it is made visible, for performance reasons.
       
   284          *
       
   285          * @method _uiSetShim
       
   286          * @protected
       
   287          * @param {boolean} enable If true, creates/renders the shim, if false, removes it.
       
   288          */
       
   289         _uiSetShim: function (enable) {
       
   290             if (enable) {
       
   291                 // Lazy creation
       
   292                 if (this.get(VISIBLE)) {
       
   293                     this._renderShim();
       
   294                 } else {
       
   295                     this._renderShimDeferred();
       
   296                 }
       
   297 
       
   298                 // Eagerly attach resize handlers
       
   299                 //
       
   300                 // Required because of Event stack behavior, commit ref: cd8dddc
       
   301                 // Should be revisted after Ticket #2531067 is resolved.
       
   302                 if (UA.ie == 6) {
       
   303                     this._addShimResizeHandlers();
       
   304                 }
       
   305             } else {
       
   306                 this._destroyShim();
       
   307             }
       
   308         },
       
   309 
       
   310         /**
       
   311          * Sets up change handlers for the visible attribute, to defer shim creation/rendering
       
   312          * until the Widget is made visible.
       
   313          *
       
   314          * @method _renderShimDeferred
       
   315          * @private
       
   316          */
       
   317         _renderShimDeferred : function() {
       
   318 
       
   319             this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || [];
       
   320 
       
   321             var handles = this._stackHandles[SHIM_DEFERRED],
       
   322                 createBeforeVisible = function(e) {
       
   323                     if (e.newVal) {
       
   324                         this._renderShim();
       
   325                     }
       
   326                 };
       
   327 
       
   328             handles.push(this.on(VisibleChange, createBeforeVisible));
       
   329             // Depending how how Ticket #2531067 is resolved, a reversal of
       
   330             // commit ref: cd8dddc could lead to a more elagent solution, with
       
   331             // the addition of this line here:
       
   332             //
       
   333             // handles.push(this.after(VisibleChange, this.sizeShim));
       
   334         },
       
   335 
       
   336         /**
       
   337          * Sets up event listeners to resize the shim when the size of the Widget changes.
       
   338          * <p>
       
   339          * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to
       
   340          * resize the shim purely through CSS, when the Widget does not have an explicit width/height
       
   341          * set.
       
   342          * </p>
       
   343          * @method _addShimResizeHandlers
       
   344          * @private
       
   345          */
       
   346         _addShimResizeHandlers : function() {
       
   347 
       
   348             this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || [];
       
   349 
       
   350             var sizeShim = this.sizeShim,
       
   351                 handles = this._stackHandles[SHIM_RESIZE];
       
   352 
       
   353             handles.push(this.after(VisibleChange, sizeShim));
       
   354             handles.push(this.after(WidthChange, sizeShim));
       
   355             handles.push(this.after(HeightChange, sizeShim));
       
   356             handles.push(this.after(ContentUpdate, sizeShim));
       
   357         },
       
   358 
       
   359         /**
       
   360          * Detaches any handles stored for the provided key
       
   361          *
       
   362          * @method _detachStackHandles
       
   363          * @param String handleKey The key defining the group of handles which should be detached
       
   364          * @private
       
   365          */
       
   366         _detachStackHandles : function(handleKey) {
       
   367             var handles = this._stackHandles[handleKey],
       
   368                 handle;
       
   369 
       
   370             if (handles && handles.length > 0) {
       
   371                 while((handle = handles.pop())) {
       
   372                     handle.detach();
       
   373                 }
       
   374             }
       
   375         },
       
   376 
       
   377         /**
       
   378          * Creates the shim element and adds it to the DOM
       
   379          *
       
   380          * @method _renderShim
       
   381          * @private
       
   382          */
       
   383         _renderShim : function() {
       
   384             var shimEl = this._shimNode,
       
   385                 stackEl = this._stackNode;
       
   386 
       
   387             if (!shimEl) {
       
   388                 shimEl = this._shimNode = this._getShimTemplate();
       
   389                 stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD));
       
   390 
       
   391                 this._detachStackHandles(SHIM_DEFERRED);
       
   392                 this.sizeShim();
       
   393             }
       
   394         },
       
   395 
       
   396         /**
       
   397          * Removes the shim from the DOM, and detaches any related event
       
   398          * listeners.
       
   399          *
       
   400          * @method _destroyShim
       
   401          * @private
       
   402          */
       
   403         _destroyShim : function() {
       
   404             if (this._shimNode) {
       
   405                 this._shimNode.get(PARENT_NODE).removeChild(this._shimNode);
       
   406                 this._shimNode = null;
       
   407 
       
   408                 this._detachStackHandles(SHIM_DEFERRED);
       
   409                 this._detachStackHandles(SHIM_RESIZE);
       
   410             }
       
   411         },
       
   412 
       
   413         /**
       
   414          * For IE6, synchronizes the size and position of iframe shim to that of
       
   415          * Widget bounding box which it is protecting. For all other browsers,
       
   416          * this method does not do anything.
       
   417          *
       
   418          * @method sizeShim
       
   419          */
       
   420         sizeShim: function () {
       
   421             var shim = this._shimNode,
       
   422                 node = this._stackNode;
       
   423 
       
   424             if (shim && UA.ie === 6 && this.get(VISIBLE)) {
       
   425                 shim.setStyle(WIDTH, node.get(OFFSET_WIDTH) + PX);
       
   426                 shim.setStyle(HEIGHT, node.get(OFFSET_HEIGHT) + PX);
       
   427             }
       
   428         },
       
   429 
       
   430         /**
       
   431          * Creates a cloned shim node, using the SHIM_TEMPLATE html template, for use on a new instance.
       
   432          *
       
   433          * @method _getShimTemplate
       
   434          * @private
       
   435          * @return {Node} node A new shim Node instance.
       
   436          */
       
   437         _getShimTemplate : function() {
       
   438             return Node.create(Stack.SHIM_TEMPLATE, this._stackNode.get(OWNER_DOCUMENT));
       
   439         }
       
   440     };
       
   441 
       
   442     Y.WidgetStack = Stack;
       
   443 
       
   444 
       
   445 }, '3.10.3', {"requires": ["base-build", "widget"], "skinnable": true});