src/cm/media/js/lib/yui/yui_3.0.0b1/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.0b1
       
     6 build: 1163
       
     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 
       
    35         WIDTH = "width",
       
    36         HEIGHT = "height",
       
    37         PX = "px",
       
    38 
       
    39         // HANDLE KEYS
       
    40         SHIM_DEFERRED = "shimdeferred",
       
    41         SHIM_RESIZE = "shimresize",
       
    42 
       
    43         // Events
       
    44         VisibleChange = "visibleChange",
       
    45         WidthChange = "widthChange",
       
    46         HeightChange = "heightChange",
       
    47         ShimChange = "shimChange",
       
    48         ZIndexChange = "zIndexChange",
       
    49         ContentUpdate = "contentUpdate",
       
    50 
       
    51         // CSS
       
    52         STACKED = "stacked";
       
    53 
       
    54     /**
       
    55      * Widget extension, which can be used to add stackable (z-index) support to the 
       
    56      * base Widget class along with a shimming solution, through the 
       
    57      * <a href="Base.html#method_build">Base.build</a> method.
       
    58      *
       
    59      * @class WidgetStack
       
    60      * @param {Object} User configuration object
       
    61      */
       
    62     function Stack(config) {
       
    63         this._stackNode = this.get(BOUNDING_BOX);
       
    64         this._stackHandles = {};
       
    65 
       
    66         // WIDGET METHOD OVERLAP
       
    67         Y.after(this._renderUIStack, this, RENDER_UI);
       
    68         Y.after(this._syncUIStack, this, SYNC_UI);
       
    69         Y.after(this._bindUIStack, this, BIND_UI);
       
    70     }
       
    71 
       
    72     // Static Properties
       
    73     /**
       
    74      * Static property used to define the default attribute 
       
    75      * configuration introduced by WidgetStack.
       
    76      * 
       
    77      * @property WidgetStack.ATTRS
       
    78      * @type Object
       
    79      * @static
       
    80      */
       
    81     Stack.ATTRS = {
       
    82         /**
       
    83          * @attribute shim
       
    84          * @type boolean
       
    85          * @default false, for all browsers other than IE6, for which a shim is enabled by default.
       
    86          * 
       
    87          * @description Boolean flag to indicate whether or not a shim should be added to the Widgets
       
    88          * boundingBox, to protect it from select box bleedthrough.
       
    89          */
       
    90         shim: {
       
    91             value: (UA.ie == 6)
       
    92         },
       
    93 
       
    94         /**
       
    95          * @attribute zIndex
       
    96          * @type number
       
    97          * @default 0
       
    98          * @description The z-index to apply to the Widgets boundingBox. Non-numerical values for 
       
    99          * zIndex will be converted to 0
       
   100          */
       
   101         zIndex: {
       
   102             value:0,
       
   103             setter: function(val) {
       
   104                 return this._setZIndex(val);
       
   105             }
       
   106         }
       
   107     };
       
   108 
       
   109     /**
       
   110      * The HTML parsing rules for the WidgetStack class.
       
   111      * 
       
   112      * @property WidgetStack.HTML_PARSER
       
   113      * @static
       
   114      * @type Object
       
   115      */
       
   116     Stack.HTML_PARSER = {
       
   117         zIndex: function(contentBox) {
       
   118             return contentBox.getStyle(ZINDEX);
       
   119         }
       
   120     };
       
   121 
       
   122     /**
       
   123      * Default class used to mark the shim element
       
   124      *
       
   125      * @property WidgetStack.SHIM_CLASS_NAME
       
   126      * @type String
       
   127      * @static
       
   128      * @default "yui-widget-shim"
       
   129      */
       
   130     Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM);
       
   131 
       
   132     /**
       
   133      * Default class used to mark the boundingBox of a stacked widget.
       
   134      * 
       
   135      * @property WidgetStack.STACKED_CLASS_NAME
       
   136      * @type String
       
   137      * @static
       
   138      * @default "yui-widget-stacked"
       
   139      */
       
   140     Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED);
       
   141 
       
   142     /**
       
   143      * Default markup template used to generate the shim element.
       
   144      * 
       
   145      * @property WidgetStack.SHIM_TEMPLATE
       
   146      * @type String
       
   147      * @static
       
   148      */
       
   149     Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>';
       
   150 
       
   151     Stack.prototype = {
       
   152 
       
   153         /**
       
   154          * Synchronizes the UI to match the Widgets stack state. This method in 
       
   155          * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure.
       
   156          *
       
   157          * @method _syncUIStack
       
   158          * @protected
       
   159          */
       
   160         _syncUIStack: function() {
       
   161             this._uiSetShim(this.get(SHIM));
       
   162             this._uiSetZIndex(this.get(ZINDEX));
       
   163         },
       
   164 
       
   165         /**
       
   166          * Binds event listeners responsible for updating the UI state in response to 
       
   167          * Widget stack related state changes.
       
   168          * <p>
       
   169          * This method is invoked after bindUI is invoked for the Widget class
       
   170          * using YUI's aop infrastructure.
       
   171          * </p>
       
   172          * @method _bindUIStack
       
   173          * @protected
       
   174          */
       
   175         _bindUIStack: function() {
       
   176             this.after(ShimChange, this._afterShimChange);
       
   177             this.after(ZIndexChange, this._afterZIndexChange);
       
   178         },
       
   179 
       
   180         /**
       
   181          * Creates/Initializes the DOM to support stackability.
       
   182          * <p>
       
   183          * This method in invoked after renderUI is invoked for the Widget class
       
   184          * using YUI's aop infrastructure.
       
   185          * </p>
       
   186          * @method _renderUIStack
       
   187          * @protected
       
   188          */
       
   189         _renderUIStack: function() {
       
   190             this._stackNode.addClass(Stack.STACKED_CLASS_NAME);
       
   191         },
       
   192 
       
   193         /**
       
   194          * Default setter for zIndex attribute changes. Normalizes zIndex values to 
       
   195          * numbers, converting non-numerical values to 0.
       
   196          *
       
   197          * @method _setZIndex
       
   198          * @protected
       
   199          * @param {String | Number} zIndex
       
   200          * @return {Number} Normalized zIndex
       
   201          */
       
   202         _setZIndex: function(zIndex) {
       
   203             if (L.isString(zIndex)) {
       
   204                 zIndex = parseInt(zIndex, 10);
       
   205             }
       
   206             if (!L.isNumber(zIndex)) {
       
   207                 zIndex = 0;
       
   208             }
       
   209             return zIndex;
       
   210         },
       
   211 
       
   212         /**
       
   213          * Default attribute change listener for the shim attribute, responsible
       
   214          * for updating the UI, in response to attribute changes.
       
   215          *
       
   216          * @method _afterShimChange
       
   217          * @protected
       
   218          * @param {EventFacade} e The event facade for the attribute change
       
   219          */
       
   220         _afterShimChange : function(e) {
       
   221             this._uiSetShim(e.newVal);
       
   222         },
       
   223 
       
   224         /**
       
   225          * Default attribute change listener for the zIndex attribute, responsible
       
   226          * for updating the UI, in response to attribute changes.
       
   227          * 
       
   228          * @method _afterZIndexChange
       
   229          * @protected
       
   230          * @param {EventFacade} e The event facade for the attribute change
       
   231          */
       
   232         _afterZIndexChange : function(e) {
       
   233             this._uiSetZIndex(e.newVal);
       
   234         },
       
   235 
       
   236         /**
       
   237          * Updates the UI to reflect the zIndex value passed in.
       
   238          *
       
   239          * @method _uiSetZIndex
       
   240          * @protected
       
   241          * @param {number} zIndex The zindex to be reflected in the UI
       
   242          */
       
   243         _uiSetZIndex: function (zIndex) {
       
   244             this._stackNode.setStyle(ZINDEX, zIndex);
       
   245         },
       
   246 
       
   247         /**
       
   248          * Updates the UI to enable/disable the shim. If the widget is not currently visible,
       
   249          * creation of the shim is deferred until it is made visible, for performance reasons.
       
   250          *
       
   251          * @method _uiSetShim
       
   252          * @protected
       
   253          * @param {boolean} enable If true, creates/renders the shim, if false, removes it.
       
   254          */
       
   255         _uiSetShim: function (enable) {
       
   256             if (enable) {
       
   257                 // Lazy creation
       
   258                 if (this.get(VISIBLE)) {
       
   259                     this._renderShim();
       
   260                 } else {
       
   261                     this._renderShimDeferred();
       
   262                 }
       
   263             } else {
       
   264                 this._destroyShim();
       
   265             }
       
   266         },
       
   267 
       
   268         /**
       
   269          * Sets up change handlers for the visible attribute, to defer shim creation/rendering 
       
   270          * until the Widget is made visible.
       
   271          * 
       
   272          * @method _renderShimDeferred
       
   273          * @private
       
   274          */
       
   275         _renderShimDeferred : function() {
       
   276 
       
   277             this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || [];
       
   278 
       
   279             var handles = this._stackHandles[SHIM_DEFERRED],
       
   280                 createBeforeVisible = function(e) {
       
   281                     if (e.newVal) {
       
   282                         this._renderShim();
       
   283                     }
       
   284                 };
       
   285 
       
   286             handles.push(this.on(VisibleChange, createBeforeVisible));
       
   287         },
       
   288 
       
   289         /**
       
   290          * Sets up event listeners to resize the shim when the size of the Widget changes.
       
   291          * <p>
       
   292          * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to
       
   293          * resize the shim purely through CSS, when the Widget does not have an explicit width/height 
       
   294          * set.
       
   295          * </p>
       
   296          * @method _addShimResizeHandlers
       
   297          * @private
       
   298          */
       
   299         _addShimResizeHandlers : function() {
       
   300 
       
   301             this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || [];
       
   302 
       
   303             var sizeShim = this.sizeShim,
       
   304                 handles = this._stackHandles[SHIM_RESIZE];
       
   305 
       
   306             this.sizeShim();
       
   307 
       
   308             handles.push(this.after(VisibleChange, sizeShim));
       
   309             handles.push(this.after(WidthChange, sizeShim));
       
   310             handles.push(this.after(HeightChange, sizeShim));
       
   311             handles.push(this.after(ContentUpdate, sizeShim));
       
   312         },
       
   313 
       
   314         /**
       
   315          * Detaches any handles stored for the provided key
       
   316          *
       
   317          * @method _detachStackHandles
       
   318          * @param String handleKey The key defining the group of handles which should be detached
       
   319          * @private
       
   320          */
       
   321         _detachStackHandles : function(handleKey) {
       
   322             var handles = this._stackHandles[handleKey],
       
   323                 handle;
       
   324 
       
   325             if (handles && handles.length > 0) {
       
   326                 while((handle = handles.pop())) {
       
   327                     handle.detach();
       
   328                 }
       
   329             }
       
   330         },
       
   331 
       
   332         /**
       
   333          * Creates the shim element and adds it to the DOM
       
   334          *
       
   335          * @method _renderShim
       
   336          * @private
       
   337          */
       
   338         _renderShim : function() {
       
   339             var shimEl = this._shimNode,
       
   340                 stackEl = this._stackNode;
       
   341 
       
   342             if (!shimEl) {
       
   343                 shimEl = this._shimNode = this._getShimTemplate();
       
   344                 stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD));
       
   345 
       
   346                 if (UA.ie == 6) {
       
   347                     this._addShimResizeHandlers();
       
   348                 }
       
   349                 this._detachStackHandles(SHIM_DEFERRED);
       
   350             }
       
   351         },
       
   352 
       
   353         /**
       
   354          * Removes the shim from the DOM, and detaches any related event
       
   355          * listeners.
       
   356          *
       
   357          * @method _destroyShim
       
   358          * @private
       
   359          */
       
   360         _destroyShim : function() {
       
   361             if (this._shimNode) {
       
   362                 this._shimNode.get(PARENT_NODE).removeChild(this._shimNode);
       
   363                 this._shimNode = null;
       
   364 
       
   365                 this._detachStackHandles(SHIM_DEFERRED);
       
   366                 this._detachStackHandles(SHIM_RESIZE);
       
   367             }
       
   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             if (!Stack._SHIM_TEMPLATE) {
       
   397                 Stack._SHIM_TEMPLATE = Node.create(Stack.SHIM_TEMPLATE);
       
   398             }
       
   399             return Stack._SHIM_TEMPLATE.cloneNode(true);
       
   400         }
       
   401     };
       
   402 
       
   403     Y.WidgetStack = Stack;
       
   404 
       
   405 
       
   406 
       
   407 }, '3.0.0b1' ,{requires:['widget']});