src/cm/media/js/lib/yui/yui3.0.0/build/widget/widget-stack-debug.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.0
       
     6 build: 1549
       
     7 */
       
     8 YUI.add('widget-stack', function(Y) {
       
     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 WidgetStack.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: function(val) {
       
   105                 return this._setZIndex(val);
       
   106             }
       
   107         }
       
   108     };
       
   109 
       
   110     /**
       
   111      * The HTML parsing rules for the WidgetStack class.
       
   112      * 
       
   113      * @property WidgetStack.HTML_PARSER
       
   114      * @static
       
   115      * @type Object
       
   116      */
       
   117     Stack.HTML_PARSER = {
       
   118         zIndex: function(contentBox) {
       
   119             return contentBox.getStyle(ZINDEX);
       
   120         }
       
   121     };
       
   122 
       
   123     /**
       
   124      * Default class used to mark the shim element
       
   125      *
       
   126      * @property WidgetStack.SHIM_CLASS_NAME
       
   127      * @type String
       
   128      * @static
       
   129      * @default "yui-widget-shim"
       
   130      */
       
   131     Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM);
       
   132 
       
   133     /**
       
   134      * Default class used to mark the boundingBox of a stacked widget.
       
   135      * 
       
   136      * @property WidgetStack.STACKED_CLASS_NAME
       
   137      * @type String
       
   138      * @static
       
   139      * @default "yui-widget-stacked"
       
   140      */
       
   141     Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED);
       
   142 
       
   143     /**
       
   144      * Default markup template used to generate the shim element.
       
   145      * 
       
   146      * @property WidgetStack.SHIM_TEMPLATE
       
   147      * @type String
       
   148      * @static
       
   149      */
       
   150     Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>';
       
   151 
       
   152     Stack.prototype = {
       
   153 
       
   154         /**
       
   155          * Synchronizes the UI to match the Widgets stack state. This method in 
       
   156          * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure.
       
   157          *
       
   158          * @method _syncUIStack
       
   159          * @protected
       
   160          */
       
   161         _syncUIStack: function() {
       
   162             this._uiSetShim(this.get(SHIM));
       
   163             this._uiSetZIndex(this.get(ZINDEX));
       
   164         },
       
   165 
       
   166         /**
       
   167          * Binds event listeners responsible for updating the UI state in response to 
       
   168          * Widget stack related state changes.
       
   169          * <p>
       
   170          * This method is invoked after bindUI is invoked for the Widget class
       
   171          * using YUI's aop infrastructure.
       
   172          * </p>
       
   173          * @method _bindUIStack
       
   174          * @protected
       
   175          */
       
   176         _bindUIStack: function() {
       
   177             this.after(ShimChange, this._afterShimChange);
       
   178             this.after(ZIndexChange, this._afterZIndexChange);
       
   179         },
       
   180 
       
   181         /**
       
   182          * Creates/Initializes the DOM to support stackability.
       
   183          * <p>
       
   184          * This method in invoked after renderUI is invoked for the Widget class
       
   185          * using YUI's aop infrastructure.
       
   186          * </p>
       
   187          * @method _renderUIStack
       
   188          * @protected
       
   189          */
       
   190         _renderUIStack: function() {
       
   191             this._stackNode.addClass(Stack.STACKED_CLASS_NAME);
       
   192         },
       
   193 
       
   194         /**
       
   195          * Default setter for zIndex attribute changes. Normalizes zIndex values to 
       
   196          * numbers, converting non-numerical values to 0.
       
   197          *
       
   198          * @method _setZIndex
       
   199          * @protected
       
   200          * @param {String | Number} zIndex
       
   201          * @return {Number} Normalized zIndex
       
   202          */
       
   203         _setZIndex: function(zIndex) {
       
   204             if (L.isString(zIndex)) {
       
   205                 zIndex = parseInt(zIndex, 10);
       
   206             }
       
   207             if (!L.isNumber(zIndex)) {
       
   208                 zIndex = 0;
       
   209             }
       
   210             return zIndex;
       
   211         },
       
   212 
       
   213         /**
       
   214          * Default attribute change listener for the shim attribute, responsible
       
   215          * for updating the UI, in response to attribute changes.
       
   216          *
       
   217          * @method _afterShimChange
       
   218          * @protected
       
   219          * @param {EventFacade} e The event facade for the attribute change
       
   220          */
       
   221         _afterShimChange : function(e) {
       
   222             this._uiSetShim(e.newVal);
       
   223         },
       
   224 
       
   225         /**
       
   226          * Default attribute change listener for the zIndex attribute, responsible
       
   227          * for updating the UI, in response to attribute changes.
       
   228          * 
       
   229          * @method _afterZIndexChange
       
   230          * @protected
       
   231          * @param {EventFacade} e The event facade for the attribute change
       
   232          */
       
   233         _afterZIndexChange : function(e) {
       
   234             this._uiSetZIndex(e.newVal);
       
   235         },
       
   236 
       
   237         /**
       
   238          * Updates the UI to reflect the zIndex value passed in.
       
   239          *
       
   240          * @method _uiSetZIndex
       
   241          * @protected
       
   242          * @param {number} zIndex The zindex to be reflected in the UI
       
   243          */
       
   244         _uiSetZIndex: function (zIndex) {
       
   245             this._stackNode.setStyle(ZINDEX, zIndex);
       
   246         },
       
   247 
       
   248         /**
       
   249          * Updates the UI to enable/disable the shim. If the widget is not currently visible,
       
   250          * creation of the shim is deferred until it is made visible, for performance reasons.
       
   251          *
       
   252          * @method _uiSetShim
       
   253          * @protected
       
   254          * @param {boolean} enable If true, creates/renders the shim, if false, removes it.
       
   255          */
       
   256         _uiSetShim: function (enable) {
       
   257             if (enable) {
       
   258                 // Lazy creation
       
   259                 if (this.get(VISIBLE)) {
       
   260                     this._renderShim();
       
   261                 } else {
       
   262                     this._renderShimDeferred();
       
   263                 }
       
   264             } else {
       
   265                 this._destroyShim();
       
   266             }
       
   267         },
       
   268 
       
   269         /**
       
   270          * Sets up change handlers for the visible attribute, to defer shim creation/rendering 
       
   271          * until the Widget is made visible.
       
   272          * 
       
   273          * @method _renderShimDeferred
       
   274          * @private
       
   275          */
       
   276         _renderShimDeferred : function() {
       
   277 
       
   278             this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || [];
       
   279 
       
   280             var handles = this._stackHandles[SHIM_DEFERRED],
       
   281                 createBeforeVisible = function(e) {
       
   282                     if (e.newVal) {
       
   283                         this._renderShim();
       
   284                     }
       
   285                 };
       
   286 
       
   287             handles.push(this.on(VisibleChange, createBeforeVisible));
       
   288         },
       
   289 
       
   290         /**
       
   291          * Sets up event listeners to resize the shim when the size of the Widget changes.
       
   292          * <p>
       
   293          * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to
       
   294          * resize the shim purely through CSS, when the Widget does not have an explicit width/height 
       
   295          * set.
       
   296          * </p>
       
   297          * @method _addShimResizeHandlers
       
   298          * @private
       
   299          */
       
   300         _addShimResizeHandlers : function() {
       
   301 
       
   302             this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || [];
       
   303 
       
   304             var sizeShim = this.sizeShim,
       
   305                 handles = this._stackHandles[SHIM_RESIZE];
       
   306 
       
   307             this.sizeShim();
       
   308 
       
   309             handles.push(this.after(VisibleChange, sizeShim));
       
   310             handles.push(this.after(WidthChange, sizeShim));
       
   311             handles.push(this.after(HeightChange, sizeShim));
       
   312             handles.push(this.after(ContentUpdate, sizeShim));
       
   313         },
       
   314 
       
   315         /**
       
   316          * Detaches any handles stored for the provided key
       
   317          *
       
   318          * @method _detachStackHandles
       
   319          * @param String handleKey The key defining the group of handles which should be detached
       
   320          * @private
       
   321          */
       
   322         _detachStackHandles : function(handleKey) {
       
   323             var handles = this._stackHandles[handleKey],
       
   324                 handle;
       
   325 
       
   326             if (handles && handles.length > 0) {
       
   327                 while((handle = handles.pop())) {
       
   328                     handle.detach();
       
   329                 }
       
   330             }
       
   331         },
       
   332 
       
   333         /**
       
   334          * Creates the shim element and adds it to the DOM
       
   335          *
       
   336          * @method _renderShim
       
   337          * @private
       
   338          */
       
   339         _renderShim : function() {
       
   340             var shimEl = this._shimNode,
       
   341                 stackEl = this._stackNode;
       
   342 
       
   343             if (!shimEl) {
       
   344                 shimEl = this._shimNode = this._getShimTemplate();
       
   345                 stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD));
       
   346 
       
   347                 if (UA.ie == 6) {
       
   348                     this._addShimResizeHandlers();
       
   349                 }
       
   350                 this._detachStackHandles(SHIM_DEFERRED);
       
   351             }
       
   352         },
       
   353 
       
   354         /**
       
   355          * Removes the shim from the DOM, and detaches any related event
       
   356          * listeners.
       
   357          *
       
   358          * @method _destroyShim
       
   359          * @private
       
   360          */
       
   361         _destroyShim : function() {
       
   362             if (this._shimNode) {
       
   363                 this._shimNode.get(PARENT_NODE).removeChild(this._shimNode);
       
   364                 this._shimNode = null;
       
   365 
       
   366                 this._detachStackHandles(SHIM_DEFERRED);
       
   367                 this._detachStackHandles(SHIM_RESIZE);
       
   368             }
       
   369         },
       
   370 
       
   371         /**
       
   372          * For IE6, synchronizes the size and position of iframe shim to that of 
       
   373          * Widget bounding box which it is protecting. For all other browsers,
       
   374          * this method does not do anything.
       
   375          *
       
   376          * @method sizeShim
       
   377          */
       
   378         sizeShim: function () {
       
   379             var shim = this._shimNode,
       
   380                 node = this._stackNode;
       
   381 
       
   382             if (shim && UA.ie === 6 && this.get(VISIBLE)) {
       
   383                 shim.setStyle(WIDTH, node.get(OFFSET_WIDTH) + PX);
       
   384                 shim.setStyle(HEIGHT, node.get(OFFSET_HEIGHT) + PX);
       
   385             }
       
   386         },
       
   387 
       
   388         /**
       
   389          * Creates a cloned shim node, using the SHIM_TEMPLATE html template, for use on a new instance.
       
   390          *
       
   391          * @method _getShimTemplate
       
   392          * @private
       
   393          * @return {Node} node A new shim Node instance.
       
   394          */
       
   395         _getShimTemplate : function() {
       
   396             return Node.create(Stack.SHIM_TEMPLATE, this._stackNode.get(OWNER_DOCUMENT));
       
   397         }
       
   398     };
       
   399 
       
   400     Y.WidgetStack = Stack;
       
   401 
       
   402 
       
   403 }, '3.0.0' ,{requires:['widget']});