1YUI.add('widget-stack', function (Y, NAME) { 2 3/** 4 * Provides stackable (z-index) support for Widgets through an extension. 5 * 6 * @module widget-stack 7 */ 8 var L = Y.Lang, 9 UA = Y.UA, 10 Node = Y.Node, 11 Widget = Y.Widget, 12 13 ZINDEX = "zIndex", 14 SHIM = "shim", 15 VISIBLE = "visible", 16 17 BOUNDING_BOX = "boundingBox", 18 19 RENDER_UI = "renderUI", 20 BIND_UI = "bindUI", 21 SYNC_UI = "syncUI", 22 23 OFFSET_WIDTH = "offsetWidth", 24 OFFSET_HEIGHT = "offsetHeight", 25 PARENT_NODE = "parentNode", 26 FIRST_CHILD = "firstChild", 27 OWNER_DOCUMENT = "ownerDocument", 28 29 WIDTH = "width", 30 HEIGHT = "height", 31 PX = "px", 32 33 // HANDLE KEYS 34 SHIM_DEFERRED = "shimdeferred", 35 SHIM_RESIZE = "shimresize", 36 37 // Events 38 VisibleChange = "visibleChange", 39 WidthChange = "widthChange", 40 HeightChange = "heightChange", 41 ShimChange = "shimChange", 42 ZIndexChange = "zIndexChange", 43 ContentUpdate = "contentUpdate", 44 45 // CSS 46 STACKED = "stacked"; 47 48 /** 49 * Widget extension, which can be used to add stackable (z-index) support to the 50 * base Widget class along with a shimming solution, through the 51 * <a href="Base.html#method_build">Base.build</a> method. 52 * 53 * @class WidgetStack 54 * @param {Object} User configuration object 55 */ 56 function Stack(config) {} 57 58 // Static Properties 59 /** 60 * Static property used to define the default attribute 61 * configuration introduced by WidgetStack. 62 * 63 * @property ATTRS 64 * @type Object 65 * @static 66 */ 67 Stack.ATTRS = { 68 /** 69 * @attribute shim 70 * @type boolean 71 * @default false, for all browsers other than IE6, for which a shim is enabled by default. 72 * 73 * @description Boolean flag to indicate whether or not a shim should be added to the Widgets 74 * boundingBox, to protect it from select box bleedthrough. 75 */ 76 shim: { 77 value: (UA.ie == 6) 78 }, 79 80 /** 81 * @attribute zIndex 82 * @type number 83 * @default 0 84 * @description The z-index to apply to the Widgets boundingBox. Non-numerical values for 85 * zIndex will be converted to 0 86 */ 87 zIndex: { 88 value : 0, 89 setter: '_setZIndex' 90 } 91 }; 92 93 /** 94 * The HTML parsing rules for the WidgetStack class. 95 * 96 * @property HTML_PARSER 97 * @static 98 * @type Object 99 */ 100 Stack.HTML_PARSER = { 101 zIndex: function (srcNode) { 102 return this._parseZIndex(srcNode); 103 } 104 }; 105 106 /** 107 * Default class used to mark the shim element 108 * 109 * @property SHIM_CLASS_NAME
110 * @type String 111 * @static 112 * @default "yui3-widget-shim" 113 */ 114 Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM); 115 116 /** 117 * Default class used to mark the boundingBox of a stacked widget. 118 * 119 * @property STACKED_CLASS_NAME 120 * @type String 121 * @static 122 * @default "yui3-widget-stacked" 123 */ 124 Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED); 125 126 /** 127 * Default markup template used to generate the shim element. 128 * 129 * @property SHIM_TEMPLATE 130 * @type String 131 * @static 132 */ 133 Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>'; 134 135 Stack.prototype = { 136 137 initializer : function() { 138 this._stackNode = this.get(BOUNDING_BOX); 139 this._stackHandles = {}; 140 141 // WIDGET METHOD OVERLAP 142 Y.after(this._renderUIStack, this, RENDER_UI); 143 Y.after(this._syncUIStack, this, SYNC_UI); 144 Y.after(this._bindUIStack, this, BIND_UI); 145 }, 146 147 /** 148 * Synchronizes the UI to match the Widgets stack state. This method in 149 * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure. 150 * 151 * @method _syncUIStack 152 * @protected 153 */ 154 _syncUIStack: function() { 155 this._uiSetShim(this.get(SHIM)); 156 this._uiSetZIndex(this.get(ZINDEX)); 157 }, 158 159 /** 160 * Binds event listeners responsible for updating the UI state in response to 161 * Widget stack related state changes. 162 * <p> 163 * This method is invoked after bindUI is invoked for the Widget class 164 * using YUI's aop infrastructure. 165 * </p> 166 * @method _bindUIStack 167 * @protected 168 */ 169 _bindUIStack: function() { 170 this.after(ShimChange, this._afterShimChange); 171 this.after(ZIndexChange, this._afterZIndexChange); 172 }, 173 174 /** 175 * Creates/Initializes the DOM to support stackability. 176 * <p> 177 * This method in invoked after renderUI is invoked for the Widget class 178 * using YUI's aop infrastructure. 179 * </p> 180 * @method _renderUIStack 181 * @protected 182 */ 183 _renderUIStack: function() { 184 this._stackNode.addClass(Stack.STACKED_CLASS_NAME); 185 }, 186 187 /** 188 Parses a `zIndex` attribute value from this widget's `srcNode`. 189 190 @method _parseZIndex 191 @param {Node} srcNode The node to parse a `zIndex` value from. 192 @return {Mixed} The parsed `zIndex` value. 193 @protected 194 **/ 195 _parseZIndex: function (srcNode) { 196 var zIndex; 197 198 // Prefers how WebKit handles `z-index` which better matches the 199 // spec: 200 // 201 // * http://www.w3.org/TR/CSS2/visuren.html#z-index 202 // * https://bugs.webkit.org/show_bug.cgi?id=15562 203 // 204 // When a node isn't rendered in the document, and/or when a 205 // node is not positioned, then it doesn't have a context to derive 206 // a valid `z-index` value from. 207 if (!srcNode.inDoc() || srcNode.getStyle('position') === 'static') { 208 zIndex = 'auto'; 209 } else { 210 // Uses `getComputedStyle()` because it has greater accuracy in 211 // more browsers than `getStyle()` does for `z-index`. 212 zIndex = srcNode.getComputedStyle('zIndex'); 213 } 214 215 // This extension adds a stacking context to widgets, therefore a 216 // `srcNode` witout a stacking context (i.e. "auto") will return 217 // `null` from this DOM parser. This way the widget's default or 218 // user provided value for `zIndex` will be used. 219 return zIndex === 'auto' ? null : zIndex; 220 }, 221 222 /** 223 * Default setter for zIndex attribute changes. Normalizes zIndex values to 224 * numbers, converting non-numerical values to 0. 225 * 226 * @method _setZIndex 227 * @protected 228 * @param {String | Number} zIndex 229 * @return {Number} Normalized zIndex 230 */ 231 _setZIndex: function(zIndex) { 232 if (L.isString(zIndex)) { 233 zIndex = parseInt(zIndex, 10); 234 } 235 if (!L.isNumber(zIndex)) { 236 zIndex = 0; 237 } 238 return zIndex; 239 }, 240 241 /** 242 * Default attribute change listener for the shim attribute, responsible 243 * for updating the UI, in response to attribute changes. 244 * 245 * @method _afterShimChange 246 * @protected 247 * @param {EventFacade} e The event facade for the attribute change 248 */ 249 _afterShimChange : function(e) { 250 this._uiSetShim(e.newVal); 251 }, 252 253 /** 254 * Default attribute change listener for the zIndex attribute, responsible 255 * for updating the UI, in response to attribute changes. 256 * 257 * @method _afterZIndexChange 258 * @protected 259 * @param {EventFacade} e The event facade for the attribute change 260 */ 261 _afterZIndexChange : function(e) { 262 this._uiSetZIndex(e.newVal); 263 }, 264 265 /** 266 * Updates the UI to reflect the zIndex value passed in. 267 * 268 * @method _uiSetZIndex 269 * @protected 270 * @param {number} zIndex The zindex to be reflected in the UI 271 */ 272 _uiSetZIndex: function (zIndex) { 273 this._stackNode.setStyle(ZINDEX, zIndex); 274 }, 275 276 /** 277 * Updates the UI to enable/disable the shim. If the widget is not currently visible, 278 * creation of the shim is deferred until it is made visible, for performance reasons. 279 * 280 * @method _uiSetShim 281 * @protected 282 * @param {boolean} enable If true, creates/renders the shim, if false, removes it. 283 */ 284 _uiSetShim: function (enable) { 285 if (enable) { 286 // Lazy creation 287 if (this.get(VISIBLE)) { 288 this._renderShim(); 289 } else { 290 this._renderShimDeferred(); 291 } 292 293 // Eagerly attach resize handlers 294 // 295 // Required because of Event stack behavior, commit ref: cd8dddc 296 // Should be revisted after Ticket #2531067 is resolved. 297 if (UA.ie == 6) { 298 this._addShimResizeHandlers(); 299 } 300 } else { 301 this._destroyShim(); 302 } 303 }, 304 305 /** 306 * Sets up change handlers for the visible attribute, to defer shim creation/rendering 307 * until the Widget is made visible. 308 * 309 * @method _renderShimDeferred 310 * @private 311 */ 312 _renderShimDeferred : function() { 313 314 this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || []; 315 316 var handles = this._stackHandles[SHIM_DEFERRED], 317 createBeforeVisible = function(e) { 318 if (e.newVal) { 319 this._renderShim(); 320 } 321 }; 322 323 handles.push(this.on(VisibleChange, createBeforeVisible)); 324 // Depending how how Ticket #2531067 is resolved, a reversal of 325 // commit ref: cd8dddc could lead to a more elagent solution, with 326 // the addition of this line here: 327 // 328 // handles.push(this.after(VisibleChange, this.sizeShim)); 329 }, 330 331 /** 332 * Sets up event listeners to resize the shim when the size of the Widget changes. 333 * <p> 334 * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to 335 * resize the shim purely through CSS, when the Widget does not have an explicit width/height 336 * set. 337 * </p> 338 * @method _addShimResizeHandlers 339 * @private 340 */ 341 _addShimResizeHandlers : function() { 342 343 this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || []; 344 345 var sizeShim = this.sizeShim, 346 handles = this._stackHandles[SHIM_RESIZE]; 347 348 handles.push(this.after(VisibleChange, sizeShim)); 349 handles.push(this.after(WidthChange, sizeShim)); 350 handles.push(this.after(HeightChange, sizeShim)); 351 handles.push(this.after(ContentUpdate, sizeShim)); 352 }, 353 354 /** 355 * Detaches any handles stored for the provided key 356 * 357 * @method _detachStackHandles 358 * @param String handleKey The key defining the group of handles which should be detached 359 * @private 360 */ 361 _detachStackHandles : function(handleKey) { 362 var handles = this._stackHandles[handleKey], 363 handle; 364 365 if (handles && handles.length > 0) { 366 while((handle = handles.pop())) { 367 handle.detach(); 368 } 369 } 370 }, 371 372 /** 373 * Creates the shim element and adds it to the DOM 374 * 375 * @method _renderShim 376 * @private 377 */ 378 _renderShim : function() { 379 var shimEl = this._shimNode, 380 stackEl = this._stackNode; 381 382 if (!shimEl) { 383 shimEl = this._shimNode = this._getShimTemplate(); 384 stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD)); 385 386 this._detachStackHandles(SHIM_DEFERRED); 387 this.sizeShim(); 388 } 389 }, 390 391 /** 392 * Removes the shim from the DOM, and detaches any related event 393 * listeners. 394 * 395 * @method _destroyShim 396 * @private 397 */ 398 _destroyShim : function() { 399 if (this._shimNode) { 400 this._shimNode.get(PARENT_NODE).removeChild(this._shimNode); 401 this._shimNode = null; 402 403 this._detachStackHandles(SHIM_DEFERRED); 404 this._detachStackHandles(SHIM_RESIZE); 405 } 406 }, 407 408 /** 409 * For IE6, synchronizes the size and position of iframe shim to that of 410 * Widget bounding box which it is protecting. For all other browsers, 411 * this method does not do anything. 412 * 413 * @method sizeShim 414 */ 415 sizeShim: function () { 416 var shim = this._shimNode, 417 node = this._stackNode; 418 419 if (shim && UA.ie === 6 && this.get(VISIBLE)) { 420 shim.setStyle(WIDTH, node.get(OFFSET_WIDTH) + PX); 421 shim.setStyle(HEIGHT, node.get(OFFSET_HEIGHT) + PX); 422 } 423 }, 424 425 /** 426 * Creates a cloned shim node, using the SHIM_TEMPLATE html template, for use on a new instance. 427 * 428 * @method _getShimTemplate 429 * @private 430 * @return {Node} node A new shim Node instance. 431 */ 432 _getShimTemplate : function() { 433 return Node.create(Stack.SHIM_TEMPLATE, this._stackNode.get(OWNER_DOCUMENT)); 434 } 435 }; 436
437 Y.WidgetStack = Stack; 438 439 440}, 'patched-v3.18.1', {"requires": ["base-build", "widget"], "skinnable": true}); 441 442YUI.add('widget-stdmod', function (Y, NAME) { 443 444/** 445 * Provides standard module support for Widgets through an extension. 446 * 447 * @module widget-stdmod 448 */ 449 var L = Y.Lang, 450 Node = Y.Node, 451 UA = Y.UA, 452 Widget = Y.Widget, 453 454 EMPTY = "", 455 HD = "hd", 456 BD = "bd", 457 FT = "ft", 458 HEADER = "header", 459 BODY = "body", 460 FOOTER = "footer", 461 FILL_HEIGHT = "fillHeight", 462 STDMOD = "stdmod", 463 464 NODE_SUFFIX = "Node", 465 CONTENT_SUFFIX = "Content", 466 467 FIRST_CHILD = "firstChild", 468 CHILD_NODES = "childNodes", 469 OWNER_DOCUMENT = "ownerDocument", 470 471 CONTENT_BOX = "contentBox", 472 473 HEIGHT = "height", 474 OFFSET_HEIGHT = "offsetHeight", 475 AUTO = "auto", 476 477 HeaderChange = "headerContentChange", 478 BodyChange = "bodyContentChange", 479 FooterChange = "footerContentChange", 480 FillHeightChange = "fillHeightChange", 481 HeightChange = "heightChange", 482 ContentUpdate = "contentUpdate", 483 484 RENDERUI = "renderUI", 485 BINDUI = "bindUI", 486 SYNCUI = "syncUI", 487 488 APPLY_PARSED_CONFIG = "_applyParsedConfig", 489 490 UI = Y.Widget.UI_SRC; 491 492 /** 493 * Widget extension, which can be used to add Standard Module support to the 494 * base Widget class, through the <a href="Base.html#method_build">Base.build</a> 495 * method. 496 * <p> 497 * The extension adds header, body and footer sections to the Widget's content box and 498 * provides the corresponding methods and attributes to modify the contents of these sections. 499 * </p> 500 * @class WidgetStdMod 501 * @param {Object} The user configuration object 502 */ 503 function StdMod(config) {} 504 505 /** 506 * Constant used to refer the the standard module header, in methods which expect a section specifier 507 * 508 * @property HEADER 509 * @static
510 * @type String 511 */ 512 StdMod.HEADER = HEADER; 513 514 /** 515 * Constant used to refer the the standard module body, in methods which expect a section specifier 516 * 517 * @property BODY 518 * @static 519 * @type String 520 */ 521 StdMod.BODY = BODY; 522 523 /** 524 * Constant used to refer the the standard module footer, in methods which expect a section specifier 525 * 526 * @property FOOTER 527 * @static 528 * @type String 529 */ 530 StdMod.FOOTER = FOOTER; 531 532 /** 533 * Constant used to specify insertion position, when adding content to sections of the standard module in 534 * methods which expect a "where" argument. 535 * <p> 536 * Inserts new content <em>before</em> the sections existing content. 537 * </p> 538 * @property AFTER 539 * @static 540 * @type String 541 */ 542 StdMod.AFTER = "after"; 543 544 /** 545 * Constant used to specify insertion position, when adding content to sections of the standard module in 546 * methods which expect a "where" argument. 547 * <p> 548 * Inserts new content <em>before</em> the sections existing content. 549 * </p> 550 * @property BEFORE 551 * @static
552 * @type String 553 */ 554 StdMod.BEFORE = "before"; 555 /** 556 * Constant used to specify insertion position, when adding content to sections of the standard module in 557 * methods which expect a "where" argument. 558 * <p> 559 * <em>Replaces</em> the sections existing content, with new content. 560 * </p> 561 * @property REPLACE 562 * @static 563 * @type String 564 */ 565 StdMod.REPLACE = "replace"; 566 567 var STD_HEADER = StdMod.HEADER, 568 STD_BODY = StdMod.BODY, 569 STD_FOOTER = StdMod.FOOTER, 570 571 HEADER_CONTENT = STD_HEADER + CONTENT_SUFFIX, 572 FOOTER_CONTENT = STD_FOOTER + CONTENT_SUFFIX, 573 BODY_CONTENT = STD_BODY + CONTENT_SUFFIX; 574 575 /** 576 * Static property used to define the default attribute 577 * configuration introduced by WidgetStdMod. 578 * 579 * @property ATTRS 580 * @type Object 581 * @static 582 */ 583 StdMod.ATTRS = { 584 585 /** 586 * @attribute headerContent 587 * @type HTML 588 * @default undefined 589 * @description The content to be added to the header section. This will replace any existing content 590 * in the header. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method. 591 */ 592 headerContent: { 593 value:null 594 }, 595 596 /** 597 * @attribute footerContent 598 * @type HTML 599 * @default undefined 600 * @description The content to be added to the footer section. This will replace any existing content 601 * in the footer. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method. 602 */ 603 footerContent: { 604 value:null 605 }, 606 607 /** 608 * @attribute bodyContent 609 * @type HTML 610 * @default undefined 611 * @description The content to be added to the body section. This will replace any existing content 612 * in the body. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method. 613 */ 614 bodyContent: { 615 value:null 616 }, 617 618 /** 619 * @attribute fillHeight 620 * @type {String} 621 * @default WidgetStdMod.BODY 622 * @description The section (WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER) which should be resized to fill the height of the standard module, when a 623 * height is set on the Widget. If a height is not set on the widget, then all sections are sized based on 624 * their content. 625 */ 626 fillHeight: { 627 value: StdMod.BODY, 628 validator: function(val) { 629 return this._validateFillHeight(val); 630 } 631 } 632 }; 633 634 /** 635 * The HTML parsing rules for the WidgetStdMod class. 636 * 637 * @property HTML_PARSER 638 * @static 639 * @type Object 640 */ 641 StdMod.HTML_PARSER = { 642 headerContent: function(contentBox) { 643 return this._parseStdModHTML(STD_HEADER); 644 }, 645 646 bodyContent: function(contentBox) { 647 return this._parseStdModHTML(STD_BODY); 648 }, 649 650 footerContent : function(contentBox) { 651 return this._parseStdModHTML(STD_FOOTER); 652 } 653 }; 654 655 /** 656 * Static hash of default class names used for the header, 657 * body and footer sections of the standard module, keyed by 658 * the section identifier (WidgetStdMod.STD_HEADER, WidgetStdMod.STD_BODY, WidgetStdMod.STD_FOOTER) 659 * 660 * @property SECTION_CLASS_NAMES 661 * @static 662 * @type Object 663 */ 664 StdMod.SECTION_CLASS_NAMES = { 665 header: Widget.getClassName(HD), 666 body: Widget.getClassName(BD), 667 footer: Widget.getClassName(FT) 668 }; 669 670 /** 671 * The template HTML strings for each of the standard module sections. Section entries are keyed by the section constants, 672 * WidgetStdMod.HEADER, WidgetStdMod.BODY, WidgetStdMod.FOOTER, and contain the HTML to be added for each section. 673 * e.g. 674 * <pre> 675 * { 676 * header : '<div class="yui-widget-hd"></div>', 677 * body : '<div class="yui-widget-bd"></div>', 678 * footer : '<div class="yui-widget-ft"></div>' 679 * } 680 * </pre> 681 * @property TEMPLATES 682 * @type Object 683 * @static 684 */ 685 StdMod.TEMPLATES = { 686 header : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_HEADER] + '"></div>', 687 body : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_BODY] + '"></div>', 688 footer : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_FOOTER] + '"></div>' 689 }; 690 691 StdMod.prototype = { 692 693 initializer : function() { 694 this._stdModNode = this.get(CONTENT_BOX); 695 696 Y.before(this._renderUIStdMod, this, RENDERUI); 697 Y.before(this._bindUIStdMod, this, BINDUI); 698 Y.before(this._syncUIStdMod, this, SYNCUI); 699 }, 700 701 /** 702 * Synchronizes the UI to match the Widgets standard module state. 703 * <p> 704 * This method is invoked after syncUI is invoked for the Widget class
705 * using YUI's aop infrastructure. 706 * </p> 707 * @method _syncUIStdMod 708 * @protected 709 */ 710 _syncUIStdMod : function() { 711 var stdModParsed = this._stdModParsed; 712 713 if (!stdModParsed || !stdModParsed[HEADER_CONTENT]) { 714 this._uiSetStdMod(STD_HEADER, this.get(HEADER_CONTENT)); 715 } 716 717 if (!stdModParsed || !stdModParsed[BODY_CONTENT]) { 718 this._uiSetStdMod(STD_BODY, this.get(BODY_CONTENT)); 719 } 720 721 if (!stdModParsed || !stdModParsed[FOOTER_CONTENT]) { 722 this._uiSetStdMod(STD_FOOTER, this.get(FOOTER_CONTENT)); 723 } 724 725 this._uiSetFillHeight(this.get(FILL_HEIGHT)); 726 }, 727 728 /** 729 * Creates/Initializes the DOM for standard module support. 730 * <p> 731 * This method is invoked after renderUI is invoked for the Widget class 732 * using YUI's aop infrastructure. 733 * </p> 734 * @method _renderUIStdMod 735 * @protected 736 */ 737 _renderUIStdMod : function() { 738 this._stdModNode.addClass(Widget.getClassName(STDMOD)); 739 this._renderStdModSections(); 740 741 //This normally goes in bindUI but in order to allow setStdModContent() to work before renderUI 742 //stage, these listeners should be set up at the earliest possible time. 743 this.after(HeaderChange, this._afterHeaderChange); 744 this.after(BodyChange, this._afterBodyChange); 745 this.after(FooterChange, this._afterFooterChange); 746 }, 747 748 _renderStdModSections : function() { 749 if (L.isValue(this.get(HEADER_CONTENT))) { this._renderStdMod(STD_HEADER); } 750 if (L.isValue(this.get(BODY_CONTENT))) { this._renderStdMod(STD_BODY); } 751 if (L.isValue(this.get(FOOTER_CONTENT))) { this._renderStdMod(STD_FOOTER); } 752 }, 753 754 /** 755 * Binds event listeners responsible for updating the UI state in response to 756 * Widget standard module related state changes. 757 * <p> 758 * This method is invoked after bindUI is invoked for the Widget class 759 * using YUI's aop infrastructure. 760 * </p> 761 * @method _bindUIStdMod 762 * @protected 763 */ 764 _bindUIStdMod : function() { 765 // this.after(HeaderChange, this._afterHeaderChange); 766 // this.after(BodyChange, this._afterBodyChange); 767 // this.after(FooterChange, this._afterFooterChange); 768 769 this.after(FillHeightChange, this._afterFillHeightChange); 770 this.after(HeightChange, this._fillHeight); 771 this.after(ContentUpdate, this._fillHeight); 772 }, 773 774 /** 775 * Default attribute change listener for the headerContent attribute, responsible 776 * for updating the UI, in response to attribute changes. 777 * 778 * @method _afterHeaderChange 779 * @protected 780 * @param {EventFacade} e The event facade for the attribute change 781 */ 782 _afterHeaderChange : function(e) { 783 if (e.src !== UI) { 784 this._uiSetStdMod(STD_HEADER, e.newVal, e.stdModPosition); 785 } 786 }, 787 788 /** 789 * Default attribute change listener for the bodyContent attribute, responsible 790 * for updating the UI, in response to attribute changes. 791 * 792 * @method _afterBodyChange 793 * @protected 794 * @param {EventFacade} e The event facade for the attribute change 795 */ 796 _afterBodyChange : function(e) { 797 if (e.src !== UI) { 798 this._uiSetStdMod(STD_BODY, e.newVal, e.stdModPosition); 799 } 800 }, 801 802 /** 803 * Default attribute change listener for the footerContent attribute, responsible 804 * for updating the UI, in response to attribute changes. 805 * 806 * @method _afterFooterChange 807 * @protected 808 * @param {EventFacade} e The event facade for the attribute change 809 */ 810 _afterFooterChange : function(e) { 811 if (e.src !== UI) { 812 this._uiSetStdMod(STD_FOOTER, e.newVal, e.stdModPosition); 813 } 814 }, 815 816 /** 817 * Default attribute change listener for the fillHeight attribute, responsible 818 * for updating the UI, in response to attribute changes. 819 * 820 * @method _afterFillHeightChange 821 * @protected 822 * @param {EventFacade} e The event facade for the attribute change 823 */ 824 _afterFillHeightChange: function (e) { 825 this._uiSetFillHeight(e.newVal); 826 }, 827 828 /** 829 * Default validator for the fillHeight attribute. Verifies that the 830 * value set is a valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER, 831 * or a falsey value if fillHeight is to be disabled. 832 * 833 * @method _validateFillHeight 834 * @protected 835 * @param {String} val The section which should be setup to fill height, or false/null to disable fillHeight 836 * @return true if valid, false if not 837 */ 838 _validateFillHeight : function(val) { 839 return !val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER; 840 }, 841 842 /** 843 * Updates the rendered UI, to resize the provided section so that the standard module fills out 844 * the specified widget height. Note: This method does not check whether or not a height is set 845 * on the Widget. 846 * 847 * @method _uiSetFillHeight 848 * @protected 849 * @param {String} fillSection A valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER 850 */ 851 _uiSetFillHeight : function(fillSection) {
852 var fillNode = this.getStdModNode(fillSection); 853 var currNode = this._currFillNode; 854 855 if (currNode && fillNode !== currNode){ 856 currNode.setStyle(HEIGHT, EMPTY); 857 } 858 859 if (fillNode) { 860 this._currFillNode = fillNode; 861 } 862 863 this._fillHeight(); 864 }, 865 866 /** 867 * Updates the rendered UI, to resize the current section specified by the fillHeight attribute, so 868 * that the standard module fills out the Widget height. If a height has not been set on Widget, 869 * the section is not resized (height is set to "auto"). 870 * 871 * @method _fillHeight 872 * @private 873 */ 874 _fillHeight : function() { 875 if (this.get(FILL_HEIGHT)) { 876 var height = this.get(HEIGHT); 877 if (height != EMPTY && height != AUTO) { 878 this.fillHeight(this.getStdModNode(this.get(FILL_HEIGHT))); 879 } 880 } 881 }, 882 883 /** 884 * Updates the rendered UI, adding the provided content (either an HTML string, or node reference), 885 * to the specified section. The content is either added before, after or replaces existing content 886 * in the section, based on the value of the <code>where</code> argument. 887 * 888 * @method _uiSetStdMod 889 * @protected 890 * 891 * @param {String} section The section to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 892 * @param {String | Node} content The new content (either as an HTML string, or Node reference) to add to the section 893 * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE. 894 * If not provided, the content will replace existing content in the section. 895 */ 896 _uiSetStdMod : function(section, content, where) { 897 // Using isValue, so that "" is valid content 898 if (L.isValue(content)) { 899 var node = this.getStdModNode(section, true); 900 901 this._addStdModContent(node, content, where); 902 903 this.set(section + CONTENT_SUFFIX, this._getStdModContent(section), {src:UI}); 904 } else { 905 this._eraseStdMod(section); 906 } 907 this.fire(ContentUpdate); 908 }, 909 910 /** 911 * Creates the DOM node for the given section, and inserts it into the correct location in the contentBox. 912 * 913 * @method _renderStdMod 914 * @protected 915 * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 916 * @return {Node} A reference to the added section node 917 */ 918 _renderStdMod : function(section) { 919 920 var contentBox = this.get(CONTENT_BOX), 921 sectionNode = this._findStdModSection(section); 922 923 if (!sectionNode) { 924 sectionNode = this._getStdModTemplate(section); 925 } 926 927 this._insertStdModSection(contentBox, section, sectionNode); 928 929 this[section + NODE_SUFFIX] = sectionNode; 930 return this[section + NODE_SUFFIX]; 931 }, 932 933 /** 934 * Removes the DOM node for the given section. 935 * 936 * @method _eraseStdMod 937 * @protected 938 * @param {String} section The section to remove. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 939 */ 940 _eraseStdMod : function(section) { 941 var sectionNode = this.getStdModNode(section); 942 if (sectionNode) { 943 sectionNode.remove(true); 944 delete this[section + NODE_SUFFIX]; 945 } 946 }, 947 948 /** 949 * Helper method to insert the Node for the given section into the correct location in the contentBox. 950 * 951 * @method _insertStdModSection 952 * @private 953 * @param {Node} contentBox A reference to the Widgets content box. 954 * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 955 * @param {Node} sectionNode The Node for the section. 956 */ 957 _insertStdModSection : function(contentBox, section, sectionNode) { 958 var fc = contentBox.get(FIRST_CHILD); 959 960 if (section === STD_FOOTER || !fc) { 961 contentBox.appendChild(sectionNode); 962 } else { 963 if (section === STD_HEADER) { 964 contentBox.insertBefore(sectionNode, fc); 965 } else { 966 var footer = this[STD_FOOTER + NODE_SUFFIX]; 967 if (footer) { 968 contentBox.insertBefore(sectionNode, footer); 969 } else { 970 contentBox.appendChild(sectionNode); 971 } 972 } 973 } 974 }, 975 976 /** 977 * Gets a new Node reference for the given standard module section, by cloning 978 * the stored template node. 979 * 980 * @method _getStdModTemplate 981 * @protected 982 * @param {String} section The section to create a new node for. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 983 * @return {Node} The new Node instance for the section 984 */ 985 _getStdModTemplate : function(section) { 986 return Node.create(StdMod.TEMPLATES[section], this._stdModNode.get(OWNER_DOCUMENT)); 987 }, 988 989 /** 990 * Helper method to add content to a StdMod section node. 991 * The content is added either before, after or replaces the existing node content 992 * based on the value of the <code>where</code> argument. 993 * 994 * @method _addStdModContent 995 * @private 996 * 997 * @param {Node} node The section Node to be updated. 998 * @param {Node|NodeList|String} children The new content Node, NodeList or String to be added to section Node provided. 999 * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE. 1000 * If not provided, the content will replace existing content in the Node. 1001 */ 1002 _addStdModContent : function(node, children, where) { 1003 1004 // StdMod where to Node where 1005 switch (where) { 1006 case StdMod.BEFORE: // 0 is before fistChild 1007 where = 0; 1008 break; 1009 case StdMod.AFTER: // undefined is appendChild 1010 where = undefined; 1011 break; 1012 default: // replace is replace, not specified is replace 1013 where = StdMod.REPLACE; 1014 } 1015 1016 node.insert(children, where); 1017 }, 1018 1019 /** 1020 * Helper method to obtain the precise height of the node provided, including padding and border. 1021 * The height could be a sub-pixel value for certain browsers, such as Firefox 3. 1022 *
1023 * @method _getPreciseHeight 1024 * @private 1025 * @param {Node} node The node for which the precise height is required. 1026 * @return {Number} The height of the Node including borders and padding, possibly a float. 1027 */ 1028 _getPreciseHeight : function(node) { 1029 var height = (node) ? node.get(OFFSET_HEIGHT) : 0, 1030 getBCR = "getBoundingClientRect"; 1031 1032 if (node && node.hasMethod(getBCR)) { 1033 var preciseRegion = node.invoke(getBCR); 1034 if (preciseRegion) { 1035 height = preciseRegion.bottom - preciseRegion.top; 1036 } 1037 } 1038 1039 return height; 1040 }, 1041 1042 /** 1043 * Helper method to to find the rendered node for the given section, 1044 * if it exists. 1045 * 1046 * @method _findStdModSection 1047 * @private 1048 * @param {String} section The section for which the render Node is to be found. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 1049 * @return {Node} The rendered node for the given section, or null if not found. 1050 */ 1051 _findStdModSection: function(section) { 1052 return this.get(CONTENT_BOX).one("> ." + StdMod.SECTION_CLASS_NAMES[section]); 1053 }, 1054 1055 /** 1056 * Utility method, used by WidgetStdMods HTML_PARSER implementation 1057 * to extract data for each section from markup. 1058 * 1059 * @method _parseStdModHTML 1060 * @private 1061 * @param {String} section 1062 * @return {String}
1062 Inner HTML string with the contents of the section 1063 */ 1064 _parseStdModHTML : function(section) { 1065 1066 var node = this._findStdModSection(section); 1067 1068 if (node) { 1069 if (!this._stdModParsed) { 1070 this._stdModParsed = {}; 1071 Y.before(this._applyStdModParsedConfig, this, APPLY_PARSED_CONFIG); 1072 } 1073 this._stdModParsed[section + CONTENT_SUFFIX] = 1; 1074 1075 return node.get("innerHTML"); 1076 } 1077 1078 return null; 1079 }, 1080 1081 /** 1082 * This method is injected before the _applyParsedConfig step in 1083 * the application of HTML_PARSER, and sets up the state to 1084 * identify whether or not we should remove the current DOM content 1085 * or not, based on whether or not the current content attribute value 1086 * was extracted from the DOM, or provided by the user configuration 1087 * 1088 * @method _applyStdModParsedConfig 1089 * @private 1090 */ 1091 _applyStdModParsedConfig : function(node, cfg, parsedCfg) { 1092 var parsed = this._stdModParsed; 1093 if (parsed) { 1094 parsed[HEADER_CONTENT] = !(HEADER_CONTENT in cfg) && (HEADER_CONTENT in parsed); 1095 parsed[BODY_CONTENT] = !(BODY_CONTENT in cfg) && (BODY_CONTENT in parsed); 1096 parsed[FOOTER_CONTENT] = !(FOOTER_CONTENT in cfg) && (FOOTER_CONTENT in parsed); 1097 } 1098 }, 1099 1100 /** 1101 * Retrieves the child nodes (content) of a standard module section 1102 * 1103 * @method _getStdModContent 1104 * @private 1105 * @param {String} section The standard module section whose child nodes are to be retrieved. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 1106 * @return {Node} The child node collection of the standard module section. 1107 */ 1108 _getStdModContent : function(section) { 1109 return (this[section + NODE_SUFFIX]) ? this[section + NODE_SUFFIX].get(CHILD_NODES) : null; 1110 }, 1111 1112 /** 1113 * Updates the body section of the standard module with the content provided (either an HTML string, or node reference). 1114 * <p> 1115 * This method can be used instead of the corresponding section content attribute if you'd like to retain the current content of the section, 1116 * and insert content before or after it, by specifying the <code>where</code> argument. 1117 * </p> 1118 * @method setStdModContent 1119 * @param {String} section The standard module section whose content is to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER. 1120 * @param {String | Node} content The content to be added, either an HTML string or a Node reference. 1121 * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE. 1122 * If not provided, the content will replace existing content in the section. 1123 */ 1124 setStdModContent : function(section, content, where) { 1125 //var node = this.getStdModNode(section) || this._renderStdMod(section); 1126 this.set(section + CONTENT_SUFFIX, content, {stdModPosition:where}); 1127 //this._addStdModContent(node, content, where); 1128 }, 1129 1130 /** 1131 Returns the node reference for the specified `section`. 1132 1133 **Note:** The DOM is not queried for the node reference. The reference 1134 stored by the widget instance is returned if it was set. Passing a 1135 truthy for `forceCreate` will create the section node if it does not 1136 already exist. 1137 1138 @method getStdModNode 1139 @param {String} section The section whose node reference is required. 1140 Either `WidgetStdMod.HEADER`, `WidgetStdMod.BODY`, or 1141 `WidgetStdMod.FOOTER`. 1142 @param {Boolean} forceCreate Whether the section node should be created 1143 if it does not already exist. 1144 @return {Node} The node reference for the `section`, or null if not set. 1145 **/ 1146 getStdModNode : function(section, forceCreate) { 1147 var node = this[section + NODE_SUFFIX] || null; 1148 1149 if (!node && forceCreate) { 1150 node = this._renderStdMod(section); 1151 } 1152 1153 return node; 1154 }, 1155 1156 /** 1157 * Sets the height on the provided header, body or footer element to 1158 * fill out the height of the Widget. It determines the height of the 1159 * widgets bounding box, based on it's configured height value, and 1160 * sets the height of the provided section to fill out any 1161 * space remaining after the other standard module section heights 1162 * have been accounted for. 1163 * 1164 * <p><strong>NOTE:</strong> This method is not designed to work if an explicit 1165 * height has not been set on the Widget, since for an "auto" height Widget, 1166 * the heights of the header/body/footer will drive the height of the Widget.</p> 1167 * 1168 * @method fillHeight 1169 * @param {Node} node The node which should be resized to fill out the height 1170 * of the Widget bounding box. Should be a standard module section node which belongs 1171 * to the widget. 1172 */ 1173 fillHeight : function(node) { 1174 if (node) { 1175 var contentBox = this.get(CONTENT_BOX), 1176 stdModNodes = [this.headerNode, this.bodyNode, this.footerNode], 1177 stdModNode, 1178 cbContentHeight, 1179 filled = 0, 1180 remaining = 0, 1181 1182 validNode = false;
1183 1184 for (var i = 0, l = stdModNodes.length; i < l; i++) { 1185 stdModNode = stdModNodes[i]; 1186 if (stdModNode) { 1187 if (stdModNode !== node) { 1188 filled += this._getPreciseHeight(stdModNode); 1189 } else { 1190 validNode = true; 1191 } 1192 } 1193 } 1194 1195 if (validNode) { 1196 if (UA.ie || UA.opera) { 1197 // Need to set height to 0, to allow height to be reduced 1198 node.set(OFFSET_HEIGHT, 0); 1199 } 1200 1201 cbContentHeight = contentBox.get(OFFSET_HEIGHT) - 1202 parseInt(contentBox.getComputedStyle("paddingTop"), 10) - 1203 parseInt(contentBox.getComputedStyle("paddingBottom"), 10) - 1204 parseInt(contentBox.getComputedStyle("borderBottomWidth"), 10) - 1205 parseInt(contentBox.getComputedStyle("borderTopWidth"), 10); 1206 1207 if (L.isNumber(cbContentHeight)) { 1208 remaining = cbContentHeight - filled; 1209 if (remaining >= 0) { 1210 node.set(OFFSET_HEIGHT, remaining); 1211 } 1212 } 1213 } 1214 } 1215 } 1216 }; 1217 1218 Y.WidgetStdMod = StdMod; 1219 1220 1221}, 'patched-v3.18.1', {"requires": ["base-build", "widget"]}); 1222 1223YUI.add('aui-aria', function (A, NAME) { 1224 1225/** 1226 * The Aria Component. 1227 * 1228 * @module aui-aria 1229 */ 1230 1231var Lang = A.Lang, 1232 isBoolean = Lang.isBoolean, 1233 isFunction = Lang.isFunction, 1234 isObject = Lang.isObject, 1235 isString = Lang.isString, 1236 STR_REGEX = /([^a-z])/ig, 1237 1238 _toAriaRole = A.cached(function(str) { 1239 return str.replace(STR_REGEX, function() { 1240 return ''; 1241 }).toLowerCase(); 1242 }); 1243 1244/** 1245 * A base class for Aria. 1246 * 1247 * @class A.Plugin.Aria 1248 * @extends Plugin.Base 1249 * @param {Object} config Object literal specifying widget configuration 1250 * properties. 1251 * @constructor 1252 */ 1253var Aria = A.Component.create({ 1254 1255 /** 1256 * Static property provides a string to identify the class. 1257 * 1258 * @property NAME
1259 * @type String 1260 * @static 1261 */ 1262 NAME: 'aria', 1263 1264 /** 1265 * Static property provides a string to identify the namespace. 1266 * 1267 * @property NS 1268 * @type String 1269 * @static 1270 */ 1271 NS: 'aria', 1272 1273 /** 1274 * Static property used to define the default attribute configuration for 1275 * the `A.Aria`. 1276 * 1277 * @property ATTRS 1278 * @type Object 1279 * @static 1280 */ 1281 ATTRS: { 1282 1283 /** 1284 * The ARIA attributes collection. 1285 * 1286 * @attribute attributes 1287 * @default {} 1288 * @type Object 1289 */ 1290 attributes: { 1291 value: {}, 1292 validator: isObject 1293 }, 1294 1295 /** 1296 * The ARIA attribute value format. 1297 * 1298 * @attribute attributeValueFormat 1299 * @type Function 1300 */ 1301 attributeValueFormat: { 1302 value: function(val) { 1303 return val; 1304 }, 1305 validator: isFunction 1306 }, 1307 1308 /** 1309 * Node container for the ARIA attribute. 1310 * 1311 * @attribute attributeNode 1312 * @writeOnce 1313 */ 1314 attributeNode: { 1315 writeOnce: true, 1316 setter: A.one, 1317 valueFn: function() { 1318 return this.get('host').get('boundingBox'); 1319 } 1320 }, 1321 1322 /** 1323 * The ARIA role name. 1324 * 1325 * @attribute roleName
1326 * @type String 1327 */ 1328 roleName: { 1329 valueFn: function() { 1330 var instance = this; 1331 var host = instance.get('host'); 1332 var roleName = _toAriaRole(host.constructor.NAME || ''); 1333 1334 return (instance.isValidRole(roleName) ? roleName : ''); 1335 }, 1336 validator: isString 1337 }, 1338 1339 /** 1340 * Node container for the ARIA role. 1341 * 1342 * @attribute roleNode 1343 * @writeOnce 1344 */ 1345 roleNode: { 1346 writeOnce: true, 1347 setter: A.one, 1348 valueFn: function() { 1349 return this.get('host').get('boundingBox'); 1350 } 1351 }, 1352 1353 /** 1354 * Checks if the attribute is valid with W3C rules. 1355 * 1356 * @attribute validateW3C 1357 * @default true 1358 * @type Boolean 1359 */ 1360 validateW3C: { 1361 value: true, 1362 validator: isBoolean 1363 } 1364 }, 1365 1366 /** 1367 * Static property used to define which component it extends. 1368 * 1369 * @property EXTENDS 1370 * @type Object 1371 * @static 1372 */ 1373 EXTENDS: A.Plugin.Base, 1374 1375 prototype: { 1376 1377 /** 1378 * Construction logic executed during Aria instantiation. Lifecycle. 1379 * 1380 * @method initializer 1381 * @protected 1382 */ 1383 initializer: function() { 1384 var instance = this; 1385 1386 instance.publish('aria:processAttribute', { 1387 defaultFn: instance._defProcessFn, 1388 queuable: false, 1389 emitFacade: true, 1390 bubbles: true, 1391 prefix: 'aria' 1392 }); 1393 1394 instance._uiSetRoleName( 1395 instance.get('roleName') 1396 ); 1397 1398 instance.after('roleNameChange', instance._afterRoleNameChange); 1399 1400 instance._bindHostAttributes(); 1401 }, 1402 1403 /** 1404 * Checks if the ARIA attribute is valid. 1405 * 1406 * @method isValidAttribute 1407 * @param attrName 1408 * @return {Boolean} 1409 */ 1410 isValidAttribute: function(attrName) { 1411 var instance = this; 1412 1413 return (instance.get('validateW3C') ? A.Plugin.Aria.W3C_ATTRIBUTES[attrName] : true); 1414 }, 1415 1416 /** 1417 * Checks if the ARIA role is valid. 1418 * 1419 * @method isValidRole 1420 * @param roleName 1421 * @return {Boolean} 1422 */ 1423 isValidRole: function(roleName) { 1424 var instance = this; 1425 1426 return (instance.get('validateW3C') ? A.Plugin.Aria.W3C_ROLES[roleName] : true); 1427 }, 1428 1429 /** 1430 * Set a single ARIA attribute. 1431 * 1432 * @method setAttribute 1433 * @param attrName 1434 * @param attrValue 1435 * @param node 1436 * @return {Boolean} 1437 */ 1438 setAttribute: function(attrName, attrValue, node) { 1439 var instance = this; 1440 1441 if (instance.isValidAttribute(attrName)) { 1442 (node || instance.get('attributeNode')).set('aria-' + attrName, attrValue); 1443 1444 return true; 1445 } 1446 1447 return false; 1448 }, 1449 1450 /** 1451 * Set a list of ARIA attributes. 1452 * 1453 * @method setAttributes 1454 * @param attributes 1455 */ 1456 setAttributes: function(attributes) { 1457 var instance = this; 1458 1459 A.Array.each(attributes, function(attribute) { 1460 instance.setAttribute(attribute.name, attribute.value, attribute.node); 1461 }); 1462 }, 1463 1464 /** 1465 * Set a single ARIA role. 1466 * 1467 * @method setRole 1468 * @param roleName 1469 * @param node 1470 * @return {Boolean} 1471 */ 1472 setRole: function(roleName, node) { 1473 var instance = this; 1474 1475 if (instance.isValidRole(roleName)) { 1476 (node || instance.get('roleNode')).set('role', roleName); 1477 1478 return true; 1479 } 1480 1481 return false; 1482 }, 1483 1484 /** 1485 * Set a list of ARIA roles. 1486 * 1487 * @method setRoles 1488 * @param roles 1489 */ 1490 setRoles: function(roles) { 1491 var instance = this; 1492 1493 A.Array.each(roles, function(role) { 1494 instance.setRole(role.name, role.node); 1495 }); 1496 }, 1497 1498 /** 1499 * Fires after a host attribute change. 1500 * 1501 * @method _afterHostAttributeChange 1502 * @param event 1503 * @protected 1504 */ 1505 _afterHostAttributeChange: function(event) { 1506 var instance = this; 1507 1508 instance._handleProcessAttribute(event); 1509 }, 1510 1511 /** 1512 * Triggers after `roleName` attribute change. 1513 * 1514 * @method _afterRoleNameChange 1515 * @param event 1516 * @protected 1517 */ 1518 _afterRoleNameChange: function(event) { 1519 var instance = this; 1520 1521 instance._uiSetRoleName(event.newVal); 1522 }, 1523 1524 /** 1525 * Bind the list of host attributes. 1526 * 1527 * @method _bindHostAttributes 1528 * @protected 1529 */ 1530 _bindHostAttributes: function() { 1531 var instance = this; 1532 var attributes = instance.get('attributes'); 1533 1534 A.each(attributes, function(aria, attrName) { 1535 var ariaAttr = instance._getAriaAttribute(aria, attrName); 1536 1537 instance._handleProcessAttribute({ 1538 aria: ariaAttr 1539 }); 1540 1541 instance.afterHostEvent(attrName + 'Change', function(event) { 1542 event.aria = ariaAttr; 1543 instance._afterHostAttributeChange(event); 1544 }); 1545 }); 1546 }, 1547 1548 /** 1549 * Calls the `_setAttribute` method. 1550 * 1551 * @method _defProcessFn 1552 * @param event 1553 * @protected 1554 */ 1555 _defProcessFn: function(event) { 1556 var instance = this; 1557 1558 instance._setAttribute(event.aria); 1559 }, 1560 1561 /** 1562 * Get the ARIA attribute. 1563 * 1564 * @method _getAriaAttribute 1565 * @param aria 1566 * @param attrName 1567 * @protected 1568 * @return {Object} 1569 */ 1570 _getAriaAttribute: function(aria, attrName) { 1571 var instance = this; 1572 var attributeValueFormat = instance.get('attributeValueFormat'); 1573 var prepared = {}; 1574 1575 if (isString(aria)) { 1576 prepared = A.merge(prepared, { 1577 ariaName: aria, 1578 attrName: attrName, 1579 format: attributeValueFormat, 1580 node: null 1581 }); 1582 } 1583 else if (isObject(aria)) { 1584 prepared = A.mix(aria, { 1585 ariaName: '', 1586 attrName: attrName, 1587 format: attributeValueFormat, 1588 node: null 1589 }); 1590 } 1591 1592 return prepared; 1593 }, 1594 1595 /** 1596 * Fires ARIA process attribute event handle. 1597 * 1598 * @method _handleProcessAttribute 1599 * @param event 1600 * @protected 1601 */ 1602 _handleProcessAttribute: function(event) { 1603 var instance = this; 1604 1605 instance.fire('aria:processAttribute', { 1606 aria: event.aria 1607 }); 1608 }, 1609 1610 /** 1611 * Set the attribute in the DOM. 1612 * 1613 * @method _setAttribute 1614 * @param ariaAttr 1615 * @protected 1616 */ 1617 _setAttribute: function(ariaAttr) { 1618 var instance = this; 1619 var host = instance.get('host'); 1620 var attrValue = host.get(ariaAttr.attrName); 1621 var attrNode = ariaAttr.node; 1622 1623 if (isFunction(attrNode)) { 1624 attrNode = attrNode.apply(instance, [ariaAttr]); 1625 } 1626 1627 instance.setAttribute( 1628 ariaAttr.ariaName, 1629 ariaAttr.format.apply(instance, [attrValue, ariaAttr]), 1630 attrNode 1631 ); 1632 }, 1633 1634 /** 1635 * Set the `roleName` attribute on the UI. 1636 * 1637 * @method _uiSetRoleName 1638 * @param val 1639 * @protected 1640 */ 1641 _uiSetRoleName: function(val) { 1642 var instance = this; 1643 1644 instance.setRole(val); 1645 } 1646 } 1647}); 1648 1649A.Plugin.Aria = Aria; 1650/** 1651 * Static property used to define [W3C's Roles Model](http://www.w3.org/TR/wai- 1652 * aria/roles). 1653 * 1654 * @property W3C_ROLES 1655 * @type Object 1656 * @static 1657 */ 1658A.Plugin.Aria.W3C_ROLES = { 1659 'alert': 1, 1660 'alertdialog': 1, 1661 'application': 1, 1662 'article': 1, 1663 'banner': 1, 1664 'button': 1, 1665 'checkbox': 1, 1666 'columnheader': 1, 1667 'combobox': 1, 1668 'command': 1, 1669 'complementary': 1, 1670 'composite': 1, 1671 'contentinfo': 1, 1672 'definition': 1, 1673 'dialog': 1, 1674 'directory': 1, 1675 'document': 1, 1676 'form': 1, 1677 'grid': 1, 1678 'gridcell': 1, 1679 'group': 1, 1680 'heading': 1, 1681 'img': 1, 1682 'input': 1, 1683 'landmark': 1, 1684 'link': 1, 1685 'list': 1, 1686 'listbox': 1, 1687 'listitem': 1, 1688 'log': 1, 1689 'main': 1, 1690 'marquee': 1, 1691 'math': 1, 1692 'menu': 1, 1693 'menubar': 1, 1694 'menuitem': 1, 1695 'menuitemcheckbox': 1, 1696 'menuitemradio': 1, 1697 'navigation': 1, 1698 'note': 1, 1699 'option': 1, 1700 'presentation': 1, 1701 'progressbar': 1, 1702 'radio': 1, 1703 'radiogroup': 1, 1704 'range': 1, 1705 'region': 1, 1706 'roletype': 1, 1707 'row': 1, 1708 'rowheader': 1, 1709 'scrollbar': 1, 1710 'search': 1, 1711 'section': 1, 1712 'sectionhead': 1, 1713 'select': 1, 1714 'separator': 1, 1715 'slider': 1, 1716 'spinbutton': 1, 1717 'status': 1, 1718 'structure': 1, 1719 'tab': 1, 1720 'tablist': 1, 1721 'tabpanel': 1, 1722 'textbox': 1, 1723 'timer': 1, 1724 'toolbar': 1, 1725 'tooltip': 1, 1726 'tree': 1, 1727 'treegrid': 1, 1728 'treeitem': 1, 1729 'widget': 1, 1730 'window': 1 1731}; 1732/**
1733 * Static property used to define [W3C's Supported States and 1734 * Properties](http://www.w3.org/TR/wai-aria/states_and_properties). 1735 * 1736 * @property W3C_ATTRIBUTES 1737 * @type Object 1738 * @static 1739 */ 1740A.Plugin.Aria.W3C_ATTRIBUTES = { 1741 'activedescendant': 1, 1742 'atomic': 1, 1743 'autocomplete': 1, 1744 'busy': 1, 1745 'checked': 1, 1746 'controls': 1, 1747 'describedby': 1, 1748 'disabled': 1, 1749 'dropeffect': 1, 1750 'expanded': 1, 1751 'flowto': 1, 1752 'grabbed': 1, 1753 'haspopup': 1, 1754 'hidden': 1, 1755 'invalid': 1, 1756 'label': 1, 1757 'labelledby': 1, 1758 'level': 1, 1759 'live': 1, 1760 'multiline': 1, 1761 'multiselectable': 1, 1762 'orientation': 1, 1763 'owns': 1, 1764 'posinset': 1, 1765 'pressed': 1, 1766 'readonly': 1, 1767 'relevant': 1, 1768 'required': 1, 1769 'selected': 1, 1770 'setsize': 1, 1771 'sort': 1, 1772 'valuemax': 1, 1773 'valuemin': 1, 1774 'valuenow': 1, 1775 'valuetext': 1 1776}; 1777 1778 1779}, '3.1.0-deprecated.70', {"requires": ["plugin", "aui-component"]}); 1780 1781YUI.add('aui-io-plugin-deprecated', function (A, NAME) { 1782 1783/** 1784 * The IOPlugin Utility - When plugged to a Node or Widget loads the content 1785 * of a URI and set as its content, parsing the <code>script</code> tags if 1786 * present on the code. 1787 * 1788 * @module aui-io 1789 * @submodule aui-io-plugin 1790 */ 1791 1792var L = A.Lang, 1793 isBoolean = L.isBoolean, 1794 isString = L.isString, 1795 1796 isNode = function(v) { 1797 return (v instanceof A.Node); 1798 }, 1799
1800 StdMod = A.WidgetStdMod, 1801 1802 TYPE_NODE = 'Node', 1803 TYPE_WIDGET = 'Widget', 1804 1805 EMPTY = '', 1806 FAILURE = 'failure', 1807 FAILURE_MESSAGE = 'failureMessage', 1808 HOST = 'host', 1809 ICON = 'icon', 1810 IO = 'io', 1811 IO_PLUGIN = 'IOPlugin', 1812 LOADING = 'loading', 1813 LOADING_MASK = 'loadingMask', 1814 NODE = 'node', 1815 OUTER = 'outer', 1816 PARSE_CONTENT = 'parseContent', 1817 QUEUE = 'queue', 1818 RENDERED = 'rendered', 1819 SECTION = 'section', 1820 SHOW_LOADING = 'showLoading', 1821 SUCCESS = 'success', 1822 TYPE = 'type', 1823 WHERE = 'where', 1824 1825 getCN = A.getClassName, 1826 1827 CSS_ICON_LOADING = getCN(ICON, LOADING); 1828 1829/** 1830 * A base class for IOPlugin, providing: 1831 * <ul> 1832 * <li>Loads the content of a URI as content of a Node or Widget</li> 1833 * <li>Use <a href="ParseContent.html">ParseContent</a> to parse the JavaScript tags from the content and evaluate them</li> 1834 * </ul> 1835 * 1836 * Quick Example:<br/> 1837 * 1838 * <pre><code>A.one('#content').plug(A.Plugin.IO, { uri: 'assets/content.html', method: 'GET' });</code></pre> 1839 * 1840 * Check the list of <a href="A.Plugin.IO.html#configattributes">Configuration Attributes</a> available for 1841 * IOPlugin. 1842 * 1843 * @param config {Object} Object literal specifying widget configuration properties. 1844 * 1845 * @class A.Plugin.IO 1846 * @constructor 1847 * @extends IORequest 1848 */ 1849var IOPlugin = A.Component.create({ 1850 /** 1851 * Static property provides a string to identify the class. 1852 * 1853 * @property A.Plugin.IO.NAME
1854 * @type String 1855 * @static 1856 */ 1857 NAME: IO_PLUGIN, 1858 1859 /** 1860 * Static property provides a string to identify the namespace. 1861 * 1862 * @property A.Plugin.IO.NS 1863 * @type String 1864 * @static 1865 */ 1866 NS: IO, 1867 1868 /** 1869 * Static property used to define the default attribute 1870 * configuration for the A.Plugin.IO. 1871 * 1872 * @property A.Plugin.IO.ATTRS 1873 * @type Object 1874 * @static 1875 */ 1876 ATTRS: { 1877 /** 1878 * Plug IO in any object we want, the setContent will use the node to 1879 * set the content. 1880 * 1881 * @attribute node 1882 * @default null 1883 * @type Node | String 1884 */ 1885 node: { 1886 value: null, 1887 getter: function(value) { 1888 var instance = this; 1889 1890 if (!value) { 1891 var host = instance.get(HOST); 1892 var type = instance.get(TYPE); 1893 1894 if (type == TYPE_NODE) { 1895 value = host; 1896 } 1897 else if (type == TYPE_WIDGET) { 1898 var section = instance.get(SECTION); 1899 1900 // if there is no node for the SECTION, forces creation 1901 if (!host.getStdModNode(section)) { 1902 host.setStdModContent(section, EMPTY); 1903 } 1904 1905 value = host.getStdModNode(section); 1906 } 1907 } 1908 1909 return A.one(value); 1910 }, 1911 validator: isNode 1912 }, 1913 1914 /** 1915 * Message to be set on the content when the transaction fails. 1916 * 1917 * @attribute failureMessage 1918 * @default 'Failed to retrieve content'
1919 * @type String 1920 */ 1921 failureMessage: { 1922 value: 'Failed to retrieve content', 1923 validator: isString 1924 }, 1925 1926 /** 1927 * Options passed to the <a href="LoadingMask.html">LoadingMask</a>. 1928 * 1929 * @attribute loadingMask 1930 * @default {} 1931 * @type Object 1932 */ 1933 loadingMask: { 1934 value: {} 1935 }, 1936 1937 /** 1938 * If true the <a href="ParseContent.html">ParseContent</a> plugin 1939 * will be plugged to the <a href="A.Plugin.IO.html#config_node">node</a>. 1940 * 1941 * @attribute parseContent 1942 * @default true 1943 * @type boolean 1944 */ 1945 parseContent: { 1946 value: true, 1947 validator: isBoolean 1948 }, 1949 1950 /** 1951 * Show the <a href="LoadingMask.html">LoadingMask</a> covering the <a 1952 * href="A.Plugin.IO.html#config_node">node</a> while loading. 1953 * 1954 * @attribute showLoading 1955 * @default true 1956 * @type boolean 1957 */ 1958 showLoading: { 1959 value: true, 1960 validator: isBoolean 1961 }, 1962 1963 /** 1964 * Section where the content will be set in case you are plugging it 1965 * on a instace of <a href="WidgetStdMod.html">WidgetStdMod</a>. 1966 * 1967 * @attribute section 1968 * @default StdMod.BODY
1969 * @type String 1970 */ 1971 section: { 1972 value: StdMod.BODY, 1973 validator: function(val) { 1974 return (!val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER); 1975 } 1976 }, 1977 1978 /** 1979 * Type of the <code>instance</code> we are pluggin the A.Plugin.IO. 1980 * Could be a Node, or a Widget. 1981 * 1982 * @attribute type 1983 * @default 'Node' 1984 * @readOnly 1985 * @type String 1986 */ 1987 type: { 1988 readOnly: true, 1989 valueFn: function() { 1990 var instance = this; 1991 // NOTE: default type 1992 var type = TYPE_NODE; 1993 1994 if (instance.get(HOST) instanceof A.Widget) { 1995 type = TYPE_WIDGET; 1996 } 1997 1998 return type; 1999 }, 2000 validator: isString 2001 }, 2002 2003 /** 2004 * Where to insert the content, AFTER, BEFORE or REPLACE. If you're plugging a Node, there is a fourth option called OUTER that will not only replace the entire node itself. This is different from REPLACE, in that REPLACE will replace the *contents* of the node, OUTER will replace the entire Node itself. 2005 * 2006 * @attribute where 2007 * @default StdMod.REPLACE
2008 * @type String 2009 */ 2010 where: { 2011 value: StdMod.REPLACE, 2012 validator: function(val) { 2013 return (!val || val == StdMod.AFTER || val == StdMod.BEFORE || val == StdMod.REPLACE || val == 2014 OUTER); 2015 } 2016 } 2017 }, 2018 2019 EXTENDS: A.IORequest, 2020 2021 prototype: { 2022 /** 2023 * Bind the events on the A.Plugin.IO UI. Lifecycle. 2024 * 2025 * @method bindUI 2026 * @protected 2027 */ 2028 bindUI: function() { 2029 var instance = this; 2030 2031 instance.on('activeChange', instance._onActiveChange); 2032 2033 instance.on(SUCCESS, instance._successHandler); 2034 instance.on(FAILURE, instance._failureHandler); 2035 2036 if ((instance.get(TYPE) == TYPE_WIDGET) && instance.get(SHOW_LOADING)) { 2037 var host = instance.get(HOST); 2038 2039 host.after('heightChange', instance._syncLoadingMaskUI, instance); 2040 host.after('widthChange', instance._syncLoadingMaskUI, instance); 2041 } 2042 }, 2043 2044 /** 2045 * Invoke the <code>start</code> method (autoLoad attribute). 2046 * 2047 * @method _autoStart 2048 * @protected 2049 */ 2050 _autoStart: function() { 2051 var instance = this; 2052 2053 instance.bindUI(); 2054 2055 IOPlugin.superclass._autoStart.apply(this, arguments); 2056 }, 2057 2058 /** 2059 * Bind the ParseContent plugin on the <code>instance</code>. 2060 * 2061 * @method _bindParseContent 2062 * @protected 2063 */ 2064 _bindParseContent: function() { 2065 var instance = this; 2066 var node = instance.get(NODE); 2067 2068 if (node && !node.ParseContent && instance.get(PARSE_CONTENT)) { 2069 node.plug(A.Plugin.ParseContent); 2070 } 2071 }, 2072 2073 /** 2074 * Invoke the <a href="OverlayMask.html#method_hide">OverlayMask hide</a> method. 2075 * 2076 * @method hideLoading 2077 */ 2078 hideLoading: function() { 2079 var instance = this; 2080 2081 var node = instance.get(NODE); 2082 2083 if (node.loadingmask) { 2084 node.loadingmask.hide(); 2085 } 2086 }, 2087 2088 /** 2089 * Set the content of the <a href="A.Plugin.IO.html#config_node">node</a>. 2090 * 2091 * @method setContent 2092 */ 2093 setContent: function(content) { 2094 var instance = this; 2095 2096 instance._bindParseContent(); 2097 2098 instance._getContentSetterByType().apply(instance, [content]); 2099 2100 if (instance.overlayMaskBoundingBox) { 2101 instance.overlayMaskBoundingBox.remove(); 2102 } 2103 }, 2104 2105 /** 2106 * Invoke the <a href="OverlayMask.html#method_show">OverlayMask show</a> method. 2107 * 2108 * @method showLoading 2109 */ 2110 showLoading: function() { 2111 var instance = this; 2112 var node = instance.get(NODE); 2113 2114 if (node.loadingmask) { 2115 if (instance.overlayMaskBoundingBox) { 2116 node.append(instance.overlayMaskBoundingBox); 2117 } 2118 } 2119 else { 2120 node.plug( 2121 A.LoadingMask, 2122 instance.get(LOADING_MASK) 2123 ); 2124 2125 instance.overlayMaskBoundingBox = node.loadingmask.overlayMask.get('boundingBox'); 2126 } 2127 2128 node.loadingmask.show(); 2129 }, 2130 2131 /** 2132 * Overload to the <a href="IORequest.html#method_start">IORequest 2133 * start</a> method. Check if the <code>host</code> is already rendered, 2134 * otherwise wait to after render phase and to show the LoadingMask. 2135 * 2136 * @method start 2137 */ 2138 start: function() { 2139 var instance = this; 2140 var host = instance.get(HOST); 2141 2142 if (!host.get(RENDERED)) { 2143 host.after('render', function() { 2144 instance._setLoadingUI(true); 2145 }); 2146 } 2147 2148 IOPlugin.superclass.start.apply(instance, arguments); 2149 }, 2150 2151 /** 2152 * Get the appropriated <a 2153 * href="A.Plugin.IO.html#method_setContent">setContent</a> function 2154 * implementation for each <a href="A.Plugin.IO.html#config_type">type</a>. 2155 * 2156 * @method _getContentSetterByType 2157 * @protected 2158 * @return {function} 2159 */ 2160 _getContentSetterByType: function() { 2161 var instance = this; 2162 2163 var setters = { 2164 // NOTE: default setter, see 'type' attribute definition 2165 Node: function(content) { 2166 var instance = this; 2167 // when this.get(HOST) is a Node instance the NODE is the host 2168 var node = instance.get(NODE); 2169 2170 if (content instanceof A.NodeList) { 2171 content = content.toFrag(); 2172 } 2173 2174 if (content instanceof A.Node) { 2175 content = content._node; 2176 } 2177 2178 var where = instance.get(WHERE); 2179 2180 if (where == OUTER) { 2181 node.replace(content); 2182 } 2183 else { 2184 node.insert(content, where); 2185 } 2186 }, 2187
2188 // Widget forces set the content on the SECTION node using setStdModContent method 2189 Widget: function(content) { 2190 var instance = this; 2191 var host = instance.get(HOST); 2192 2193 host.setStdModContent.apply(host, [ 2194 instance.get(SECTION), 2195 content, 2196 instance.get(WHERE) 2197 ]); 2198 } 2199 }; 2200 2201 return setters[this.get(TYPE)]; 2202 }, 2203 2204 /** 2205 * Whether the <code>show</code> is true show the LoadingMask. 2206 * 2207 * @method _setLoadingUI 2208 * @param {boolean} show 2209 * @protected 2210 */ 2211 _setLoadingUI: function(show) { 2212 var instance = this; 2213 2214 if (instance.get(SHOW_LOADING)) { 2215 if (show) { 2216 instance.showLoading(); 2217 } 2218 else { 2219 instance.hideLoading(); 2220 } 2221 } 2222 }, 2223 2224 /** 2225 * Sync the loading mask UI. 2226 * 2227 * @method _syncLoadingMaskUI 2228 * @protected 2229 */ 2230 _syncLoadingMaskUI: function() { 2231 var instance = this; 2232 2233 instance.get(NODE).loadingmask.refreshMask(); 2234 }, 2235 2236 /** 2237 * Internal success callback for the IO transaction. 2238 * 2239 * @method _successHandler 2240 * @param {EventFavade} event 2241 * @param {String} id Id of the IO transaction. 2242 * @param {Object} obj XHR transaction Object. 2243 * @protected 2244 */ 2245 _successHandler: function(event, id, xhr) { 2246 var instance = this; 2247 2248 instance.setContent( 2249 this.get('responseData') 2250 ); 2251 }, 2252 2253 /** 2254 * Internal failure callback for the IO transaction. 2255 * 2256 * @method _failureHandler 2257 * @param {EventFavade} event 2258 * @param {String} id Id of the IO transaction. 2259 * @param {Object} obj XHR transaction Object. 2260 * @protected 2261 */ 2262 _failureHandler: function(event, id, xhr) { 2263 var instance = this; 2264 2265 instance.setContent( 2266 instance.get(FAILURE_MESSAGE) 2267 ); 2268 }, 2269 2270 /** 2271 * Fires after the value of the 2272 * <a href="A.Plugin.IO.html#config_active">active</a> attribute change. 2273 * 2274 * @method _onActiveChange 2275 * @param {EventFacade} event 2276 * @protected 2277 */ 2278 _onActiveChange: function(event) { 2279 var instance = this; 2280 var host = instance.get(HOST); 2281 var widget = instance.get(TYPE) == TYPE_WIDGET; 2282 2283 if (!widget || (widget && host && host.get(RENDERED))) { 2284 instance._setLoadingUI(event.newVal); 2285 } 2286 } 2287 } 2288}); 2289 2290A.Node.prototype.load = function(uri, config, callback) { 2291 var instance = this; 2292 2293 var index = uri.indexOf(' '); 2294 var selector; 2295 2296 if (index > 0) { 2297 selector = uri.slice(index, uri.length); 2298 2299 uri = uri.slice(0, index); 2300 } 2301 2302 if (L.isFunction(config)) { 2303 callback = config; 2304 config = null; 2305 } 2306 2307 config = config || {}; 2308 2309 if (callback) { 2310 config.after = config.after || {}; 2311 2312 config.after.success = callback; 2313 } 2314 2315 var where = config.where; 2316 2317 config.uri = uri; 2318 config.where = where; 2319 2320 if (selector) { 2321 config.selector = selector; 2322 config.where = where || 'replace'; 2323 } 2324 2325 instance.plug(A.Plugin.IO, config); 2326 2327 return instance; 2328}; 2329 2330A.namespace('Plugin').IO = IOPlugin; 2331 2332 2333}, '3.1.0-deprecated.70', { 2334 "requires": [ 2335 "aui-overlay-base-deprecated", 2336 "aui-parse-content", 2337 "aui-io-request", 2338 "aui-loading-mask-deprecated" 2339 ] 2340}); 2341 2342YUI.add('aui-io-request', function (A, NAME) { 2343 2344/** 2345 * The IORequest Utility - Provides response data normalization for 'xml', 'json', 2346 * JavaScript and cache option. 2347 * 2348 * @module aui-io 2349 * @submodule aui-io-request 2350 */ 2351 2352var L = A.Lang, 2353 isBoolean = L.isBoolean, 2354 isFunction = L.isFunction, 2355 isString = L.isString, 2356 2357 defaults = A.namespace('config.io'), 2358 2359 getDefault = function(attr) { 2360 return function() { 2361 return defaults[attr]; 2362 }; 2363 }, 2364 2365 ACCEPTS = { 2366 all: '*/*', 2367 html: 'text/html', 2368 json: 'application/json, text/javascript', 2369 text: 'text/plain', 2370 xml: 'application/xml, text/xml' 2371 }; 2372 2373/** 2374 * A base class for IORequest, providing: 2375 * 2376 * - Response data normalization for XML, JSON, JavaScript 2377 * - Cache options 2378 * 2379 * Check the [live demo](http://alloyui.com/examples/io/). 2380 * 2381 * @class A.IORequest 2382 * @extends Plugin.Base 2383 * @param {Object} config Object literal specifying widget configuration 2384 * properties.
2385 * @uses io 2386 * @constructor 2387 * @include http://alloyui.com/examples/io/basic.js 2388 */ 2389var IORequest = A.Component.create({ 2390 /** 2391 * Static property provides a string to identify the class. 2392 * 2393 * @property NAME 2394 * @type String 2395 * @static 2396 */ 2397 NAME: 'IORequest', 2398 2399 /** 2400 * Static property used to define the default attribute 2401 * configuration for the IORequest. 2402 * 2403 * @property ATTRS 2404 * @type Object 2405 * @static 2406 */ 2407 ATTRS: { 2408 2409 /** 2410 * If `true` invoke the [start](A.IORequest.html#method_start) method 2411 * automatically, initializing the IO transaction. 2412 * 2413 * @attribute autoLoad 2414 * @default true 2415 * @type Boolean 2416 */ 2417 autoLoad: { 2418 value: true, 2419 validator: isBoolean 2420 }, 2421 2422 /** 2423 * If `false` the current timestamp will be appended to the 2424 * url, avoiding the url to be cached. 2425 * 2426 * @attribute cache 2427 * @default true 2428 * @type Boolean 2429 */ 2430 cache: { 2431 value: true, 2432 validator: isBoolean 2433 }, 2434 2435 /** 2436 * The type of the request (i.e., could be xml, json, javascript, text). 2437 * 2438 * @attribute dataType 2439 * @default null
2440 * @type String 2441 */ 2442 dataType: { 2443 setter: function(v) { 2444 return (v || '').toLowerCase(); 2445 }, 2446 value: null, 2447 validator: isString 2448 }, 2449 2450 /** 2451 * This is a normalized attribute for the response data. It's useful to 2452 * retrieve the correct type for the 2453 * [dataType](A.IORequest.html#attr_dataType) (i.e., in json requests 2454 * the `responseData`) is a JSONObject. 2455 * 2456 * @attribute responseData 2457 * @default null 2458 * @type String | JSONObject | XMLDocument 2459 */ 2460 responseData: { 2461 setter: function(v) { 2462 return this._setResponseData(v); 2463 }, 2464 value: null 2465 }, 2466 2467 /** 2468 * URI to be requested using AJAX. 2469 * 2470 * @attribute uri 2471 * @default null 2472 * @type String 2473 */ 2474 uri: { 2475 setter: function(v) { 2476 return this._parseURL(v); 2477 }, 2478 value: null, 2479 validator: isString 2480 }, 2481 2482 // User readOnly variables 2483 2484 /** 2485 * Whether the transaction is active or not. 2486 * 2487 * @attribute active 2488 * @default false 2489 * @type Boolean 2490 */ 2491 active: { 2492 value: false, 2493 validator: isBoolean 2494 }, 2495 2496 /** 2497 * Object containing all the [IO Configuration Attributes](A.io.html). 2498 * This Object is passed to the `A.io` internally. 2499 * 2500 * @attribute cfg 2501 * @default Object containing all the [IO Configuration 2502 * Attributes](A.io.html). 2503 * @readOnly
2504 * @type String 2505 */ 2506 cfg: { 2507 getter: function() { 2508 var instance = this; 2509 2510 // keep the current cfg object always synchronized with the 2511 // mapped public attributes when the user call .start() it 2512 // always retrieve the last set values for each mapped attr 2513 return { 2514 arguments: instance.get('arguments'), 2515 context: instance.get('context'), 2516 data: instance.getFormattedData(), 2517 form: instance.get('form'), 2518 headers: instance.get('headers'), 2519 method: instance.get('method'), 2520 on: { 2521 complete: A.bind(instance.fire, instance, 'complete'), 2522 end: A.bind(instance._end, instance), 2523 failure: A.bind(instance.fire, instance, 'failure'), 2524 start: A.bind(instance.fire, instance, 'start'), 2525 success: A.bind(instance._success, instance) 2526 }, 2527 sync: instance.get('sync'), 2528 timeout: instance.get('timeout'), 2529 xdr: instance.get('xdr') 2530 }; 2531 }, 2532 readOnly: true 2533 }, 2534 2535 /** 2536 * Stores the IO Object of the current transaction. 2537 * 2538 * @attribute transaction 2539 * @default null 2540 * @type Object 2541 */ 2542 transaction: { 2543 value: null 2544 }, 2545 2546 // Configuration Object mapping 2547 // To take advantages of the Attribute listeners of A.Base
2548 // See: http://yuilibrary.com/yui/docs/io/ 2549 2550 /** 2551 * See [IO 2552 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2553 * 2554 * @attribute arguments 2555 * @default Value mapped on YUI.AUI.defaults.io. 2556 * @type Object 2557 */ 2558 arguments: { 2559 valueFn: getDefault('arguments') 2560 }, 2561 2562 /** 2563 * See [IO 2564 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2565 * 2566 * @attribute context 2567 * @default Value mapped on YUI.AUI.defaults.io. 2568 * @type Object 2569 */ 2570 context: { 2571 valueFn: getDefault('context') 2572 }, 2573 2574 /** 2575 * See [IO 2576 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2577 * 2578 * @attribute data 2579 * @default Value mapped on YUI.AUI.defaults.io. 2580 * @type Object 2581 */ 2582 data: { 2583 valueFn: getDefault('data') 2584 }, 2585 2586 /** 2587 * See [IO
2588 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2589 * 2590 * @attribute form 2591 * @default Value mapped on YUI.AUI.defaults.io. 2592 * @type Object 2593 */ 2594 form: { 2595 valueFn: getDefault('form') 2596 }, 2597 2598 /** 2599 * Set the correct ACCEPT header based on the dataType. 2600 * 2601 * @attribute headers 2602 * @default Object 2603 * @type Object 2604 */ 2605 headers: { 2606 getter: function(value) { 2607 var header = []; 2608 var instance = this; 2609 var dataType = instance.get('dataType'); 2610 2611 if (dataType) { 2612 header.push( 2613 ACCEPTS[dataType] 2614 ); 2615 } 2616 2617 // always add *.* to the accept header 2618 header.push( 2619 ACCEPTS.all 2620 ); 2621 2622 return A.merge( 2623 value, { 2624 Accept: header.join(', ') 2625 } 2626 ); 2627 }, 2628 valueFn: getDefault('headers') 2629 }, 2630 2631 /** 2632 * See [IO
2633 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2634 * 2635 * @attribute method 2636 * @default Value mapped on YUI.AUI.defaults.io. 2637 * @type String 2638 */ 2639 method: { 2640 setter: function(val) { 2641 return val.toLowerCase(); 2642 }, 2643 valueFn: getDefault('method') 2644 }, 2645 2646 /** 2647 * A selector to be used to query against the response of the 2648 * request. Only works if the response is XML or HTML. 2649 * 2650 * @attribute selector 2651 * @default null 2652 * @type String 2653 */ 2654 selector: { 2655 value: null 2656 }, 2657 2658 /** 2659 * See [IO 2660 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2661 * 2662 * @attribute sync 2663 * @default Value mapped on YUI.AUI.defaults.io. 2664 * @type Boolean 2665 */ 2666 sync: { 2667 valueFn: getDefault('sync') 2668 }, 2669 2670 /** 2671 * See [IO
2672 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2673 * 2674 * @attribute timeout 2675 * @default Value mapped on YUI.AUI.defaults.io. 2676 * @type Number 2677 */ 2678 timeout: { 2679 valueFn: getDefault('timeout') 2680 }, 2681 2682 /** 2683 * See [IO 2684 * Configuration](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2685 * 2686 * @attribute xdr 2687 * @default Value mapped on YUI.AUI.defaults.io. 2688 * @type Object 2689 */ 2690 xdr: { 2691 valueFn: getDefault('xdr') 2692 } 2693 }, 2694 2695 /** 2696 * Static property used to define which component it extends. 2697 * 2698 * @property EXTENDS 2699 * @type Object 2700 * @static 2701 */ 2702 EXTENDS: A.Plugin.Base, 2703 2704 prototype: { 2705 2706 /** 2707 * Construction logic executed during IORequest instantiation. 2708 * Lifecycle. 2709 * 2710 * @method initializer 2711 * @param config 2712 * @protected 2713 */ 2714 init: function() { 2715 var instance = this; 2716 2717 IORequest.superclass.init.apply(this, arguments); 2718 2719 instance._autoStart(); 2720 }, 2721 2722 /** 2723 * Destructor lifecycle implementation for the `IORequest` class. 2724 * Purges events attached to the node (and all child nodes). 2725 * 2726 * @method destructor 2727 * @protected 2728 */ 2729 destructor: function() { 2730 var instance = this; 2731 2732 instance.stop(); 2733 2734 instance.set('transaction', null); 2735 }, 2736 2737 /** 2738 * Applies the `YUI.AUI.defaults.io.dataFormatter` if 2739 * defined and return the formatted data. 2740 * 2741 * @method getFormattedData 2742 * @return {String} 2743 */ 2744 getFormattedData: function() { 2745 var instance = this; 2746 var value = instance.get('data'); 2747 var dataFormatter = defaults.dataFormatter; 2748 2749 if (isFunction(dataFormatter)) { 2750 value = dataFormatter.call(instance, value); 2751 } 2752 2753 return value; 2754 }, 2755 2756 /** 2757 * Starts the IO transaction. Used to refresh the content also. 2758 * 2759 * @method start 2760 */ 2761 start: function() { 2762 var instance = this; 2763 2764 instance.destructor(); 2765 2766 instance.set('active', true); 2767 2768 var ioObj = instance._yuiIOObj; 2769 2770 if (!ioObj) { 2771 ioObj = new A.IO(); 2772 2773 instance._yuiIOObj = ioObj; 2774 } 2775 2776 var transaction = ioObj.send( 2777 instance.get('uri'), 2778 instance.get('cfg') 2779 ); 2780 2781 instance.set('transaction', transaction); 2782 }, 2783 2784 /** 2785 * Stops the IO transaction. 2786 * 2787 * @method stop 2788 */ 2789 stop: function() { 2790 var instance = this; 2791 var transaction = instance.get('transaction'); 2792 2793 if (transaction) { 2794 transaction.abort(); 2795 } 2796 }, 2797 2798 /** 2799 * Invoke the `start` method (autoLoad attribute). 2800 * 2801 * @method _autoStart 2802 * @protected 2803 */ 2804 _autoStart: function() { 2805 var instance = this; 2806 2807 if (instance.get('autoLoad')) { 2808 instance.start(); 2809 } 2810 }, 2811 2812 /** 2813 * Parse the [uri](A.IORequest.html#attr_uri) to add a 2814 * timestamp if [cache](A.IORequest.html#attr_cache) is 2815 * `true`. Also applies the `YUI.AUI.defaults.io.uriFormatter`. 2816 * 2817 * @method _parseURL 2818 * @param {String} url 2819 * @protected 2820 * @return {String} 2821 */ 2822 _parseURL: function(url) { 2823 var instance = this; 2824 var cache = instance.get('cache'); 2825 var method = instance.get('method'); 2826 2827 // reusing logic to add a timestamp on the url from jQuery 1.3.2 2828 if ((cache === false) && (method === 'get')) { 2829 var ts = +new Date(); 2830 // try replacing _= if it is there 2831 var ret = url.replace(/(\?|&)_=.*?(&|$)/, '$1_=' + ts + '$2'); 2832 // if nothing was replaced, add timestamp to the end 2833 url = ret + ((ret === url) ? (url.match(/\?/) ? '&' : '?') + '_=' + ts : ''); 2834 } 2835 2836 // formatting the URL with the default uriFormatter after the cache 2837 // timestamp was added 2838 var uriFormatter = defaults.uriFormatter; 2839 2840 if (isFunction(uriFormatter)) { 2841 url = uriFormatter.apply(instance, [url]); 2842 } 2843 2844 return url; 2845 }, 2846 2847 /** 2848 * Internal end callback for the IO transaction. 2849 * 2850 * @method _end 2851 * @param {Number} id ID of the IO transaction. 2852 * @param {Object} args Custom arguments, passed to the event handler.
2853 * See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2854 * @protected 2855 */ 2856 _end: function(id, args) { 2857 var instance = this; 2858 2859 instance.set('active', false); 2860 instance.set('transaction', null); 2861 2862 instance.fire('end', id, args); 2863 }, 2864 2865 /** 2866 * Internal success callback for the IO transaction. 2867 * 2868 * @method _success 2869 * @param {Number} id ID of the IO transaction. 2870 * @param {Object} obj IO transaction Object. 2871 * @param {Object} args Custom arguments, passed to the event handler. 2872 * See [IO](http://yuilibrary.com/yui/docs/io/#the-configuration-object). 2873 * @protected 2874 */ 2875 _success: function(id, obj, args) { 2876 var instance = this; 2877 2878 // update the responseData attribute with the new data from xhr 2879 instance.set('responseData', obj); 2880 2881 instance.fire('success', id, obj, args); 2882 }, 2883 2884 /** 2885 * Setter for [responseData](A.IORequest.html#attr_responseData). 2886 * 2887 * @method _setResponseData 2888 * @protected 2889 * @param {Object} xhr XHR Object. 2890 * @return {Object} 2891 */ 2892 _setResponseData: function(xhr) { 2893 var data = null; 2894 var instance = this; 2895 2896 if (xhr) { 2897 var dataType = instance.get('dataType'); 2898 var contentType = xhr.getResponseHeader('content-type') || ''; 2899 2900 // if the dataType or the content-type is XML... 2901 if ((dataType === 'xml') || 2902 (!dataType && contentType.indexOf('xml') >= 0)) { 2903 2904 // use responseXML 2905 data = xhr.responseXML; 2906 2907 // check if the XML was parsed correctly 2908 if (data.documentElement.tagName === 'parsererror') { 2909 throw 'Parser error: IO dataType is not correctly parsing'; 2910 } 2911 } 2912 else { 2913 // otherwise use the responseText 2914 data = xhr.responseText; 2915 } 2916 2917 // empty string is not a valid 'json', convert it to null 2918 if (data === '') { 2919 data = null; 2920 } 2921 2922 // trying to parse to JSON if dataType is a valid json 2923 if (dataType === 'json') { 2924 try { 2925 data = A.JSON.parse(data); 2926 } 2927 catch (e) { 2928 // throw 'Parser error: IO dataType is not correctly parsing'; 2929 } 2930 } 2931 else { 2932 var selector = instance.get('selector'); 2933 2934 if (data && selector) { 2935 var tempRoot; 2936 2937 if (data.documentElement) { 2938 tempRoot = A.one(data); 2939 } 2940 else { 2941 tempRoot = A.Node.create(data); 2942 } 2943 2944 data = tempRoot.all(selector); 2945 } 2946 } 2947 } 2948 2949 return data; 2950 } 2951 } 2952}); 2953 2954A.IORequest = IORequest; 2955 2956/** 2957 * Alloy IO extension 2958 * 2959 * @class A.io 2960 * @static 2961 */ 2962 2963/** 2964 * Static method to invoke the [IORequest](A.IORequest.html). 2965 * Likewise [IO](A.io.html). 2966 * 2967 * @method A.io.request 2968 * @for A.io 2969 * @param {String} uri URI to be requested. 2970 * @param {Object} config Configuration Object for the [IO](A.io.html). 2971 * @return {IORequest} 2972 */ 2973A.io.request = function(uri, config) { 2974 return new A.IORequest( 2975 A.merge(config, { 2976 uri: uri 2977 }) 2978 ); 2979}; 2980 2981 2982}, '3.1.0-deprecated.70', {"requires": ["io-base", "json", "plugin", "querystring-stringify", "aui-component"]}); 2983 2984YUI.add('aui-loading-mask-deprecated', function (A, NAME) { 2985 2986/** 2987 * The LoadingMask Utility 2988 * 2989 * @module aui-loading-mask 2990 */ 2991 2992var Lang = A.Lang, 2993 2994 BOUNDING_BOX = 'boundingBox', 2995 CONTENT_BOX = 'contentBox', 2996 HIDE = 'hide', 2997 HOST = 'host', 2998 MESSAGE_EL = 'messageEl', 2999 NAME = 'loadingmask', 3000 POSITION = 'position', 3001 SHOW = 'show', 3002 STATIC = 'static',
3003 STRINGS = 'strings', 3004 TARGET = 'target', 3005 TOGGLE = 'toggle', 3006 3007 getClassName = A.getClassName, 3008 3009 CSS_LOADINGMASK = getClassName(NAME), 3010 CSS_MASKED = getClassName(NAME, 'masked'), 3011 CSS_MASKED_RELATIVE = getClassName(NAME, 'masked', 'relative'), 3012 CSS_MESSAGE_LOADING = getClassName(NAME, 'message'), 3013 CSS_MESSAGE_LOADING_CONTENT = getClassName(NAME, 'message', 'content'), 3014 3015 TPL_MESSAGE_LOADING = '<div class="' + CSS_MESSAGE_LOADING + '"><div class="' + CSS_MESSAGE_LOADING_CONTENT + 3016 '">{0}</div></div>'; 3017 3018/** 3019 * <p><img src="assets/images/aui-loading-mask/main.png"/></p> 3020 * 3021 * A base class for LoadingMask, providing: 3022 * <ul> 3023 * <li>Cross browser mask functionality to cover an element or the entire page</li> 3024 * <li>Customizable mask (i.e., background, opacity)</li> 3025 * <li>Display a centered "loading" message on the masked node</li> 3026 * </ul> 3027 * 3028 * Quick Example:<br/> 3029 * 3030 * <pre><code>node.plug(A.LoadingMask, { background: '#000' });</code></pre> 3031 * 3032 * Check the list of <a href="LoadingMask.html#configattributes">Configuration Attributes</a> available for 3033 * LoadingMask. 3034 * 3035 * @param config {Object} Object literal specifying widget configuration properties. 3036 * 3037 * @class LoadingMask 3038 * @constructor 3039 * @extends Plugin.Base 3040 */ 3041var LoadingMask = A.Component.create({ 3042 3043 /** 3044 * Static property provides a string to identify the class. 3045 * 3046 * @property LoadingMask.NAME
3047 * @type String 3048 * @static 3049 */ 3050 NAME: NAME, 3051 3052 /** 3053 * Static property provides a string to identify the namespace. 3054 * 3055 * @property LoadingMask.NS 3056 * @type String 3057 * @static 3058 */ 3059 NS: NAME, 3060 3061 /** 3062 * Static property used to define the default attribute 3063 * configuration for the LoadingMask. 3064 * 3065 * @property LoadingMask.ATTRS 3066 * @type Object 3067 * @static 3068 */ 3069 ATTRS: { 3070 /** 3071 * Node element to display the message. 3072 * 3073 * @attribute messageEl 3074 * @default Generated HTML div element. 3075 * @type String 3076 */ 3077 messageEl: { 3078 valueFn: function(val) { 3079 var instance = this; 3080 var strings = instance.get(STRINGS); 3081 3082 return A.Node.create( 3083 Lang.sub(TPL_MESSAGE_LOADING, [strings.loading]) 3084 ); 3085 } 3086 }, 3087 3088 /** 3089 * Strings used on the LoadingMask. See 3090 * <a href="Widget.html#method_strings">strings</a>. 3091 * 3092 * @attribute strings 3093 * @default { loading: 'Loading…' } 3094 * @type Object 3095 */ 3096 strings: { 3097 value: { 3098 loading: 'Loading…' 3099 } 3100 }, 3101 3102 /** 3103 * Node where the mask will be positioned and re-dimensioned. 3104 * 3105 * @attribute target 3106 * @default null 3107 * @type Node | Widget 3108 */ 3109 target: { 3110 setter: function() { 3111 var instance = this; 3112 var target = instance.get(HOST); 3113 3114 if (target instanceof A.Widget) { 3115 target = target.get(CONTENT_BOX); 3116 } 3117 3118 return target; 3119 }, 3120 value: null 3121 } 3122 }, 3123 3124 EXTENDS: A.Plugin.Base, 3125 3126 prototype: { 3127 /** 3128 * Construction logic executed during LoadingMask instantiation. Lifecycle. 3129 * 3130 * @method initializer 3131 * @protected 3132 */ 3133 initializer: function(config) { 3134 var instance = this; 3135 3136 instance.IGNORED_ATTRS = A.merge({ 3137 host: true 3138 }, 3139 LoadingMask.ATTRS 3140 ); 3141 3142 instance.renderUI(); 3143 instance.bindUI(); 3144 3145 instance._createDynamicAttrs(config); 3146 }, 3147 3148 /** 3149 * Create the DOM structure for the LoadingMask. Lifecycle. 3150 * 3151 * @method renderUI 3152 * @protected 3153 */ 3154 renderUI: function() { 3155 var instance = this; 3156 var strings = instance.get(STRINGS); 3157 3158 instance._renderOverlayMask(); 3159 3160 instance.overlayMask.get(BOUNDING_BOX).append( 3161 instance.get(MESSAGE_EL) 3162 ); 3163 }, 3164 3165 /** 3166 * Bind the events on the LoadingMask UI. Lifecycle. 3167 * 3168 * @method bindUI 3169 * @protected 3170 */ 3171 bindUI: function() { 3172 var instance = this; 3173 3174 instance._bindOverlayMaskUI(); 3175 }, 3176 3177 destructor: function() { 3178 var instance = this; 3179 3180 instance.overlayMask.destroy(); 3181 3182 instance._visibleChangeHandle.detach(); 3183 }, 3184 3185 /** 3186 * Bind events to the 3187 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a>. 3188 * 3189 * @method _bindOverlayMaskUI 3190 * @protected 3191 */ 3192 _bindOverlayMaskUI: function() { 3193 var instance = this; 3194 3195 instance._visibleChangeHandle = instance.overlayMask.after('visibleChange', instance._afterVisibleChange, instance); 3196 }, 3197 3198 /** 3199 * Center the 3200 * <a href="LoadingMask.html#config_messageEl">messageEl</a> with the 3201 * <a href="LoadingMask.html#config_target">target</a> node. 3202 * 3203 * @method centerMessage 3204 */ 3205 centerMessage: function() { 3206 var instance = this; 3207 3208 instance.get(MESSAGE_EL).center( 3209 instance.overlayMask.get(BOUNDING_BOX) 3210 ); 3211 }, 3212 3213 /** 3214 * Invoke the 3215 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> 3216 * <code>refreshMask</code> method. 3217 * 3218 * @method refreshMask 3219 */ 3220 refreshMask: function() { 3221 var instance = this; 3222 3223 instance.overlayMask.refreshMask(); 3224 3225 instance.centerMessage(); 3226 }, 3227 3228 /** 3229 * Fires after the value of the 3230 * <a href="LoadingMask.html#config_visible">visible</a> attribute change. 3231 * 3232 * @method _afterVisibleChange 3233 * @param {EventFacade} event 3234 * @protected 3235 */ 3236 _afterVisibleChange: function(event) { 3237 var instance = this; 3238 var target = instance.get(TARGET); 3239 var isStaticPositioned = (target.getStyle(POSITION) == STATIC); 3240 3241 target.toggleClass(CSS_MASKED, (event.newVal)); 3242 target.toggleClass(CSS_MASKED_RELATIVE, (event.newVal && isStaticPositioned)); 3243 3244 if (event.newVal) { 3245 instance.refreshMask(); 3246 } 3247 }, 3248 3249 /**
3250 * Render 3251 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> 3252 * instance. 3253 * 3254 * @method _renderOverlayMask 3255 * @protected 3256 */ 3257 _renderOverlayMask: function() { 3258 var instance = this; 3259 var target = instance.get(TARGET); 3260 3261 /** 3262 * Stores the <a href="OverlayMask.html">OverlayMask</a> used 3263 * internally. 3264 * 3265 * @property overlayMask 3266 * @type OverlayMask 3267 * @protected 3268 */ 3269 instance.overlayMask = new A.OverlayMask({ 3270 target: target, 3271 cssClass: CSS_LOADINGMASK 3272 }).render(target); 3273 }, 3274 3275 /** 3276 * Create dynamic attributes listeners to invoke the setter on 3277 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> after 3278 * the attribute is set on the LoadingMask instance. 3279 * 3280 * @method _createDynamicAttrs 3281 * @param {Object} config Object literal specifying widget configuration properties. 3282 * @protected 3283 */ 3284 _createDynamicAttrs: function(config) { 3285 var instance = this; 3286 3287 A.each(config, function(value, key) { 3288 var ignoredAttr = instance.IGNORED_ATTRS[key]; 3289 3290 if (!ignoredAttr) { 3291 instance.addAttr(key, { 3292 setter: function(val) { 3293 this.overlayMask.set(key, val); 3294 3295 return val; 3296 }, 3297 value: value 3298 }); 3299 } 3300 }); 3301 } 3302 } 3303}); 3304 3305A.each([HIDE, SHOW, TOGGLE], function(method) { 3306 /** 3307 * Invoke the 3308 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> 3309 * <code>hide</code> method. 3310 * 3311 * @method hide 3312 */ 3313 3314 /** 3315 * Invoke the 3316 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> 3317 * <code>show</code> method. 3318 * 3319 * @method show 3320 */ 3321 3322 /** 3323 * Invoke the 3324 * <a href="LoadingMask.html#property_overlayMask">overlayMask</a> 3325 * <code>toggle</code> method. 3326 * 3327 * @method toggle 3328 */ 3329 LoadingMask.prototype[method] = function() { 3330 this.overlayMask[method](); 3331 }; 3332}); 3333 3334A.LoadingMask = LoadingMask; 3335 3336 3337}, '3.1.0-deprecated.70', {"requires": ["plugin", "aui-overlay-mask-deprecated"], "skinnable": true}); 3338 3339YUI.add('aui-overlay-base-deprecated', function (A, NAME) { 3340 3341/** 3342 * Provides a basic Overlay widget, with Standard Module content support. The Overlay widget 3343 * provides Page XY positioning support, alignment and centering support along with basic 3344 * stackable support (z-index and shimming). 3345 * 3346 * @module aui-overlay 3347 * @submodule aui-overlay-base 3348 */ 3349 3350/** 3351 * A basic Overlay Widget, which can be positioned based on Page XY co-ordinates and is stackable (z-index support). 3352 * It also provides alignment and centering support and uses a standard module format for it's content, with header, 3353 * body and footer section support. 3354 * 3355 * @class OverlayBase 3356 * @constructor 3357 * @extends Component 3358 * @uses WidgetStdMod 3359 * @uses WidgetPosition 3360 * @uses WidgetStack 3361 * @uses WidgetPositionAlign 3362 * @uses WidgetPositionConstrain 3363 * @param {Object} object The user configuration for the instance. 3364 */ 3365A.OverlayBase = A.Component.create({ 3366 NAME: 'overlay', 3367 ATTRS: { 3368 hideClass: { 3369 value: false 3370 } 3371 }, 3372 AUGMENTS: [A.WidgetPosition, A.WidgetStack, A.WidgetPositionAlign, A.WidgetPositionConstrain, A.WidgetStdMod] 3373}); 3374 3375 3376}, '3.1.0-deprecated.70', { 3377 "requires": [ 3378 "widget-position", 3379 "widget-stack", 3380 "widget-position-align", 3381 "widget-position-constrain", 3382 "widget-stdmod", 3383 "aui-component" 3384 ] 3385}); 3386 3387YUI.add('aui-overlay-context-deprecated', function (A, NAME) { 3388 3389/** 3390 * The OverlayContext Utility 3391 * 3392 * @module aui-overlay 3393 * @submodule aui-overlay-context 3394 */ 3395 3396var L = A.Lang, 3397 isString = L.isString, 3398 isNumber = L.isNumber, 3399 isObject = L.isObject, 3400 isBoolean = L.isBoolean, 3401 3402 isNodeList = function(v) { 3403 return (v instanceof A.NodeList); 3404 }, 3405 3406 ALIGN = 'align', 3407 BL = 'bl', 3408 BOUNDING_BOX = 'boundingBox', 3409 CANCELLABLE_HIDE = 'cancellableHide', 3410 OVERLAY_CONTEXT = 'overlaycontext', 3411 CURRENT_NODE = 'currentNode', 3412 FOCUSED = 'focused', 3413 HIDE = 'hide', 3414 HIDE_DELAY = 'hideDelay',
3415 HIDE_ON = 'hideOn', 3416 HIDE_ON_DOCUMENT_CLICK = 'hideOnDocumentClick', 3417 MOUSEDOWN = 'mousedown', 3418 SHOW = 'show', 3419 SHOW_DELAY = 'showDelay', 3420 SHOW_ON = 'showOn', 3421 TL = 'tl', 3422 TRIGGER = 'trigger', 3423 USE_ARIA = 'useARIA', 3424 VISIBLE = 'visible'; 3425 3426/** 3427 * <p><img src="assets/images/aui-overlay-context/main.png"/></p> 3428 * 3429 * A base class for OverlayContext, providing: 3430 * <ul> 3431 * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li> 3432 * <li>Able to display an <a href="Overlay.html">Overlay</a> at a specified corner of an element <a href="OverlayContext.html#config_trigger">trigger</a></li> 3433 * </ul> 3434 * 3435 * Quick Example:<br/> 3436 * 3437 * <pre><code>var instance = new A.OverlayContext({ 3438 * boundingBox: '#OverlayBoundingBox', 3439 * hideOn: 'mouseleave', 3440 * showOn: 'mouseenter', 3441 * trigger: '.menu-trigger' 3442 * }).render(); 3443 * </code></pre> 3444 * 3445 * Check the list of <a href="OverlayContext.html#configattributes">Configuration Attributes</a> available for 3446 * OverlayContext. 3447 * 3448 * @class OverlayContext 3449 * @constructor 3450 * @extends OverlayBase 3451 * @param config {Object} Object literal specifying widget configuration properties. 3452 */ 3453var OverlayContext = A.Component.create({ 3454 /** 3455 * Static property provides a string to identify the class. 3456 * 3457 * @property OverlayContext.NAME
3458 * @type String 3459 * @static 3460 */ 3461 NAME: OVERLAY_CONTEXT, 3462 3463 /** 3464 * Static property used to define the default attribute 3465 * configuration for the OverlayContext. 3466 * 3467 * @property OverlayContext.ATTRS 3468 * @type Object 3469 * @static 3470 */ 3471 ATTRS: { 3472 /** 3473 * Inherited from <a href="Overlay.html#config_align">Overlay</a>. 3474 * 3475 * @attribute align 3476 * @default { node: null, points: [ TL, BL ] } 3477 * @type Object 3478 */ 3479 align: { 3480 value: { 3481 node: null, 3482 points: [TL, BL] 3483 } 3484 }, 3485 3486 /** 3487 * Cancel auto hide delay if the user interact with the Overlay 3488 * (focus, click, mouseover) 3489 * 3490 * @attribute cancellableHide 3491 * @default true 3492 * @type boolean 3493 */ 3494 cancellableHide: { 3495 value: true, 3496 validator: isBoolean 3497 }, 3498 3499 /** 3500 * OverlayContext allow multiple elements to be the 3501 * <a href="OverlayContext.html#config_trigger">trigger</a>, the 3502 * currentNode stores the current active one. 3503 * 3504 * @attribute currentNode 3505 * @default First item of the 3506 * <a href="OverlayContext.html#config_trigger">trigger</a> NodeList. 3507 * @type Node 3508 */ 3509 currentNode: { 3510 valueFn: function() { 3511 // define default currentNode as the first item from trigger 3512 return this.get(TRIGGER).item(0); 3513 } 3514 }, 3515 3516 delay: { 3517 value: null, 3518 validator: isObject 3519 }, 3520 3521 /** 3522 * The event which is responsible to hide the OverlayContext. 3523 * 3524 * @attribute hideOn 3525 * @default mouseout
3526 * @type String 3527 */ 3528 hideOn: { 3529 lazyAdd: false, 3530 value: 'mouseout', 3531 setter: function(v) { 3532 return this._setHideOn(v); 3533 } 3534 }, 3535 3536 /** 3537 * If true the instance is registered on the 3538 * <a href="OverlayContextManager.html">OverlayContextManager</a> static 3539 * class and will be hide when the user click on document. 3540 * 3541 * @attribute hideOnDocumentClick 3542 * @default true 3543 * @type boolean 3544 */ 3545 hideOnDocumentClick: { 3546 lazyAdd: false, 3547 setter: function(v) { 3548 return this._setHideOnDocumentClick(v); 3549 }, 3550 value: true, 3551 validator: isBoolean 3552 }, 3553 3554 /** 3555 * Number of milliseconds after the hide method is invoked to hide the 3556 * OverlayContext. 3557 * 3558 * @attribute hideDelay 3559 * @default 0 3560 * @type Number 3561 */ 3562 hideDelay: { 3563 lazyAdd: false, 3564 setter: '_setHideDelay', 3565 value: 0, 3566 validator: isNumber 3567 }, 3568 3569 /** 3570 * The event which is responsible to show the OverlayContext. 3571 * 3572 * @attribute showOn 3573 * @default mouseover
3574 * @type String 3575 */ 3576 showOn: { 3577 lazyAdd: false, 3578 value: 'mouseover', 3579 setter: function(v) { 3580 return this._setShowOn(v); 3581 } 3582 }, 3583 3584 /** 3585 * Number of milliseconds after the show method is invoked to show the 3586 * OverlayContext. 3587 * 3588 * @attribute showDelay 3589 * @default 0 3590 * @type Number 3591 */ 3592 showDelay: { 3593 lazyAdd: false, 3594 setter: '_setShowDelay', 3595 value: 0, 3596 validator: isNumber 3597 }, 3598 3599 /** 3600 * Node, NodeList or Selector which will be used as trigger elements 3601 * to show or hide the OverlayContext. 3602 * 3603 * @attribute trigger 3604 * @default null 3605 * @type {Node | NodeList | String} 3606 */ 3607 trigger: { 3608 lazyAdd: false, 3609 setter: function(v) { 3610 if (isNodeList(v)) { 3611 return v; 3612 } 3613 else if (isString(v)) { 3614 return A.all(v); 3615 } 3616 3617 return new A.NodeList([v]); 3618 } 3619 }, 3620 3621 /** 3622 * True if Overlay should use ARIA plugin 3623 * 3624 * @attribute useARIA 3625 * @default true 3626 * @type Boolean 3627 */ 3628 useARIA: { 3629 value: true 3630 }, 3631 3632 /** 3633 * If true the OverlayContext is visible by default after the render phase. 3634 * Inherited from <a href="Overlay.html">Overlay</a>. 3635 * 3636 * @attribute visible 3637 * @default false 3638 * @type boolean 3639 */ 3640 visible: { 3641 value: false 3642 } 3643 }, 3644 3645 EXTENDS: A.OverlayBase, 3646 3647 constructor: function(config) { 3648 var instance = this; 3649 3650 instance._showCallback = null; 3651 instance._hideCallback = null; 3652 3653 OverlayContext.superclass.constructor.apply(this, arguments); 3654 }, 3655 3656 prototype: { 3657 /** 3658 * Construction logic executed during OverlayContext instantiation. Lifecycle. 3659 * 3660 * @method initializer 3661 * @protected 3662 */ 3663 initializer: function() { 3664 var instance = this; 3665 3666 var trigger = instance.get(TRIGGER); 3667 3668 if (trigger && trigger.size()) { 3669 instance.set('align.node', trigger.item(0)); 3670 } 3671 }, 3672 3673 /** 3674 * Bind the events on the OverlayContext UI. Lifecycle. 3675 * 3676 * @method bindUI 3677 * @protected 3678 */ 3679 bindUI: function() { 3680 var instance = this; 3681 var boundingBox = instance.get(BOUNDING_BOX); 3682 3683 boundingBox.on(MOUSEDOWN, instance._stopTriggerEventPropagation); 3684 3685 instance.before('triggerChange', instance._beforeTriggerChange); 3686 instance.before('showOnChange', instance._beforeShowOnChange); 3687 instance.before('hideOnChange', instance._beforeHideOnChange); 3688 3689 instance.after('triggerChange', instance._afterTriggerChange); 3690 instance.after('showOnChange', instance._afterShowOnChange); 3691 instance.after('hideOnChange', instance._afterHideOnChange); 3692 3693 boundingBox.on('click', A.bind(instance._cancelAutoHide, instance)); 3694 boundingBox.on('mouseenter', A.bind(instance._cancelAutoHide, instance)); 3695 boundingBox.on('mouseleave', A.bind(instance._invokeHideTaskOnInteraction, instance)); 3696 instance.after('focusedChange', A.bind(instance._invokeHideTaskOnInteraction, instance)); 3697 3698 instance.on('visibleChange', instance._onVisibleChangeOverlayContext); 3699 }, 3700 3701 /** 3702 * Hides the OverlayContext. 3703 * 3704 * @method hide 3705 */ 3706 hide: function() { 3707 var instance = this; 3708 3709 instance.clearIntervals(); 3710 3711 instance.fire('hide'); 3712 3713 OverlayContext.superclass.hide.apply(instance, arguments); 3714 }, 3715 3716 /** 3717 * Shows the OverlayContext. 3718 * 3719 * @method hide 3720 */ 3721 show: function(event) { 3722 var instance = this; 3723 3724 instance.clearIntervals(); 3725 3726 instance.updateCurrentNode(event); 3727 3728 instance.fire('show'); 3729 3730 OverlayContext.superclass.show.apply(instance, arguments); 3731 3732 instance.refreshAlign(); 3733 }, 3734 3735 /** 3736 * Refreshes the rendered UI, based on Widget State 3737 * 3738 * @method syncUI 3739 * @protected 3740 * 3741 */ 3742 syncUI: function() { 3743 var instance = this; 3744 3745 if (instance.get(USE_ARIA)) { 3746 instance.plug(A.Plugin.Aria, { 3747 attributes: { 3748 trigger: { 3749 ariaName: 'controls', 3750 format: function(value) { 3751 var id = instance.get(BOUNDING_BOX).generateID(); 3752 3753 return id; 3754 }, 3755 node: function() { 3756 return instance.get(TRIGGER); 3757 } 3758 }, 3759 visible: { 3760 ariaName: 'hidden', 3761 format: function(value) { 3762 return !value; 3763 } 3764 } 3765 }, 3766 roleName: 'dialog' 3767 }); 3768 } 3769 }, 3770 3771 /** 3772 * Toggles visibility of the OverlayContext. 3773 * 3774 * @method toggle 3775 * @param {EventFacade} event 3776 */ 3777 toggle: function(event) { 3778 var instance = this; 3779 3780 if (instance.get(VISIBLE)) { 3781 instance._hideTask(event); 3782 } 3783 else { 3784 instance._showTask(event); 3785 } 3786 }, 3787 3788 /**
3789 * Clear the intervals to show or hide the OverlayContext. See 3790 * <a href="OverlayContext.html#config_hideDelay">hideDelay</a> and 3791 * <a href="OverlayContext.html#config_showDelay">showDelay</a>. 3792 * 3793 * @method clearIntervals 3794 */ 3795 clearIntervals: function() { 3796 this._hideTask.cancel(); 3797 this._showTask.cancel(); 3798 }, 3799 3800 /** 3801 * Refreshes the alignment of the OverlayContext with the 3802 * <a href="OverlayContext.html#config_currentNode">currentNode</a>. See 3803 * also <a href="OverlayContext.html#config_align">align</a>. 3804 * 3805 * @method refreshAlign 3806 */ 3807 refreshAlign: function() { 3808 var instance = this; 3809 var align = instance.get(ALIGN); 3810 var currentNode = instance.get(CURRENT_NODE); 3811 3812 if (currentNode) { 3813 instance._uiSetAlign(currentNode, align.points); 3814 } 3815 }, 3816 3817 /** 3818 * Update the 3819 * <a href="OverlayContext.html#config_currentNode">currentNode</a> with the 3820 * <a href="OverlayContext.html#config_align">align</a> node or the 3821 * event.currentTarget and in last case with the first item of the 3822 * <a href="OverlayContext.html#config_trigger">trigger</a>. 3823 * 3824 * @method updateCurrentNode 3825 * @param {EventFacade} event 3826 */ 3827 updateCurrentNode: function(event) { 3828 var instance = this; 3829 var align = instance.get(ALIGN); 3830 var trigger = instance.get(TRIGGER); 3831 var currentTarget = null; 3832 3833 if (event) { 3834 currentTarget = event.currentTarget; 3835 } 3836 3837 var node = currentTarget || trigger.item(0) || align.node; 3838 3839 if (node) { 3840 instance.set(CURRENT_NODE, node); 3841 } 3842 }, 3843 3844 /** 3845 * Handles the logic for the 3846 * <a href="OverlayContext.html#method_toggle">toggle</a>. 3847 * 3848 * @method _toggle 3849 * @param {EventFacade} event 3850 * @protected 3851 */ 3852 _toggle: function(event) { 3853 var instance = this; 3854 3855 if (instance.get('disabled')) { 3856 return; 3857 } 3858 3859 var currentTarget = event.currentTarget; 3860 3861 // check if the target is different and simulate a .hide() before toggle 3862 if (instance._lastTarget != currentTarget) { 3863 instance.hide(); 3864 } 3865 3866 instance.toggle(event); 3867 3868 event.stopPropagation(); 3869 3870 instance._lastTarget = currentTarget; 3871 }, 3872 3873 /** 3874 * Fires after the <a href="OverlayContext.html#config_showOn">showOn</a> 3875 * attribute change. 3876 * 3877 * @method _afterShowOnChange 3878 * @param {EventFacade} event 3879 * @protected 3880 */ 3881 _afterShowOnChange: function(event) { 3882 var instance = this; 3883 var wasToggle = event.prevVal == instance.get(HIDE_ON); 3884 3885 if (wasToggle) { 3886 var trigger = instance.get(TRIGGER); 3887 3888 // if wasToggle remove the toggle callback 3889 trigger.detach(event.prevVal, instance._hideCallback); 3890 // and re attach the hide event 3891 instance._setHideOn(instance.get(HIDE_ON)); 3892 } 3893 }, 3894 3895 /** 3896 * Fires after the <a href="OverlayContext.html#config_hideOn">hideOn</a> 3897 * attribute change. 3898 * 3899 * @method _afterHideOnChange 3900 * @param {EventFacade} event 3901 * @protected 3902 */ 3903 _afterHideOnChange: function(event) { 3904 var instance = this; 3905 var wasToggle = event.prevVal == instance.get(SHOW_ON); 3906 3907 if (wasToggle) { 3908 var trigger = instance.get(TRIGGER); 3909 3910 // if wasToggle remove the toggle callback 3911 trigger.detach(event.prevVal, instance._showCallback); 3912 // and re attach the show event 3913 instance._setShowOn(instance.get(SHOW_ON)); 3914 } 3915 }, 3916 3917 /** 3918 * Fires after the <a href="OverlayContext.html#config_trigger">trigger</a> 3919 * attribute change. 3920 * 3921 * @method _afterTriggerChange 3922 * @param {EventFacade} event 3923 * @protected 3924 */ 3925 _afterTriggerChange: function(event) { 3926 var instance = this; 3927 3928 instance._setShowOn(instance.get(SHOW_ON)); 3929 instance._setHideOn(instance.get(HIDE_ON)); 3930 }, 3931 3932 /** 3933 * Fires before the <a href="OverlayContext.html#config_showOn">showOn</a> 3934 * attribute change. 3935 * 3936 * @method _beforeShowOnChange 3937 * @param {EventFacade} event 3938 * @protected 3939 */ 3940 _beforeShowOnChange: function(event) { 3941 var instance = this; 3942 var trigger = instance.get(TRIGGER); 3943 3944 // detach the old callback 3945 trigger.detach(event.prevVal, instance._showCallback); 3946 }, 3947 3948 /** 3949 * Fires before the <a href="OverlayContext.html#config_hideOn">hideOn</a> 3950 * attribute change. 3951 * 3952 * @method _beforeHideOnChange 3953 * @param {EventFacade} event 3954 * @protected 3955 */ 3956 _beforeHideOnChange: function(event) { 3957 var instance = this; 3958 var trigger = instance.get(TRIGGER); 3959 3960 // detach the old callback 3961 trigger.detach(event.prevVal, instance._hideCallback); 3962 }, 3963 3964 /** 3965 * Fires before the <a href="OverlayContext.html#config_trigger">trigger</a> 3966 * attribute change. 3967 * 3968 * @method _beforeTriggerChange 3969 * @param {EventFacade} event 3970 * @protected 3971 */ 3972 _beforeTriggerChange: function(event) { 3973 var instance = this; 3974 var trigger = instance.get(TRIGGER); 3975 var showOn = instance.get(SHOW_ON); 3976 var hideOn = instance.get(HIDE_ON); 3977 3978 trigger.detach(showOn, instance._showCallback); 3979 trigger.detach(hideOn, instance._hideCallback); 3980 trigger.detach(MOUSEDOWN, instance._stopTriggerEventPropagation); 3981 }, 3982 3983 /** 3984 * Cancel hide event if the user does some interaction with the 3985 * OverlayContext (focus, click or mouseover). 3986 *
3987 * @method _cancelAutoHide 3988 * @param {EventFacade} event 3989 * @protected 3990 */ 3991 _cancelAutoHide: function(event) { 3992 var instance = this; 3993 3994 if (instance.get(CANCELLABLE_HIDE)) { 3995 instance.clearIntervals(); 3996 } 3997 3998 event.stopPropagation(); 3999 }, 4000 4001 /** 4002 * Invoke the hide event when the OverlayContext looses the focus. 4003 * 4004 * @method _invokeHideTaskOnInteraction 4005 * @param {EventFacade} event 4006 * @protected 4007 */ 4008 _invokeHideTaskOnInteraction: function(event) { 4009 var instance = this; 4010 var cancellableHide = instance.get(CANCELLABLE_HIDE); 4011 var focused = instance.get(FOCUSED); 4012 4013 if (!focused && !cancellableHide) { 4014 instance._hideTask(); 4015 } 4016 }, 4017 4018 /** 4019 * Fires when the <a href="OverlayContext.html#config_visible">visible</a> 4020 * attribute changes. 4021 * 4022 * @method _onVisibleChangeOverlayContext 4023 * @param {EventFacade} event 4024 * @protected 4025 */ 4026 _onVisibleChangeOverlayContext: function(event) { 4027 var instance = this; 4028 4029 if (event.newVal && instance.get('disabled')) { 4030 event.preventDefault(); 4031 } 4032 }, 4033 4034 /** 4035 * Helper method to invoke event.stopPropagation(). 4036 * 4037 * @method _stopTriggerEventPropagation 4038 * @param {EventFacade} event 4039 * @protected 4040 */ 4041 _stopTriggerEventPropagation: function(event) { 4042 event.stopPropagation(); 4043 }, 4044 4045 /** 4046 * Setter for the 4047 * <a href="OverlayContext.html#config_hideDelay">hideDelay</a> 4048 * attribute. 4049 * 4050 * @method _setHideDelay 4051 * @param {number} val 4052 * @protected 4053 * @return {number} 4054 */ 4055 _setHideDelay: function(val) { 4056 var instance = this; 4057 4058 instance._hideTask = A.debounce(instance.hide, val, instance); 4059 4060 return val; 4061 }, 4062 4063 /** 4064 * Setter for the <a href="OverlayContext.html#config_hideOn">hideOn</a> 4065 * attribute. 4066 * 4067 * @method _setHideOn 4068 * @param {String} eventType Event type 4069 * @protected 4070 * @return {String} 4071 */ 4072 _setHideOn: function(eventType) { 4073 var instance = this; 4074 var trigger = instance.get(TRIGGER); 4075 var toggle = eventType == instance.get(SHOW_ON); 4076 4077 if (toggle) { 4078 instance._hideCallback = A.bind(instance._toggle, instance); 4079 4080 // only one attached event is enough for toggle 4081 trigger.detach(eventType, instance._showCallback); 4082 } 4083 else { 4084 var delay = instance.get(HIDE_DELAY); 4085 4086 instance._hideCallback = function(event) { 4087 instance._hideTask(event); 4088 4089 event.stopPropagation(); 4090 }; 4091 } 4092 4093 trigger.on(eventType, instance._hideCallback); 4094 4095 return eventType; 4096 }, 4097 4098 /** 4099 * Setter for the 4100 * <a href="OverlayContext.html#config_hideOnDocumentClick">hideOnDocumentClick</a> 4101 * attribute. 4102 * 4103 * @method _setHideOn 4104 * @param {boolean} value 4105 * @protected 4106 * @return {boolean} 4107 */ 4108 _setHideOnDocumentClick: function(value) { 4109 var instance = this; 4110 4111 if (value) { 4112 A.OverlayContextManager.register(instance); 4113 } 4114 else { 4115 A.OverlayContextManager.remove(instance); 4116 } 4117 4118 return value; 4119 }, 4120 4121 /** 4122 * Setter for the 4123 * <a href="OverlayContext.html#config_showDelay">showDelay</a> 4124 * attribute. 4125 * 4126 * @method _setShowDelay 4127 * @param {number} val 4128 * @protected 4129 * @return {number} 4130 */ 4131 _setShowDelay: function(val) { 4132 var instance = this; 4133 4134 instance._showTask = A.debounce(instance.show, val, instance); 4135 4136 return val; 4137 }, 4138 4139 /** 4140 * Setter for the <a href="OverlayContext.html#config_showOn">showOn</a> 4141 * attribute. 4142 * 4143 * @method _setShowOn 4144 * @param {String} eventType Event type 4145 * @protected 4146 * @return {String} 4147 */ 4148 _setShowOn: function(eventType) { 4149 var instance = this; 4150 var trigger = instance.get(TRIGGER); 4151 var toggle = eventType == instance.get(HIDE_ON); 4152 4153 if (toggle) { 4154 instance._showCallback = A.bind(instance._toggle, instance); 4155 4156 // only one attached event is enough for toggle 4157 trigger.detach(eventType, instance._hideCallback); 4158 } 4159 else {
4160 var delay = instance.get(SHOW_DELAY); 4161 4162 instance._showCallback = function(event) { 4163 instance._showTask(event); 4164 4165 event.stopPropagation(); 4166 }; 4167 } 4168 4169 if (eventType != MOUSEDOWN) { 4170 trigger.on(MOUSEDOWN, instance._stopTriggerEventPropagation); 4171 } 4172 else { 4173 trigger.detach(MOUSEDOWN, instance._stopTriggerEventPropagation); 4174 } 4175 4176 trigger.on(eventType, instance._showCallback); 4177 4178 return eventType; 4179 } 4180 } 4181}); 4182 4183A.OverlayContext = OverlayContext; 4184 4185/** 4186 * A base class for OverlayContextManager: 4187 * 4188 * @param config {Object} Object literal specifying widget configuration properties. 4189 * 4190 * @class OverlayContextManager 4191 * @constructor 4192 * @extends OverlayManager 4193 * @static 4194 */ 4195A.OverlayContextManager = new A.OverlayManager({}); 4196 4197A.on(MOUSEDOWN, function() { 4198 A.OverlayContextManager.hideAll(); 4199}, A.getDoc()); 4200 4201 4202}, '3.1.0-deprecated.70', {"requires": ["aui-overlay-manager-deprecated", "aui-delayed-task-deprecated", "aui-aria"]}); 4203 4204YUI.add('aui-overlay-manager-deprecated', function (A, NAME) { 4205 4206/** 4207 * The OverlayManager Utility 4208 * 4209 * @module aui-overlay 4210 * @submodule aui-overlay-manager 4211 */ 4212 4213var Lang = A.Lang, 4214 isArray = Lang.isArray, 4215 isBoolean = Lang.isBoolean, 4216 isNumber = Lang.isNumber, 4217 isString = Lang.isString, 4218 4219 BOUNDING_BOX = 'boundingBox', 4220 DEFAULT = 'default', 4221 HOST = 'host', 4222 OVERLAY_MANAGER = 'OverlayManager', 4223 GROUP = 'group', 4224 Z_INDEX = 'zIndex', 4225 Z_INDEX_BASE = 'zIndexBase'; 4226 4227/** 4228 * <p><img src="assets/images/aui-overlay-manager/main.png"/></p> 4229 * 4230 * A base class for OverlayManager, providing: 4231 * <ul> 4232 * <li>Grouping overlays</li> 4233 * <li>Show or hide the entire group of registered overlays</li> 4234 * <li>Basic Overlay Stackability (zIndex support)</li> 4235 * </ul> 4236 * 4237 * Quick Example:<br/> 4238 * 4239 * <pre><code>var groupOverlayManager = new A.OverlayManager(); 4240 * groupOverlayManager.register([overlay1, overlay2, overlay3]); 4241 * groupOverlayManager.hideAll(); 4242 * </code></pre> 4243 * 4244 * Check the list of <a href="OverlayManager.html#configattributes">Configuration Attributes</a> available for 4245 * OverlayManager. 4246 * 4247 * @param config {Object} Object literal specifying widget configuration properties. 4248 * 4249 * @class OverlayManager 4250 * @constructor 4251 * @extends Base 4252 */ 4253var OverlayManager = A.Component.create({ 4254 /** 4255 * Static property provides a string to identify the class. 4256 * 4257 * @property OverlayManager.NAME
4258 * @type String 4259 * @static 4260 */ 4261 NAME: OVERLAY_MANAGER.toLowerCase(), 4262 4263 /** 4264 * Static property used to define the default attribute 4265 * configuration for the OverlayManager. 4266 * 4267 * @property OverlayManager.ATTRS 4268 * @type Object 4269 * @static 4270 */ 4271 ATTRS: { 4272 /** 4273 * The zIndex base to be used on the stacking for all overlays 4274 * registered on the OverlayManager. 4275 * 4276 * @attribute zIndexBase 4277 * @default 1000 4278 * @type Number 4279 */ 4280 zIndexBase: { 4281 value: 1000, 4282 validator: isNumber, 4283 setter: Lang.toInt 4284 } 4285 }, 4286 4287 EXTENDS: A.Base, 4288 4289 prototype: { 4290 /** 4291 * Construction logic executed during OverlayManager instantiation. Lifecycle. 4292 * 4293 * @method initializer 4294 * @protected 4295 */ 4296 initializer: function() { 4297 var instance = this; 4298 4299 instance._overlays = []; 4300 }, 4301 4302 /** 4303 * Set the passed overlay zIndex to the highest value. 4304 * 4305 * @method bringToTop 4306 * @param {Overlay} overlay Instance of 4307 * <a href="Overlay.html">Overlay</a>. 4308 */ 4309 bringToTop: function(overlay) { 4310 var instance = this; 4311 4312 var overlays = instance._overlays.sort(instance.sortByZIndexDesc); 4313 4314 var highest = overlays[0]; 4315 4316 if (highest !== overlay) { 4317 var overlayZ = overlay.get(Z_INDEX); 4318 var highestZ = highest.get(Z_INDEX); 4319 4320 overlay.set(Z_INDEX, highestZ + 1); 4321 4322 overlay.set('focused', true); 4323 } 4324 }, 4325 4326 /** 4327 * Destructor lifecycle implementation for the OverlayManager class. 4328 * Purges events attached to the node (and all child nodes). 4329 * 4330 * @method destructor 4331 * @protected 4332 */ 4333 destructor: function() { 4334 var instance = this; 4335 4336 instance._overlays = []; 4337 }, 4338 4339 /** 4340 * Register the passed <a href="Overlay.html">Overlay</a> to this 4341 * OverlayManager. 4342 * 4343 * @method register 4344 * @param {Overlay} overlay <a href="Overlay.html">Overlay</a> instance to be registered 4345 * @return {Array} Registered overlays 4346 */ 4347 register: function(overlay) { 4348 var instance = this; 4349 4350 var overlays = instance._overlays; 4351 4352 if (isArray(overlay)) { 4353 A.Array.each(overlay, function(o) { 4354 instance.register(o); 4355 }); 4356 } 4357 else { 4358 var zIndexBase = instance.get(Z_INDEX_BASE); 4359 var registered = instance._registered(overlay); 4360 4361 if (!registered && overlay && 4362 ((overlay instanceof A.Overlay) || 4363 (A.Component && overlay instanceof A.Component)) 4364 ) { 4365 var boundingBox = overlay.get(BOUNDING_BOX); 4366 4367 overlays.push(overlay); 4368 4369 var zIndex = overlay.get(Z_INDEX) || 0; 4370 var newZIndex = overlays.length + zIndex + zIndexBase; 4371 4372 overlay.set(Z_INDEX, newZIndex); 4373 4374 overlay.on('focusedChange', instance._onFocusedChange, instance); 4375 boundingBox.on('mousedown', instance._onMouseDown, instance); 4376 } 4377 } 4378 4379 return overlays; 4380 }, 4381 4382 /** 4383 * Remove the passed <a href="Overlay.html">Overlay</a> from this 4384 * OverlayManager. 4385 * 4386 * @method remove 4387 * @param {Overlay} overlay <a href="Overlay.html">Overlay</a> instance to be removed 4388 * @return {null} 4389 */ 4390 remove: function(overlay) { 4391 var instance = this; 4392 4393 var overlays = instance._overlays; 4394 4395 if (overlays.length) { 4396 return A.Array.removeItem(overlays, overlay); 4397 } 4398 4399 return null; 4400 }, 4401 4402 /** 4403 * Loop through all registered <a href="Overlay.html">Overlay</a> and 4404 * execute a callback. 4405 * 4406 * @method each 4407 * @param {function} fn Callback to be executed on the 4408 * <a href="Array.html#method_each">Array.each</a> 4409 * @return {null} 4410 */ 4411 each: function(fn) { 4412 var instance = this; 4413 4414 var overlays = instance._overlays; 4415 4416 A.Array.each(overlays, fn); 4417 }, 4418 4419 /** 4420 * Invoke the <a href="Overlay.html#method_show">show</a> method from 4421 * all registered Overlays. 4422 * 4423 * @method showAll 4424 */ 4425 showAll: function() { 4426 this.each( 4427 function(overlay) { 4428 overlay.show(); 4429 } 4430 ); 4431 }, 4432 4433 /** 4434 * Invoke the <a href="Overlay.html#method_hide">hide</a> method from 4435 * all registered Overlays. 4436 * 4437 * @method hideAll 4438 */ 4439 hideAll: function() { 4440 this.each( 4441 function(overlay) { 4442 overlay.hide(); 4443 } 4444 ); 4445 }, 4446 4447 /** 4448 * zIndex comparator. Used on Array.sort. 4449 * 4450 * @method sortByZIndexDesc 4451 * @param {Overlay} a Overlay 4452 * @param {Overlay} b Overlay 4453 * @return {Number} 4454 */ 4455 sortByZIndexDesc: function(a, b) { 4456 if (!a || !b || !a.hasImpl(A.WidgetStack) || !b.hasImpl(A.WidgetStack)) { 4457 return 0; 4458 } 4459 else { 4460 var aZ = a.get(Z_INDEX); 4461 var bZ = b.get(Z_INDEX); 4462 4463 if (aZ > bZ) { 4464 return -1; 4465 } 4466 else if (aZ < bZ) { 4467 return 1; 4468 } 4469 else { 4470 return 0; 4471 } 4472 } 4473 }, 4474 4475 /** 4476 * Check if the overlay is registered. 4477 * 4478 * @method _registered 4479 * @param {Overlay} overlay Overlay 4480 * @protected 4481 * @return {boolean} 4482 */ 4483 _registered: function(overlay) { 4484 var instance = this; 4485 4486 return A.Array.indexOf(instance._overlays, overlay) != -1; 4487 }, 4488 4489 /** 4490 * Mousedown event handler, used to invoke 4491 * <a href="OverlayManager.html#method_bringToTop">bringToTop</a>. 4492 * 4493 * @method _onMouseDown 4494 * @param {EventFacade} event 4495 * @protected 4496 */ 4497 _onMouseDown: function(event) { 4498 var instance = this;
4499 var overlay = A.Widget.getByNode(event.currentTarget || event.target); 4500 var registered = instance._registered(overlay); 4501 4502 if (overlay && registered) { 4503 instance.bringToTop(overlay); 4504 } 4505 }, 4506 4507 /** 4508 * Fires when the <a href="Widget.html#config_focused">focused</a> 4509 * attribute change. Used to invoke 4510 * <a href="OverlayManager.html#method_bringToTop">bringToTop</a>. 4511 * 4512 * @method _onFocusedChange 4513 * @param {EventFacade} event 4514 * @protected 4515 */ 4516 _onFocusedChange: function(event) { 4517 var instance = this; 4518 4519 if (event.newVal) { 4520 var overlay = event.currentTarget || event.target; 4521 var registered = instance._registered(overlay); 4522 4523 if (overlay && registered) { 4524 instance.bringToTop(overlay); 4525 } 4526 } 4527 } 4528 } 4529}); 4530 4531A.OverlayManager = OverlayManager; 4532 4533 4534}, '3.1.0-deprecated.70', {"requires": ["overlay", "plugin", "aui-base-deprecated", "aui-overlay-base-deprecated"]}); 4535 4536YUI.add('aui-overlay-mask-deprecated', function (A, NAME) { 4537 4538/** 4539 * The OverlayMask Utility 4540 * 4541 * @module aui-overlay 4542 * @submodule aui-overlay-mask 4543 */ 4544 4545var L = A.Lang, 4546 isArray = L.isArray, 4547 isString = L.isString, 4548 isNumber = L.isNumber, 4549 isValue = L.isValue, 4550 4551 CONFIG = A.config, 4552 4553 UA = A.UA, 4554 4555 IE6 = (UA.ie <= 6), 4556 4557 ABSOLUTE = 'absolute', 4558 ALIGN_POINTS = 'alignPoints', 4559 BACKGROUND = 'background', 4560 BOUNDING_BOX = 'boundingBox', 4561 CONTENT_BOX = 'contentBox', 4562 FIXED = 'fixed', 4563 HEIGHT = 'height', 4564 OFFSET_HEIGHT = 'offsetHeight', 4565 OFFSET_WIDTH = 'offsetWidth', 4566 OPACITY = 'opacity', 4567 OVERLAY_MASK = 'overlaymask', 4568 POSITION = 'position', 4569 TARGET = 'target', 4570 WIDTH = 'width'; 4571 4572/** 4573 * A base class for OverlayMask, providing: 4574 * <ul> 4575 * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li> 4576 * <li>Cross browser mask functionality to cover an element or the entire page</li> 4577 * <li>Customizable mask (i.e., background, opacity)</li> 4578 * </ul> 4579 * 4580 * Quick Example:<br/> 4581 * 4582 * <pre><code>var instance = new A.OverlayMask().render();</code></pre> 4583 * 4584 * Check the list of <a href="OverlayMask.html#configattributes">Configuration Attributes</a> available for 4585 * OverlayMask. 4586 * 4587 * @param config {Object} Object literal specifying widget configuration properties. 4588 * 4589 * @class OverlayMask 4590 * @constructor 4591 * @extends OverlayBase 4592 */ 4593var OverlayMask = A.Component.create({ 4594 /** 4595 * Static property provides a string to identify the class. 4596 * 4597 * @property OverlayMask.NAME
4598 * @type String 4599 * @static 4600 */ 4601 NAME: OVERLAY_MASK, 4602 4603 /** 4604 * Static property used to define the default attribute 4605 * configuration for the OverlayMask. 4606 * 4607 * @property OverlayMask.ATTRS 4608 * @type Object 4609 * @static 4610 */ 4611 ATTRS: { 4612 /** 4613 * Points to align the <a href="Overlay.html">Overlay</a> used as 4614 * mask. 4615 * 4616 * @attribute alignPoints 4617 * @default [ 'tl', 'tl' ] 4618 * @type Array 4619 */ 4620 alignPoints: { 4621 value: ['tl', 'tl'], 4622 validator: isArray 4623 }, 4624 4625 /** 4626 * Background color of the mask. 4627 * 4628 * @attribute background 4629 * @default null 4630 * @type String 4631 */ 4632 background: { 4633 lazyAdd: false, 4634 value: null, 4635 validator: isString, 4636 setter: function(v) { 4637 if (v) { 4638 this.get(CONTENT_BOX).setStyle(BACKGROUND, v); 4639 } 4640 4641 return v; 4642 } 4643 }, 4644 4645 /** 4646 * Node where the mask will be positioned and re-dimensioned. The 4647 * default is the document, which means that if not specified the mask 4648 * takes the full screen. 4649 * 4650 * @attribute target 4651 * @default document 4652 * @type Node | String 4653 */ 4654 target: { 4655 cloneDefaultValue: false, 4656 lazyAdd: false, 4657 value: CONFIG.doc, 4658 setter: function(v) { 4659 var instance = this; 4660 4661 var target = A.one(v); 4662 4663 var isDoc = instance._isDoc = target.compareTo(CONFIG.doc); 4664 var isWin = instance._isWin = target.compareTo(CONFIG.win); 4665 4666 instance._fullPage = isDoc || isWin; 4667 4668 return target; 4669 } 4670 }, 4671 4672 /** 4673 * CSS opacity of the mask. 4674 * 4675 * @attribute opacity 4676 * @default .5 4677 * @type Number 4678 */ 4679 opacity: { 4680 value: 0.5, 4681 validator: isNumber, 4682 setter: function(v) { 4683 return this._setOpacity(v); 4684 } 4685 }, 4686 4687 /** 4688 * Use shim option. 4689 * 4690 * @attribute shim 4691 * @default True on IE. 4692 * @type boolean 4693 */ 4694 shim: { 4695 value: A.UA.ie 4696 }, 4697 4698 /** 4699 * If true the Overlay is visible by default after the render phase. 4700 * Inherited from <a href="Overlay.html">Overlay</a>. 4701 * 4702 * @attribute visible 4703 * @default false 4704 * @type boolean 4705 */ 4706 visible: { 4707 value: false 4708 }, 4709 4710 /** 4711 * zIndex of the OverlayMask. 4712 * 4713 * @attribute zIndex 4714 * @default 1000 4715 * @type Number 4716 */ 4717 zIndex: { 4718 value: 1000 4719 } 4720 }, 4721 4722 EXTENDS: A.OverlayBase, 4723 4724 prototype: { 4725 /** 4726 * Bind the events on the OverlayMask UI. Lifecycle. 4727 * 4728 * @method bindUI 4729 * @protected 4730 */ 4731 bindUI: function() { 4732 var instance = this; 4733 4734 OverlayMask.superclass.bindUI.apply(this, arguments); 4735 4736 instance._eventHandles = [ 4737 instance.after('targetChange', instance._afterTargetChange), 4738 instance.after('visibleChange', instance._afterVisibleChange), 4739 4740 // window:resize YUI normalized event is not working, bug? 4741 A.on('windowresize', A.bind(instance.refreshMask, instance)) 4742 ]; 4743 }, 4744 4745 /** 4746 * Sync the OverlayMask UI. Lifecycle. 4747 * 4748 * @method syncUI 4749 * @protected 4750 */ 4751 syncUI: function() { 4752 var instance = this; 4753 4754 instance.refreshMask(); 4755 }, 4756 4757 destructor: function() { 4758 var instance = this; 4759 4760 (new A.EventHandle(instance._eventHandles)).detach(); 4761 }, 4762 4763 /** 4764 * Get the size of the 4765 * <a href="OverlayMask.html#config_target">target</a>. Used to dimension 4766 * the mask node. 4767 * 4768 * @method getTargetSize 4769 * @return {Object} Object containing the { height: height, width: width }. 4770 */ 4771 getTargetSize: function() { 4772 var instance = this; 4773 var target = instance.get(TARGET); 4774 4775 var isDoc = instance._isDoc; 4776 var isWin = instance._isWin; 4777 4778 var height = target.get(OFFSET_HEIGHT); 4779 var width = target.get(OFFSET_WIDTH); 4780 4781 if (IE6) { 4782 // IE6 doesn't support height/width 100% on doc/win 4783 if (isWin) { 4784 width = A.DOM.winWidth(); 4785 height = A.DOM.winHeight(); 4786 } 4787 else if (isDoc) { 4788 width = A.DOM.docWidth(); 4789 height = A.DOM.docHeight(); 4790 } 4791 } 4792 // good browsers... 4793 else if (instance._fullPage) { 4794 height = '100%'; 4795 width = '100%'; 4796 } 4797 4798 return { 4799 height: height, 4800 width: width 4801 }; 4802 }, 4803 4804 /** 4805 * Repaint the OverlayMask UI, respecting the 4806 * <a href="OverlayMask.html#config_target">target</a> size and the 4807 * <a href="OverlayMask.html#config_alignPoints">alignPoints</a>. 4808 * 4809 * @method refreshMask 4810 */ 4811 refreshMask: function() { 4812 var instance = this; 4813 var alignPoints = instance.get(ALIGN_POINTS); 4814 var target = instance.get(TARGET); 4815 var boundingBox = instance.get(BOUNDING_BOX); 4816 var targetSize = instance.getTargetSize(); 4817 4818 var fullPage = instance._fullPage; 4819 4820 boundingBox.setStyles({ 4821 position: (IE6 || !fullPage) ? ABSOLUTE : FIXED, 4822 left: 0, 4823 top: 0 4824 }); 4825 4826 var height = targetSize.height; 4827 var width = targetSize.width; 4828 4829 if (isValue(height)) { 4830 instance.set(HEIGHT, height); 4831 } 4832 4833 if (isValue(width)) { 4834 instance.set(WIDTH, width); 4835 } 4836 4837 // if its not a full mask... 4838 if (!fullPage) { 4839 // if the target is not document|window align the overlay 4840 instance.align(target, alignPoints); 4841 } 4842 }, 4843 4844 /** 4845 * Setter for <a href="Paginator.html#config_opacity">opacity</a>. 4846 * 4847 * @method _setOpacity 4848 * @protected 4849 * @param {Number} v 4850 * @return {Number} 4851 */ 4852 _setOpacity: function(v) { 4853 var instance = this; 4854 4855 instance.get(CONTENT_BOX).setStyle(OPACITY, v); 4856 4857 return v; 4858 }, 4859 4860 /** 4861 * Invoke the <code>OverlayMask.superclass._uiSetVisible</code>. Used to 4862 * reset the <code>opacity</code> to work around IE bugs when set opacity 4863 * of hidden elements. 4864 * 4865 * @method _uiSetVisible 4866 * @param {boolean} val 4867 * @protected 4868 */ 4869 _uiSetVisible: function(val) { 4870 var instance = this; 4871 4872 OverlayMask.superclass._uiSetVisible.apply(this, arguments); 4873 4874 if (val) { 4875 instance._setOpacity( 4876 instance.get(OPACITY) 4877 ); 4878 } 4879 }, 4880 4881 /** 4882 * Fires after the value of the 4883 * <a href="Paginator.html#config_target">target</a> attribute change. 4884 * 4885 * @method _afterTargetChange 4886 * @param {EventFacade} event 4887 * @protected 4888 */ 4889 _afterTargetChange: function(event) { 4890 var instance = this; 4891 4892 instance.refreshMask(); 4893 }, 4894 4895 /** 4896 * Fires after the value of the 4897 * <a href="Paginator.html#config_visible">visible</a> attribute change. 4898 * 4899 * @method _afterVisibleChange 4900 * @param {EventFacade} event 4901 * @protected 4902 */ 4903 _afterVisibleChange: function(event) { 4904 var instance = this; 4905 4906 instance._uiSetVisible(event.newVal); 4907 }, 4908 4909 /** 4910 * UI Setter for the 4911 * <a href="Paginator.html#config_xy">XY</a> attribute. 4912 * 4913 * @method _uiSetXY 4914 * @param {EventFacade} event 4915 * @protected 4916 */ 4917 _uiSetXY: function() { 4918 var instance = this; 4919 4920 if (!instance._fullPage || IE6) { 4921 OverlayMask.superclass._uiSetXY.apply(instance, arguments); 4922 } 4923 } 4924 } 4925}); 4926 4927A.OverlayMask = OverlayMask; 4928 4929 4930}, '3.1.0-deprecated.70', {"requires": ["event-resize", "aui-base-deprecated", "aui-overlay-base-deprecated"], "skinnable": true}); 4931 4932YUI.add('aui-parse-content', function (A, NAME) { 4933 4934/** 4935 * The ParseContent Utility - Parse the content of a Node so that all of the 4936 * javascript contained in that Node will be executed according to the order 4937 * that it appears. 4938 * 4939 * @module aui-parse-content 4940 */ 4941 4942/* 4943 * NOTE: The inspiration of ParseContent cames from the "Caridy Patino" Node 4944 * Dispatcher Plugin http://github.com/caridy/yui3-gallery/blob/master/src 4945 * /gallery-dispatcher/ 4946 */ 4947 4948var L = A.Lang, 4949 isString = L.isString, 4950 4951 DOC = A.config.doc, 4952 PADDING_NODE = '<div>_</div>', 4953 4954 SCRIPT_TYPES = { 4955 '': 1, 4956 'text/javascript': 1, 4957 'text/parsed': 1 4958 }; 4959 4960/** 4961 * A base class for ParseContent, providing: 4962 * 4963 * - After plug ParseContent on a A.Node instance the javascript chunks will be 4964 * executed (remote and inline scripts) 4965 * - All the javascripts within a content will be executed according to the 4966 * order of apparition 4967 * 4968 * **NOTE:** For performance reasons on DOM manipulation, 4969 * ParseContent only parses the content passed to the 4970 * [setContent](Node.html#method_setContent), 4971 * [prepend](Node.html#method_prepend) and 4972 * [append](Node.html#method_append) methods. 4973 * 4974 * Quick Example: 4975 * 4976 * ``` 4977 * node.plug(A.Plugin.ParseContent); 4978 * ``` 4979 * 4980 * @class A.ParseContent 4981 * @extends Plugin.Base 4982 * @param {Object} config Object literal specifying widget configuration 4983 * properties. 4984 * @constructor 4985 */ 4986var ParseContent = A.Component.create({ 4987 /** 4988 * Static property provides a string to identify the class. 4989 * 4990 * @property NAME
4991 * @type String 4992 * @static 4993 */ 4994 NAME: 'ParseContent', 4995 4996 /** 4997 * Static property provides a string to identify the namespace. 4998 * 4999 * @property NS 5000 * @type String 5001 * @static 5002 */ 5003 NS: 'ParseContent', 5004 5005 /** 5006 * Static property used to define the default attribute 5007 * configuration for the ParseContent. 5008 * 5009 * @property ATTRS 5010 * @type Object 5011 * @static 5012 */ 5013 ATTRS: { 5014 /** 5015 * A queue of elements to be parsed. 5016 * 5017 * @attribute queue 5018 * @default null 5019 */ 5020 queue: { 5021 value: null 5022 }, 5023 5024 /** 5025 * When true, script nodes will not be removed from original content, 5026 * instead the script type attribute will be set to `text/plain`. 5027 * 5028 * @attribute preserveScriptNodes 5029 * @default false 5030 */ 5031 preserveScriptNodes: { 5032 validator: L.isBoolean, 5033 value: false 5034 } 5035 }, 5036 5037 /** 5038 * Static property used to define which component it extends. 5039 * 5040 * @property EXTENDS 5041 * @type Object 5042 * @static 5043 */ 5044 EXTENDS: A.Plugin.Base, 5045 5046 prototype: { 5047 5048 /** 5049 * Construction logic executed during ParseContent instantiation. 5050 * Lifecycle. 5051 * 5052 * @method initializer 5053 * @protected 5054 */ 5055 initializer: function() { 5056 var instance = this; 5057 5058 ParseContent.superclass.initializer.apply(this, arguments); 5059 5060 instance.set( 5061 'queue', 5062 new A.AsyncQueue() 5063 ); 5064 5065 instance._bindAOP(); 5066 }, 5067 5068 /** 5069 * Global eval the <data>data</data> passed. 5070 * 5071 * @method globalEval 5072 * @param {String} data JavaScript String. 5073 */ 5074 globalEval: function(data) { 5075 var doc = A.getDoc(); 5076 var head = doc.one('head') || doc.get('documentElement'); 5077 5078 // NOTE: A.Node.create('<script></script>') doesn't work correctly 5079 // on Opera 5080 var newScript = DOC.createElement('script'); 5081 5082 newScript.type = 'text/javascript'; 5083 5084 if (data) { 5085 // NOTE: newScript.set(TEXT, data) breaks on IE, YUI BUG. 5086 newScript.text = L.trim(data); 5087 } 5088 5089 //removes the script node immediately after executing it 5090 head.appendChild(newScript).remove(); 5091 }, 5092 5093 /** 5094 * Extract the `script` tags from the string content and 5095 * evaluate the chunks. 5096 * 5097 * @method parseContent 5098 * @param {String} content HTML string 5099 * @return {String} 5100 */ 5101 parseContent: function(content) { 5102 var instance = this; 5103 5104 var output = instance._extractScripts(content); 5105 5106 instance._dispatch(output); 5107 5108 return output; 5109 }, 5110 5111 /** 5112 * Add inline script data to the queue. 5113 * 5114 * @method _addInlineScript 5115 * @param {String} data The script content which should be added to the 5116 * queue 5117 * @protected 5118 */ 5119 _addInlineScript: function(data) { 5120 var instance = this; 5121 5122 instance.get('queue').add({ 5123 args: data, 5124 context: instance, 5125 fn: instance.globalEval, 5126 timeout: 0 5127 }); 5128 }, 5129 5130 /** 5131 * Bind listeners on the `insert` and `setContent` methods of the Node 5132 * instance where you are plugging the ParseContent. These listeners are 5133 * responsible for intercept the HTML passed and parse them. 5134 * 5135 * @method _bindAOP 5136 * @protected 5137 */ 5138 _bindAOP: function() { 5139 var instance = this; 5140 5141 var cleanFirstArg = function(content) { 5142 var args = Array.prototype.slice.call(arguments); 5143 var output = instance.parseContent(content); 5144 5145 // replace the first argument with the clean fragment 5146 args.splice(0, 1, output.fragment); 5147
5148 return new A.Do.AlterArgs(null, args); 5149 }; 5150 5151 this.doBefore('insert', cleanFirstArg); 5152 this.doBefore('replaceChild', cleanFirstArg); 5153 5154 var cleanArgs = function(content) { 5155 var output = instance.parseContent(content); 5156 5157 return new A.Do.AlterArgs(null, [output.fragment]); 5158 }; 5159 5160 this.doBefore('replace', cleanArgs); 5161 this.doBefore('setContent', cleanArgs); 5162 }, 5163 5164 /** 5165 * Create an HTML fragment with the String passed, extract all the 5166 * script tags and return an Object with a reference for the extracted 5167 * scripts and the fragment. 5168 * 5169 * @method clean 5170 * @param {String} content HTML content. 5171 * @protected 5172 * @return {Object} 5173 */ 5174 _extractScripts: function(content) { 5175 var instance = this, 5176 fragment = A.Node.create('<div></div>'), 5177 output = {}, 5178 preserveScriptNodes = instance.get('preserveScriptNodes'); 5179 5180 // For PADDING_NODE, instead of fixing all tags in the content to be 5181 // "XHTML"-style, we make the firstChild be a valid non-empty tag, 5182 // then we remove it later 5183 5184 if (isString(content)) { 5185 content = PADDING_NODE + content; 5186 5187 // create fragment from {String} 5188 A.DOM.addHTML(fragment, content, 'append'); 5189 } 5190 else { 5191 fragment.append(PADDING_NODE); 5192 5193 // create fragment from {Y.Node | HTMLElement} 5194 fragment.append(content); 5195 } 5196 5197 output.js = fragment.all('script').filter(function(script) { 5198 var includeScript = SCRIPT_TYPES[script.getAttribute('type').toLowerCase()]; 5199 if (preserveScriptNodes) { 5200 script.setAttribute('type', 'text/parsed'); 5201 } 5202 return includeScript; 5203 }); 5204 5205 if (!preserveScriptNodes) { 5206 output.js.each( 5207 function(node) { 5208 node.remove(); 5209 } 5210 ); 5211 } 5212 5213 // remove PADDING_NODE 5214 fragment.get('firstChild').remove(); 5215 5216 output.fragment = fragment.get('childNodes').toFrag(); 5217 5218 return output; 5219 }, 5220 5221 /** 5222 * Loop trough all extracted `script` tags and evaluate them. 5223 * 5224 * @method _dispatch 5225 * @param {Object} output Object containing the reference for the 5226 * fragment and the extracted `script` tags. 5227 * @protected 5228 * @return {String} 5229 */ 5230 _dispatch: function(output) { 5231 var instance = this; 5232 5233 var queue = instance.get('queue'); 5234 5235 var scriptContent = []; 5236 5237 output.js.each(function(node) { 5238 var src = node.get('src'); 5239 5240 if (src) { 5241 if (scriptContent.length) { 5242 instance._addInlineScript(scriptContent.join(';')); 5243 5244 scriptContent.length = 0; 5245 } 5246 5247 queue.add({ 5248 autoContinue: false, 5249 fn: function() { 5250 A.Get.script(src, { 5251 onEnd: function(o) { 5252 //removes the script node immediately after 5253 //executing it 5254 o.purge(); 5255 queue.run(); 5256 } 5257 }); 5258 }, 5259 timeout: 0 5260 }); 5261 } 5262 else { 5263 var dom = node._node; 5264 5265 scriptContent.push(dom.text || dom.textContent || dom.innerHTML || ''); 5266 } 5267 }); 5268 5269 if (scriptContent.length) { 5270 instance._addInlineScript(scriptContent.join(';')); 5271 } 5272 5273 queue.run(); 5274 } 5275 } 5276}); 5277 5278A.namespace('Plugin').ParseContent = ParseContent; 5279 5280 5281}, '3.1.0-deprecated.70', {"requires": ["async-queue", "plugin", "io-base", "aui-component", "aui-node-base"]}); 5282 5283/** 5284 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 5285 * 5286 * This library is free software; you can redistribute it and/or modify it under 5287 * the terms of the GNU Lesser General Public License as published by the Free 5288 * Software Foundation; either version 2.1 of the License, or (at your option) 5289 * any later version. 5290 * 5291 * This library is distributed in the hope that it will be useful, but WITHOUT 5292 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 5293 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 5294 * details. 5295 */ 5296(function (A, Liferay) { 5297 var LayoutExporter = { 5298 icons: { 5299 minus: themeDisplay.getPathThemeImages() + '/arrows/01_minus.png', 5300 plus: themeDisplay.getPathThemeImages() + '/arrows/01_plus.png' 5301 }, 5302 publishToLive: function publishToLive(options) { 5303 options = options || {}; 5304 Liferay.Util.openWindow({ 5305 dialog: { 5306 constrain: true, 5307 modal: true, 5308 on: { 5309 visibleChange: function visibleChange(event) { 5310 var instance = this; 5311 5312 if (!event.newVal) { 5313 instance.destroy(); 5314 } 5315 } 5316 } 5317 }, 5318 title: options.title, 5319 uri: options.url 5320 }); 5321 } 5322 }; 5323 Liferay.provide(LayoutExporter, 'all', function (options) { 5324 options = options || {}; 5325 var obj = options.obj; 5326 var pane = options.pane; 5327 5328 if (obj && obj.checked) { 5329 pane = A.one(pane); 5330 5331 if (pane) { 5332 pane.hide(); 5333 } 5334 } 5335 }, ['aui-base']); 5336 Liferay.provide(LayoutExporter, 'details', function (options) { 5337 options = options || {}; 5338 var detail = A.one(options.detail); 5339 var img = A.one(options.toggle); 5340 5341 if (detail && img) { 5342 var icon = LayoutExporter.icons.plus; 5343 5344 if (detail.hasClass('hide')) { 5345 detail.show(); 5346 icon = LayoutExporter.icons.minus; 5347 } else { 5348 detail.hide(); 5349 } 5350 5351 img.attr('src', icon); 5352 } 5353 }, ['aui-base']); 5354 Liferay.provide(LayoutExporter, 'proposeLayout', function (options) { 5355 options = options || {}; 5356 var namespace = options.namespace; 5357 var reviewers = options.reviewers; 5358 var contents = '<div>' + '<form action="' + options.url + '" method="post">'; 5359 5360 if (reviewers.length > 0) { 5361 contents += '<textarea name="' + namespace + 'description" style="height: 100px; width: 284px;"></textarea><br /><br />' + 'Revisor' + ' <select name="' + namespace + 'reviewUserId">'; 5362 5363 for (var i = 0; i < reviewers.length; i++) { 5364 contents += '<option value="' + reviewers[i].userId + '">' + reviewers[i].fullName + '</option>'; 5365 } 5366 5367 contents += '</select><br /><br />' + '<input type="submit" value="' + 'Prosseguir' + '" />'; 5368 } else { 5369 contents += 'Nenhum\x20revisor\x20foi\x20encontrado\x2e' + '<br />' + 'Por\x20favor\x2c\x20contate\x20o\x20administrador\x20para\x20atribuir\x20revisores\x2e' + '<br /><br />'; 5370 } 5371 5372 contents += '</form>' + '</div>'; 5373 Liferay.Util.openWindow({ 5374 dialog: { 5375 destroyOnHide: true 5376 }, 5377 title: contents 5378 }); 5379 }, ['liferay-util-window']); 5380 Liferay.provide(LayoutExporter, 'selected', function (options) { 5381 options = options || {}; 5382 var obj = options.obj; 5383 var pane = options.pane; 5384 5385 if (obj && obj.checked) { 5386 pane = A.one(pane); 5387 5388 if (pane) { 5389 pane.show(); 5390 } 5391 } 5392 }, ['aui-base']); 5393 Liferay.LayoutExporter = LayoutExporter; 5394})(AUI(), Liferay); 5395//# sourceMappingURL=layout_exporter.js.map 5396/** 5397 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 5398 * 5399 * This library is free software; you can redistribute it and/or modify it under 5400 * the terms of the GNU Lesser General Public License as published by the Free 5401 * Software Foundation; either version 2.1 of the License, or (at your option) 5402 * any later version. 5403 * 5404 * This library is distributed in the hope that it will be useful, but WITHOUT 5405 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 5406 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 5407 * details. 5408 */ 5409AUI.add('liferay-session', function (A) { 5410 var Lang = A.Lang; 5411 var BUFFER_TIME = []; 5412 var CONFIG = A.config; 5413 var DOC = CONFIG.doc; 5414 var MAP_SESSION_STATE_EVENTS = { 5415 active: 'activated' 5416 }; 5417 var SRC = {}; 5418 var SRC_EVENT_OBJ = { 5419 src: SRC 5420 }; 5421 var URL_BASE = themeDisplay.getPathMain() + '/portal/'; 5422 var SessionBase = A.Component.create({ 5423 ATTRS: { 5424 autoExtend: { 5425 value: false 5426 }, 5427 redirectOnExpire: { 5428 value: true 5429 }, 5430 redirectUrl: { 5431 value: '' 5432 }, 5433 sessionLength: { 5434 getter: '_getLengthInMillis', 5435 value: 0 5436 }, 5437 sessionState: { 5438 value: 'active' 5439 }, 5440 timestamp: { 5441 getter: '_getTimestamp', 5442 setter: '_setTimestamp', 5443 value: 0 5444 }, 5445 warningLength: { 5446 getter: '_getLengthInMillis', 5447 setter: '_setWarningLength', 5448 value: 0 5449 }, 5450 warningTime: { 5451 getter: '_getWarningTime', 5452 value: 0 5453 } 5454 }, 5455 EXTENDS: A.Base, 5456 NAME: 'liferaysession', 5457 prototype: { 5458 _afterSessionStateChange: function _afterSessionStateChange(event) { 5459 var instance = this; 5460 var details = event.details; 5461 var newVal = event.newVal; 5462 var src = null; 5463 5464 if ('src' in event && details.length) { 5465 src = details[0]; 5466 } 5467 5468 instance.fire(MAP_SESSION_STATE_EVENTS[newVal] || newVal, src
5468); 5469 }, 5470 _defActivatedFn: function _defActivatedFn(event) { 5471 var instance = this; 5472 instance.set('timestamp'); 5473 5474 if (event.src == SRC) { 5475 Liferay.Util.fetch(URL_BASE + 'extend_session'); 5476 } 5477 }, 5478 _defExpiredFn: function _defExpiredFn(event) { 5479 var instance = this; 5480 A.clearInterval(instance._intervalId); 5481 instance.set('timestamp', 'expired'); 5482 5483 if (event.src === SRC) { 5484 instance._expireSession(); 5485 } 5486 }, 5487 _expireSession: function _expireSession() { 5488 var instance = this; 5489 Liferay.Util.fetch(URL_BASE + 'expire_session').then(function (response) { 5490 if (response.ok) { 5491 Liferay.fire('sessionExpired'); 5492 5493 if (instance.get('redirectOnExpire')) { 5494 location.href = instance.get('redirectUrl'); 5495 } 5496 } else { 5497 A.setTimeout(function () { 5498 instance._expireSession(); 5499 }, 1000); 5500 } 5501 }); 5502 }, 5503 _getLengthInMillis: function _getLengthInMillis(value) { 5504 return value * 1000; 5505 }, 5506 _getTimestamp: function _getTimestamp() { 5507 var instance = this; 5508 return A.Cookie.get(instance._cookieKey, instance._cookieOptions) || instance._initTimestamp; 5509 }, 5510 _getWarningTime: function _getWarningTime() { 5511 var instance = this; 5512 return instance.get('sessionLength') - instance.get('warningLength'); 5513 }, 5514 _initEvents: function _initEvents() { 5515 var instance = this; 5516 instance.publish('activated', { 5517 defaultFn: A.bind('_defActivatedFn', instance) 5518 }); 5519 instance.publish('expired', { 5520 defaultFn: A.bind('_defExpiredFn', instance) 5521 }); 5522 instance.publish('warned'); 5523 instance._eventHandlers = [instance.on('sessionStateChange', instance._onSessionStateChange), instance.after('sessionStateChange', instance._afterSessionStateChange), A.on('io:complete', function (transactionId, response, args) { 5524 if (!args || args && args.sessionExtend || !Lang.isBoolean(args.sessionExtend)) { 5525 instance.resetInterval(); 5526 } 5527 }), Liferay.once('screenLoad', function () { 5528 instance.destroy(); 5529 })]; 5530 }, 5531 _onSessionStateChange: function _onSessionStateChange(event) { 5532 var instance = this; 5533 var newVal = event.newVal; 5534 var prevVal = event.prevVal; 5535 5536 if (prevVal == 'expired' && prevVal != newVal) { 5537 event.preventDefault(); 5538 } else if (prevVal == 'active' && prevVal == newVal) { 5539 instance._afterSessionStateChange(event); 5540 } 5541 }, 5542 _setTimestamp: function _setTimestamp(value) { 5543 var instance = this; 5544 value = String(value || Date.now()); 5545 instance._initTimestamp = value; 5546 5547 if (navigator.cookieEnabled) { 5548 A.Cookie.set(instance._cookieKey, value, instance._cookieOptions); 5549 } 5550 }, 5551 _setWarningLength: function _setWarningLength(value) { 5552 var instance = this; 5553 return Math.min(instance.get('sessionLength'), value); 5554 }, 5555 _startTimer: function _startTimer() { 5556 var instance = this; 5557 var sessionLength = instance.get('sessionLength'); 5558 var sessionState = instance.get('sessionState'); 5559 var warningTime = instance.get('warningTime'); 5560 var registered = instance._registered; 5561 var interval = 1000; 5562 instance._intervalId = A.setInterval(function () { 5563 var timeOffset; 5564 var timestamp = instance.get('timestamp'); 5565 var elapsed = sessionLength; 5566 5567 if (Lang.toInt(timestamp)) { 5568 timeOffset = Math.floor((Date.now() - timestamp) / 1000) * 1000; 5569 elapsed = timeOffset; 5570 5571 if (instance._initTimestamp !== timestamp) { 5572 instance.set('timestamp', timestamp); 5573 5574 if (sessionState != 'active') { 5575 instance.set('sessionState', 'active', SRC_EVENT_OBJ); 5576 } 5577 } 5578 } else { 5579 timestamp = 'expired'; 5580 } 5581 5582 var extend = instance.get('autoExtend'); 5583 var expirationMoment = false;
5584 var warningMoment = false; 5585 var hasExpired = elapsed >= sessionLength; 5586 var hasWarned = elapsed >= warningTime; 5587 5588 if (hasWarned) { 5589 if (timestamp == 'expired') { 5590 expirationMoment = true; 5591 extend = false; 5592 hasExpired = true; 5593 } 5594 5595 if (hasExpired && sessionState != 'expired') { 5596 if (extend) { 5597 expirationMoment = false; 5598 hasExpired = false; 5599 hasWarned = false; 5600 warningMoment = false; 5601 instance.extend(); 5602 } else { 5603 instance.expire(); 5604 expirationMoment = true; 5605 } 5606 } else if (hasWarned && !hasExpired && !extend && sessionState != 'warned') { 5607 instance.warn(); 5608 warningMoment = true; 5609 } 5610 } 5611 5612 for (var i in registered) { 5613 registered[i](elapsed, interval, hasWarned, hasExpired, warningMoment, expirationMoment); 5614 } 5615 }, interval); 5616 }, 5617 _stopTimer: function _stopTimer() { 5618 var instance = this; 5619 A.clearInterval(instance._intervalId); 5620 }, 5621 destructor: function destructor() { 5622 var instance = this; 5623 new A.EventHandle(instance._eventHandlers).detach(); 5624 5625 instance._stopTimer(); 5626 }, 5627 expire: function expire() { 5628 var instance = this; 5629 instance.set('sessionState', 'expired', SRC_EVENT_OBJ); 5630 }, 5631 extend: function extend() { 5632 var instance = this; 5633 instance.set('sessionState', 'active', SRC_EVENT_OBJ); 5634 }, 5635 initializer: function initializer() { 5636 var instance = this; 5637 instance._cookieKey = 'LFR_SESSION_STATE_' + themeDisplay.getUserId(); 5638 instance._cookieOptions = { 5639 path: '/', 5640 secure: A.UA.secure 5641 }; 5642 instance._registered = {}; 5643 instance.set('timestamp'); 5644 5645 instance._initEvents(); 5646 5647 instance._startTimer(); 5648 }, 5649 registerInterval: function registerInterval(fn) { 5650 var instance = this; 5651 var fnId; 5652 var registered = instance._registered; 5653 5654 if (Lang.isFunction(fn)) { 5655 fnId = A.stamp(fn); 5656 registered[fnId] = fn; 5657 } 5658 5659 return fnId; 5660 }, 5661 resetInterval: function resetInterval() { 5662 var instance = this; 5663 5664 instance._stopTimer(); 5665 5666 instance._startTimer(); 5667 }, 5668 unregisterInterval: function unregisterInterval(fnId) { 5669 var instance = this; 5670 var registered = instance._registered; 5671 5672 if (Object.prototype.hasOwnProperty.call(registered, fnId)) { 5673 delete registered[fnId]; 5674 } 5675 5676 return fnId; 5677 }, 5678 warn: function warn() { 5679 var instance = this; 5680 instance.set('sessionState', 'warned', SRC_EVENT_OBJ); 5681 } 5682 } 5683 }); 5684 SessionBase.SRC = SRC; 5685 var SessionDisplay = A.Component.create({ 5686 ATTRS: { 5687 pageTitle: { 5688 value: DOC.title 5689 } 5690 }, 5691 EXTENDS: A.Plugin.Base, 5692 NAME: 'liferaysessiondisplay', 5693 NS: 'display', 5694 prototype: { 5695 _afterDefActivatedFn: function _afterDefActivatedFn() { 5696 var instance = this; 5697 5698 instance._uiSetActivated(); 5699 }, 5700 _afterDefExpiredFn: function _afterDefExpiredFn() { 5701 var instance = this; 5702 5703 instance._host.unregisterInterval(instance._intervalId); 5704 5705 instance._uiSetExpired(); 5706 }, 5707 _beforeHostWarned: function _beforeHostWarned() { 5708 var instance = this; 5709 var host = instance._host; 5710 var sessionLength = host.get('sessionLength'); 5711 var timestamp = host.get('timestamp'); 5712 var warningLength = host.get('warningLength'); 5713 var elapsed = sessionLength; 5714 5715 if (Lang.toInt(timestamp)) { 5716 elapsed = Math.floor((Date.now() - timestamp) / 1000) * 1000; 5717 } 5718 5719 var remainingTime = sessionLength - elapsed; 5720 5721 if (remainingTime > warningLength) { 5722 remainingTime = warningLength; 5723 } 5724 5725 var banner = instance._getBanner(); 5726 5727 var counterTextNode = banner.one('.countdown-timer'); 5728 5729 instance._uiSetRemainingTime(remainingTime, counterTextNode); 5730 5731 banner.show(); 5732 instance._intervalId = host.registerInterval(function (elapsed, interval, hasWarned, hasExpired, warningMoment) { 5733 if (!hasWarned) { 5734 instance._uiSetActivated(); 5735 } else if (!hasExpired) { 5736 if (warningMoment) { 5737 if (remainingTime <= 0) { 5738 remainingTime = warningLength; 5739 } 5740 5741 banner.show(); 5742 } 5743
5744 elapsed = Math.floor((Date.now() - timestamp) / 1000) * 1000; 5745 remainingTime = sessionLength - elapsed; 5746 5747 instance._uiSetRemainingTime(remainingTime, counterTextNode); 5748 } 5749 5750 remainingTime -= interval; 5751 }); 5752 }, 5753 _destroyBanner: function _destroyBanner() { 5754 var instance = this; 5755 instance._banner = false; 5756 var notificationContainer = A.one('.lfr-notification-container'); 5757 5758 if (notificationContainer) { 5759 notificationContainer.remove(); 5760 } 5761 }, 5762 _formatNumber: function _formatNumber(value) { 5763 return Lang.String.padNumber(Math.floor(value), 2); 5764 }, 5765 _formatTime: function _formatTime(time) { 5766 var instance = this; 5767 time = Number(time); 5768 5769 if (Lang.isNumber(time) && time > 0) { 5770 time /= 1000; 5771 BUFFER_TIME[0] = instance._formatNumber(time / 3600); 5772 time %= 3600; 5773 BUFFER_TIME[1] = instance._formatNumber(time / 60); 5774 time %= 60; 5775 BUFFER_TIME[2] = instance._formatNumber(time); 5776 time = BUFFER_TIME.join(':'); 5777 } else { 5778 time = 0; 5779 } 5780 5781 return time; 5782 }, 5783 _getBanner: function _getBanner() { 5784 var instance = this; 5785 var banner = instance._banner; 5786 5787 if (!banner) { 5788 banner = new Liferay.Notification({ 5789 closeable: true, 5790 delay: { 5791 hide: 0, 5792 show: 0 5793 }, 5794 duration: 500, 5795 message: instance._warningText, 5796 on: { 5797 click: function click(event) { 5798 if (event.domEvent.target.test('.alert-link')) { 5799 event.domEvent.preventDefault(); 5800 5801 instance._host.extend(); 5802 } else if (event.domEvent.target.test('.close')) { 5803 instance._destroyBanner(); 5804 5805 instance._alertClosed = true; 5806 } 5807 } 5808 }, 5809 title: 'Aviso', 5810 type: 'warning' 5811 }).render('body'); 5812 instance._banner = banner; 5813 } 5814 5815 return banner; 5816 }, 5817 _onHostSessionStateChange: function _onHostSessionStateChange(event) { 5818 var instance = this; 5819 5820 if (event.newVal == 'warned') { 5821 instance._beforeHostWarned(event); 5822 } 5823 }, 5824 _uiSetActivated: function _uiSetActivated() { 5825 var instance = this; 5826 DOC.title = instance.reset('pageTitle').get('pageTitle'); 5827 5828 instance._host.unregisterInterval(instance._intervalId); 5829 5830 var banner = instance._getBanner(); 5831 5832 if (banner) { 5833 instance._destroyBanner(); 5834 } 5835 }, 5836 _uiSetExpired: function _uiSetExpired() { 5837 var instance = this; 5838 5839 var banner = instance._getBanner(); 5840 5841 banner.setAttrs({ 5842 message: instance._expiredText, 5843 title: 'Perigo', 5844 type: 'danger' 5845 }); 5846 DOC.title = instance.get('pageTitle'); 5847 }, 5848 _uiSetRemainingTime: function _uiSetRemainingTime(remainingTime) { 5849 var instance = this; 5850 remainingTime = instance._formatTime(remainingTime); 5851 5852 if (!instance._alertClosed) { 5853 var banner = instance._getBanner(); 5854 5855 banner.set('message', Lang.sub(instance._warningText, [remainingTime])); 5856 } 5857 5858 DOC.title = Lang.sub('Session\x20expires\x20in\x20\x7b0\x7d\x2e', [remainingTime]) + ' | ' + instance.get('pageTitle'); 5859 }, 5860 destructor: function destructor() { 5861 var instance = this; 5862 5863 if (instance._banner) { 5864 instance._destroyBanner(); 5865 } 5866 }, 5867 initializer: function initializer() { 5868 var instance = this; 5869 var host = instance.get('host'); 5870 5871 if (Liferay.Util.getTop() == CONFIG.win) { 5872 instance._host = host; 5873 instance._toggleText = { 5874 hide: 'Ocultar', 5875 show: 'Mostrar' 5876 }; 5877 instance._expiredText = 'Devido\x20a\x20inactividade\x2c\x20a\x20sua\x20sessão\x20expirou\x2e\x20Por\x20favor\x2c\x20salve\x20quaisquer\x20dados\x20que\x20você\x20pode\x20ter\x20digitado\x20antes\x20de\x20atualizar\x20a\x20página\x2e'; 5878 instance._warningText = 'Due\x20to\x20inactivity\x2c\x20your\x20session\x20will\x20expire\x20in\x20\x7b0\x7d\x2e\x20To\x20extend\x20your\x20session\x20another\x20\x7b1\x7d\x20minute\x28s\x29\x2c\x20please\x20press\x20the\x20\x3cem\x3eExtend\x3c\x2fem\x3e\x20button\x2e\x20\x7b2\x7d'; 5879 instance._warningText = Lang.sub(instance._warningText, ['<span class="countdown-timer">{0}</span>', host.get('sessionLength') / 60000, '<a class="alert-link" href="#">
5879' + 'Estender' + '</a>']); 5880 host.on('sessionStateChange', instance._onHostSessionStateChange, instance); 5881 instance.afterHostMethod('_defActivatedFn', instance._afterDefActivatedFn); 5882 instance.afterHostMethod('_defExpiredFn', instance._afterDefExpiredFn); 5883 } else { 5884 host.unplug(instance); 5885 } 5886 } 5887 } 5888 }); 5889 Liferay.SessionBase = SessionBase; 5890 Liferay.SessionDisplay = SessionDisplay; 5891}, '', { 5892 requires: ['aui-timer', 'cookie', 'liferay-notification'] 5893}); 5894//# sourceMappingURL=session.js.map 5895/** 5896 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 5897 * 5898 * This library is free software; you can redistribute it and/or modify it under 5899 * the terms of the GNU Lesser General Public License as published by the Free 5900 * Software Foundation; either version 2.1 of the License, or (at your option) 5901 * any later version. 5902 * 5903 * This library is distributed in the hope that it will be useful, but WITHOUT 5904 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 5905 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 5906 * details. 5907 */ 5908// For details about this file see: LPS-2155 5909(function (A, Liferay) { 5910 var Util = Liferay.namespace('Util'); 5911 var Lang = A.Lang; 5912 var AArray = A.Array; 5913 var AObject = A.Object; 5914 var AString = A.Lang.String; 5915 var htmlEscapedValues = []; 5916 var htmlUnescapedValues = []; 5917 var MAP_HTML_CHARS_ESCAPED = { 5918 '"': '"', 5919 '&': '&', 5920 "'": ''', 5921 '/': '/', 5922 '<': '<', 5923 '>': '>', 5924 '`': '`' 5925 }; 5926 var MAP_HTML_CHARS_UNESCAPED = {}; 5927 AObject.each(MAP_HTML_CHARS_ESCAPED, function (item, index) { 5928 MAP_HTML_CHARS_UNESCAPED[item] = index; 5929 htmlEscapedValues.push(item); 5930 htmlUnescapedValues.push(index); 5931 }); 5932 var REGEX_DASH = /-([a-z])/gi; 5933 var STR_LEFT_SQUARE_BRACKET = '['; 5934 var STR_RIGHT_SQUARE_BRACKET = ']'; 5935 var REGEX_HTML_ESCAPE = new RegExp(STR_LEFT_SQUARE_BRACKET + htmlUnescapedValues.join('') + STR_RIGHT_SQUARE_BRACKET, 'g'); 5936 var REGEX_HTML_UNESCAPE = new RegExp(htmlEscapedValues.join('|'), 'gi'); 5937 Util.MAP_HTML_CHARS_ESCAPED = MAP_HTML_CHARS_ESCAPED; 5938 5939 Util.actsAsAspect = function (object) { 5940 object["yield"] = null; 5941 object.rv = {}; 5942 5943 object.before = function (method, f) { 5944 var original = eval('this.' + method); 5945 5946 this[method] = function () { 5947 f.apply(this, arguments); 5948 return original.apply(this, arguments); 5949 }; 5950 }; 5951 5952 object.after = function (method, f) { 5953 var original = eval('this.' + method); 5954 5955 this[method] = function () { 5956 this.rv[method] = original.apply(this, arguments); 5957 return f.apply(this, arguments); 5958 }; 5959 }; 5960 5961 object.around = function (method, f) { 5962 var original = eval('this.' + method); 5963 5964 this[method] = function () { 5965 this["yield"] = original; 5966 return f.apply(this, arguments); 5967 }; 5968 }; 5969 }; 5970 5971 Util.addInputFocus = function () { 5972 A.use('aui-base', function (A) { 5973 var handleFocus = function handleFocus(event) { 5974 var target = event.target; 5975 var tagName = target.get('tagName'); 5976 5977 if (tagName) { 5978 tagName = tagName.toLowerCase(); 5979 } 5980 5981 var nodeType = target.get('type'); 5982 5983 if (tagName == 'input' && /text|password/.test(nodeType) || tagName == 'textarea') { 5984 var action = 'addClass'; 5985 5986 if (/blur|focusout/.test(event.type)) { 5987 action = 'removeClass'; 5988 } 5989 5990 target[action]('focus'); 5991 } 5992 }; 5993 5994 A.on('focus', handleFocus, document); 5995 A.on('blur', handleFocus, document); 5996 }); 5997 5998 Util.addInputFocus = function () {}; 5999 }; 6000 6001 Util.addInputType = function (el) { 6002 Util.addInputType = Lang.emptyFn; 6003 6004 if (Liferay.Browser.isIe() && Liferay.Browser.getMajorVersion() < 7) { 6005 Util.addInputType = function (el) { 6006 if (el) { 6007 el = A.one(el); 6008 } else { 6009 el = A.one(document.body); 6010 } 6011 6012 var defaultType = 'text'; 6013 el.all('input').each(function (item) { 6014 var type = item.get('type') || defaultType; 6015 item.addClass(type); 6016 }); 6017 }; 6018 } 6019 6020 return Util.addInputType(el); 6021 }; 6022 6023 Util.camelize = function (value, separator) { 6024 var regex = REGEX_DASH; 6025 6026 if (separator) { 6027 regex = new RegExp(separator + '([a-z])', 'gi'); 6028 } 6029 6030 value = value.replace(regex, function (match0, match1) { 6031 return match1.toUpperCase(); 6032 }); 6033 return value; 6034 }; 6035 6036 Util.clamp = function (value, min, max) { 6037 return Math.min(Math.max(value, min), max); 6038 }; 6039 6040 Util.escapeHTML = function (str, preventDoubleEscape, entities) { 6041 var regex = REGEX_HTML_ESCAPE; 6042 var entitiesList = []; 6043 var entitiesValues; 6044 6045 if (Lang.isObject(entities)) { 6046 entitiesValues = []; 6047 AObject.each(entities, function (item, index) { 6048 entitiesList.push(index); 6049 entitiesValues.push(item); 6050 }); 6051 regex = new RegExp(STR_LEFT_SQUARE_BRACKET + AString.escapeRegEx(entitiesList.join('')) + STR_RIGHT_SQUARE_BRACKET, 'g'); 6052 } else { 6053 entities = MAP_HTML_CHARS_ESCAPED; 6054 entitiesValues = htmlEscapedValues; 6055 } 6056 6057 return str.replace(regex, A.bind('_escapeHTML', Util, !!preventDoubleEscape, entities, entitiesValues)); 6058 }; 6059 6060 Util.isEditorPresent = function (editorName) { 6061 return Liferay.EDITORS && Liferay.EDITORS[editorName]; 6062 }; 6063 6064 Util.randomMinMax = function (min, max) { 6065 return Math.round(Math.random() * (max - min)) + min; 6066 }; 6067 6068 Util.selectAndCopy = function (el) { 6069 el.focus(); 6070 el.select(); 6071 6072 if (document.all) { 6073 var textRange = el.createTextRange(); 6074 textRange.execCommand('copy'); 6075 } 6076 }; 6077 6078 Util.setBox = function (oldBox, newBox) { 6079 for (var i = oldBox.length - 1; i > -1; i--) { 6080 oldBox.options[i] = null; 6081 } 6082 6083 for (i = 0; i < newBox.length; i++) { 6084 oldBox.options[i] = new Option(newBox[i].value, i); 6085 } 6086 6087 oldBox.options[0].selected = true; 6088 }; 6089 6090 Util.startsWith = function (str, x) { 6091 return str.indexOf(x) === 0; 6092 }; 6093 6094 Util.textareaTabs = function (event) { 6095 var el = event.currentTarget.getDOM(); 6096 6097 if (event.isKey('TAB')) { 6098 event.halt(); 6099 var oldscroll = el.scrollTop; 6100 6101 if (el.setSelectionRange) { 6102 var caretPos = el.selectionStart + 1; 6103 var elValue = el.value; 6104 el.value = elValue.substring(0, el.selectionStart) + '\t' + elValue.substring(el.selectionEnd, elValue.length); 6105 setTimeout(function () { 6106 el.focus(); 6107 el.setSelectionRange(caretPos, caretPos); 6108 }, 0); 6109 } else { 6110 document.selection.createRange().text = '\t'; 6111 } 6112 6113 el.scrollTop = oldscroll; 6114 return false;
6115 } 6116 }; 6117 6118 Util.uncamelize = function (value, separator) { 6119 separator = separator || ' '; 6120 value = value.replace(/([a-zA-Z][a-zA-Z])([A-Z])([a-z])/g, '$1' + separator + '$2$3'); 6121 value = value.replace(/([a-z])([A-Z])/g, '$1' + separator + '$2'); 6122 return value; 6123 }; 6124 6125 Util.unescapeHTML = function (str, entities) { 6126 var regex = REGEX_HTML_UNESCAPE; 6127 var entitiesMap = MAP_HTML_CHARS_UNESCAPED; 6128 6129 if (entities) { 6130 var entitiesValues = []; 6131 entitiesMap = {}; 6132 AObject.each(entities, function (item, index) { 6133 entitiesMap[item] = index; 6134 entitiesValues.push(item); 6135 }); 6136 regex = new RegExp(entitiesValues.join('|'), 'gi'); 6137 } 6138 6139 return str.replace(regex, A.bind('_unescapeHTML', Util, entitiesMap)); 6140 }; 6141 6142 Util._escapeHTML = function (preventDoubleEscape, entities, entitiesValues, match) { 6143 var result; 6144 6145 if (preventDoubleEscape) { 6146 var arrayArgs = AArray(arguments); 6147 var length = arrayArgs.length; 6148 var offset = arrayArgs[length - 2]; 6149 var string = arrayArgs[length - 1]; 6150 var nextSemicolonIndex = string.indexOf(';', offset); 6151 6152 if (nextSemicolonIndex >= 0) { 6153 var entity = string.substring(offset, nextSemicolonIndex + 1); 6154 6155 if (entitiesValues.indexOf(entity) >= 0) { 6156 result = match; 6157 } 6158 } 6159 } 6160 6161 if (!result) { 6162 result = entities[match]; 6163 } 6164 6165 return result; 6166 }; 6167 6168 Util._unescapeHTML = function (entities, match) { 6169 return entities[match]; 6170 }; 6171 6172 Liferay.provide(Util, 'check', function (form, name, checked) { 6173 var checkbox = A.one(form[name]); 6174 6175 if (checkbox) { 6176 checkbox.attr('checked', checked); 6177 } 6178 }, ['aui-base']); 6179 Liferay.provide(Util, 'disableSelectBoxes', function (toggleBoxId, value, selectBoxId) { 6180 var selectBox = A.one('#' + selectBoxId); 6181 var toggleBox = A.one('#' + toggleBoxId); 6182 6183 if (selectBox && toggleBox) { 6184 var dynamicValue = Lang.isFunction(value); 6185 6186 var disabled = function disabled() { 6187 var currentValue = selectBox.val(); 6188 var visible = value == currentValue; 6189 6190 if (dynamicValue) { 6191 visible = value(currentValue, value); 6192 } 6193 6194 toggleBox.attr('disabled', !visible); 6195 }; 6196 6197 disabled(); 6198 selectBox.on('change', disabled); 6199 } 6200 }, ['aui-base']); 6201 Liferay.provide(Util, 'disableTextareaTabs', function (textarea) { 6202 textarea = A.one(textarea); 6203 6204 if (textarea && textarea.attr('textareatabs') != 'enabled') { 6205 textarea.attr('textareatabs', 'disabled'); 6206 textarea.detach('keydown', Util.textareaTabs); 6207 } 6208 }, ['aui-base']); 6209 Liferay.provide(Util, 'enableTextareaTabs', function (textarea) { 6210 textarea = A.one(textarea); 6211 6212 if (textarea && textarea.attr('textareatabs') != 'enabled') { 6213 textarea.attr('textareatabs', 'disabled'); 6214 textarea.on('keydown', Util.textareaTabs); 6215 } 6216 }, ['aui-base']); 6217 Liferay.provide(Util, 'removeItem', function (box, value) { 6218 box = A.one(box); 6219 var selectedIndex = box.get('selectedIndex'); 6220 6221 if (!value) { 6222 box.all('option').item(selectedIndex).remove(true); 6223 } else { 6224 box.all('option[value=' + value + STR_RIGHT_SQUARE_BRACKET).item(selectedIndex).remove(true); 6225 } 6226 }, ['aui-base']); 6227 Liferay.provide(Util, 'resizeTextarea', function (elString, usingRichEditor) { 6228 var el = A.one('#' + elString); 6229 6230 if (!el) { 6231 el = A.one('textarea[name=' + elString + STR_RIGHT_SQUARE_BRACKET); 6232 } 6233 6234 if (el) { 6235 var pageBody = A.getBody(); 6236 var diff; 6237 6238 var resize = function resize(event) { 6239 var pageBodyHeight = pageBody.get('winHeight'); 6240 6241 if (usingRichEditor) { 6242 try { 6243 if (el.get('nodeName').toLowerCase() != 'iframe') { 6244 el = window[elString]; 6245 } 6246 } catch (e) {} 6247 } 6248 6249 if (!diff) { 6250 var buttonRow = pageBody.one('.button-holder'); 6251 var templateEditor = pageBody.one('.lfr-template-editor'); 6252 6253 if (buttonRow && templateEditor) { 6254 var region = templateEditor.getXY(); 6255 diff = buttonRow.outerHeight(true) + region[1] + 25; 6256 } else { 6257 diff = 170; 6258 } 6259 } 6260 6261 el = A.one(el); 6262 var styles = { 6263 width: '98%' 6264 }; 6265 6266 if (event) { 6267 styles.height = pageBodyHeight - diff; 6268 } 6269 6270 if (usingRichEditor) { 6271 if (!el || !A.DOM.inDoc(el)) { 6272 A.on('available', function () { 6273 el = A.one(window[elString]); 6274 6275 if (el) { 6276 el.setStyles(styles); 6277 } 6278 }, '#' + elString + '_cp'); 6279 return; 6280 } 6281 } 6282 6283 if (el) { 6284 el.setStyles(styles); 6285 } 6286 }; 6287 6288 resize(); 6289 var dialog = Liferay.Util.getWindow(); 6290 6291 if (dialog) { 6292 var resizeEventHandle = dialog.iframe.after('resizeiframe:heightChange', resize); 6293 A.getWin().on('unload', resizeEventHandle.detach, resizeEventHandle); 6294 } 6295 } 6296 }, ['aui-base']); 6297 Liferay.provide(Util, 'setSelectedValue', function (col, value) { 6298 var option = A.one(col).one('option[value=' + value + STR_RIGHT_SQUARE_BRACKET); 6299 6300 if (option) { 6301 option.attr('selected', true); 6302 } 6303 }, ['aui-base']); 6304 Liferay.provide(Util, 'switchEditor', function (options) { 6305 var uri = options.uri; 6306 var windowName = Liferay.Util.getWindowName(); 6307 var dialog = Liferay.Util.getWindow(windowName); 6308 6309 if (dialog) {
6310 dialog.iframe.set('uri', uri); 6311 } 6312 }, ['aui-io']); 6313})(AUI(), Liferay); 6314//# sourceMappingURL=deprecated.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.