[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/widget-stack/ -> widget-stack-debug.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1