[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |