https://www.provincia.terni.it/portal/combo?browserId=chrome&minif…/aui/widget-stack/widget-stack.js
1YUI.add('widget-skin', function (Y, NAME) { 2 3/** 4 * Provides skin related utlility methods. 5 * 6 * @module widget 7 * @submodule widget-skin 8 */ 9var BOUNDING_BOX = "boundingBox", 10 CONTENT_BOX = "contentBox", 11 SKIN = "skin", 12 _getClassName = Y.ClassNameManager.getClassName; 13 14/** 15 * Returns the name of the skin that's currently applied to the widget. 16 * 17 * Searches up the Widget's ancestor axis for, by default, a class 18 * yui3-skin-(name), and returns the (name) portion. Otherwise, returns null. 19 * 20 * This is only really useful after the widget's DOM structure is in the 21 * document, either by render or by progressive enhancement. 22 * 23 * @method getSkinName 24 * @for Widget 25 * @param {String} [skinPrefix] The prefix which the implementation uses for the skin 26 * ("yui3-skin-" is the default). 27 * 28 * NOTE: skinPrefix will be used as part of a regular expression: 29 * 30 * new RegExp('\\b' + skinPrefix + '(\\S+)') 31 * 32 * Although an unlikely use case, literal characters which may result in an invalid 33 * regular expression should be escaped. 34 * 35 * @return {String} The name of the skin, or null, if a matching skin class is not found. 36 */ 37 38Y.Widget.prototype.getSkinName = function (skinPrefix) { 39 40 var root = this.get( CONTENT_BOX ) || this.get( BOUNDING_BOX ), 41 match, 42 search; 43 44 skinPrefix = skinPrefix || _getClassName(SKIN, ""); 45 46 search = new RegExp( '\\b' + skinPrefix + '(\\S+)' ); 47 48 if ( root ) { 49 root.ancestor( function ( node ) { 50 match = node.get( 'className' ).match( search ); 51 return match; 52 } ); 53 } 54 55 return ( match ) ? match[1] : null; 56}; 57 58 59}, 'patched-v3.18.1', {"requires": ["widget-base"]}); 60 61YUI.add('widget-uievents', function (Y, NAME) { 62 63/** 64 * Support for Widget UI Events (Custom Events fired by the widget, which wrap the underlying DOM events - e.g. widget:click, widget:mousedown) 65 * 66 * @module widget 67 * @submodule widget-uievents 68 */ 69 70var BOUNDING_BOX = "boundingBox", 71 Widget = Y.Widget, 72 RENDER = "render", 73 L = Y.Lang, 74 EVENT_PREFIX_DELIMITER = ":", 75 76 // Map of Node instances serving as a delegation containers for a specific 77 // event type to Widget instances using that delegation container. 78 _uievts = Y.Widget._uievts = Y.Widget._uievts || {}; 79 80Y.mix(Widget.prototype, { 81 82 /**
83 * Destructor logic for UI event infrastructure, 84 * invoked during Widget destruction. 85 * 86 * @method _destroyUIEvents 87 * @for Widget 88 * @private 89 */ 90 _destroyUIEvents: function() { 91 92 var widgetGuid = Y.stamp(this, true); 93 94 Y.each(_uievts, function (info, key) { 95 if (info.instances[widgetGuid]) { 96 // Unregister this Widget instance as needing this delegated 97 // event listener. 98 delete info.instances[widgetGuid]; 99 100 // There are no more Widget instances using this delegated 101 // event listener, so detach it. 102 103 if (Y.Object.isEmpty(info.instances)) { 104 info.handle.detach(); 105 106 if (_uievts[key]) { 107 delete _uievts[key]; 108 } 109 } 110 } 111 }); 112 }, 113 114 /** 115 * Map of DOM events that should be fired as Custom Events by the 116 * Widget instance. 117 * 118 * @property UI_EVENTS 119 * @for Widget 120 * @type Object 121 */ 122 UI_EVENTS: Y.Node.DOM_EVENTS, 123 124 /** 125 * Returns the node on which to bind delegate listeners. 126 * 127 * @method _getUIEventNode 128 * @for Widget 129 * @protected 130 */ 131 _getUIEventNode: function () { 132 return this.get(BOUNDING_BOX); 133 }, 134 135 /** 136 * Binds a delegated DOM event listener of the specified type to the 137 * Widget's outtermost DOM element to facilitate the firing of a Custom 138 * Event of the same type for the Widget instance. 139 * 140 * @method _createUIEvent 141 * @for Widget 142 * @param type {String} String representing the name of the event 143 * @private 144 */ 145 _createUIEvent: function (type) { 146 147 var uiEvtNode = this._getUIEventNode(), 148 key = (Y.stamp(uiEvtNode) + type), 149 info = _uievts[key], 150 handle; 151 152 // For each Node instance: Ensure that there is only one delegated 153 // event listener used to fire Widget UI events. 154 155 if (!info) { 156 157 handle = uiEvtNode.delegate(type, function (evt) { 158 159 var widget = Widget.getByNode(this); 160
161 // Widget could be null if node instance belongs to 162 // another Y instance. 163 164 if (widget) { 165 if (widget._filterUIEvent(evt)) { 166 widget.fire(evt.type, { domEvent: evt }); 167 } 168 } 169 170 }, "." + Y.Widget.getClassName()); 171 172 _uievts[key] = info = { instances: {}, handle: handle }; 173 } 174 175 // Register this Widget as using this Node as a delegation container. 176 info.instances[Y.stamp(this)] = 1; 177 }, 178 179 /** 180 * This method is used to determine if we should fire 181 * the UI Event or not. The default implementation makes sure 182 * that for nested delegates (nested unrelated widgets), we don't 183 * fire the UI event listener more than once at each level. 184 * 185 * <p>For example, without the additional filter, if you have nested 186 * widgets, each widget will have a delegate listener. If you 187 * click on the inner widget, the inner delegate listener's 188 * filter will match once, but the outer will match twice 189 * (based on delegate's design) - once for the inner widget, 190 * and once for the outer.</p> 191 * 192 * @method _filterUIEvent 193 * @for Widget 194 * @param {DOMEventFacade} evt 195 * @return {boolean} true if it's OK to fire the custom UI event, false if not. 196 * @private 197 * 198 */ 199 _filterUIEvent: function(evt) { 200 // Either it's hitting this widget's delegate container (and not some other widget's), 201 // or the container it's hitting is handling this widget's ui events. 202 return (evt.currentTarget.compareTo(evt.container) || evt.container.compareTo(this._getUIEventNode())); 203 }, 204 205 /** 206 * Determines if the specified event is a UI event. 207 * 208 * @private 209 * @method _isUIEvent 210 * @for Widget 211 * @param type {String} String representing the name of the event 212 * @return {String} Event Returns the name of the UI Event, otherwise 213 * undefined. 214 */ 215 _getUIEvent: function (type) { 216 217 if (L.isString(type)) { 218 var sType = this.parseType(type)[1], 219 iDelim, 220 returnVal; 221 222 if (sType) { 223 // TODO: Get delimiter from ET, or have ET support this. 224 iDelim = sType.indexOf(EVENT_PREFIX_DELIMITER); 225 if (iDelim > -1) { 226 sType = sType.substring(iDelim + EVENT_PREFIX_DELIMITER.length); 227 } 228 229 if (this.UI_EVENTS[sType]) { 230 returnVal = sType; 231 } 232 } 233 234 return returnVal; 235 } 236 }, 237 238 /** 239 * Sets up infrastructure required to fire a UI event. 240 * 241 * @private 242 * @method _initUIEvent 243 * @for Widget 244 * @param type {String} String representing the name of the event 245 * @return {String} 246 */ 247 _initUIEvent: function (type) { 248 var sType = this._getUIEvent(type), 249 queue = this._uiEvtsInitQueue || {}; 250 251 if (sType && !queue[sType]) { 252 253 this._uiEvtsInitQueue = queue[sType] = 1; 254 255 this.after(RENDER, function() { 256 this._createUIEvent(sType); 257 delete this._uiEvtsInitQueue[sType]; 258 }); 259 } 260 }, 261 262 // Override of "on" from Base to facilitate the firing of Widget events 263 // based on DOM events of the same name/type (e.g. "click", "mouseover"). 264 // Temporary solution until we have the ability to listen to when 265 // someone adds an event listener (bug 2528230) 266 on: function (type) { 267 this._initUIEvent(type); 268 return Widget.superclass.on.apply(this, arguments); 269 }, 270 271 // Override of "publish" from Base to facilitate the firing of Widget events 272 // based on DOM events of the same name/type (e.g. "click", "mouseover"). 273 // Temporary solution until we have the ability to listen to when 274 // someone publishes an event (bug 2528230) 275 publish: function (type, config) { 276 var sType = this._getUIEvent(type); 277 if (sType && config && config.defaultFn) { 278 this._initUIEvent(sType); 279 } 280 return Widget.superclass.publish.apply(this, arguments); 281 } 282 283}, true); // overwrite existing EventTarget methods 284 285 286}, 'patched-v3.18.1', {"requires": ["node-event-delegate", "widget-base"]}); 287 288YUI.add('yui-throttle', function (Y, NAME) { 289 290/** 291Throttles a call to a method based on the time between calls. This method is attached 292to the `Y` object and is <a href="../classes/YUI.html#method_throttle">documented there</a>. 293 294 var fn = Y.throttle(function() { 295 counter++; 296 }); 297 298 for (i; i< 35000; i++) { 299 out++; 300 fn(); 301 } 302 303 304@module yui 305@submodule yui-throttle 306*/ 307 308/*! Based on work by Simon Willison: http://gist.github.com/292562 */ 309/** 310 * Throttles a call to a method based on the time between calls. 311 * @method throttle 312 * @for YUI 313 * @param fn {function} The function call to throttle. 314 * @param ms {Number} The number of milliseconds to throttle the method call. 315 * Can set globally with Y.config.throttleTime or by call. Passing a -1 will 316 * disable the throttle. Defaults to 150. 317 * @return {function} Returns a wrapped function that calls fn throttled. 318 * @since 3.1.0 319 */ 320Y.throttle = function(fn, ms) { 321 ms = (ms) ? ms : (Y.config.throttleTime || 150); 322 323 if (ms === -1) { 324 return function() { 325 fn.apply(this, arguments); 326 }; 327 } 328 329 var last = Y.Lang.now(); 330 331 return function() { 332 var now = Y.Lang.now(); 333 if (now - last > ms) { 334 last = now; 335 fn.apply(this, arguments); 336 } 337 }; 338}; 339 340 341}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 342 343YUI.add('aui-base-core', function (A, NAME) { 344 345var Y = A; 346YUI.Env.aliases = YUI.Env.aliases || {}; 347Y.mix(YUI.Env.aliases, { 348 "aui-autosize": ["aui-autosize-iframe"], 349 "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"], 350 "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"], 351 "aui-button": ["aui-button-core"], 352 "aui-collection": ["aui-map","aui-set","aui-linkedset"], 353 "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"], 354 "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"], 355 "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"], 356 "aui-datatable-edit": ["datatable-base","calendar","overlay","sortable","aui-datatype","aui-toolbar","aui-form-validator","aui-datatable-base-cell-editor","aui-datatable-base-options-cell-editor","aui-datatable-cell-editor-support","aui-datatable-core","aui-datatable-checkbox-cell-editor","aui-datatable-date-cell-editor","aui-datatable-dropdown-cell-editor","aui-datatable-radio-cell-editor","aui-datatable-text-cell-editor","aui-datatable-text-area-cell-editor"], 357 "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"], 358 "aui-event": ["aui-event-base"], 359 "aui-form-deprecated": ["aui-form-base-deprecated","aui-form-combobox-deprecated","aui-form-field-deprecated","aui-form-select-deprecated","aui-form-textarea-deprecated","aui-form-textfield-deprecated"], 360 "aui-io": ["aui-io-request"], 361 "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"], 362 "aui-node": ["aui-node-base"], 363 "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"], 364 "aui-rating": ["aui-rating-base","aui-rating-thumb"], 365 "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"], 366 "aui-scheduler": ["event-gestures","aui-scheduler-base","aui-scheduler-event-recorder","aui-scheduler-view-agenda","aui-scheduler-view-day","aui-scheduler-view-month","aui-scheduler-view-table-dd","aui-scheduler-view-table","aui-scheduler-view-week","aui-viewport"], 367 "aui-search": ["aui-search-tst"], 368 "aui-sortable": ["aui-sortable-layout","aui-sortable-list"], 369 "aui-surface": ["aui-surface-app","aui-surface-screen"], 370 "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"], 371 "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"], 372 "aui-tpl-snippets-deprecated": ["aui-tpl-snippets-base-deprecated","aui-tpl-snippets-checkbox-deprecated","aui-tpl-snippets-input-deprecated","aui-tpl-snippets-select-deprecated","aui-tpl-snippets-textarea-deprecated"], 373 "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"], 374 "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"], 375 "aui-widget-core": ["aui-widget-cssclass"] 376}); 377/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */ 378 379/*jshint maxlen:900, eqeqeq: false */ 380 381/** 382 * YUI 3 module metadata 383 * @module loader 384 * @submodule loader-yui3 385 */ 386YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; 387Y.mix(YUI.Env[Y.version].modules, { 388 "aui-ace-autocomplete-base": { 389 "requires": [ 390 "aui-ace-editor" 391 ] 392 }, 393 "aui-ace-autocomplete-freemarker": { 394 "requires": [ 395 "aui-ace-autocomplete-templateprocessor" 396 ] 397 }, 398 "aui-ace-autocomplete-list": { 399 "requires": [ 400 "aui-ace-autocomplete-base", 401 "overlay", 402 "widget-autohide" 403 ], 404 "skinnable": true 405 }, 406 "aui-ace-autocomplete-plugin": { 407 "requires": [ 408 "aui-ace-autocomplete-list", 409 "plugin" 410 ] 411 }, 412 "aui-ace-autocomplete-templateprocessor": { 413 "requires": [ 414 "aui-ace-autocomplete-base" 415 ] 416 }, 417 "aui-ace-autocomplete-velocity": { 418 "requires": [ 419 "aui-ace-autocomplete-templateprocessor" 420 ] 421 }, 422 "aui-ace-editor": { 423 "requires": [ 424 "aui-node", 425 "aui-component" 426 ] 427 }, 428 "aui-affix": { 429 "requires": [ 430 "base", 431 "node-screen", 432 "aui-node" 433 ] 434 }, 435 "aui-alert": { 436 "requires": [ 437 "aui-aria", 438 "aui-classnamemanager", 439 "aui-widget-cssclass", 440 "aui-widget-transition", 441 "timers", 442 "widget", 443 "widget-stdmod" 444 ], 445 "skinnable": true 446 }, 447 "aui-aria": { 448 "requires": [ 449 "plugin", 450 "aui-component" 451 ] 452 }, 453 "aui-aria-table-sortable": { 454 "requires": [ 455 "aui-aria" 456 ] 457 }, 458 "aui-arraysort": { 459 "requires": [ 460 "arraysort" 461 ] 462 }, 463 "aui-audio": { 464 "requires": [ 465 "aui-aria", 466 "aui-node", 467 "aui-component", 468 "node-event-html5", 469 "querystring-stringify-simple" 470 ], 471 "skinnable": true 472 }, 473 "aui-autocomplete-deprecated": { 474 "requires": [ 475 "aui-base-deprecated", 476 "aui-overlay-base-deprecated", 477 "datasource", 478 "dataschema", 479 "aui-form-combobox-deprecated" 480 ], 481 "skinnable": true 482 }, 483 "aui-autosize": { 484 "use": [ 485 "aui-autosize-iframe" 486 ] 487 }, 488 "aui-autosize-deprecated": { 489 "requires": [ 490 "event-valuechange", 491 "plugin", 492 "aui-base-deprecated" 493 ], 494 "skinnable": true 495 }, 496 "aui-autosize-iframe": { 497 "requires": [ 498 "plugin", 499 "aui-component", 500 "aui-timer", 501 "aui-node-base" 502 ] 503 }, 504 "aui-base": { 505 "use": [ 506 "oop", 507 "yui-throttle", 508 "aui-classnamemanager", 509 "aui-debounce", 510 "aui-base-core", 511 "aui-base-lang", 512 "aui-node-base" 513 ] 514 }, 515 "aui-base-core": {}, 516 "aui-base-deprecated": { 517 "use": [ 518 "aui-base", 519 "aui-node", 520 "aui-component", 521 "aui-delayed-task-deprecated", 522 "aui-selector", 523 "aui-event-base" 524 ] 525 }, 526 "aui-base-html5-shiv": { 527 "condition": { 528 "name": "aui-base-html5-shiv", 529 "trigger": "node-base", 530 "ua": "ie" 531 } 532 }, 533 "aui-base-lang": {}, 534 "aui-boolean-data-editor": { 535 "requires": [ 536 "aui-button-switch", 537 "aui-data-editor" 538 ] 539 }, 540 "aui-button": { 541 "use": [ 542 "aui-button-core" 543 ] 544 }, 545 "aui-button-core": { 546 "requires": [ 547 "button", 548 "button-group", 549 "button-plugin", 550 "aui-component", 551 "aui-widget-cssclass", 552 "aui-widget-toggle" 553 ], 554 "skinnable": true 555 }, 556 "aui-button-item-deprecated": { 557 "requires": [ 558 "aui-base-deprecated", 559 "aui-state-interaction-deprecated", 560 "widget-child" 561 ], 562 "skinnable": true 563 }, 564 "aui-button-search-cancel": { 565 "requires": [ 566 "array-invoke", 567 "base", 568 "base-build", 569 "event-focus", 570 "event-move", 571 "event-resize", 572 "node-screen", 573 "node-event-delegate", 574 "aui-node-base", 575 "aui-classnamemanager", 576 "aui-event-input" 577 ] 578 }, 579 "aui-button-switch": { 580 "requires": [ 581 "aui-node-base", 582 "base-build", 583 "event-key", 584 "transition", 585 "widget" 586 ], 587 "skinnable": true 588 }, 589 "aui-carousel": { 590 "requires": [ 591 "anim", 592 "aui-event", 593 "aui-image-viewer-base", 594 "aui-image-viewer-slideshow", 595 "node-event-delegate", 596 "node-focusmanager" 597 ], 598 "skinnable": true 599 }, 600 "aui-carousel-mobile-touch": { 601 "condition": { 602 "name": "aui-carousel-mobile-touch", 603 "test": function(A) { 604 return A.UA.mobile && A.UA.touchEnabled; 605}, 606 "trigger": "aui-carousel" 607 }, 608 "requires": [ 609 "base-build", 610 "aui-carousel" 611 ] 612 }, 613 "aui-carousel-swipe": { 614 "condition": { 615 "name": "aui-carousel-swipe", 616 "trigger": "aui-carousel", 617 "ua": "touchEnabled" 618 }, 619 "requires": [ 620 "aui-carousel", 621 "aui-widget-swipe", 622 "base-build" 623 ], 624 "skinnable": true 625 },
626 "aui-char-counter": { 627 "requires": [ 628 "aui-aria", 629 "aui-node", 630 "aui-event-input", 631 "aui-component" 632 ] 633 }, 634 "aui-chart-deprecated": { 635 "requires": [ 636 "datasource", 637 "json", 638 "aui-swf-deprecated" 639 ] 640 }, 641 "aui-classnamemanager": { 642 "requires": [ 643 "classnamemanager" 644 ] 645 }, 646 "aui-collection": { 647 "use": [ 648 "aui-map", 649 "aui-set", 650 "aui-linkedset" 651 ] 652 }, 653 "aui-color-palette": { 654 "requires": [ 655 "array-extras", 656 "aui-palette", 657 "color-base", 658 "node-core", 659 "aui-widget-cssclass", 660 "aui-widget-toggle" 661 ], 662 "skinnable": true 663 }, 664 "aui-color-picker-base": { 665 "requires": [ 666 "aui-color-palette", 667 "aui-hsva-palette-modal", 668 "event-outside" 669 ], 670 "skinnable": true 671 }, 672 "aui-color-picker-base-deprecated": { 673 "requires": [ 674 "dd-drag", 675 "panel", 676 "slider", 677 "aui-button-item-deprecated", 678 "aui-color-util-deprecated", 679 "aui-form-base-deprecated", 680 "aui-overlay-context-deprecated" 681 ], 682 "skinnable": true 683 }, 684 "aui-color-picker-deprecated": { 685 "use": [ 686 "aui-color-picker-base-deprecated", 687 "aui-color-picker-grid-plugin-deprecated" 688 ] 689 }, 690 "aui-color-picker-grid-plugin-deprecated": { 691 "requires": [ 692 "plugin", 693 "aui-color-picker-base-deprecated" 694 ], 695 "skinnable": true 696 }, 697 "aui-color-picker-popover": { 698 "requires": [ 699 "aui-color-picker-base", 700 "aui-popover", 701 "aui-widget-cssclass", 702 "aui-widget-toggle" 703 ], 704 "skinnable": true 705 }, 706 "aui-color-util-deprecated": { 707 "requires": [] 708 }, 709 "aui-component": { 710 "requires": [ 711 "aui-classnamemanager", 712 "aui-widget-cssclass", 713 "aui-widget-toggle", 714 "base-build", 715 "widget-base" 716 ] 717 }, 718 "aui-css": { 719 "type": "css" 720 }, 721 "aui-data-editor": { 722 "requires": [ 723 "aui-classnamemanager", 724 "base-build", 725 "node-base" 726 ], 727 "skinnable": true 728 }, 729 "aui-data-set-deprecated": { 730 "requires": [ 731 "oop", 732 "collection", 733 "base" 734 ] 735 }, 736 "aui-datasource-control-base-deprecated": { 737 "requires": [ 738 "datasource", 739 "dataschema", 740 "aui-base-deprecated" 741 ] 742 }, 743 "aui-datasource-control-deprecated": { 744 "use": [ 745 "aui-datasource-control-base-deprecated", 746 "aui-input-text-control-deprecated" 747 ] 748 }, 749 "aui-datatable": { 750 "use": [ 751 "aui-datatable-edit", 752 "aui-datatable-highlight", 753 "aui-datatable-selection", 754 "aui-datatable-property-list" 755 ] 756 }, 757 "aui-datatable-base-cell-editor": { 758 "requires": [ 759 "datatable-base", 760 "overlay" 761 ], 762 "skinnable": true 763 }, 764 "aui-datatable-base-options-cell-editor": { 765 "requires": [ 766 "aui-datatable-base-cell-editor", 767 "escape" 768 ], 769 "skinnable": true 770 }, 771 "aui-datatable-body": { 772 "requires": [ 773 "aui-classnamemanager", 774 "datatable-base", 775 "event-key", 776 "aui-event-base" 777 ] 778 }, 779 "aui-datatable-cell-editor-support": { 780 "requires": [ 781 "datatable-base" 782 ] 783 }, 784 "aui-datatable-checkbox-cell-editor": { 785 "requires": [ 786 "aui-datatable-base-options-cell-editor" 787 ] 788 }, 789 "aui-datatable-core": { 790 "requires": [ 791 "aui-datatable-body", 792 "datatable-base", 793 "event-key", 794 "aui-event-base" 795 ], 796 "skinnable": true 797 }, 798 "aui-datatable-date-cell-editor": { 799 "requires": [ 800 "aui-datatable-base-options-cell-editor" 801 ] 802 }, 803 "aui-datatable-dropdown-cell-editor": { 804 "requires": [ 805 "aui-datatable-base-options-cell-editor" 806 ] 807 }, 808 "aui-datatable-edit": { 809 "use": [ 810 "datatable-base", 811 "calendar", 812 "overlay", 813 "sortable", 814 "aui-datatype", 815 "aui-toolbar", 816 "aui-form-validator", 817 "aui-datatable-base-cell-editor", 818 "aui-datatable-base-options-cell-editor", 819 "aui-datatable-cell-editor-support", 820 "aui-datatable-core", 821 "aui-datatable-checkbox-cell-editor", 822 "aui-datatable-date-cell-editor", 823 "aui-datatable-dropdown-cell-editor", 824 "aui-datatable-radio-cell-editor", 825 "aui-datatable-text-cell-editor", 826 "aui-datatable-text-area-cell-editor" 827 ] 828 }, 829 "aui-datatable-highlight": { 830 "requires": [ 831 "aui-datatable-selection" 832 ], 833 "skinnable": true 834 }, 835 "aui-datatable-property-list": { 836 "requires": [ 837 "datatable-scroll", 838 "datatable-sort", 839 "aui-datatable-core", 840 "aui-datatable-edit", 841 "aui-datatable-highlight", 842 "aui-datatable-selection", 843 "aui-widget-cssclass", 844 "aui-widget-toggle" 845 ], 846 "skinnable": true 847 }, 848 "aui-datatable-radio-cell-editor": { 849 "requires": [ 850 "aui-datatable-base-options-cell-editor" 851 ] 852 }, 853 "aui-datatable-selection": { 854 "requires": [ 855 "aui-datatable-core" 856 ], 857 "skinnable": true 858 }, 859 "aui-datatable-text-area-cell-editor": { 860 "requires": [ 861 "aui-datatable-base-options-cell-editor" 862 ] 863 }, 864 "aui-datatable-text-cell-editor": { 865 "requires": [ 866 "aui-datatable-base-options-cell-editor" 867 ] 868 }, 869 "aui-datatype": { 870 "requires": [ 871 "datatype", 872 "aui-datatype-date-parse" 873 ] 874 }, 875 "aui-datatype-date-parse": { 876 "requires": [ 877 "aui-base-lang", 878 "datatype-date-format", 879 "datatype-date-parse", 880 "intl" 881 ] 882 }, 883 "aui-datepicker": { 884 "requires": [ 885 "aui-aria", 886 "aui-datepicker-delegate", 887 "aui-datepicker-popover", 888 "base", 889 "base-build", 890 "calendar" 891 ], 892 "skinnable": true 893 }, 894 "aui-datepicker-base-deprecated": { 895 "requires": [ 896 "calendar", 897 "aui-datatype", 898 "aui-overlay-context-deprecated" 899 ], 900 "skinnable": true 901 }, 902 "aui-datepicker-delegate": { 903 "requires": [ 904 "aui-datatype-date-parse", 905 "aui-event-input", 906 "event-focus", 907 "node-event-delegate" 908 ] 909 }, 910 "aui-datepicker-deprecated": { 911 "skinnable": true, 912 "use": [ 913 "aui-datepicker-base-deprecated", 914 "aui-datepicker-select-deprecated" 915 ] 916 }, 917 "aui-datepicker-native": { 918 "requires": [ 919 "aui-datepicker-delegate", 920 "aui-node-base", 921 "base", 922 "base-build" 923 ] 924 }, 925 "aui-datepicker-popover": { 926 "requires": [ 927 "aui-classnamemanager", 928 "aui-popover" 929 ] 930 }, 931 "aui-datepicker-select-deprecated": { 932 "requires": [ 933 "aui-datepicker-base-deprecated", 934 "aui-button-item-deprecated" 935 ], 936 "skinnable": true 937 }, 938 "aui-debounce": {}, 939 "aui-delayed-task-deprecated": { 940 "requires": [ 941 "yui-base" 942 ] 943 }, 944 "aui-diagram-builder": { 945 "requires": [ 946 "aui-aria", 947 "aui-map", 948 "aui-property-builder",
949 "aui-diagram-builder-connector", 950 "aui-property-builder-settings", 951 "aui-diagram-node-condition", 952 "aui-diagram-node-end", 953 "aui-diagram-node-fork", 954 "aui-diagram-node-join", 955 "aui-diagram-node-start", 956 "aui-diagram-node-state", 957 "aui-diagram-node-task", 958 "overlay" 959 ], 960 "skinnable": true 961 }, 962 "aui-diagram-builder-connector": { 963 "requires": [ 964 "arraylist-add", 965 "arraylist-filter", 966 "escape", 967 "json", 968 "graphics", 969 "dd" 970 ], 971 "skinnable": true 972 }, 973 "aui-diagram-node": { 974 "requires": [ 975 "aui-aria", 976 "aui-diagram-node-manager-base", 977 "escape", 978 "overlay" 979 ] 980 }, 981 "aui-diagram-node-condition": { 982 "requires": [ 983 "aui-diagram-node-state" 984 ] 985 }, 986 "aui-diagram-node-end": { 987 "requires": [ 988 "aui-diagram-node-state" 989 ] 990 }, 991 "aui-diagram-node-fork": { 992 "requires": [ 993 "aui-diagram-node-state" 994 ] 995 }, 996 "aui-diagram-node-join": { 997 "requires": [ 998 "aui-diagram-node-state" 999 ] 1000 }, 1001 "aui-diagram-node-manager-base": { 1002 "requires": [ 1003 "base" 1004 ] 1005 }, 1006 "aui-diagram-node-start": { 1007 "requires": [ 1008 "aui-diagram-node-state" 1009 ] 1010 }, 1011 "aui-diagram-node-state": { 1012 "requires": [ 1013 "aui-diagram-node" 1014 ] 1015 }, 1016 "aui-diagram-node-task": { 1017 "requires": [ 1018 "aui-diagram-node-state" 1019 ] 1020 }, 1021 "aui-dialog-iframe-deprecated": { 1022 "requires": [ 1023 "plugin", 1024 "array-invoke", 1025 "aui-base-deprecated", 1026 "aui-loading-mask-deprecated" 1027 ], 1028 "skinnable": true 1029 }, 1030 "aui-dropdown": { 1031 "requires": [ 1032 "event-delegate", 1033 "event-key", 1034 "event-outside", 1035 "node-focusmanager", 1036 "widget", 1037 "widget-stack", 1038 "aui-classnamemanager", 1039 "aui-node", 1040 "aui-widget-cssclass", 1041 "aui-widget-toggle", 1042 "aui-widget-trigger" 1043 ], 1044 "skinnable": true 1045 }, 1046 "aui-editable-deprecated": { 1047 "requires": [ 1048 "aui-base-deprecated", 1049 "aui-form-combobox-deprecated", 1050 "escape", 1051 "event-resize" 1052 ], 1053 "skinnable": true 1054 }, 1055 "aui-event": { 1056 "use": [ 1057 "aui-event-base" 1058 ] 1059 }, 1060 "aui-event-base": { 1061 "requires": [ 1062 "event-base" 1063 ] 1064 }, 1065 "aui-event-delegate-change": { 1066 "condition": { 1067 "name": "aui-event-delegate-change", 1068 "trigger": "event-base-ie", 1069 "ua": "ie" 1070 }, 1071 "requires": [ 1072 "aui-event-base", 1073 "event-delegate", 1074 "event-synthetic" 1075 ] 1076 }, 1077 "aui-event-delegate-submit": { 1078 "condition": { 1079 "name": "aui-event-delegate-submit", 1080 "trigger": "event-base-ie", 1081 "ua": "ie" 1082 }, 1083 "requires": [ 1084 "aui-event-base", 1085 "event-delegate", 1086 "event-synthetic" 1087 ] 1088 }, 1089 "aui-event-input": { 1090 "condition": { 1091 "name": "aui-event-input", 1092 "test": function(A) { 1093 var supportsDOMEvent = A.supportsDOMEvent, 1094 testFeature = A.Features.test, 1095 addFeature = A.Features.add; 1096 1097 if (testFeature('event', 'input') === undefined) { 1098 addFeature('event', 'input', { 1099 test: function() { 1100 return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9); 1101 } 1102 }); 1103 } 1104 1105 return !testFeature('event', 'input'); 1106}, 1107 "trigger": "aui-event-base" 1108 }, 1109 "requires": [ 1110 "aui-event-base", 1111 "event-delegate", 1112 "event-synthetic", 1113 "timers" 1114 ] 1115 }, 1116 "aui-form-base-deprecated": { 1117 "requires": [ 1118 "io-form", 1119 "querystring-parse", 1120 "aui-base-deprecated", 1121 "aui-data-set-deprecated", 1122 "aui-form-field-deprecated" 1123 ] 1124 }, 1125 "aui-form-builder": { 1126 "requires": [ 1127 "aui-modal", 1128 "aui-layout",
1129 "aui-form-builder-field-list", 1130 "aui-form-builder-field-toolbar", 1131 "aui-form-builder-field-type", 1132 "aui-form-builder-field-types", 1133 "aui-form-builder-layout-builder", 1134 "aui-form-builder-page-manager", 1135 "aui-form-builder-settings-modal", 1136 "event-focus", 1137 "event-tap" 1138 ], 1139 "skinnable": true 1140 }, 1141 "aui-form-builder-available-field-deprecated": { 1142 "requires": [ 1143 "aui-property-builder-available-field" 1144 ] 1145 }, 1146 "aui-form-builder-deprecated": { 1147 "requires": [ 1148 "aui-button", 1149 "aui-collection", 1150 "aui-form-builder-available-field-deprecated", 1151 "aui-form-builder-field-deprecated", 1152 "aui-form-builder-field-button-deprecated", 1153 "aui-form-builder-field-checkbox-deprecated", 1154 "aui-form-builder-field-fieldset-deprecated", 1155 "aui-form-builder-field-file-upload-deprecated", 1156 "aui-form-builder-field-multiple-choice-deprecated", 1157 "aui-form-builder-field-radio-deprecated", 1158 "aui-form-builder-field-select-deprecated", 1159 "aui-form-builder-field-text-deprecated", 1160 "aui-form-builder-field-textarea-deprecated", 1161 "aui-property-builder", 1162 "aui-property-builder-settings", 1163 "aui-sortable-list", 1164 "aui-tabview", 1165 "aui-tooltip-base", 1166 "escape", 1167 "transition" 1168 ], 1169 "skinnable": true 1170 }, 1171 "aui-form-builder-field-base": { 1172 "requires": [ 1173 "aui-classnamemanager", 1174 "aui-node-base", 1175 "aui-text-data-editor", 1176 "aui-toggler", 1177 "base", 1178 "node-base" 1179 ], 1180 "skinnable": true 1181 }, 1182 "aui-form-builder-field-button-deprecated": { 1183 "requires": [ 1184 "aui-form-builder-field-deprecated" 1185 ] 1186 }, 1187 "aui-form-builder-field-checkbox-deprecated": { 1188 "requires": [ 1189 "aui-form-builder-field-deprecated" 1190 ] 1191 }, 1192 "aui-form-builder-field-choice": { 1193 "requires": [ 1194 "aui-boolean-data-editor", 1195 "aui-options-data-editor", 1196 "aui-tabs-data-editor", 1197 "aui-form-builder-field-base", 1198 "aui-form-field-choice" 1199 ] 1200 }, 1201 "aui-form-builder-field-deprecated": { 1202 "requires": [ 1203 "panel", 1204 "aui-datatype", 1205 "aui-datatable-edit", 1206 "aui-property-builder-field-support" 1207 ], 1208 "skinnable": true 1209 }, 1210 "aui-form-builder-field-fieldset-deprecated": { 1211 "requires": [ 1212 "aui-form-builder-field-deprecated" 1213 ] 1214 }, 1215 "aui-form-builder-field-file-upload-deprecated": { 1216 "requires": [ 1217 "aui-form-builder-field-deprecated" 1218 ] 1219 }, 1220 "aui-form-builder-field-list": { 1221 "requires": [ 1222 "aui-form-builder-field-type", 1223 "aui-form-builder-field-types", 1224 "aui-form-builder-layout-builder" 1225 ], 1226 "skinnable": true 1227 }, 1228 "aui-form-builder-field-multiple-choice-deprecated": { 1229 "requires": [ 1230 "aui-form-builder-field-deprecated" 1231 ] 1232 }, 1233 "aui-form-builder-field-radio-deprecated": { 1234 "requires": [ 1235 "aui-form-builder-field-deprecated" 1236 ] 1237 }, 1238 "aui-form-builder-field-select-deprecated": { 1239 "requires": [ 1240 "aui-form-builder-field-deprecated" 1241 ] 1242 }, 1243 "aui-form-builder-field-sentence": { 1244 "requires": [ 1245 "aui-form-builder-field-base", 1246 "aui-form-field" 1247 ] 1248 }, 1249 "aui-form-builder-field-text": { 1250 "requires": [ 1251 "aui-boolean-data-editor", 1252 "aui-radio-group-data-editor", 1253 "aui-form-builder-field-base", 1254 "aui-form-field-text" 1255 ] 1256 }, 1257 "aui-form-builder-field-text-deprecated": { 1258 "requires": [ 1259 "aui-form-builder-field-deprecated" 1260 ] 1261 },
1262 "aui-form-builder-field-textarea-deprecated": { 1263 "requires": [ 1264 "aui-form-builder-field-deprecated" 1265 ] 1266 }, 1267 "aui-form-builder-field-toolbar": { 1268 "requires": [ 1269 "aui-classnamemanager", 1270 "base", 1271 "node-base" 1272 ], 1273 "skinnable": true 1274 }, 1275 "aui-form-builder-field-type": { 1276 "requires": [ 1277 "base", 1278 "node-base" 1279 ], 1280 "skinnable": true 1281 }, 1282 "aui-form-builder-field-types": { 1283 "requires": [ 1284 "aui-classnamemanager", 1285 "aui-form-builder-field-types-modal", 1286 "base", 1287 "node-base" 1288 ], 1289 "skinnable": true 1290 }, 1291 "aui-form-builder-field-types-modal": { 1292 "requires": [ 1293 "aui-modal" 1294 ], 1295 "skinnable": true 1296 }, 1297 "aui-form-builder-layout-builder": { 1298 "requires": [ 1299 "aui-classnamemanager", 1300 "aui-layout-builder", 1301 "aui-modal", 1302 "base", 1303 "node-base" 1304 ], 1305 "skinnable": true 1306 }, 1307 "aui-form-builder-page-manager": { 1308 "requires": [ 1309 "aui-pagination", 1310 "aui-popover", 1311 "aui-tabview", 1312 "base", 1313 "event-valuechange", 1314 "node-base" 1315 ], 1316 "skinnable": true 1317 }, 1318 "aui-form-builder-settings-modal": { 1319 "requires": [ 1320 "aui-classnamemanager", 1321 "aui-modal", 1322 "base", 1323 "node-base" 1324 ], 1325 "skinnable": true 1326 }, 1327 "aui-form-combobox-deprecated": { 1328 "requires": [ 1329 "aui-form-textarea-deprecated", 1330 "aui-toolbar" 1331 ], 1332 "skinnable": true 1333 }, 1334 "aui-form-deprecated": { 1335 "use": [ 1336 "aui-form-base-deprecated", 1337 "aui-form-combobox-deprecated", 1338 "aui-form-field-deprecated", 1339 "aui-form-select-deprecated", 1340 "aui-form-textarea-deprecated", 1341 "aui-form-textfield-deprecated" 1342 ] 1343 }, 1344 "aui-form-field": { 1345 "requires": [ 1346 "aui-classnamemanager", 1347 "aui-node-base", 1348 "base-build" 1349 ], 1350 "skinnable": true 1351 }, 1352 "aui-form-field-choice": { 1353 "requires": [ 1354 "aui-form-field-required" 1355 ], 1356 "skinnable": true 1357 }, 1358 "aui-form-field-deprecated": { 1359 "requires": [ 1360 "aui-base-deprecated", 1361 "aui-component" 1362 ] 1363 }, 1364 "aui-form-field-required": { 1365 "requires": [ 1366 "aui-form-field" 1367 ] 1368 }, 1369 "aui-form-field-text": { 1370 "requires": [ 1371 "aui-form-field-required" 1372 ], 1373 "skinnable": true 1374 }, 1375 "aui-form-select-deprecated": { 1376 "requires": [ 1377 "aui-form-field-deprecated" 1378 ] 1379 }, 1380 "aui-form-textarea-deprecated": { 1381 "requires": [ 1382 "node-pluginhost", 1383 "aui-autosize-deprecated", 1384 "aui-form-textfield-deprecated" 1385 ] 1386 }, 1387 "aui-form-textfield-deprecated": { 1388 "requires": [ 1389 "aui-form-field-deprecated" 1390 ] 1391 }, 1392 "aui-form-validator": { 1393 "requires": [ 1394 "escape", 1395 "selector-css3", 1396 "node-event-delegate", 1397 "aui-node", 1398 "aui-component", 1399 "aui-event-input" 1400 ] 1401 }, 1402 "aui-hsv-palette": { 1403 "requires": [ 1404 "aui-classnamemanager", 1405 "aui-widget-cssclass", 1406 "aui-widget-toggle", 1407 "aui-event-input", 1408 "base-build", 1409 "clickable-rail", 1410 "color-hsv", 1411 "dd-constrain", 1412 "slider", 1413 "widget" 1414 ], 1415 "skinnable": true 1416 }, 1417 "aui-hsva-palette": { 1418 "requires": [ 1419 "aui-hsv-palette" 1420 ], 1421 "skinnable": true 1422 }, 1423 "aui-hsva-palette-modal": { 1424 "requires": [ 1425 "aui-hsva-palette", 1426 "aui-modal" 1427 ], 1428 "skinnable": true 1429 }, 1430 "aui-image-cropper": { 1431 "requires": [ 1432 "resize-base", 1433 "resize-constrain", 1434 "dd-constrain", 1435 "aui-node-base", 1436 "aui-component" 1437 ], 1438 "skinnable": true 1439 }, 1440 "aui-image-viewer": { 1441 "requires": [ 1442 "widget", 1443 "widget-modality", 1444 "widget-position", 1445 "widget-position-align", 1446 "widget-position-constrain", 1447 "widget-stack", 1448 "widget-stdmod", 1449 "aui-event", 1450 "aui-image-viewer-base", 1451 "aui-image-viewer-multiple", 1452 "aui-image-viewer-slideshow", 1453 "aui-node-base", 1454 "aui-widget-cssclass", 1455 "aui-widget-toggle" 1456 ], 1457 "skinnable": true 1458 }, 1459 "aui-image-viewer-base": { 1460 "requires": [ 1461 "anim", 1462 "aui-aria", 1463 "aui-classnamemanager", 1464 "aui-node", 1465 "aui-widget-responsive", 1466 "base-build", 1467 "imageloader", 1468 "node-base", 1469 "widget", 1470 "widget-stack" 1471 ], 1472 "skinnable": true 1473 }, 1474 "aui-image-viewer-media": { 1475 "requires": [ 1476 "plugin", 1477 "aui-component", 1478 "aui-image-viewer" 1479 ] 1480 }, 1481 "aui-image-viewer-multiple": { 1482 "requires": [ 1483 "base-build", 1484 "node-base", 1485 "aui-classnamemanager", 1486 "aui-image-viewer-base" 1487 ], 1488 "skinnable": true 1489 }, 1490 "aui-image-viewer-multiple-swipe": { 1491 "condition": { 1492 "name": "aui-image-viewer-multiple-swipe", 1493 "trigger": "aui-image-viewer-multiple", 1494 "ua": "touchEnabled" 1495 }, 1496 "requires": [ 1497 "aui-image-viewer-multiple",
1498 "aui-image-viewer-swipe" 1499 ] 1500 }, 1501 "aui-image-viewer-slideshow": { 1502 "requires": [ 1503 "node", 1504 "aui-classnamemanager" 1505 ] 1506 }, 1507 "aui-image-viewer-swipe": { 1508 "condition": { 1509 "name": "aui-image-viewer-swipe", 1510 "trigger": "aui-image-viewer-base", 1511 "ua": "touchEnabled" 1512 }, 1513 "requires": [ 1514 "event-resize", 1515 "aui-image-viewer-base", 1516 "aui-widget-swipe" 1517 ] 1518 }, 1519 "aui-input-text-control-deprecated": { 1520 "requires": [ 1521 "aui-base-deprecated", 1522 "aui-datasource-control-base-deprecated", 1523 "aui-form-combobox-deprecated" 1524 ] 1525 }, 1526 "aui-io": { 1527 "use": [ 1528 "aui-io-request" 1529 ] 1530 }, 1531 "aui-io-deprecated": { 1532 "use": [ 1533 "aui-io-request", 1534 "aui-io-plugin-deprecated" 1535 ] 1536 }, 1537 "aui-io-plugin-deprecated": { 1538 "requires": [ 1539 "aui-overlay-base-deprecated", 1540 "aui-parse-content", 1541 "aui-io-request", 1542 "aui-loading-mask-deprecated" 1543 ] 1544 }, 1545 "aui-io-request": { 1546 "requires": [ 1547 "io-base", 1548 "json", 1549 "plugin", 1550 "querystring-stringify", 1551 "aui-component" 1552 ] 1553 }, 1554 "aui-io-request-deprecated": { 1555 "requires": [ 1556 "io-base", 1557 "json", 1558 "plugin", 1559 "querystring-stringify", 1560 "aui-base-deprecated" 1561 ] 1562 }, 1563 "aui-layout": { 1564 "requires": [ 1565 "aui-layout-col", 1566 "aui-layout-row", 1567 "aui-node-base", 1568 "base-build", 1569 "datatype-number-parse", 1570 "event-resize" 1571 ] 1572 }, 1573 "aui-layout-builder": { 1574 "requires": [ 1575 "aui-classnamemanager", 1576 "aui-layout", 1577 "aui-layout-builder-add-col", 1578 "aui-layout-builder-add-row", 1579 "aui-layout-builder-move", 1580 "aui-layout-builder-remove-row", 1581 "aui-layout-builder-resize-col", 1582 "aui-node-base", 1583 "base-build", 1584 "node-event-delegate", 1585 "node-screen", 1586 "node-style" 1587 ] 1588 }, 1589 "aui-layout-builder-add-col": { 1590 "requires": [ 1591 "event-key", 1592 "node-base" 1593 ], 1594 "skinnable": true 1595 }, 1596 "aui-layout-builder-add-row": { 1597 "requires": [ 1598 "aui-node-base", 1599 "base-build", 1600 "node-scroll-info" 1601 ], 1602 "skinnable": true 1603 }, 1604 "aui-layout-builder-move": { 1605 "requires": [ 1606 "aui-node-base", 1607 "base-build" 1608 ], 1609 "skinnable": true 1610 }, 1611 "aui-layout-builder-remove-row": { 1612 "requires": [ 1613 "aui-node-base", 1614 "base-build" 1615 ], 1616 "skinnable": true 1617 }, 1618 "aui-layout-builder-resize-col": { 1619 "requires": [ 1620 "dd-constrain", 1621 "dd-delegate", 1622 "dd-drop-plugin", 1623 "dd-proxy", 1624 "event-mouseenter", 1625 "node-base" 1626 ], 1627 "skinnable": true 1628 }, 1629 "aui-layout-col": { 1630 "requires": [ 1631 "aui-classnamemanager", 1632 "aui-node-base", 1633 "base-build" 1634 ], 1635 "skinnable": true 1636 }, 1637 "aui-layout-row": { 1638 "requires": [ 1639 "array-invoke", 1640 "aui-node-base", 1641 "base-build" 1642 ], 1643 "skinnable": true 1644 }, 1645 "aui-linkedset": { 1646 "requires": [ 1647 "aui-set" 1648 ] 1649 }, 1650 "aui-live-search-deprecated": { 1651 "requires": [ 1652 "aui-base-deprecated" 1653 ] 1654 }, 1655 "aui-loading-mask-deprecated": { 1656 "requires": [ 1657 "plugin", 1658 "aui-overlay-mask-deprecated" 1659 ], 1660 "skinnable": true 1661 }, 1662 "aui-map": { 1663 "requires": [ 1664 "base-build" 1665 ] 1666 }, 1667 "aui-menu": { 1668 "requires": [ 1669 "base-build", 1670 "event-mouseenter", 1671 "event-resize", 1672 "widget", 1673 "widget-position", 1674 "widget-position-align", 1675 "widget-position-constrain", 1676 "widget-stack", 1677 "aui-classnamemanager", 1678 "aui-debounce", 1679 "aui-dropdown", 1680 "aui-menu-item" 1681 ], 1682 "skinnable": true 1683 }, 1684 "aui-menu-item": { 1685 "requires": [ 1686 "base-build", 1687 "node-base", 1688 "aui-classnamemanager", 1689 "aui-node", 1690 "aui-widget-shortcut" 1691 ] 1692 }, 1693 "aui-messaging": { 1694 "requires": [ 1695 "querystring", 1696 "aui-timer" 1697 ] 1698 }, 1699 "aui-modal": { 1700 "requires": [ 1701 "widget", 1702 "widget-autohide", 1703 "widget-buttons", 1704 "widget-modality", 1705 "widget-position", 1706 "widget-position-align", 1707 "widget-position-constrain", 1708 "widget-stack", 1709 "widget-stdmod", 1710 "dd-plugin", 1711 "dd-constrain", 1712 "timers", 1713 "aui-classnamemanager", 1714 "aui-widget-cssclass", 1715 "aui-widget-toggle", 1716 "aui-widget-toolbars" 1717 ], 1718 "skinnable": true 1719 }, 1720 "aui-modal-resize": { 1721 "condition": { 1722 "name": "aui-modal-resize", 1723 "test": function(A) { 1724 return !A.UA.mobile; 1725}, 1726 "trigger": "aui-modal" 1727 }, 1728 "requires": [ 1729 "aui-modal", 1730 "resize-plugin" 1731 ] 1732 }, 1733 "aui-node": { 1734 "use": [ 1735 "aui-node-base" 1736 ] 1737 }, 1738 "aui-node-accessible": { 1739 "requires": [ 1740 "aui-node-base", 1741 "event-custom-base" 1742 ] 1743 }, 1744 "aui-node-base": { 1745 "requires": [ 1746 "array-extras", 1747 "aui-base-lang", 1748 "aui-classnamemanager", 1749 "aui-debounce", 1750 "node" 1751 ] 1752 }, 1753 "aui-node-html5": { 1754 "condition": { 1755 "name": "aui-node-html5", 1756 "trigger": "aui-node", 1757 "ua": "ie" 1758 }, 1759 "requires": [ 1760 "collection", 1761 "aui-node-base" 1762 ] 1763 }, 1764 "aui-options-data-editor": { 1765 "requires": [ 1766 "aui-data-editor", 1767 "dd-constrain", 1768 "dd-delegate", 1769 "dd-drop-plugin", 1770 "dd-proxy", 1771 "event-valuechange", 1772 "node-event-delegate" 1773 ], 1774 "skinnable": true 1775 }, 1776 "aui-overlay-base-deprecated": { 1777 "requires": [ 1778 "widget-position", 1779 "widget-stack", 1780 "widget-position-align", 1781 "widget-position-constrain", 1782 "widget-stdmod", 1783 "aui-component" 1784 ] 1785 }, 1786 "aui-overlay-context-deprecated": { 1787 "requires": [ 1788 "aui-overlay-manager-deprecated", 1789 "aui-delayed-task-deprecated", 1790 "aui-aria" 1791 ] 1792 }, 1793 "aui-overlay-context-panel-deprecated": { 1794 "requires": [ 1795 "anim", 1796 "aui-overlay-context-deprecated" 1797 ], 1798 "skinnable": true 1799 }, 1800 "aui-overlay-deprecated": { 1801 "use": [ 1802 "aui-overlay-base-deprecated", 1803 "aui-overlay-context-deprecated", 1804 "aui-overlay-context-panel-deprecated", 1805 "aui-overlay-manager-deprecated", 1806 "aui-overlay-mask-deprecated" 1807 ] 1808 }, 1809 "aui-overlay-manager-deprecated": { 1810 "requires": [ 1811 "overlay", 1812 "plugin", 1813 "aui-base-deprecated", 1814 "aui-overlay-base-deprecated" 1815 ] 1816 }, 1817 "aui-overlay-mask-deprecated": { 1818 "requires": [ 1819 "event-resize", 1820 "aui-base-deprecated", 1821 "aui-overlay-base-deprecated" 1822 ], 1823 "skinnable": true 1824 }, 1825 "aui-pagination": { 1826 "requires": [ 1827 "node-event-delegate", 1828 "aui-node", 1829 "aui-component", 1830 "widget-htmlparser" 1831 ], 1832 "skinnable": true 1833 }, 1834 "aui-palette": { 1835 "requires": [ 1836 "base-build", 1837 "event-hover", 1838 "widget", 1839 "aui-classnamemanager", 1840 "aui-base", 1841 "aui-widget-cssclass", 1842 "aui-widget-toggle" 1843 ], 1844 "skinnable": true 1845 }, 1846 "aui-parse-content": { 1847 "requires": [ 1848 "async-queue", 1849 "plugin", 1850 "io-base", 1851 "aui-component", 1852 "aui-node-base" 1853 ] 1854 }, 1855 "aui-popover": { 1856 "requires": [ 1857 "event-resize", 1858 "widget", 1859 "widget-autohide", 1860 "widget-buttons", 1861 "widget-modality", 1862 "widget-position", 1863 "widget-position-align", 1864 "widget-position-constrain", 1865 "widget-stack", 1866 "widget-stdmod", 1867 "aui-classnamemanager", 1868 "aui-widget-cssclass", 1869 "aui-widget-toggle", 1870 "aui-widget-toolbars", 1871 "aui-widget-transition", 1872 "aui-widget-trigger", 1873 "aui-widget-position-align-suggestion", 1874 "aui-component", 1875 "aui-node-base" 1876 ], 1877 "skinnable": true 1878 }, 1879 "aui-progressbar": { 1880 "requires": [ 1881 "aui-node", 1882 "aui-component", 1883 "aui-aria" 1884 ], 1885 "skinnable": true 1886 }, 1887 "aui-promise": { 1888 "requires": [ 1889 "array-invoke", 1890 "promise", 1891 "oop" 1892 ] 1893 }, 1894 "aui-property-builder": { 1895 "requires": [ 1896 "dd", 1897 "collection", 1898 "aui-property-builder-available-field", 1899 "aui-property-builder-field-support", 1900 "aui-property-builder-settings", 1901 "aui-tabview" 1902 ], 1903 "skinnable": true 1904 }, 1905 "aui-property-builder-available-field": { 1906 "requires": [ 1907 "base", 1908 "aui-component", 1909 "aui-node" 1910 ] 1911 }, 1912 "aui-property-builder-field-support": {}, 1913 "aui-property-builder-settings": { 1914 "requires": [ 1915 "aui-tabview", 1916 "aui-datatable-property-list" 1917 ] 1918 }, 1919 "aui-radio-group-data-editor": { 1920 "requires": [ 1921 "aui-data-editor", 1922 "node-event-delegate" 1923 ], 1924 "skinnable": true 1925 }, 1926 "aui-rating": { 1927 "use": [ 1928 "aui-rating-base", 1929 "aui-rating-thumb" 1930 ] 1931 }, 1932 "aui-rating-base": { 1933 "requires": [ 1934 "aui-component", 1935 "aui-node-base", 1936 "widget-htmlparser", 1937 "widget-uievents" 1938 ], 1939 "skinnable": true 1940 }, 1941 "aui-rating-thumb": { 1942 "requires": [ 1943 "aui-rating-base" 1944 ] 1945 }, 1946 "aui-resize-base-deprecated": { 1947 "requires": [ 1948 "dd-drag", 1949 "dd-delegate", 1950 "dd-drop", 1951 "aui-base-deprecated" 1952 ], 1953 "skinnable": true 1954 }, 1955 "aui-resize-constrain-deprecated": { 1956 "requires": [ 1957 "dd-constrain", 1958 "plugin", 1959 "aui-resize-base-deprecated" 1960 ] 1961 }, 1962 "aui-resize-deprecated": { 1963 "skinnable": true, 1964 "use": [ 1965 "aui-resize-base-deprecated", 1966 "aui-resize-constrain-deprecated" 1967 ] 1968 }, 1969 "aui-scale-data-editor": { 1970 "requires": [ 1971 "aui-classnamemanager", 1972 "aui-data-editor", 1973 "event-valuechange" 1974 ] 1975 }, 1976 "aui-scheduler": { 1977 "use": [ 1978 "event-gestures", 1979 "aui-scheduler-base", 1980 "aui-scheduler-event-recorder", 1981 "aui-scheduler-view-agenda", 1982 "aui-scheduler-view-day", 1983 "aui-scheduler-view-month", 1984 "aui-scheduler-view-table-dd", 1985 "aui-scheduler-view-table", 1986 "aui-scheduler-view-week", 1987 "aui-viewport" 1988 ] 1989 }, 1990 "aui-scheduler-base": { 1991 "requires": [ 1992 "model", 1993 "model-list", 1994 "widget-stdmod", 1995 "color-hsl", 1996 "aui-event-base", 1997 "aui-node-base", 1998 "aui-component", 1999 "aui-datatype", 2000 "aui-button", 2001 "node-focusmanager" 2002 ], 2003 "skinnable": true 2004 }, 2005 "aui-scheduler-event-recorder": { 2006 "requires": [ 2007 "querystring", 2008 "io-form", 2009 "overlay", 2010 "aui-scheduler-base", 2011 "aui-popover" 2012 ], 2013 "skinnable": true 2014 }, 2015 "aui-scheduler-touch": { 2016 "condition": { 2017 "name": "aui-scheduler-touch", 2018 "trigger": "aui-scheduler", 2019 "ua": "touchEnabled" 2020 }, 2021 "requires": [ 2022 "base-build", 2023 "aui-scheduler" 2024 ], 2025 "skinnable": true 2026 }, 2027 "aui-scheduler-view-agenda": { 2028 "requires": [ 2029 "aui-scheduler-base" 2030 ], 2031 "skinnable": true 2032 }, 2033 "aui-scheduler-view-day": { 2034 "requires": [ 2035 "dd-drag", 2036 "dd-delegate", 2037 "dd-drop", 2038 "dd-constrain", 2039 "aui-scheduler-view-table" 2040 ], 2041 "skinnable": true 2042 }, 2043 "aui-scheduler-view-month": { 2044 "requires": [ 2045 "aui-scheduler-view-table" 2046 ], 2047 "skinnable": true 2048 }, 2049 "aui-scheduler-view-table": { 2050 "requires": [ 2051 "overlay", 2052 "aui-scheduler-base" 2053 ], 2054 "skinnable": true 2055 }, 2056 "aui-scheduler-view-table-dd": { 2057 "requires": [ 2058 "dd-drag", 2059 "dd-delegate", 2060 "dd-drop", 2061 "aui-scheduler-view-table" 2062 ] 2063 }, 2064 "aui-scheduler-view-week": { 2065 "requires": [ 2066 "aui-scheduler-view-day" 2067 ], 2068 "skinnable": true 2069 }, 2070 "aui-scroller-deprecated": { 2071 "requires": [ 2072 "event-mouseenter", 2073 "aui-base-deprecated", 2074 "aui-simple-anim-deprecated" 2075 ], 2076 "skinnable": true 2077 }, 2078 "aui-scrollspy": { 2079 "requires": [ 2080 "base-build", 2081 "node-screen", 2082 "aui-classnamemanager" 2083 ] 2084 }, 2085 "aui-search": { 2086 "use": [ 2087 "aui-search-tst" 2088 ] 2089 }, 2090 "aui-search-tst": { 2091 "requires": [ 2092 "aui-component" 2093 ] 2094 }, 2095 "aui-selector": { 2096 "requires": [ 2097 "selector-css3", 2098 "aui-classnamemanager" 2099 ] 2100 }, 2101 "aui-set": { 2102 "requires": [ 2103 "aui-map" 2104 ] 2105 }, 2106 "aui-simple-anim-deprecated": { 2107 "requires": [ 2108 "aui-base-deprecated" 2109 ] 2110 }, 2111 "aui-skin-deprecated": { 2112 "type": "css" 2113 }, 2114 "aui-sortable": { 2115 "use": [ 2116 "aui-sortable-layout", 2117 "aui-sortable-list" 2118 ] 2119 }, 2120 "aui-sortable-layout": { 2121 "requires": [ 2122 "dd-delegate", 2123 "dd-drag", 2124 "dd-drop", 2125 "dd-proxy", 2126 "aui-node", 2127 "aui-component" 2128 ], 2129 "skinnable": true 2130 }, 2131 "aui-sortable-list": { 2132 "requires": [ 2133 "dd-drag", 2134 "dd-drop", 2135 "dd-proxy", 2136 "dd-scroll", 2137 "aui-node", 2138 "aui-component" 2139 ] 2140 }, 2141 "aui-state-interaction-deprecated": { 2142 "requires": [ 2143 "aui-base-deprecated", 2144 "plugin" 2145 ] 2146 }, 2147 "aui-surface": { 2148 "use": [ 2149 "aui-surface-app", 2150 "aui-surface-screen" 2151 ] 2152 }, 2153 "aui-surface-app": { 2154 "requires": [ 2155 "event-delegate", 2156 "node-event-html5", 2157 "aui-surface-base", 2158 "aui-surface-screen", 2159 "aui-surface-screen-route" 2160 ] 2161 }, 2162 "aui-surface-base": { 2163 "requires": [ 2164 "base-build", 2165 "node-style", 2166 "timers", 2167 "aui-debounce", 2168 "aui-promise", 2169 "aui-parse-content" 2170 ] 2171 }, 2172 "aui-surface-screen": { 2173 "requires": [ 2174 "base-build" 2175 ] 2176 }, 2177 "aui-surface-screen-html": { 2178 "requires": [ 2179 "aui-base", 2180 "aui-io-request", 2181 "aui-promise", 2182
2182 "aui-surface-screen", 2183 "aui-url" 2184 ] 2185 }, 2186 "aui-surface-screen-route": { 2187 "requires": [ 2188 "base-build" 2189 ] 2190 }, 2191 "aui-swf-deprecated": { 2192 "requires": [ 2193 "querystring-parse-simple", 2194 "querystring-stringify-simple", 2195 "aui-base-deprecated" 2196 ] 2197 }, 2198 "aui-tabs-data-editor": { 2199 "requires": [ 2200 "aui-data-editor", 2201 "aui-tabview" 2202 ] 2203 }, 2204 "aui-tabview": { 2205 "requires": [ 2206 "selector-css3", 2207 "tabview", 2208 "aui-component", 2209 "aui-widget-css" 2210 ], 2211 "skinnable": true 2212 }, 2213 "aui-template-deprecated": { 2214 "requires": [ 2215 "aui-base-deprecated" 2216 ] 2217 }, 2218 "aui-text-data-editor": { 2219 "requires": [ 2220 "aui-data-editor", 2221 "event-valuechange" 2222 ], 2223 "skinnable": true 2224 }, 2225 "aui-text-data-unicode": { 2226 "requires": [ 2227 "text" 2228 ] 2229 }, 2230 "aui-text-unicode": { 2231 "requires": [ 2232 "aui-text-data-unicode" 2233 ] 2234 }, 2235 "aui-textboxlist-deprecated": { 2236 "requires": [ 2237 "anim-node-plugin", 2238 "aui-autocomplete-deprecated", 2239 "aui-button-item-deprecated", 2240 "aui-data-set-deprecated", 2241 "escape", 2242 "node-focusmanager" 2243 ], 2244 "skinnable": true 2245 }, 2246 "aui-timepicker": { 2247 "requires": [ 2248 "autocomplete", 2249 "aui-datepicker-delegate", 2250 "aui-datepicker-popover" 2251 ], 2252 "skinnable": true 2253 }, 2254 "aui-timepicker-native": { 2255 "requires": [ 2256 "base", 2257 "base-build", 2258 "aui-node-base", 2259 "aui-datepicker-delegate", 2260 "aui-datepicker-native" 2261 ] 2262 }, 2263 "aui-timer": { 2264 "requires": [ 2265 "oop" 2266 ] 2267 }, 2268 "aui-toggler": { 2269 "use": [ 2270 "aui-toggler-base", 2271 "aui-toggler-delegate" 2272 ] 2273 }, 2274 "aui-toggler-accessibility": { 2275 "requires": [ 2276 "aui-toggler-base" 2277 ] 2278 }, 2279 "aui-toggler-base": { 2280 "requires": [ 2281 "transition", 2282 "aui-selector", 2283 "aui-event-base", 2284 "aui-node", 2285 "aui-component", 2286 "event-tap" 2287 ], 2288 "skinnable": true 2289 }, 2290 "aui-toggler-delegate": { 2291 "requires": [ 2292 "array-invoke", 2293 "node-event-delegate", 2294 "aui-toggler-base" 2295 ] 2296 }, 2297 "aui-toolbar": { 2298 "requires": [ 2299 "arraylist", 2300 "arraylist-add", 2301 "aui-component", 2302 "aui-button-core" 2303 ] 2304 }, 2305 "aui-tooltip": { 2306 "use": [ 2307 "aui-tooltip-base", 2308 "aui-tooltip-delegate" 2309 ] 2310 }, 2311 "aui-tooltip-base": { 2312 "requires": [ 2313 "aui-aria", 2314 "aui-classnamemanager", 2315 "aui-component", 2316 "aui-debounce", 2317 "aui-node-base", 2318 "aui-widget-cssclass", 2319 "aui-widget-toggle", 2320 "aui-widget-transition", 2321 "aui-widget-trigger", 2322 "aui-widget-position-align-suggestion", 2323 "event-hover", 2324 "event-resize", 2325 "escape", 2326 "widget", 2327 "widget-autohide", 2328 "widget-position", 2329 "widget-position-align", 2330 "widget-position-constrain", 2331 "widget-stack", 2332 "widget-stdmod" 2333 ], 2334 "skinnable": true 2335 }, 2336 "aui-tooltip-delegate": { 2337 "requires": [ 2338 "aui-tooltip-base", 2339 "node-event-delegate" 2340 ] 2341 }, 2342 "aui-tooltip-deprecated": { 2343 "requires": [ 2344 "aui-overlay-context-panel-deprecated" 2345 ], 2346 "skinnable": true 2347 }, 2348 "aui-tpl-snippets-base-deprecated": { 2349 "requires": [ 2350 "aui-template-deprecated" 2351 ] 2352 }, 2353 "aui-tpl-snippets-checkbox-deprecated": { 2354 "requires": [ 2355 "aui-tpl-snippets-base-deprecated" 2356 ] 2357 }, 2358 "aui-tpl-snippets-deprecated": { 2359 "use": [ 2360 "aui-tpl-snippets-base-deprecated", 2361 "aui-tpl-snippets-checkbox-deprecated", 2362 "aui-tpl-snippets-input-deprecated", 2363 "aui-tpl-snippets-select-deprecated", 2364 "aui-tpl-snippets-textarea-deprecated" 2365 ] 2366 }, 2367 "aui-tpl-snippets-input-deprecated": { 2368 "requires": [ 2369 "aui-tpl-snippets-base-deprecated" 2370 ] 2371 }, 2372 "aui-tpl-snippets-select-deprecated": { 2373 "requires": [ 2374 "aui-tpl-snippets-base-deprecated" 2375 ] 2376 }, 2377 "aui-tpl-snippets-textarea-deprecated": { 2378 "requires": [ 2379 "aui-tpl-snippets-base-deprecated" 2380 ] 2381 }, 2382 "aui-tree": { 2383 "use": [ 2384 "aui-tree-data", 2385 "aui-tree-io", 2386 "aui-tree-node", 2387 "aui-tree-paginator", 2388 "aui-tree-view" 2389 ] 2390 }, 2391 "aui-tree-data": { 2392 "requires": [ 2393 "aui-base-core", 2394 "aui-base-lang", 2395 "aui-node-base", 2396 "aui-timer", 2397 "aui-component" 2398 ] 2399 }, 2400 "aui-tree-io": { 2401 "requires": [ 2402 "aui-component", 2403 "aui-io" 2404 ] 2405 }, 2406 "aui-tree-node": { 2407 "requires": [ 2408 "json", 2409 "querystring-stringify", 2410 "aui-tree-data", 2411 "aui-tree-io", 2412 "aui-tree-paginator", 2413 "event-key" 2414 ] 2415 }, 2416 "aui-tree-paginator": { 2417 "requires": [ 2418 "yui-base" 2419 ] 2420 }, 2421 "aui-tree-view": { 2422 "requires": [ 2423 "dd-delegate", 2424 "dd-proxy", 2425 "widget", 2426 "aui-tree-node", 2427 "aui-tree-paginator", 2428 "aui-tree-io" 2429 ], 2430 "skinnable": true 2431 }, 2432 "aui-undo-redo": { 2433 "requires": [ 2434 "aui-base", 2435 "base", 2436 "base-build", 2437 "event-key", 2438 "promise" 2439 ] 2440 }, 2441 "aui-url": { 2442 "requires": [ 2443 "oop", 2444 "querystring-parse", 2445 "querystring-stringify" 2446 ] 2447 }, 2448 "aui-video": { 2449 "requires": [ 2450 "event-resize", 2451 "node-event-html5", 2452 "querystring-stringify-simple", 2453 "aui-aria", 2454 "aui-node", 2455 "aui-component", 2456 "aui-debounce" 2457 ], 2458 "skinnable": true 2459 }, 2460 "aui-viewport": { 2461 "requires": [ 2462 "aui-node", 2463 "aui-component" 2464 ] 2465 }, 2466 "aui-widget": { 2467 "use": [ 2468 "aui-widget-cssclass", 2469 "aui-widget-toolbars" 2470 ] 2471 }, 2472 "aui-widget-core": { 2473 "use": [ 2474 "aui-widget-cssclass" 2475 ] 2476 }, 2477 "aui-widget-cssclass": { 2478 "requires": [ 2479 "widget-base" 2480 ] 2481 }, 2482 "aui-widget-position-align-suggestion": { 2483 "requires": [ 2484 "widget-position-align", 2485 "widget-stdmod" 2486 ] 2487 }, 2488 "aui-widget-responsive": { 2489 "requires": [ 2490 "event-resize", 2491 "widget-base" 2492 ] 2493 }, 2494 "aui-widget-shortcut": { 2495 "requires": [ 2496 "base" 2497 ] 2498 }, 2499 "aui-widget-swipe": { 2500 "requires": [ 2501 "classnamemanager", 2502 "scrollview-base", 2503 "scrollview-paginator", 2504 "timers" 2505 ] 2506 }, 2507 "aui-widget-toggle": {}, 2508 "aui-widget-toolbars": { 2509 "requires": [ 2510 "widget-stdmod", 2511 "aui-toolbar" 2512 ] 2513 }, 2514 "aui-widget-transition": { 2515 "requires": [ 2516 "transition" 2517 ] 2518 }, 2519 "aui-widget-trigger": { 2520 "requires": [ 2521 "node" 2522 ] 2523 } 2524}); 2525YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480'; 2526/* 2527 * Alloy JavaScript Library 2528 * http://alloy.liferay.com/ 2529 * 2530 * Copyright (c) 2010 Liferay Inc. 2531 * http://alloy.liferay.com/LICENSE.txt 2532 * 2533 * Nate Cavanaugh ([email protected]) 2534 * Eduardo Lundgren ([email protected]) 2535 * 2536 * Attribution/Third-party licenses 2537 * http://alloy.liferay.com/ATTRIBUTION.txt 2538 */ 2539 2540// Simple version of 2541// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 2542 2543A.UA.edge = (function() { 2544 var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/); 2545 2546 if (edgeVersion) { 2547 return edgeVersion[1]; 2548 } 2549 2550 return 0; 2551})(); 2552 2553A.supportsDOMEvent = function(domNode, eventName) { 2554 eventName = 'on' + eventName; 2555 2556 if (!(eventName in domNode)) { 2557 if (!domNode.setAttribute) { 2558 domNode = A.config.doc.createElement('div'); 2559 } 2560 2561 if (domNode.setAttribute) { 2562 domNode.setAttribute(eventName, ''); 2563 return (typeof domNode[eventName] === 'function'); 2564 } 2565 } 2566 2567 domNode = null; 2568 2569 return true; 2570}; 2571(function() { 2572 var slice = Array.prototype.slice; 2573 2574 YUI.prototype.ready = function() { 2575 var instance = this, 2576 xargs = arguments, 2577 index = xargs.length - 1, 2578 modules = slice.call(arguments, 0, index); 2579 2580 modules.unshift('event-base'); 2581 modules.push(function(instance) { 2582 var args = arguments; 2583 2584 instance.on('domready', function() { 2585 xargs[index].apply(this, args); 2586 }); 2587 }); 2588 instance.use.apply(instance, modules); 2589 }; 2590}()); 2591 2592 2593}, '3.1.0-deprecated.77'); 2594 2595YUI.add('aui-classnamemanager', function (A, NAME) { 2596 2597var ClassNameManager = A.ClassNameManager, 2598 _getClassName = ClassNameManager.getClassName; 2599 2600A.getClassName = A.cached( 2601 function() { 2602 var args = A.Array(arguments, 0, true); 2603 2604 args[args.length] = true; 2605 2606 return _getClassName.apply(ClassNameManager, args); 2607 } 2608); 2609 2610 2611}, '3.1.0-deprecated.77', {"requires": ["classnamemanager"]}); 2612 2613YUI.add('aui-component', function (A, NAME) { 2614 2615/** 2616 * The Component Utility 2617 * 2618 * @module aui-component 2619 */ 2620 2621var Lang = A.Lang, 2622 AArray = A.Array, 2623 2624 concat = function(arr, arr2) { 2625 return (arr || []).concat(arr2 || []); 2626 }, 2627 2628 _INSTANCES = {}, 2629 _CONSTRUCTOR_OBJECT = A.config.win.Object.prototype.constructor, 2630 2631 ClassNameManager = A.ClassNameManager, 2632 2633 _getClassName = ClassNameManager.getClassName, 2634 _getWidgetClassName = A.Widget.getClassName, 2635 2636 getClassName = A.getClassName, 2637 2638 CSS_HIDE = getClassName('hide'); 2639 2640/** 2641 * A base class for `A.Component`, providing: 2642 * 2643 * - Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor) 2644 * 2645 * @class A.Component 2646 * @extends Widget
2647 * @uses A.WidgetCssClass, A.WidgetToggle 2648 * @param {Object} config Object literal specifying widget configuration 2649 * properties. 2650 * @constructor 2651 */ 2652var Component = A.Base.create('component', A.Widget, [ 2653 A.WidgetCssClass, 2654 A.WidgetToggle 2655 ], { 2656 initializer: function(config) { 2657 var instance = this; 2658 2659 instance._originalConfig = config; 2660 2661 instance._setRender(config); 2662 2663 _INSTANCES[instance.get('id')] = instance; 2664 }, 2665 2666 /** 2667 * Clone the current `A.Component`. 2668 * 2669 * @method clone 2670 * @param {Object} config 2671 * @return {Widget} Cloned instance. 2672 */ 2673 clone: function(config) { 2674 var instance = this; 2675 2676 config = config || {}; 2677 2678 config.id = config.id || A.guid(); 2679 2680 A.mix(config, instance._originalConfig); 2681 2682 return new instance.constructor(config); 2683 }, 2684 2685 /** 2686 * Set the visibility on the UI. 2687 * 2688 * @method _uiSetVisible 2689 * @param value 2690 * @protected 2691 */ 2692 _uiSetVisible: function(value) { 2693 var instance = this; 2694 2695 var superUISetVisible = Component.superclass._uiSetVisible; 2696 2697 if (superUISetVisible) { 2698 superUISetVisible.apply(instance, arguments); 2699 } 2700 2701 var hideClass = instance.get('hideClass'); 2702 2703 if (hideClass !== false) { 2704 var boundingBox = instance.get('boundingBox'); 2705 2706 boundingBox.toggleClass(hideClass || CSS_HIDE, !value); 2707 } 2708 }, 2709 2710 /** 2711 * Applies standard class names to the `boundingBox` and `contentBox`. 2712 * 2713 * @method _renderBoxClassNames 2714 * @protected 2715 */ 2716 _renderBoxClassNames: function() { 2717 var instance = this; 2718 2719 var boundingBoxNode = instance.get('boundingBox')._node; 2720 var contentBoxNode = instance.get('contentBox')._node; 2721 2722 var boundingBoxNodeClassName = boundingBoxNode.className; 2723 var contentBoxNodeClassName = contentBoxNode.className; 2724 2725 var boundingBoxBuffer = (boundingBoxNodeClassName) ? boundingBoxNodeClassName.split(' ') : []; 2726 var contentBoxBuffer = (contentBoxNodeClassName) ? contentBoxNodeClassName.split(' ') : []; 2727 2728 var classes = instance._getClasses(); 2729 2730 var classLength = classes.length; 2731 2732 var auiClassesLength = classLength - 4; 2733 2734 var classItem; 2735 var classItemName; 2736 2737 boundingBoxBuffer.push(_getWidgetClassName()); 2738 2739 for (var i = classLength - 3; i >= 0; i--) { 2740 classItem = classes[i]; 2741 2742 classItemName = String(classItem.NAME).toLowerCase(); 2743 2744 boundingBoxBuffer.push(classItem.CSS_PREFIX || _getClassName(classItemName)); 2745 2746 if (i <= auiClassesLength) { 2747 classItemName = classItemName; 2748 2749 contentBoxBuffer.push(getClassName(classItemName, 'content')); 2750 } 2751 } 2752 2753 contentBoxBuffer.push(instance.getClassName('content')); 2754 2755 if (boundingBoxNode === contentBoxNode) { 2756 contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer.concat(boundingBoxBuffer)).join(' '); 2757 } 2758 else { 2759 boundingBoxNode.className = AArray.dedupe(boundingBoxBuffer).join(' '); 2760 2761 contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer).join(' '); 2762 } 2763 2764 contentBoxNode.className = contentBoxNodeClassName; 2765 }, 2766 2767 /** 2768 * Renders the `A.Component` based upon a passed in interaction. 2769 * 2770 * @method _renderInteraction 2771 * @param event 2772 * @param parentNode 2773 * @protected 2774 */ 2775 _renderInteraction: function(event, parentNode) { 2776 var instance = this; 2777 2778 instance.render(parentNode); 2779 2780 var renderHandles = instance._renderHandles; 2781 2782 for (var i = renderHandles.length - 1; i >= 0; i--) { 2783 var handle = renderHandles.pop(); 2784 2785 handle.detach(); 2786 } 2787 }, 2788 2789 /** 2790 * Sets the interaction and render behavior based upon an object (intercepts 2791 * the default rendering behavior). 2792 * 2793 * @method _setRender 2794 * @param config 2795 * @protected 2796 */ 2797 _setRender: function(config) { 2798 var instance = this; 2799 2800 var render = config && config.render; 2801 2802 if (render && render.constructor === _CONSTRUCTOR_OBJECT) { 2803 var eventType = render.eventType || 'mousemove'; 2804 var parentNode = render.parentNode; 2805 var selector = render.selector || parentNode; 2806 2807 if (selector) { 2808 instance._renderHandles = []; 2809 2810 var renderHandles = instance._renderHandles; 2811 2812 if (!Lang.isArray(eventType)) { 2813 eventType = [eventType]; 2814 } 2815 2816 var renderInteraction = A.rbind(instance._renderInteraction, instance, parentNode); 2817 2818 var interactionNode = A.one(selector); 2819 2820 for (var i = eventType.length - 1; i >= 0; i--) { 2821 renderHandles[i] = interactionNode.once(eventType[i], renderInteraction); 2822 } 2823 2824 delete config.render; 2825 } 2826 } 2827 } 2828}, { 2829 /** 2830 * Static property used to define the default attribute configuration for 2831 * the Component. 2832 * 2833 * @property ATTRS 2834 * @type Object 2835 * @static 2836 */ 2837 ATTRS: { 2838 /** 2839 * Indicates if use of the WAI-ARIA Roles and States should be enabled 2840 * for the Widget. 2841 * 2842 * @attribute useARIA 2843 * @default false 2844 * @type Boolean 2845 * @writeOnce 2846 */ 2847 useARIA: { 2848 writeOnce: true, 2849 value: false, 2850 validator: Lang.isBoolean 2851 }, 2852 2853 /** 2854 * CSS class added to hide the `boundingBox` when 2855 * [visible](A.Component.html#attr_visible) is set to `false`. 2856 * 2857 * @attribute hideClass 2858 * @default 'aui-hide'
2859 * @type String 2860 */ 2861 hideClass: { 2862 value: CSS_HIDE 2863 }, 2864 2865 /** 2866 * If `true` the render phase will be autimatically invoked preventing 2867 * the `.render()` manual call. 2868 * 2869 * @attribute render 2870 * @default false 2871 * @type Boolean | Node 2872 * @writeOnce 2873 */ 2874 render: { 2875 value: false, 2876 writeOnce: true 2877 } 2878 } 2879}); 2880 2881/** 2882 * Static property used to define the map to store Component instances by id. 2883 * 2884 * @property _INSTANCES 2885 * @type Object 2886 * @static 2887 */ 2888Component._INSTANCES = _INSTANCES; 2889 2890/** 2891 * Gets component's instance by id. 2892 * 2893 * @method getById 2894 * @param id 2895 */ 2896Component.getById = function(id) { 2897 return _INSTANCES[id]; 2898}; 2899 2900var DEFAULT_UI_ATTRS = A.Widget.prototype._UI_ATTRS; 2901 2902/** 2903 * Applies a CSS prefix on a component. 2904 * 2905 * @method _applyCssPrefix 2906 * @param component 2907 * @protected 2908 */ 2909Component._applyCssPrefix = function(component) { 2910 if (component && component.NAME && !('CSS_PREFIX' in component)) { 2911 component.CSS_PREFIX = A.getClassName(String(component.NAME).toLowerCase()); 2912 } 2913 2914 return component; 2915}; 2916 2917/** 2918 * Applies standard extensions from a given config to create a new class using 2919 * the static `Base.build` method. 2920 * 2921 * @method create 2922 * @param config 2923 */ 2924Component.create = function(config) { 2925 config = config || {}; 2926 2927 var extendsClass = config.EXTENDS || A.Component; 2928 2929 var component = config.constructor; 2930 2931 if (!A.Object.owns(config, 'constructor')) { 2932 component = function() { 2933 component.superclass.constructor.apply(this, arguments); 2934 }; 2935 } 2936 2937 var configProto = config.prototype; 2938 2939 if (configProto) { 2940 if (config.UI_ATTRS || config.BIND_UI_ATTRS || config.SYNC_UI_ATTRS) { 2941 var BIND_UI_ATTRS = concat(config.BIND_UI_ATTRS, config.UI_ATTRS); 2942 var SYNC_UI_ATTRS = concat(config.SYNC_UI_ATTRS, config.UI_ATTRS); 2943 2944 var extendsProto = extendsClass.prototype; 2945 var extendsUIAttrs = (extendsProto && extendsProto._UI_ATTRS) || DEFAULT_UI_ATTRS; 2946 2947 BIND_UI_ATTRS = concat(extendsUIAttrs.BIND, BIND_UI_ATTRS); 2948 SYNC_UI_ATTRS = concat(extendsUIAttrs.SYNC, SYNC_UI_ATTRS); 2949 2950 var configProtoUIAttrs = configProto._UI_ATTRS; 2951 2952 if (!configProtoUIAttrs) { 2953 configProtoUIAttrs = configProto._UI_ATTRS = {}; 2954 } 2955 2956 if (BIND_UI_ATTRS.length) { 2957 configProtoUIAttrs.BIND = BIND_UI_ATTRS; 2958 } 2959 2960 if (SYNC_UI_ATTRS.length) { 2961 configProtoUIAttrs.SYNC = SYNC_UI_ATTRS; 2962 } 2963 } 2964 } 2965 2966 var augmentsClasses = config.AUGMENTS; 2967 2968 if (augmentsClasses && !Lang.isArray(augmentsClasses)) { 2969 augmentsClasses = [augmentsClasses]; 2970 } 2971 2972 A.mix(component, config); 2973 2974 delete component.prototype; 2975 2976 A.extend(component, extendsClass, configProto); 2977 2978 if (augmentsClasses) { 2979 component = A.Base.build(config.NAME, component, augmentsClasses, { 2980 dynamic: false 2981 }); 2982 } 2983 2984 Component._applyCssPrefix(component); 2985 2986 return component; 2987}; 2988 2989/** 2990 * Static property provides a string to identify the CSS prefix. 2991 * 2992 * @property CSS_PREFIX 2993 * @type String 2994 * @static 2995 */ 2996Component.CSS_PREFIX = getClassName('component'); 2997 2998var Base = A.Base; 2999 3000/** 3001 * Applies extensions to a class using the static `Base.build` method. 3002 * 3003 * @method build 3004 */ 3005Component.build = function() { 3006 var component = Base.build.apply(Base, arguments); 3007 3008 Component._applyCssPrefix(component); 3009 3010 return component; 3011}; 3012 3013A.Component = Component; 3014 3015 3016}, '3.1.0-deprecated.77', { 3017 "requires": [ 3018 "aui-classnamemanager", 3019 "aui-widget-cssclass", 3020 "aui-widget-toggle", 3021 "base-build", 3022 "widget-base" 3023 ] 3024}); 3025 3026YUI.add('aui-debounce', function (A, NAME) { 3027 3028var Lang = A.Lang, 3029 aArray = A.Array, 3030 isString = Lang.isString, 3031 isUndefined = Lang.isUndefined, 3032 3033 DEFAULT_ARGS = []; 3034 3035var toArray = function(arr, fallback, index, arrayLike) { 3036 return !isUndefined(arr) ? aArray(arr, index || 0, (arrayLike !== false)) : fallback; 3037}; 3038
3039A.debounce = function(fn, delay, context, args) { 3040 var id; 3041 var tempArgs; 3042 var wrapped; 3043 3044 if (isString(fn) && context) { 3045 fn = A.bind(fn, context); 3046 } 3047 3048 delay = delay || 0; 3049 3050 args = toArray(arguments, DEFAULT_ARGS, 3); 3051 3052 var clearFn = function() { 3053 clearInterval(id); 3054 3055 id = null; 3056 }; 3057 3058 var base = function() { 3059 clearFn(); 3060 3061 var result = fn.apply(context, tempArgs || args || DEFAULT_ARGS); 3062 3063 tempArgs = null; 3064 3065 return result; 3066 }; 3067 3068 var delayFn = function(delayTime, newArgs, newContext, newFn) { 3069 wrapped.cancel(); 3070 3071 delayTime = !isUndefined(delayTime) ? delayTime : delay; 3072 3073 fn = newFn || fn; 3074 context = newContext || context; 3075 3076 if (newArgs !== args) { 3077 tempArgs = toArray(newArgs, DEFAULT_ARGS, 0, false).concat(args); 3078 } 3079 3080 if (delayTime > 0) { 3081 id = setInterval(base, delayTime); 3082 } 3083 else { 3084 return base(); 3085 } 3086 }; 3087 3088 var cancelFn = function() { 3089 if (id) { 3090 clearFn(); 3091 } 3092 }; 3093 3094 var setDelay = function(delay) { 3095 cancelFn(); 3096 3097 delay = delay || 0; 3098 }; 3099 3100 wrapped = function() { 3101 var currentArgs = arguments.length ? arguments : args; 3102 3103 return wrapped.delay(delay, currentArgs, context || this); 3104 }; 3105 3106 wrapped.cancel = cancelFn; 3107 wrapped.delay = delayFn; 3108 wrapped.setDelay = setDelay; 3109 3110 return wrapped; 3111}; 3112 3113 3114}, '3.1.0-deprecated.77'); 3115 3116YUI.add('aui-delayed-task-deprecated', function (A, NAME) { 3117 3118/** 3119 * The DelayedTask Utility - Executes the supplied function in the context of 3120 * the supplied object 'when' milliseconds later 3121 * 3122 * @module aui-delayed-task 3123 */ 3124 3125/** 3126 * A base class for DelayedTask, providing: 3127 * <ul> 3128 * <li>Executes the supplied function in the context of the supplied object 'when' milliseconds later</li> 3129 * </ul> 3130 * 3131 * Quick Example:<br/> 3132 * 3133 * <pre><code>var delayed = new A.DelayedTask({ 3134 * function() { 3135 * // This callback will be executed when the <code>DelayedTask</code> be invoked 3136 * }, 3137 * scope 3138 * }); 3139 * 3140 * // executes after 1000ms the callback 3141 * delayed.delay(1000); 3142 * </code></pre> 3143 * 3144 * Check the list of <a href="DelayedTask.html#configattributes">Configuration Attributes</a> available for 3145 * DelayedTask. 3146 * 3147 * @param config {Object} Object literal specifying widget configuration properties. 3148 * 3149 * @class DelayedTask 3150 * @param {function} fn Callback 3151 * @param {Object} scope Context object. Optional. 3152 * @param args 0..n additional arguments that should be provided to the listener. 3153 * @constructor 3154 */ 3155var DelayedTask = function(fn, scope, args) { 3156 var instance = this; 3157 3158 /** 3159 * Stores the passed <code>args</code> attribute. 3160 * 3161 * @property _args 3162 * @type Object 3163 * @protected 3164 */ 3165 instance._args = args; 3166 3167 /** 3168 * Stores the passed <code>delay</code> attribute. 3169 * 3170 * @property _delay 3171 * @default 0 3172 * @type Number 3173 * @protected 3174 */ 3175 instance._delay = 0; 3176 3177 /** 3178 * Stores the passed <code>fn</code> attribute. 3179 * 3180 * @property _fn 3181 * @type function 3182 * @protected 3183 */ 3184 instance._fn = fn; 3185 3186 /** 3187 * Stores the timer <code>id</code> given from the <code>setInterval</code>. 3188 * 3189 * @property _id 3190 * @default null 3191 * @type Number 3192 * @protected 3193 */ 3194 instance._id = null; 3195 3196 /** 3197 * Stores the passed <code>scope</code> attribute. 3198 * 3199 * @property _scope 3200 * @default instance 3201 * @type Object 3202 * @protected 3203 */ 3204 instance._scope = scope || instance; 3205 3206 /** 3207 * Stores the current timestamp given from 3208 * <a href="DelayedTask.html#method__getTime">_getTime</a>. 3209 * 3210 * @property _time 3211 * @default 0 3212 * @type Number 3213 * @protected 3214 */ 3215 instance._time = 0; 3216 3217 instance._base = function() { 3218 var now = instance._getTime(); 3219 3220 if (now - instance._time >= instance._delay) { 3221 clearInterval(instance._id); 3222 3223 instance._id = null; 3224 3225 instance._fn.apply(instance._scope, instance._args || []); 3226 } 3227 }; 3228}; 3229 3230DelayedTask.prototype = { 3231 /** 3232 * <p>This function is responsible to execute the user callback, passed in 3233 * the <code>constructor</code> after <code>delay</code> milliseconds.</p> 3234 * 3235 * Example: 3236 * 3237 * <pre><code>// executes after 1000ms the callback 3238 * delayed.delay(1000);</code></pre> 3239 * 3240 * @method delay 3241 * @param {Number} delay Delay in milliseconds. 3242 * @param {function} newFn Callback. 3243 * @param {Object} newScope Context object. Optional. 3244 * @param newArgs 0..n additional arguments that should be provided to the listener. 3245 */ 3246 delay: function(delay, newFn, newScope, newArgs) { 3247 var instance = this; 3248 3249 if (instance._id && instance._delay != delay) { 3250 instance.cancel(); 3251 } 3252 3253 instance._delay = delay || instance._delay; 3254 instance._time = instance._getTime(); 3255 3256 instance._fn = newFn || instance._fn; 3257 instance._scope = newScope || instance._scope; 3258 instance._args = newArgs || instance._args; 3259 3260 if (!A.Lang.isArray(instance._args)) { 3261 instance._args = [instance._args]; 3262 } 3263 3264 if (!instance._id) { 3265 if (instance._delay > 0) { 3266 instance._id = setInterval(instance._base, instance._delay); 3267 } 3268 else { 3269 instance._base(); 3270 } 3271 } 3272 }, 3273 3274 /** 3275 * Cancel the delayed task in case it's running (i.e., clearInterval from 3276 * the current running <a href="DelayedTask.html#property__id">_id</a>). 3277 * 3278 * @method cancel 3279 */ 3280 cancel: function() { 3281 var instance = this; 3282 3283 if (instance._id) { 3284 clearInterval(instance._id); 3285 3286 instance._id = null; 3287 } 3288 }, 3289 3290 /** 3291 * Get the current timestamp (i.e., now). 3292 * 3293 * @method _getTime 3294 * @protected 3295 * @return {Number} Current timestamp 3296 */ 3297 _getTime: function() { 3298 var instance = this; 3299 3300 return (+new Date()); 3301 } 3302}; 3303 3304A.DelayedTask = DelayedTask; 3305 3306 3307}, '3.1.0-deprecated.77', {"requires": ["yui-base"]}); 3308 3309YUI.add('aui-event-base', function (A, NAME) { 3310 3311/** 3312 * The Event Base. 3313 * 3314 * @module aui-event 3315 * @submodule aui-event-base 3316 */ 3317 3318var aArray = A.Array, 3319 DOMEventFacade = A.DOMEventFacade, 3320 DOMEventFacadeProto = DOMEventFacade.prototype; 3321 3322var KeyMap = { 3323 BACKSPACE: 8, 3324 TAB: 9, 3325 NUM_CENTER: 12, 3326
3327 ENTER: 13, 3328 RETURN: 13, 3329 3330 SHIFT: 16, 3331 CTRL: 17, 3332 ALT: 18, 3333 3334 PAUSE: 19, 3335 CAPS_LOCK: 20, 3336 ESC: 27, 3337 SPACE: 32, 3338 3339 PAGE_UP: 33, 3340 PAGE_DOWN: 34, 3341 3342 END: 35, 3343 HOME: 36, 3344 3345 LEFT: 37, 3346 UP: 38, 3347 RIGHT: 39, 3348 DOWN: 40, 3349 3350 PRINT_SCREEN: 44, 3351 INSERT: 45, 3352 DELETE: 46, 3353 3354 ZERO: 48, 3355 ONE: 49, 3356 TWO: 50, 3357 THREE: 51, 3358 FOUR: 52, 3359 FIVE: 53, 3360 SIX: 54, 3361 SEVEN: 55, 3362 EIGHT: 56, 3363 NINE: 57, 3364 3365 A: 65, 3366 B: 66, 3367 C: 67, 3368 D: 68, 3369 E: 69, 3370 F: 70, 3371 G: 71, 3372 H: 72, 3373 I: 73, 3374 J: 74, 3375 K: 75, 3376 L: 76, 3377 M: 77, 3378 N: 78, 3379 O: 79, 3380 P: 80, 3381 Q: 81, 3382 R: 82, 3383 S: 83, 3384 T: 84, 3385 U: 85, 3386 V: 86, 3387 W: 87, 3388 X: 88, 3389 Y: 89, 3390 Z: 90, 3391 3392 CONTEXT_MENU: 93, 3393 3394 NUM_ZERO: 96, 3395 NUM_ONE: 97, 3396 NUM_TWO: 98, 3397 NUM_THREE: 99, 3398 NUM_FOUR: 100, 3399 NUM_FIVE: 101, 3400 NUM_SIX: 102, 3401 NUM_SEVEN: 103, 3402 NUM_EIGHT: 104, 3403 NUM_NINE: 105, 3404 3405 NUM_MULTIPLY: 106, 3406 NUM_PLUS: 107, 3407 NUM_MINUS: 109, 3408 NUM_PERIOD: 110, 3409 NUM_DIVISION: 111, 3410 3411 F1: 112, 3412 F2: 113, 3413 F3: 114, 3414 F4: 115, 3415 F5: 116, 3416 F6: 117, 3417 F7: 118, 3418 F8: 119, 3419 F9: 120, 3420 F10: 121, 3421 F11: 122, 3422 F12: 123, 3423 3424 NUM_LOCK: 144, 3425 3426 WIN_KEY: 224, 3427 WIN_IME: 229, 3428 3429 NON_MODIFYING_KEYS: [ 3430 'ALT', 3431 'CAPS_LOCK', 3432 'CTRL', 3433 'DOWN', 3434 'END', 3435 'ESC', 3436 'F1', 3437 'F10', 3438 'F11', 3439 'F12', 3440 'F2', 3441 'F3', 3442 'F4', 3443 'F5', 3444 'F6', 3445 'F7', 3446 'F8', 3447 'F9', 3448 'HOME', 3449 'LEFT', 3450 'NUM_LOCK', 3451 'PAGE_DOWN', 3452 'PAGE_UP', 3453 'PAUSE', 3454 'PRINT_SCREEN', 3455 'RIGHT', 3456 'SHIFT', 3457 'SPACE', 3458 'UP', 3459 'WIN_KEY' 3460 ], 3461 3462 hasModifier: function(event) { 3463 return event && 3464 (event.ctrlKey || 3465 event.altKey || 3466 event.shiftKey || 3467 event.metaKey); 3468 }, 3469 3470 isKey: function(keyCode, name) { 3471 var instance = this; 3472 3473 return name && ((instance[name] || instance[name.toUpperCase()]) === keyCode); 3474 }, 3475 3476 isKeyInRange: function(keyCode, start, end) { 3477 var instance = this; 3478 3479 var result = false;
3480 3481 if (start && end) { 3482 var startKey = instance[start] || instance[start.toUpperCase()]; 3483 var endKey = instance[end] || instance[end.toUpperCase()]; 3484 3485 result = startKey && endKey && 3486 (keyCode >= startKey && keyCode <= endKey); 3487 } 3488 3489 return result; 3490 }, 3491 3492 isKeyInSet: function(keyCode) { 3493 var instance = this; 3494 3495 var args = aArray(arguments, 1, true); 3496 3497 return instance._isKeyInSet(keyCode, args); 3498 }, 3499 3500 isNavKey: function(keyCode) { 3501 var instance = this; 3502 3503 return instance.isKeyInRange(keyCode, 'PAGE_UP', 'DOWN') || instance.isKeyInSet(keyCode, 'ENTER', 'TAB', 'ESC'); 3504 }, 3505 3506 isSpecialKey: function(keyCode, eventType) { 3507 var instance = this; 3508 3509 var isCtrlPress = (eventType === 'keypress' && instance.ctrlKey); 3510 3511 return isCtrlPress || 3512 instance.isNavKey(keyCode) || 3513 instance.isKeyInRange(keyCode, 'SHIFT', 'CAPS_LOCK') || 3514 instance.isKeyInSet(keyCode, 'BACKSPACE', 'PRINT_SCREEN', 'INSERT', 'WIN_IME'); 3515 }, 3516 3517 isModifyingKey: function(keyCode) { 3518 var instance = this; 3519 3520 return !instance._isKeyInSet(keyCode, instance.NON_MODIFYING_KEYS); 3521 }, 3522 3523 _isKeyInSet: function(keyCode, arr) { 3524 var instance = this; 3525 3526 var i = arr.length; 3527 3528 var result = false;
3529 3530 var keyName; 3531 var key; 3532 3533 while (i--) { 3534 keyName = arr[i]; 3535 key = keyName && (instance[keyName] || instance[String(keyName).toUpperCase()]); 3536 3537 if (keyCode === key) { 3538 result = true; 3539 3540 break; 3541 } 3542 } 3543 3544 return result; 3545 } 3546}; 3547 3548A.mix( 3549 DOMEventFacadeProto, { 3550 /** 3551 * Checks if an event is triggered by a keyboard key like `CTRL`, `ALT` 3552 * or `SHIFT`. 3553 * 3554 * @method hasModifier 3555 * @return {Boolean} 3556 */ 3557 hasModifier: function() { 3558 var instance = this; 3559 3560 return KeyMap.hasModifier(instance); 3561 }, 3562 3563 /** 3564 * Checks if an event is triggered by a keyboard key. 3565 * 3566 * @method isKey 3567 * @param name 3568 * @return {Boolean} 3569 */ 3570 isKey: function(name) { 3571 var instance = this; 3572 3573 return KeyMap.isKey(instance.keyCode, name); 3574 }, 3575 3576 /** 3577 * Checks if an event is triggered by a keyboard key located between two 3578 * other keys. 3579 * 3580 * @method isKeyInRange 3581 * @param start 3582 * @param end 3583 * @return {Boolean} 3584 */ 3585 isKeyInRange: function(start, end) { 3586 var instance = this; 3587 3588 return KeyMap.isKeyInRange(instance.keyCode, start, end); 3589 }, 3590 3591 /** 3592 * Checks if an event is triggered by a keyboard key contained in the 3593 * key set. 3594 * 3595 * @method isKeyInSet 3596 * @return {Boolean} 3597 */ 3598 isKeyInSet: function() { 3599 var instance = this; 3600 3601 var args = aArray(arguments, 0, true); 3602 3603 return KeyMap._isKeyInSet(instance.keyCode, args); 3604 }, 3605 3606 /** 3607 * Checks if an event is triggered by `ENTER`, `TAB`, `ESC` keyboard 3608 * keys or by a key located between `PAGE UP` and `DOWN`. 3609 * 3610 * @method isModifyingKey 3611 */ 3612 isModifyingKey: function() { 3613 var instance = this; 3614 3615 return KeyMap.isModifyingKey(instance.keyCode); 3616 }, 3617 3618 /** 3619 * Checks if an event is triggered by navigation keys like `PAGE UP` 3620 * and `DOWN` keys. 3621 * 3622 * @method isNavKey 3623 * @return {Boolean} 3624 */ 3625 isNavKey: function() { 3626 var instance = this; 3627 3628 return KeyMap.isNavKey(instance.keyCode); 3629 }, 3630 3631 /** 3632 * Checks if an event is triggered by a special keyboard key like 3633 * `SHIFT`, `CAPS LOCK`, etc. 3634 * 3635 * @method isSpecialKey 3636 * @return {Boolean} 3637 */ 3638 isSpecialKey: function() { 3639 var instance = this; 3640 3641 return KeyMap.isSpecialKey(instance.keyCode, instance.type); 3642 } 3643 } 3644); 3645 3646A.Event.KeyMap = KeyMap; 3647 3648A.Event.supportsDOMEvent = A.supportsDOMEvent; 3649 3650 3651}, '3.1.0-deprecated.77', {"requires": ["event-base"]}); 3652 3653YUI.add('aui-event-input', function (A, NAME) { 3654 3655/** 3656 * An object that encapsulates text changed events for textareas and input 3657 * element of type text and password. This event only occurs when the element 3658 * is focused. 3659 * 3660 * @module aui-event 3661 * @submodule aui-event-input 3662 */ 3663 3664var DOM_EVENTS = A.Node.DOM_EVENTS; 3665 3666// Input event feature check should be done on textareas. WebKit before 3667// version 531 (3.0.182.2) did not support input events for textareas. 3668// See http://dev.chromium.org/developers/webkit-version-table 3669if (A.Features.test('event', 'input')) { 3670 // http://yuilibrary.com/projects/yui3/ticket/2533063 3671 DOM_EVENTS.input = 1; 3672 return; 3673} 3674 3675DOM_EVENTS.cut = 1; 3676DOM_EVENTS.dragend = 1; 3677DOM_EVENTS.paste = 1; 3678 3679var KeyMap = A.Event.KeyMap, 3680 3681 _HANDLER_DATA_KEY = '~~aui|input|event~~', 3682 _INPUT_EVENT_TYPE = ['keydown', 'paste', 'drop', 'cut'], 3683 _SKIP_FOCUS_CHECK_MAP = { 3684 cut: 1, 3685 drop: 1, 3686 paste: 1 3687 }; 3688 3689/** 3690 * Defines a new `input` event in the DOM event system. 3691 * 3692 * @event input 3693 */ 3694A.Event.define('input', { 3695 3696 /** 3697 * Implementation logic for event subscription. 3698 * 3699 * @method on 3700 * @param node 3701 * @param subscription 3702 * @param notifier 3703 */ 3704 on: function(node, subscription, notifier) { 3705 var instance = this; 3706 3707 subscription._handler = node.on( 3708 _INPUT_EVENT_TYPE, A.bind(instance._dispatchEvent, instance, subscription, notifier)); 3709 }, 3710 3711 /** 3712 * Implementation logic for subscription via `node.delegate`. 3713 * 3714 * @method delegate 3715 * @param node 3716 * @param subscription 3717 * @param notifier 3718 * @param filter 3719 */ 3720 delegate: function(node, subscription, notifier, filter) { 3721 var instance = this; 3722 3723 subscription._handles = []; 3724 subscription._handler = node.delegate('focus', function(event) { 3725 var element = event.target, 3726 handler = element.getData(_HANDLER_DATA_KEY); 3727 3728 if (!handler) { 3729 handler = element.on( 3730 _INPUT_EVENT_TYPE, 3731 A.bind(instance._dispatchEvent, instance, subscription, notifier)); 3732 3733 subscription._handles.push(handler); 3734 element.setData(_HANDLER_DATA_KEY, handler); 3735 } 3736 }, filter); 3737 }, 3738 3739 /** 3740 * Implementation logic for cleaning up a detached subscription. 3741 * 3742 * @method detach 3743 * @param node 3744 * @param subscription 3745 * @param notifier 3746 */ 3747 detach: function(node, subscription) { 3748 subscription._handler.detach(); 3749 }, 3750 3751 /** 3752 * Implementation logic for cleaning up a detached delegate subscription. 3753 * 3754 * @method detachDelegate 3755 * @param node 3756 * @param subscription 3757 * @param notifier 3758 */ 3759 detachDelegate: function(node, subscription) { 3760 A.Array.each(subscription._handles, function(handle) { 3761 var element = A.one(handle.evt.el); 3762 if (element) { 3763 element.setData(_HANDLER_DATA_KEY, null); 3764 } 3765 handle.detach(); 3766 }); 3767 subscription._handler.detach(); 3768 }, 3769 3770 /**
3771 * Dispatches an `input` event. 3772 * 3773 * @method _dispatchEvent 3774 * @param subscription 3775 * @param notifier 3776 * @param event 3777 * @protected 3778 */ 3779 _dispatchEvent: function(subscription, notifier, event) { 3780 var instance = this, 3781 input, 3782 valueBeforeKey; 3783 3784 input = event.target; 3785 3786 // Since cut, drop and paste events fires before the element is focused, 3787 // skip focus checking. 3788 if (_SKIP_FOCUS_CHECK_MAP[event.type] || 3789 (input.get('ownerDocument').get('activeElement') === input)) { 3790 3791 if (KeyMap.isModifyingKey(event.keyCode)) { 3792 if (subscription._timer) { 3793 subscription._timer.cancel(); 3794 subscription._timer = null; 3795 } 3796 3797 valueBeforeKey = KeyMap.isKey(event.keyCode, 'WIN_IME') ? null : input.get('value'); 3798 3799 subscription._timer = A.soon( 3800 A.bind('_fireEvent', instance, subscription, notifier, event, valueBeforeKey) 3801 ); 3802 } 3803 } 3804 }, 3805 3806 /** 3807 * Fires an event. 3808 * 3809 * @method _fireEvent 3810 * @param subscription 3811 * @param notifier 3812 * @param event 3813 * @param valueBeforeKey 3814 * @protected 3815 */ 3816 _fireEvent: function(subscription, notifier, event, valueBeforeKey) { 3817 var input = event.target; 3818 3819 subscription._timer = null; 3820 3821 if (input.get('value') !== valueBeforeKey) { 3822 notifier.fire(event); 3823 } 3824 } 3825}); 3826 3827 3828}, '3.1.0-deprecated.77', {"requires": ["aui-event-base", "event-delegate", "event-synthetic", "timers"]}); 3829 3830YUI.add('aui-form-validator', function (A, NAME) { 3831 3832/**
3833 * The Form Validator Component 3834 * 3835 * @module aui-form-validator 3836 */ 3837 3838// API inspired on the amazing jQuery Form Validation - 3839// http://jquery.bassistance.de/validate/ 3840 3841var Lang = A.Lang, 3842 AObject = A.Object, 3843 isBoolean = Lang.isBoolean, 3844 isDate = Lang.isDate, 3845 isEmpty = AObject.isEmpty, 3846 isFunction = Lang.isFunction, 3847 isNode = Lang.isNode, 3848 isObject = Lang.isObject, 3849 isString = Lang.isString, 3850 trim = Lang.trim, 3851 3852 defaults = A.namespace('config.FormValidator'), 3853 3854 getRegExp = A.DOM._getRegExp, 3855 3856 getCN = A.getClassName, 3857 3858 CSS_FORM_GROUP = getCN('form', 'group'), 3859 CSS_HAS_ERROR = getCN('has', 'error'), 3860 CSS_ERROR_FIELD = getCN('error', 'field'), 3861 CSS_HAS_SUCCESS = getCN('has', 'success'), 3862 CSS_SUCCESS_FIELD = getCN('success', 'field'), 3863 CSS_HELP_BLOCK = getCN('help', 'block'), 3864 CSS_STACK = getCN('form-validator', 'stack'), 3865 3866 TPL_MESSAGE = '<div role="alert"></div>', 3867 TPL_STACK_ERROR = '<div class="' + [CSS_STACK, CSS_HELP_BLOCK].join(' ') + '"></div>'; 3868 3869if (!Element.prototype.matches) { 3870 Element.prototype.matches = Element.prototype.msMatchesSelector; 3871} 3872 3873A.mix(defaults, { 3874 STRINGS: { 3875 DEFAULT: 'Please fix {field}.', 3876 acceptFiles: 'Please enter a value with a valid extension ({0}) in {field}.', 3877 alpha: 'Please enter only alpha characters in {field}.', 3878 alphanum: 'Please enter only alphanumeric characters in {field}.', 3879 date: 'Please enter a valid date in {field}.', 3880 digits: 'Please enter only digits in {field}.', 3881 email: 'Please enter a valid email address in {field}.', 3882 equalTo: 'Please enter the same value again in {field}.', 3883 iri: 'Please enter a valid IRI in {field}.', 3884 max: 'Please enter a value less than or equal to {0} in {field}.', 3885 maxLength: 'Please enter no more than {0} characters in {field}.', 3886 min: 'Please enter a value greater than or equal to {0} in {field}.', 3887 minLength: 'Please enter at least {0} characters in {field}.', 3888 number: 'Please enter a valid number in {field}.', 3889 range: 'Please enter a value between {0} and {1} in {field}.', 3890 rangeLength: 'Please enter a value between {0} and {1} characters long in {field}.', 3891 required: '{field} is required.', 3892 url: 'Please enter a valid URL in {field}.' 3893 }, 3894 3895 REGEX: { 3896 alpha: /^[a-z_]+$/i, 3897 3898 alphanum: /^\w+$/, 3899 3900 digits: /^\d+$/, 3901 3902 // Regex from Scott Gonzalez Email Address Validation: 3903 // http://projects.scottsplayground.com/email_address_validation/ 3904 email: new RegExp('^((([a-z]|\\d|[!#\\$%&\'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|' + 3905 '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#' + 3906 '\\$%&\'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF' + 3907 '\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20' + 3908 '|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\' + 3909 'x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])' + 3910 '|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-' + 3911 '\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\' + 3912 'x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\' + 3913 'uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\' + 3914 'uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\' + 3915 'uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\' + 3916 'uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\' + 3917 'uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\' + 3918 'uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\' + 3919 'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\' + 3920 'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$', 'i'), 3921 3922 // Regex from Scott Gonzalez IRI: 3923 // http://projects.scottsplayground.com/iri/demo/ 3924 iri: new RegExp('^([a-z]([a-z]|\\d|\\+|-|\\.)*):(\\/\\/(((([a-z]|\\d|' +
3925 '-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[' + 3926 '\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:)*@)?((\\[(|(v[\\da-f]{1' + 3927 ',}\\.(([a-z]|\\d|-|\\.|_|~)|[!\\$&\'\\(\\)\\*\\+,;=]|:)+))\\])' + 3928 '|((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1' + 3929 '\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d' + 3930 '|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|' + 3931 '(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-' + 3932 '\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=])*)(:\\d*)?)' + 3933 '(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' + 3934 'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)*)' + 3935 '*|(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' + 3936 'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)+' + 3937 '(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\' + 3938 'uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|' + 3939 '@)*)*)?)|((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' + 3940 'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\' + 3941 '+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\' + 3942 'uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\' + 3943 '(\\)\\*\\+,;=]|:|@)*)*)|((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\' + 3944 'uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\' + 3945 '$&\'\\(\\)\\*\\+,;=]|:|@)){0})(\\?((([a-z]|\\d|-|\\.|_|~|' + 3946 '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]' + 3947 '{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|' + 3948 '\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' + 3949 'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\' + 3950 '+,;=]|:|@)|\\/|\\?)*)?$', 'i'), 3951 3952 number: /^[+\-]?(\d+([.,]\d+)?)+([eE][+-]?\d+)?$/, 3953 3954 // Regex from Scott Gonzalez Common URL: 3955 // http://projects.scottsplayground.com/iri/demo/common.html 3956 url: new RegExp('^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\' + 3957 'u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})' + 3958 '|[!\\$&\'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|' + 3959 '2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25' + 3960 '[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.' + 3961 '(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d' + 3962 '|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\' + 3963 'd|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|' + 3964 '-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*' + 3965 '([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\' + 3966 '.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|' + 3967 '(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]' + 3968 '|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])' + 3969 '*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)' + 3970 '(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' + 3971 'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]' + 3972 '|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF' + 3973 '\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)*)' + 3974 '*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\' + 3975 'uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\'\\(\\)\\*\\+,;=]|' + 3976 ':|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|' + 3977 '[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})' + 3978 '|[!\\$&\'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$', 'i') 3979 }, 3980 3981 RULES: { 3982 acceptFiles: function(val, node, ruleValue) { 3983 var regex = null; 3984 3985 if (isString(ruleValue)) { 3986 var extensions = ruleValue.replace(/\./g, '').split(/,\s*|\b\s*/); 3987 3988 extensions = A.Array.map(extensions, A.Escape.regex); 3989 3990 regex = getRegExp('[.](' + extensions.join('|') + ')$', 'i'); 3991 } 3992 3993 return regex && regex.test(val); 3994 }, 3995 3996 date: function(val) { 3997 var date = new Date(val); 3998 3999 return (isDate(date) && (date !== 'Invalid Date') && !isNaN(date)); 4000 }, 4001 4002 equalTo: function(val, node, ruleValue) { 4003 var comparator = A.one(ruleValue); 4004 4005 return comparator && (trim(comparator.val()) === val); 4006 }, 4007 4008 hasValue: function(val, node) { 4009 var instance = this; 4010 4011 if (A.FormValidator.isCheckable(node)) { 4012 var name = node.get('name'), 4013 elements = A.all(instance.getFieldsByName(name)); 4014 4015 return (elements.filter(':checked').size() > 0); 4016 } 4017 else { 4018 return !!val; 4019 } 4020 }, 4021 4022 max: function(val, node, ruleValue) { 4023 return (Lang.toFloat(val) <= ruleValue); 4024 }, 4025 4026 maxLength: function(val, node, ruleValue) { 4027 return (val.length <= ruleValue); 4028 }, 4029 4030 min: function(val, node, ruleValue) { 4031 return (Lang.toFloat(val) >= ruleValue); 4032 }, 4033 4034 minLength: function(val, node, ruleValue) { 4035 return (val.length >= ruleValue); 4036 }, 4037 4038 range: function(val, node, ruleValue) { 4039 var num = Lang.toFloat(val); 4040 4041 return (num >= ruleValue[0]) && (num <= ruleValue[1]); 4042 }, 4043 4044 rangeLength: function(val, node, ruleValue) { 4045 var length = val.length; 4046 4047 return (length >= ruleValue[0]) && (length <= ruleValue[1]); 4048 }, 4049 4050 required: function(val, node, ruleValue) { 4051 var instance = this; 4052 4053 if (ruleValue === true) { 4054 return defaults.RULES.hasValue.apply(instance, [val, node]); 4055 } 4056 else { 4057 return true; 4058 } 4059 } 4060 } 4061}); 4062 4063/** 4064 * A base class for `A.FormValidator`. 4065 * 4066 * @class A.FormValidator 4067 * @extends Base 4068 * @param {Object} config Object literal specifying widget configuration 4069 * properties. 4070 * @constructor 4071 * @include http://alloyui.com/examples/form-validator/basic-markup.html 4072 * @include http://alloyui.com/examples/form-validator/basic.js 4073 */ 4074var FormValidator = A.Component.create({ 4075 4076 /** 4077 * Static property provides a string to identify the class. 4078 * 4079 * @property NAME
4080 * @type String 4081 * @static 4082 */ 4083 NAME: 'form-validator', 4084 4085 /** 4086 * Static property used to define the default attribute 4087 * configuration for the `A.FormValidator`. 4088 * 4089 * @property ATTRS 4090 * @type Object 4091 * @static 4092 */ 4093 ATTRS: { 4094 4095 /** 4096 * The widget's outermost node, used for sizing and positioning. 4097 * 4098 * @attribute boundingBox 4099 */ 4100 boundingBox: { 4101 setter: A.one 4102 }, 4103 4104 /** 4105 * Container for the CSS error class. 4106 * 4107 * @attribute containerErrorClass 4108 * @type String 4109 */ 4110 containerErrorClass: { 4111 value: CSS_HAS_ERROR, 4112 validator: isString 4113 }, 4114 4115 /** 4116 * Container for the CSS valid class. 4117 * 4118 * @attribute containerValidClass 4119 * @type String 4120 */ 4121 containerValidClass: { 4122 value: CSS_HAS_SUCCESS, 4123 validator: isString 4124 }, 4125 4126 /** 4127 * Defines the CSS error class. 4128 * 4129 * @attribute errorClass
4130 * @type String 4131 */ 4132 errorClass: { 4133 value: CSS_ERROR_FIELD, 4134 validator: isString 4135 }, 4136 4137 /** 4138 * If `true` the validation rules are extracted from the DOM. 4139 * 4140 * @attribute extractRules 4141 * @default true 4142 * @type Boolean 4143 */ 4144 extractRules: { 4145 value: true, 4146 validator: isBoolean 4147 }, 4148 4149 /** 4150 * Container for a field. 4151 * 4152 * @attribute fieldContainer 4153 * @type String 4154 */ 4155 fieldContainer: { 4156 value: '.' + CSS_FORM_GROUP 4157 }, 4158 4159 /** 4160 * Collection of strings used on a field. 4161 * 4162 * @attribute fieldStrings 4163 * @default {} 4164 * @type Object 4165 */ 4166 fieldStrings: { 4167 value: {}, 4168 validator: isObject 4169 }, 4170 4171 /** 4172 * The CSS class for `<label>`. 4173 * 4174 * @attribute labelCssClass 4175 * @default 'control-label' 4176 * @type Str
4176ing 4177 */ 4178 labelCssClass: { 4179 validator: isString, 4180 value: 'control-label' 4181 }, 4182 4183 /** 4184 * Container for the form message. 4185 * 4186 * @attribute messageContainer 4187 * @default '<div role="alert"></div>' 4188 */ 4189 messageContainer: { 4190 getter: function(val) { 4191 return A.Node.create(val).clone(); 4192 }, 4193 value: TPL_MESSAGE 4194 }, 4195 4196 /** 4197 * Collection of rules to validate fields. 4198 * 4199 * @attribute rules 4200 * @default {} 4201 * @type Object 4202 */ 4203 rules: { 4204 getter: function(val) { 4205 var instance = this; 4206 if (!instance._rulesAlreadyExtracted) { 4207 instance._extractRulesFromMarkup(val); 4208 } 4209 return val; 4210 }, 4211 validator: isObject, 4212 value: {} 4213 }, 4214 4215 /** 4216 * Defines if the text will be selected or not after validation. 4217 * 4218 * @attribute selectText 4219 * @default true 4220 * @type Boolean 4221 */ 4222 selectText: { 4223 value: true, 4224 validator: isBoolean 4225 }, 4226 4227 /** 4228 * Defines if the validation messages will be showed or not. 4229 * 4230 * @attribute showMessages 4231 * @default true 4232 * @type Boolean 4233 */ 4234 showMessages: { 4235 value: true, 4236 validator: isBoolean 4237 }, 4238 4239 /** 4240 * Defines if all validation messages will be showed or not. 4241 * 4242 * @attribute showAllMessages 4243 * @default false 4244 * @type Boolean 4245 */ 4246 showAllMessages: { 4247 value: false, 4248 validator: isBoolean 4249 }, 4250 4251 /** 4252 * List of CSS selectors for targets that will not get validated 4253 * 4254 * @attribute skipValidationTargetSelectors 4255 * @default 'a[class=btn-cancel' 4256 */ 4257 skipValidationTargetSelector: { 4258 value: 'a[class~=btn-cancel]' 4259 }, 4260 4261 /** 4262 * Defines a container for the stack errors. 4263 * 4264 * @attribute stackErrorContainer 4265 */ 4266 stackErrorContainer: { 4267 getter: function(val) { 4268 return A.Node.create(val).clone(); 4269 }, 4270 value: TPL_STACK_ERROR 4271 }, 4272 4273 /** 4274 * Collection of strings used to label elements of the UI. 4275 * 4276 * @attribute strings 4277 * @type Object 4278 */ 4279 strings: { 4280 valueFn: function() { 4281 return defaults.STRINGS; 4282 } 4283 }, 4284 4285 /** 4286 * If `true` the field will be validated on blur event. 4287 * 4288 * @attribute validateOnBlur 4289 * @default true 4290 * @type Boolean 4291 */ 4292 validateOnBlur: { 4293 value: true, 4294 validator: isBoolean 4295 }, 4296 4297 /** 4298 * If `true` the field will be validated on input event. 4299 * 4300 * @attribute validateOnInput 4301 * @default false 4302 * @type Boolean 4303 */ 4304 validateOnInput: { 4305 value: false, 4306 validator: isBoolean 4307 }, 4308 4309 /** 4310 * Defines the CSS valid class. 4311 * 4312 * @attribute validClass
4313 * @type String 4314 */ 4315 validClass: { 4316 value: CSS_SUCCESS_FIELD, 4317 validator: isString 4318 } 4319 }, 4320 4321 /** 4322 * Creates custom rules from user input. 4323 * 4324 * @method _setCustomRules 4325 * @param object 4326 * @protected 4327 */ 4328 _setCustomRules: function(object) { 4329 A.each( 4330 object, 4331 function(rule, fieldName) { 4332 A.config.FormValidator.RULES[fieldName] = rule.condition; 4333 A.config.FormValidator.STRINGS[fieldName] = rule.errorMessage; 4334 } 4335 ); 4336 }, 4337 4338 /** 4339 * Ability to add custom validation rules. 4340 * 4341 * @method customRules 4342 * @param object 4343 * @public 4344 * @static 4345 */ 4346 addCustomRules: function(object) { 4347 var instance = this; 4348 4349 if (isObject(object)) { 4350 instance._setCustomRules(object); 4351 } 4352 }, 4353 4354 /** 4355 * Checks if a node is a checkbox or radio input. 4356 * 4357 * @method isCheckable 4358 * @param node 4359 * @private 4360 * @return {Boolean} 4361 */ 4362 isCheckable: function(node) { 4363 var nodeType = node.get('type').toLowerCase(); 4364 4365 return (nodeType === 'checkbox' || nodeType === 'radio'); 4366 }, 4367 4368 /** 4369 * Static property used to define which component it extends. 4370 * 4371 * @property EXTENDS 4372 * @type Object 4373 * @static 4374 */ 4375 EXTENDS: A.Base, 4376 4377 prototype: { 4378 4379 /** 4380 * Construction logic executed during `A.FormValidator` instantiation. 4381 * Lifecycle. 4382 * 4383 * @method initializer 4384 * @protected 4385 */ 4386 initializer: function() { 4387 var instance = this; 4388 4389 instance.errors = {}; 4390 instance._blurHandlers = null; 4391 instance._fileBlurHandlers = null; 4392 instance._fileInputHandlers = null; 4393 instance._inputHandlers = null; 4394 instance._rulesAlreadyExtracted = false; 4395 instance._stackErrorContainers = {}; 4396 4397 instance.bindUI(); 4398 instance._uiSetValidateOnBlur(instance.get('validateOnBlur')); 4399 instance._uiSetValidateOnInput(instance.get('validateOnInput')); 4400 }, 4401 4402 /** 4403 * Bind the events on the `A.FormValidator` UI. Lifecycle. 4404 * 4405 * @method bindUI 4406 * @protected 4407 */ 4408 bindUI: function() { 4409 var instance = this, 4410 boundingBox = instance.get('boundingBox'); 4411 4412 var onceFocusHandler = boundingBox.delegate('focus', function() { 4413 instance._setARIARoles(); 4414 onceFocusHandler.detach(); 4415 }, 'input,select,textarea,button'); 4416 4417 instance.publish({ 4418 errorField: { 4419 defaultFn: instance._defErrorFieldFn 4420 }, 4421 validField: { 4422 defaultFn: instance._defValidFieldFn 4423 }, 4424 validateField: { 4425 defaultFn: instance._defValidateFieldFn 4426 } 4427 }); 4428 4429 boundingBox.on({ 4430 reset: A.bind(instance._onFormReset, instance), 4431 submit: A.bind(instance._onFormSubmit, instance) 4432 }); 4433 4434 instance.after({ 4435 extractRulesChange: instance._afterExtractRulesChange, 4436 validateOnBlurChange: instance._afterValidateOnBlurChange, 4437 validateOnInputChange: instance._afterValidateOnInputChange 4438 }); 4439 }, 4440 4441 /** 4442 * Adds a validation error in the field. 4443 * 4444 * @method addFieldError 4445 * @param {Node} field 4446 * @param ruleName 4447 */ 4448 addFieldError: function(field, ruleName) { 4449 var instance = this, 4450 errors = instance.errors, 4451 name = field.get('name'); 4452 4453 if (!errors[name]) { 4454 errors[name] = []; 4455 } 4456 4457 errors[name].push(ruleName); 4458 }, 4459 4460 /** 4461 * Deletes the field from the errors property object. 4462 * 4463 * @method clearFieldError 4464 * @param {Node|String} field 4465 */ 4466 clearFieldError: function(field) { 4467 var fieldName = isNode(field) ? field.get('name') : field; 4468 4469 if (isString(fieldName)) { 4470 delete this.errors[fieldName]; 4471 } 4472 }, 4473 4474 /** 4475 * Executes a function to each rule. 4476 * 4477 * @method eachRule 4478 * @param fn 4479 */ 4480 eachRule: function(fn) { 4481 var instance = this; 4482 4483 A.each( 4484 instance.get('rules'), 4485 function(rule, fieldName) { 4486 if (isFunction(fn)) { 4487 fn.apply(instance, [rule, fieldName]); 4488 } 4489 } 4490 ); 4491 }, 4492 4493 /** 4494 * Gets the ancestor of a given field. 4495 * 4496 * @method findFieldContainer 4497 * @param {Node} field 4498 * @return {Node} 4499 */ 4500 findFieldContainer: function(field) { 4501 var instance = this, 4502 fieldContainer = instance.get('fieldContainer'); 4503 4504 if (fieldContainer) { 4505 return field.ancestor(fieldContainer); 4506 } 4507 }, 4508 4509 /** 4510 * Focus on the invalid field. 4511 *
4512 * @method focusInvalidField 4513 */ 4514 focusInvalidField: function() { 4515 var instance = this, 4516 boundingBox = instance.get('boundingBox'), 4517 field = boundingBox.one('.' + CSS_ERROR_FIELD); 4518 4519 if (field) { 4520 field = instance.findFieldContainer(field); 4521 4522 if (instance.get('selectText')) { 4523 field.selectText(); 4524 } 4525 4526 field.focus(); 4527 4528 field.scrollIntoView(false); 4529 4530 window.scrollBy(0, field.getDOM().scrollHeight); 4531 } 4532 }, 4533 4534 /** 4535 * Gets a field from the form. 4536 * 4537 * @method getField 4538 * @param {Node|String} field 4539 * @return {Node} 4540 */ 4541 getField: function(field) { 4542 var instance = this; 4543 4544 if (isString(field)) { 4545 field = instance.getFieldsByName(field); 4546 4547 if (field && field.length && !field.name) { 4548 field = field[0]; 4549 } 4550 } 4551 4552 return A.one(field); 4553 }, 4554 4555 /** 4556 * Gets a list of fields based on its name. 4557 * 4558 * @method getFieldsByName 4559 * @param fieldName 4560 * @return {NodeList} 4561 */ 4562 getFieldsByName: function(fieldName) { 4563 var instance = this, 4564 domBoundingBox = instance.get('boundingBox').getDOM(); 4565 4566 return domBoundingBox.elements[fieldName]; 4567 }, 4568 4569 /** 4570 * Gets a list of fields with errors. 4571 * 4572 * @method getFieldError 4573 * @param {Node} field 4574 * @return {String} 4575 */ 4576 getFieldError: function(field) { 4577 var instance = this; 4578 4579 return instance.errors[field.get('name')]; 4580 }, 4581 4582 /** 4583 * Gets the stack error container of a field. 4584 * 4585 * @method getFieldStackErrorContainer 4586 * @param {Node|String} field 4587 * @return {Node} 4588 */ 4589 getFieldStackErrorContainer: function(field) { 4590 var instance = this, 4591 name = isNode(field) ? field.get('name') : field, 4592 stackContainers = instance._stackErrorContainers; 4593 4594 if (!stackContainers[name]) { 4595 stackContainers[name] = instance.get('stackErrorContainer'); 4596 } 4597 4598 return stackContainers[name]; 4599 }, 4600 4601 /** 4602 * Gets the error message of a field. 4603 * 4604 * @method getFieldErrorMessage 4605 * @param {Node} field 4606 * @param rule 4607 * @return {String} 4608 */ 4609 getFieldErrorMessage: function(field, rule) { 4610 var instance = this, 4611 fieldName = field.get('name'), 4612 fieldStrings = instance.get('fieldStrings')[fieldName] || {}, 4613 fieldRules = instance.get('rules')[fieldName], 4614 fieldLabel = instance._findFieldLabel(field), 4615 strings = instance.get('strings'), 4616 substituteRulesMap = {}; 4617 4618 if (fieldLabel) { 4619 substituteRulesMap.field = fieldLabel; 4620 } 4621 4622 if (rule in fieldRules) { 4623 var ruleValue = A.Array(fieldRules[rule]); 4624 4625 A.each( 4626 ruleValue, 4627 function(value, index) { 4628 substituteRulesMap[index] = [value].join(''); 4629 } 4630 ); 4631 } 4632 4633 var message = (fieldStrings[rule] || strings[rule] || strings.DEFAULT); 4634 4635 return Lang.sub(message, substituteRulesMap); 4636 }, 4637 4638 /** 4639 * Returns `true` if there are errors. 4640 * 4641 * @method hasErrors 4642 * @return {Boolean} 4643 */ 4644 hasErrors: function() { 4645 var instance = this; 4646 4647 return !isEmpty(instance.errors); 4648 }, 4649 4650 /** 4651 * Highlights a field with error or success. 4652 * 4653 * @method highlight 4654 * @param {Node} field 4655 * @param valid 4656 */ 4657 highlight: function(field, valid) { 4658 var instance = this, 4659 fieldContainer, 4660 fieldName, 4661 namedFieldNodes; 4662 4663 if (field) { 4664 fieldContainer = instance.findFieldContainer(field); 4665 4666 fieldName = field.get('name'); 4667 4668 if (this.validatable(field)) { 4669 namedFieldNodes = A.all(instance.getFieldsByName(fieldName)); 4670 4671 namedFieldNodes.each( 4672 function(node) { 4673 instance._highlightHelper( 4674 node, 4675 instance.get('errorClass'), 4676 instance.get('validClass'),
4677 valid 4678 ); 4679 } 4680 ); 4681 4682 if (fieldContainer) { 4683 instance._highlightHelper( 4684 fieldContainer, 4685 instance.get('containerErrorClass'), 4686 instance.get('containerValidClass'), 4687 valid 4688 ); 4689 } 4690 } 4691 else if (!field.val()) { 4692 instance.resetField(fieldName); 4693 } 4694 } 4695 }, 4696 4697 /** 4698 * Normalizes rule value. 4699 * 4700 * @method normalizeRuleValue 4701 * @param ruleValue 4702 * @param {Node} field 4703 */ 4704 normalizeRuleValue: function(ruleValue, field) { 4705 var instance = this; 4706 4707 return isFunction(ruleValue) ? ruleValue.apply(instance, [field]) : ruleValue; 4708 }, 4709 4710 /** 4711 * Removes the highlight of a field. 4712 * 4713 * @method unhighlight 4714 * @param {Node} field 4715 */ 4716 unhighlight: function(field) { 4717 var instance = this; 4718 4719 instance.highlight(field, true); 4720 }, 4721 4722 /** 4723 * Prints the stack error messages into a container. 4724 * 4725 * @method printStackError 4726 * @param {Node} field 4727 * @param {Node} container 4728 * @param {Array} errors 4729 */ 4730 printStackError: function(field, container, errors) { 4731 var instance = this; 4732 4733 if (!instance.get('showAllMessages')) { 4734 if (A.Array.indexOf(errors, 'required') !== -1) { 4735 errors = ['required']; 4736 } 4737 else { 4738 errors = errors.slice(0, 1); 4739 } 4740 } 4741 4742 container.empty(); 4743 4744 A.Array.each( 4745 errors, 4746 function(error) { 4747 var message = instance.getFieldErrorMessage(field, error), 4748 messageEl = instance.get('messageContainer').addClass(error); 4749 4750 container.append( 4751 messageEl.html(message) 4752 ); 4753 } 4754 ); 4755 }, 4756 4757 /** 4758 * Resets the CSS class and content of all fields. 4759 * 4760 * @method resetAllFields 4761 */ 4762 resetAllFields: function() { 4763 var instance = this; 4764 4765 instance.eachRule( 4766 function(rule, fieldName) { 4767 instance.resetField(fieldName); 4768 } 4769 ); 4770 }, 4771 4772 /** 4773 * Resets the CSS class and error status of a field. 4774 * 4775 * @method resetField 4776 * @param {Node|String} field 4777 */ 4778 resetField: function(field) { 4779 var instance = this, 4780 fieldName, 4781 fieldRules, 4782 namedFieldNodes, 4783 stackContainer; 4784 4785 fieldName = isNode(field) ? field.get('name') : field; 4786 4787 if (fieldName) { 4788 fieldRules = instance.get('rules')[fieldName]; 4789 4790 if (fieldRules) { 4791 instance.clearFieldError(fieldName); 4792 4793 stackContainer = instance.getFieldStackErrorContainer(fieldName); 4794 4795 stackContainer.remove(); 4796 4797 namedFieldNodes = A.all(instance.getFieldsByName(fieldName)); 4798 4799 namedFieldNodes.each( 4800 function(node) { 4801 instance.resetFieldCss(node); 4802 node.removeAttribute('aria-errormessage'); 4803 node.removeAttribute('aria-invalid'); 4804 } 4805 ); 4806 } 4807 } 4808 }, 4809 4810 /** 4811 * Removes the CSS classes of a field. 4812 * 4813 * @method resetFieldCss 4814 * @param {Node} field 4815 */ 4816 resetFieldCss: function(field) { 4817 var instance = this, 4818 fieldContainer = instance.findFieldContainer(field); 4819 4820 var removeClasses = function(elem, classAttrs) { 4821 if (elem) { 4822 A.each(classAttrs, function(attrName) { 4823 elem.removeClass( 4824 instance.get(attrName) 4825 ); 4826 }); 4827 } 4828 }; 4829 4830 removeClasses(field, ['validClass', 'errorClass']); 4831 removeClasses(fieldContainer, ['containerValidClass', 'containerErrorClass']); 4832 }, 4833 4834 /** 4835 * Checks if a field can be validated or not. 4836 * 4837 * @method validatable 4838 * @param {Node} field 4839 * @return {Boolean} 4840 */ 4841 validatable: function(field) { 4842 var instance = this, 4843 validatable = false, 4844 fieldRules = instance.get('rules')[field.get('name')]; 4845 4846 if (fieldRules) { 4847 validatable = instance.normalizeRuleValue(fieldRules.required, field) || 4848 defaults.RULES.hasValue.apply(instance, [field.val(), field]); 4849 } 4850 4851 return !!validatable; 4852 }, 4853 4854 /** 4855 * Validates all fields. 4856 * 4857 * @method validate 4858 */ 4859 validate: function() { 4860 var instance = this; 4861 4862 instance.eachRule( 4863 function(rule, fieldName) { 4864 instance.validateField(fieldName); 4865 } 4866 ); 4867 4868 instance.focusInvalidField(); 4869 }, 4870 4871 /** 4872 * Validates a single field. 4873 * 4874 * @method validateField 4875 * @param {Node|String} field 4876 */ 4877 validateField: function(field) { 4878 var fieldNode, 4879 validatable; 4880 4881 this.resetField(field); 4882 fieldNode = isString(field) ? this.getField(field) : field; 4883 4884 if (isNode(fieldNode)) { 4885 validatable = this.validatable(fieldNode); 4886 4887 if (validatable) { 4888 this.fire('validateField', { 4889 validator: { 4890 field: fieldNode 4891 } 4892 }); 4893 } 4894 } 4895 }, 4896 4897 /** 4898 * Fires after `extractRules` attribute change. 4899 *
4900 * @method _afterExtractRulesChange 4901 * @param event 4902 * @protected 4903 */ 4904 _afterExtractRulesChange: function(event) { 4905 var instance = this; 4906 4907 instance._uiSetExtractRules(event.newVal); 4908 }, 4909 4910 /** 4911 * Fires after `validateOnBlur` attribute change. 4912 * 4913 * @method _afterValidateOnBlurChange 4914 * @param event 4915 * @protected 4916 */ 4917 _afterValidateOnBlurChange: function(event) { 4918 var instance = this; 4919 4920 instance._uiSetValidateOnBlur(event.newVal); 4921 }, 4922 4923 /** 4924 * Fires after `validateOnInput` attribute change. 4925 * 4926 * @method _afterValidateOnInputChange 4927 * @param event 4928 * @protected 4929 */ 4930 _afterValidateOnInputChange: function(event) { 4931 var instance = this; 4932 4933 instance._uiSetValidateOnInput(event.newVal); 4934 }, 4935 4936 /** 4937 * Defines an error field. 4938 * 4939 * @method _defErrorFieldFn 4940 * @param event 4941 * @protected 4942 */ 4943 _defErrorFieldFn: function(event) { 4944 var instance = this, 4945 field, 4946 label, 4947 stackContainer, 4948 target, 4949 validator; 4950 4951 label = instance.get('labelCssClass'); 4952 validator = event.validator; 4953 field = validator.field; 4954 4955 instance.highlight(field); 4956 4957 if (instance.get('showMessages')) { 4958 target = field; 4959 4960 stackContainer = instance.getFieldStackErrorContainer(field); 4961 4962 if (A.FormValidator.isCheckable(target)) { 4963 target = field.ancestor('.' + CSS_HAS_ERROR).get('lastChild'); 4964 } 4965 4966 var id = field.get('id') + 'Helper'; 4967 4968 stackContainer.set('id', id); 4969 4970 target.placeAfter(stackContainer); 4971 4972 instance.printStackError( 4973 field, 4974 stackContainer, 4975 validator.errors 4976 ); 4977 } 4978 }, 4979 4980 /** 4981 * Defines a valid field. 4982 * 4983 * @method _defValidFieldFn 4984 * @param event 4985 * @protected 4986 */ 4987 _defValidFieldFn: function(event) { 4988 var instance = this; 4989 4990 var field = event.validator.field; 4991 4992 instance.unhighlight(field); 4993 }, 4994 4995 /** 4996 * Defines the validation of a field. 4997 * 4998 * @method _defValidateFieldFn 4999 * @param event 5000 * @protected 5001 */ 5002 _defValidateFieldFn: function(event) { 5003 var instance = this; 5004 5005 var field = event.validator.field; 5006 var fieldRules = instance.get('rules')[field.get('name')]; 5007 5008 A.each( 5009 fieldRules, 5010 function(ruleValue, ruleName) { 5011 var rule = defaults.RULES[ruleName]; 5012 var fieldValue = trim(field.val()); 5013 5014 ruleValue = instance.normalizeRuleValue(ruleValue, field); 5015 5016 if (isFunction(rule) && !rule.apply(instance, [fieldValue, field, ruleValue])) { 5017 5018 instance.addFieldError(field, ruleName); 5019 } 5020 } 5021 ); 5022 5023 var fieldErrors = instance.getFieldError(field); 5024 5025 if (fieldErrors) { 5026 instance.fire('errorField', { 5027 validator: { 5028 field: field, 5029 errors: fieldErrors 5030 } 5031 }); 5032 } 5033 else { 5034 instance.fire('validField', { 5035 validator: { 5036 field: field 5037 } 5038 }); 5039 } 5040 }, 5041 5042 /** 5043 * Finds the label text of a field if existing. 5044 * 5045 * @method _findFieldLabel 5046 * @param {Node} field 5047 * @return {String} 5048 */ 5049 _findFieldLabel: function(field) { 5050 var labelCssClass = '.' + this.get('labelCssClass'),
5051 label = A.one('label[for=' + field.get('id') + ']') || 5052 field.ancestor().previous(labelCssClass); 5053 5054 if (!label) { 5055 label = field.ancestor('.' + CSS_HAS_ERROR); 5056 5057 if (label) { 5058 label = label.one(labelCssClass); 5059 } 5060 } 5061 5062 if (label) { 5063 return label.get('text'); 5064 } 5065 }, 5066 5067 /** 5068 * Sets the error/success CSS classes based on the validation of a 5069 * field. 5070 * 5071 * @method _highlightHelper 5072 * @param {Node} field 5073 * @param {String} errorClass 5074 * @param {String} validClass 5075 * @param {Boolean} valid 5076 * @protected 5077 */ 5078 _highlightHelper: function(field, errorClass, validClass, valid) { 5079 var instance = this; 5080 5081 if (valid) { 5082 field.removeClass(errorClass).addClass(validClass); 5083 5084 if (validClass === CSS_SUCCESS_FIELD) { 5085 field.removeAttribute('aria-errormessage'); 5086 field.removeAttribute('aria-invalid'); 5087 } 5088 } 5089 else { 5090 field.removeClass(validClass).addClass(errorClass); 5091 5092 if (errorClass === CSS_ERROR_FIELD) { 5093 field.set('aria-errormessage', field.get('id') + 'Helper'); 5094 field.set('aria-invalid', true); 5095 } 5096 } 5097 }, 5098 5099 /** 5100 * Extracts form rules from the DOM. 5101 * 5102 * @method _extractRulesFromMarkup 5103 * @param rules 5104 * @protected 5105 */ 5106 _extractRulesFromMarkup: function(rules) { 5107 var instance = this, 5108 domBoundingBox = instance.get('boundingBox').getDOM(), 5109 elements = domBoundingBox.elements, 5110 defaultRulesKeys = AObject.keys(defaults.RULES), 5111 defaultRulesJoin = defaultRulesKeys.join('|'), 5112 regex = getRegExp('field-(' + defaultRulesJoin + ')', 'g'), 5113 i, 5114 length, 5115 ruleNameMatch = [], 5116 ruleMatcher = function(m1, m2) { 5117 ruleNameMatch.push(m2); 5118 }; 5119 5120 for (i = 0, length = elements.length; i < length; i++) { 5121 var el = elements[i], 5122 fieldName = el.name; 5123 5124 el.className.replace(regex, ruleMatcher); 5125 5126 if (ruleNameMatch.length) { 5127 var fieldRules = rules[fieldName], 5128 j, 5129 ruleNameLength; 5130 5131 if (!fieldRules) { 5132 fieldRules = {}; 5133 rules[fieldName] = fieldRules; 5134 } 5135 for (j = 0, ruleNameLength = ruleNameMatch.length; j < ruleNameLength; j++) { 5136 var rule = ruleNameMatch[j]; 5137 5138 if (!(rule in fieldRules)) { 5139 fieldRules[rule] = true; 5140 } 5141 } 5142 ruleNameMatch.length = 0; 5143 } 5144 } 5145 5146 instance._rulesAlreadyExtracted = true; 5147 }, 5148 5149 /** 5150 * Triggers when there's an input in the field. 5151 * 5152 * @method _onFieldInput 5153 * @param event 5154 * @protected 5155 */ 5156 _onFieldInput: function(event) { 5157 var instance = this; 5158 5159 var skipValidationTargetSelector = instance.get('skipValidationTargetSelector'); 5160 5161 if (!event.relatedTarget || !event.relatedTarget.getDOMNode().matches(skipValidationTargetSelector)) { 5162 setTimeout( 5163 function() { 5164 instance.validateField(event.target); 5165 }, 5166 300 5167 ); 5168 } 5169 }, 5170 5171 /** 5172 * Triggers when the form is submitted. 5173 * 5174 * @method _onFormSubmit 5175 * @param event 5176 * @protected 5177 */ 5178 _onFormSubmit: function(event) { 5179 var instance = this; 5180 5181 var data = { 5182 validator: { 5183 formEvent: event 5184 } 5185 }; 5186 5187 instance.validate(); 5188 5189 if (instance.hasErrors()) { 5190 data.validator.errors = instance.errors; 5191 5192 instance.fire('submitError', data); 5193 5194 event.halt(); 5195 } 5196 else { 5197 instance.fire('submit', data); 5198 } 5199 }, 5200 5201 /** 5202 * Triggers when the form is reseted. 5203 * 5204 * @method _onFormReset 5205 * @param event 5206 * @protected 5207 */ 5208 _onFormReset: function() { 5209 var instance = this; 5210 5211 instance.resetAllFields(); 5212 }, 5213 5214 /** 5215 * Sets the aria roles. 5216 * 5217 * @method _setARIARoles 5218 * @protected 5219 */ 5220 _setARIARoles: function() { 5221 var instance = this; 5222 5223 instance.eachRule( 5224 function(rule, fieldName) { 5225 var field = instance.getField(fieldName); 5226 5227 var required = instance.normalizeRuleValue(rule.required, field); 5228 5229 if (required) { 5230 if (field && !field.attr('aria-required')) { 5231 field.attr('aria-required', true); 5232 } 5233 } 5234 } 5235 ); 5236 }, 5237 5238 /** 5239 * Sets the `extractRules` attribute on the UI. 5240 * 5241 * @method _uiSetExtractRules 5242 * @param val 5243 * @protected 5244 */ 5245 _uiSetExtractRules: function(val) { 5246 var instance = this; 5247 if (val) { 5248 instance._extractRulesFromMarkup(instance.get('rules')); 5249 } 5250 }, 5251 5252 /** 5253 * Sets the `validateOnInput` attribute on the UI. 5254 * 5255 * @method _uiSetValidateOnInput 5256 * @param val 5257 * @protected 5258 */ 5259 _uiSetValidateOnInput: function(val) { 5260 var instance = this, 5261 boundingBox = instance.get('boundingBox'); 5262 5263 if (val) { 5264 if (!instance._inputHandlers) { 5265 instance._inputHandlers = boundingBox.delegate('input', instance._onFieldInput, 5266 'input:not([type="file"]),select,textarea,button', instance); 5267 } 5268 5269 if (!instance._fileInputHandlers) { 5270 instance._fileInputHandlers = boundingBox.delegate('change', instance._onFieldInput, 5271 'input[type="file"]', instance); 5272 } 5273 } 5274 else { 5275 if (instance._inputHandlers) { 5276 instance._inputHandlers.detach(); 5277 } 5278 5279 if (instance._fileInputHandlers) { 5280 instance._fileInputHandlers.detach(); 5281 } 5282 } 5283 }, 5284 5285 /** 5286 * Sets the `validateOnBlur` attribute on the UI. 5287 * 5288 * @method _uiSetValidateOnBlur 5289 * @param val 5290 * @protected 5291 */ 5292 _uiSetValidateOnBlur: function(val) { 5293 var instance = this, 5294 boundingBox = instance.get('boundingBox'); 5295 5296 if (val) { 5297 if (!instance._blurHandlers) { 5298 instance._blurHandlers = boundingBox.delegate('blur', instance._onFieldInput, 5299 'input:not([type="file"]),select,textarea,button', instance); 5300 } 5301 5302 if (!instance._fileBlurHandlers) { 5303 instance._fileBlurHandlers = boundingBox.delegate('change', instance._onFieldInput, 5304 'input[type="file"]', instance); 5305 } 5306 } 5307 else { 5308 if (instance._blurHandlers) { 5309 instance._blurHandlers.detach(); 5310 } 5311 5312 if (instance._fileBlurHandlers) { 5313 instance._fileBlurHandlers.detach(); 5314 } 5315 } 5316 } 5317 } 5318}); 5319 5320A.each( 5321 defaults.REGEX, 5322 function(regex, key) { 5323 defaults.RULES[key] = function(val) { 5324 return defaults.REGEX[key].test(val); 5325 }; 5326 } 5327); 5328 5329A.FormValidator = FormValidator; 5330 5331}, '3.1.0-deprecated.77', { 5332 "requires": [ 5333 "escape", 5334 "selector-css3", 5335 "node-event-delegate", 5336 "aui-node", 5337 "aui-component", 5338 "aui-event-input" 5339 ] 5340}); 5341 5342YUI.add('aui-node-base', function (A, NAME) { 5343 5344/** 5345 * A set of utility methods to the Node. 5346 * 5347 * @module aui-node 5348 * @submodule aui-node-base 5349 */ 5350 5351var Lang = A.Lang, 5352 isArray = Lang.isArray, 5353 isFunction = Lang.isFunction, 5354 isObject = Lang.isObject, 5355 isString = Lang.isString, 5356 isUndefined = Lang.isUndefined, 5357 isValue = Lang.isValue, 5358 5359 AArray = A.Array, 5360 ANode = A.Node, 5361 ANodeList = A.NodeList, 5362 5363 getClassName = A.getClassName, 5364 getRegExp = A.DOM._getRegExp, 5365 5366 CONFIG = A.config, 5367 DOC = CONFIG.doc, 5368 WIN = CONFIG.win, 5369 5370 NODE_PROTO = ANode.prototype, 5371 NODE_PROTO_HIDE = NODE_PROTO._hide, 5372 NODE_PROTO_SHOW = NODE_PROTO._show, 5373 NODELIST_PROTO = ANodeList.prototype, 5374 5375 ARRAY_EMPTY_STRINGS = ['', ''], 5376 5377 CSS_HIDE = getClassName('hide'), 5378 CSS_UNSELECTABLE_VALUE = 'none', 5379 CSS_SELECTABLE_VALUE = 'text', 5380 5381 SUPPORT_CLONED_EVENTS = false, 5382 5383 MAP_BORDER = { 5384 b: 'borderBottomWidth', 5385 l: 'borderLeftWidth', 5386 r: 'borderRightWidth', 5387 t: 'borderTopWidth' 5388 }, 5389 MAP_MARGIN = { 5390 b: 'marginBottom', 5391 l: 'marginLeft', 5392 r: 'marginRight', 5393 t: 'marginTop' 5394 }, 5395 MAP_PADDING = { 5396 b: 'paddingBottom', 5397 l: 'paddingLeft', 5398 r: 'paddingRight', 5399 t: 'paddingTop' 5400 }; 5401 5402/* Parts of this file are used from jQuery (http://jquery.com) 5403 * Dual-licensed under MIT/GPL 5404 */ 5405var div = DOC.createElement('div'); 5406 5407div.style.display = 'none'; 5408div.innerHTML = ' <table></table> '; 5409 5410if (div.attachEvent && div.fireEvent) { 5411 div.attachEvent( 5412 'onclick', 5413 function detach() { 5414 SUPPORT_CLONED_EVENTS = true; 5415 5416 div.detachEvent('onclick', detach); 5417 } 5418 ); 5419 5420 div.cloneNode(true).fireEvent('onclick'); 5421} 5422 5423var SUPPORT_OPTIONAL_TBODY = !div.getElementsByTagName('tbody').length; 5424 5425var REGEX_LEADING_WHITE_SPACE = /^\s+/, 5426 REGEX_IE8_ACTION = /\=([^=\x27\x22>\s]+\/)>/g, 5427 REGEX_TAGNAME = /<([\w:]+)/; 5428 5429div = null; 5430 5431var _setUnselectable = function(element, unselectable, noRecurse) { 5432 var descendants, 5433 value = unselectable ? 'on' : '', 5434 i, 5435 descendant; 5436 5437 element.setAttribute('unselectable', value); 5438 5439 if (!noRecurse) { 5440 descendants = element.getElementsByTagName('*'); 5441 5442 for (i = 0;
5443 (descendant = descendants[i]); i++) { 5444 descendant.setAttribute('unselectable', value); 5445 } 5446 } 5447}; 5448 5449/** 5450 * Augments the [YUI3 Node](Node.html) with more util methods. 5451 * 5452 * Check the [live demo](http://alloyui.com/examples/node/). 5453 * 5454 * @class A.Node 5455 * @uses Node 5456 * @constructor 5457 * @include http://alloyui.com/examples/node/basic-markup.html 5458 * @include http://alloyui.com/examples/node/basic.js 5459 */ 5460A.mix(NODE_PROTO, { 5461 5462 /** 5463 * Returns the current ancestors of the node element filtered by a 5464 * className. This is an optimized method for finding ancestors by a 5465 * specific CSS class name. 5466 * 5467 * Example: 5468 * 5469 * ``` 5470 * A.one('#nodeId').ancestorsByClassName('aui-hide'); 5471 * ``` 5472 * 5473 * @method ancestorsByClassName 5474 * @param {String} className A selector to filter the ancestor elements 5475 * against. 5476 * @param {Boolean} testSelf optional Whether or not to include the element 5477 * in the scan 5478 * @return {NodeList} 5479 */ 5480 ancestorsByClassName: function(className, testSelf) { 5481 var instance = this; 5482 5483 var ancestors = []; 5484 var cssRE = new RegExp('\\b' + className + '\\b'); 5485 var currentEl = instance.getDOM(); 5486 5487 if (!testSelf) { 5488 currentEl = currentEl.parentNode; 5489 } 5490 5491 while (currentEl && currentEl.nodeType !== 9) { 5492 if (currentEl.nodeType === 1 && cssRE.test(currentEl.className)) { 5493 ancestors.push(currentEl); 5494 } 5495 5496 currentEl = currentEl.parentNode; 5497 } 5498 5499 return A.all(ancestors); 5500 }, 5501 5502 /** 5503 * Gets or sets the value of an attribute for the first element in the set 5504 * of matched elements. If only the `name` is passed it works as a getter. 5505 * 5506 * Example: 5507 * 5508 * ``` 5509 * var node = A.one('#nodeId'); 5510 * node.attr('title', 'Setting a new title attribute'); 5511 * // Alert the value of the title attribute: 'Setting a new title attribute' 5512 * alert( node.attr('title') ); 5513 * ``` 5514 * 5515 * @method attr 5516 * @param {String} name The name of the attribute 5517 * @param {String} value The value of the attribute to be set. Optional. 5518 * @return {String} 5519 */ 5520 attr: function(name, value) { 5521 var instance = this, 5522 i; 5523 5524 if (!isUndefined(value)) { 5525 var el = instance.getDOM(); 5526 5527 if (name in el) { 5528 instance.set(name, value); 5529 } 5530 else { 5531 instance.setAttribute(name, value); 5532 } 5533 5534 return instance; 5535 } 5536 else { 5537 if (isObject(name)) { 5538 for (i in name) { 5539 if (name.hasOwnProperty(i)) { 5540 instance.attr(i, name[i]); 5541 } 5542 } 5543 5544 return instance; 5545 } 5546 5547 var currentValue = instance.get(name); 5548 5549 if (!Lang.isValue(currentValue)) { 5550 currentValue = instance.getAttribute(name); 5551 } 5552 5553 return currentValue; 5554 } 5555 }, 5556 5557 /** 5558 * Normalizes the behavior of cloning a node, which by default should not 5559 * clone the events that are attached to it. 5560 * 5561 * Example: 5562 * 5563 * ``` 5564 * var node = A.one('#nodeId'); 5565 * node.clone().appendTo('body'); 5566 * ``` 5567 * 5568 * @method clone 5569 * @return {Node} 5570 */ 5571 clone: (function() { 5572 var clone; 5573 5574 if (SUPPORT_CLONED_EVENTS) { 5575 clone = function() { 5576 var el = this.getDOM(); 5577 var clone; 5578 5579 if (el.nodeType !== 3) { 5580 var outerHTML = this.outerHTML(); 5581 5582 outerHTML = outerHTML.replace(REGEX_IE8_ACTION, '="$1">').replace(REGEX_LEADING_WHITE_SPACE, 5583 ''); 5584 5585 clone = ANode.create(outerHTML); 5586 } 5587 else { 5588 clone = A.one(el.cloneNode()); 5589 } 5590 5591 return clone; 5592 }; 5593 } 5594 else { 5595 clone = function() { 5596 return this.cloneNode(true); 5597 }; 5598 } 5599 5600 return clone; 5601 }()), 5602 5603 /** 5604 * Centralizes the current Node instance with the passed `val` Array, Node, 5605 * String, or Region, if not specified, the body will be used. 5606 * 5607 * Example: 5608 * 5609 * ``` 5610 * var node = A.one('#nodeId'); 5611 * // Center the `node` with the `#container`. 5612 * node.center('#container'); 5613 * ``` 5614 * 5615 * @method center 5616 * @chainable 5617 * @param {Array|Node|Region|String} val Array, Node, String, or Region to 5618 * center with. 5619 */ 5620 center: function(val) { 5621 var instance = this, 5622 nodeRegion = instance.get('region'), 5623 x, 5624 y; 5625 5626 if (isArray(val)) { 5627 x = val[0]; 5628 y = val[1]; 5629 } 5630 else { 5631 var region; 5632 5633 if (isObject(val) && !A.instanceOf(val, ANode)) { 5634 region = val; 5635 } 5636 else { 5637 region = (A.one(val) || A.getBody()).get('region'); 5638 } 5639 5640 x = region.left + (region.width / 2); 5641 y = region.top + (region.height / 2); 5642 } 5643 5644 instance.setXY([x - (nodeRegion.width / 2), y - (nodeRegion.height / 2)]); 5645 }, 5646 5647 /** 5648 * Removes not only child (and other descendant) elements, but also any text 5649 * within the set of matched elements. This is because, according to the DOM 5650 * specification, any string of text within an element is considered a child 5651 * node of that element. 5652 * 5653 * Example: 5654 * 5655 * ``` 5656 * var node = A.one('#nodeId'); 5657 * node.empty(); 5658 * ``` 5659 * 5660 * @method empty 5661 * @chainable 5662 */ 5663 empty: function() { 5664 var instance = this; 5665 5666 instance.all('>*').remove().purge(); 5667 5668 var el = ANode.getDOMNode(instance); 5669 5670 while (el.firstChild) { 5671 el.removeChild(el.firstChild); 5672 } 5673 5674 return instance; 5675 }, 5676 5677 /** 5678 * Retrieves the DOM node bound to a Node instance. See 5679 * [getDOMNode](Node.html#method_getDOMNode). 5680 * 5681 * @method getDOM 5682 * @return {HTMLNode} The DOM node bound to the Node instance. 5683 */ 5684 getDOM: function() { 5685 var instance = this; 5686 5687 return ANode.getDOMNode(instance); 5688 }, 5689 5690 /** 5691 * Returns the combined width of the border for the specified sides. 5692 * 5693 * @method getBorderWidth 5694 * @param {String} sides Can be t, r, b, l or any combination of those to 5695 * represent the top, right, bottom, or left sides. 5696 * @return {Number} 5697 */ 5698 getBorderWidth: function(sides) { 5699 var instance = this; 5700 5701 return instance._getBoxStyleAsNumber(sides, MAP_BORDER); 5702 }, 5703 5704 /** 5705 * Gets the current center position of the node in page coordinates. 5706 * 5707 * @method getCenterXY 5708 * @for Node 5709 * @return {Array} The XY position of the node 5710 */ 5711 getCenterXY: function() { 5712 var instance = this; 5713 var region = instance.get('region'); 5714 5715 return [(region.left + region.width / 2), (region.top + region.height / 2)]; 5716 }, 5717 5718 /** 5719 * Returns the combined size of the margin for the specified sides. 5720 * 5721 * @method getMargin 5722 * @param {String} sides Can be t, r, b, l or any combination of those to 5723 * represent the top, right, bottom, or left sides. 5724 * @return {Number} 5725 */ 5726 getMargin: function(sides) { 5727 var instance = this; 5728 5729 return instance._getBoxStyleAsNumber(sides, MAP_MARGIN); 5730 }, 5731 5732 /** 5733 * Returns the combined width of the border for the specified sides. 5734 * 5735 * @method getPadding 5736 * @param {String} sides Can be t, r, b, l or any combination of those to 5737 * represent the top, right, bottom, or left sides. 5738 * @return {Number} 5739 */ 5740 getPadding: function(sides) { 5741 var instance = this; 5742 5743 return instance._getBoxStyleAsNumber(sides, MAP_PADDING); 5744 }, 5745 5746 /** 5747 * Sets the id of the Node instance if the object does not have one. The 5748 * generated id is based on a guid created by the 5749 * [stamp](YUI.html#method_stamp) method. 5750 * 5751 * @method guid 5752 * @return {String} The current id of the node 5753 */ 5754 guid: function() { 5755 var instance = this; 5756 var currentId = instance.get('id'); 5757 5758 if (!currentId) { 5759 currentId = A.stamp(instance); 5760 5761 instance.set('id', currentId); 5762 } 5763 5764 return currentId; 5765 }, 5766 5767 /** 5768 * Creates a hover interaction. 5769 * 5770 * @method hover 5771 * @param {String} overFn 5772 * @param {String} outFn 5773 * @return {Node} The current Node instance 5774 */ 5775 hover: function(overFn, outFn) { 5776 var instance = this; 5777 5778 var hoverOptions; 5779 var defaultHoverOptions = instance._defaultHoverOptions; 5780 5781 if (isObject(overFn, true)) { 5782 hoverOptions = overFn; 5783 5784 hoverOptions = A.mix(hoverOptions, defaultHoverOptions); 5785 5786 overFn = hoverOptions.over; 5787 outFn = hoverOptions.out; 5788 } 5789 else { 5790 hoverOptions = A.mix({ 5791 over: overFn, 5792 out: outFn 5793 }, 5794 defaultHoverOptions 5795 ); 5796 } 5797 5798 instance._hoverOptions = hoverOptions; 5799 5800 hoverOptions.overTask = A.debounce(instance._hoverOverTaskFn, null, instance); 5801 hoverOptions.outTask = A.debounce(instance._hoverOutTaskFn, null, instance); 5802 5803 return new A.EventHandle( 5804 [ 5805 instance.on(hoverOptions.overEventType, instance._hoverOverHandler, instance), 5806 instance.on(hoverOptions.outEventType, instance._hoverOutHandler, instance) 5807 ] 5808 ); 5809 }, 5810 5811 /** 5812 * Gets or sets the HTML contents of the node. If the `value` is passed it's 5813 * set the content of the element, otherwise it works as a getter for the 5814 * current content. 5815 * 5816 * Example: 5817 * 5818 * ``` 5819 * var node = A.one('#nodeId'); 5820 * node.html('Setting new HTML'); 5821 * // Alert the value of the current content
5822 * alert( node.html() ); 5823 * ``` 5824 * 5825 * @method html 5826 * @param {String} value A string of html to set as the content of the node 5827 * instance. 5828 */ 5829 html: function() { 5830 var args = arguments, 5831 length = args.length; 5832 5833 if (length) { 5834 this.set('innerHTML', args[0]); 5835 } 5836 else { 5837 return this.get('innerHTML'); 5838 } 5839 5840 return this; 5841 }, 5842 5843 /** 5844 * Gets the outerHTML of a node, which islike innerHTML, except that it 5845 * actually contains the HTML of the node itself. 5846 * 5847 * @method outerHTML 5848 * @return {string} The outerHTML of the given element. 5849 */ 5850 outerHTML: function() { 5851 var instance = this; 5852 var domEl = instance.getDOM(); 5853 5854 // IE, Opera and WebKit all have outerHTML. 5855 if ('outerHTML' in domEl) { 5856 return domEl.outerHTML; 5857 } 5858 5859 var temp = ANode.create('<div></div>').append( 5860 this.clone() 5861 ); 5862 5863 try { 5864 return temp.html(); 5865 } 5866 catch (e) {} 5867 finally { 5868 temp = null; 5869 } 5870 }, 5871 5872 /** 5873 * Inserts a `newNode` after the node instance (i.e., as the next sibling). 5874 * If the reference node has no parent, then does nothing. 5875 * 5876 * Example: 5877 * 5878 * ``` 5879 * var titleNode = A.one('#titleNode'); 5880 * var descriptionNode = A.one('#descriptionNode'); 5881 * // the description is usually shown after the title 5882 * titleNode.placeAfter(descriptionNode); 5883 * ``` 5884 * 5885 * @method placeAfter 5886 * @chainable 5887 * @param {Node} newNode Node to insert. 5888 */ 5889 placeAfter: function(newNode) { 5890 var instance = this; 5891 5892 return instance._place(newNode, instance.get('nextSibling')); 5893 }, 5894 5895 /** 5896 * Inserts a `newNode` before the node instance (i.e., as the previous 5897 * sibling). If the reference node has no parent, then does nothing. 5898 * 5899 * Example: 5900 * 5901 * ``` 5902 * var descriptionNode = A.one('#descriptionNode'); 5903 * var titleNode = A.one('#titleNode'); 5904 * // the title is usually shown before the description 5905 * descriptionNode.placeBefore(titleNode); 5906 * ``` 5907 * 5908 * @method placeBefore 5909 * @chainable 5910 * @param {Node} newNode Node to insert. 5911 */ 5912 placeBefore: function(newNode) { 5913 var instance = this; 5914 5915 return instance._place(newNode, instance); 5916 }, 5917 5918 /** 5919 * Inserts the node instance to the begining of the `selector` node (i.e., 5920 * insert before the `firstChild` of the `selector`). 5921 * 5922 * Example: 5923 * 5924 * ``` 5925 * var node = A.one('#nodeId'); 5926 * node.prependTo('body'); 5927 * ``` 5928 * 5929 * @method prependTo 5930 * @chainable 5931 * @param {Node|String} selector A selector, element, HTML string, Node 5932 */ 5933 prependTo: function(selector) { 5934 var instance = this; 5935 5936 A.one(selector).prepend(instance); 5937 5938 return instance; 5939 }, 5940 5941 /** 5942 * Adds one or more CSS classes to an element and remove the class(es) from 5943 * the siblings of the element. 5944 * 5945 * @method radioClass 5946 * @chainable 5947 * @param {String} cssClass 5948 */ 5949 radioClass: function(cssClass) { 5950 var instance = this; 5951 5952 var siblings = instance.siblings(); 5953 5954 if (isString(cssClass)) { 5955 siblings.removeClass(cssClass); 5956 5957 instance.addClass(cssClass); 5958 } 5959 else if (isArray(cssClass)) { 5960 var siblingNodes = siblings.getDOM(); 5961 5962 var regex = getRegExp('(?:^|\\s+)(?:' + cssClass.join('|') + ')(?=\\s+|$)', 'g'), 5963 node, 5964 i; 5965 5966 for (i = siblingNodes.length - 1; i >= 0; i--) { 5967 node = siblingNodes[i]; 5968 node.className = node.className.replace(regex, ''); 5969 } 5970 5971 instance.addClass(cssClass.join(' ')); 5972 } 5973 5974 return instance; 5975 }, 5976 5977 /** 5978 * Generates an unique identifier and reset the id attribute of the node 5979 * instance using the new value. Invokes the [guid](Node.html#method_guid). 5980 * 5981 * @method resetId 5982 * @chainable 5983 * @param {String} prefix Optional prefix for the guid. 5984 */ 5985 resetId: function(prefix) { 5986 var instance = this; 5987 5988 instance.attr('id', A.guid(prefix)); 5989 5990 return instance; 5991 }, 5992 5993 /** 5994 * Selects a substring of text inside of the input element. 5995 * 5996 * @method selectText 5997 * @param {Number} start The index to start the selection range from 5998 * @param {Number} end The index to end the selection range at 5999 */ 6000 selectText: function(start, end) { 6001 var instance = this; 6002 6003 var textField = instance.getDOM(); 6004 var length = instance.val().length; 6005 6006 end = isValue(end) ? end : length; 6007 start = isValue(start) ? start : 0; 6008 6009 // Some form elements could throw a (NS_ERROR_FAILURE) 6010 // [nsIDOMNSHTMLInputElement.setSelectionRange] error when invoke the 6011 // setSelectionRange on firefox. Wrapping in a try/catch to prevent the 6012 // error be thrown 6013 try { 6014 if (textField.setSelectionRange) { 6015 textField.setSelectionRange(start, end); 6016 } 6017 else if (textField.createTextRange) { 6018 var range = textField.createTextRange(); 6019 6020 range.moveStart('character', start); 6021 range.moveEnd('character', end - length); 6022 6023 range.select(); 6024 } 6025 else { 6026 textField.select(); 6027 } 6028 6029 if (textField !== DOC.activeElement) { 6030 textField.focus(); 6031 } 6032 } 6033 catch (e) {} 6034 6035 return instance; 6036 }, 6037 6038 /** 6039 * Enables text selection for this element (normalized across browsers). 6040 * 6041 * @method selectable 6042 * @param noRecurse 6043 * @chainable 6044 */ 6045 selectable: function(noRecurse) { 6046 var instance = this; 6047 6048 instance.setStyles({
6049 '-webkit-user-select': CSS_SELECTABLE_VALUE, 6050 '-khtml-user-select': CSS_SELECTABLE_VALUE, 6051 '-moz-user-select': CSS_SELECTABLE_VALUE, 6052 '-ms-user-select': CSS_SELECTABLE_VALUE, 6053 '-o-user-select': CSS_SELECTABLE_VALUE, 6054 'user-select': CSS_SELECTABLE_VALUE 6055 }); 6056 6057 if (A.UA.ie || A.UA.opera) { 6058 _setUnselectable(instance._node, false, noRecurse); 6059 } 6060 6061 return instance; 6062 }, 6063 6064 /** 6065 * Stops the specified event(s) from bubbling and optionally prevents the 6066 * default action. 6067 * 6068 * Example: 6069 * 6070 * ``` 6071 * var anchor = A.one('a#anchorId'); 6072 * anchor.swallowEvent('click'); 6073 * ``` 6074 * 6075 * @method swallowEvent 6076 * @chainable 6077 * @param {String|Array} eventName An event or array of events to stop from 6078 * bubbling 6079 * @param {Boolean} preventDefault (optional) true to prevent the default 6080 * action too 6081 */ 6082 swallowEvent: function(eventName, preventDefault) { 6083 var instance = this; 6084 6085 var fn = function(event) { 6086 event.stopPropagation(); 6087 6088 if (preventDefault) { 6089 event.preventDefault(); 6090 6091 event.halt(); 6092 } 6093 6094 return false; 6095 }; 6096 6097 if (isArray(eventName)) { 6098 AArray.each( 6099 eventName, 6100 function(name) { 6101 instance.on(name, fn); 6102 } 6103 ); 6104 6105 return this; 6106 } 6107 else { 6108 instance.on(eventName, fn); 6109 } 6110 6111 return instance; 6112 }, 6113 6114 /** 6115 * Gets or sets the combined text contents of the node instance, including 6116 * it's descendants. If the `text` is passed it's set the content of the 6117 * element, otherwise it works as a getter for the current content. 6118 * 6119 * Example: 6120 * 6121 * ``` 6122 * var node = A.one('#nodeId'); 6123 * node.text('Setting new text content'); 6124 * // Alert the value of the current content 6125 * alert( node.text() ); 6126 * ``` 6127 * 6128 * @method text 6129 * @param {String} text A string of text to set as the content of the node 6130 * instance. 6131 */ 6132 text: function(text) { 6133 var instance = this; 6134 var el = instance.getDOM(); 6135 6136 if (!isUndefined(text)) { 6137 text = A.DOM._getDoc(el).createTextNode(text); 6138 6139 return instance.empty().append(text); 6140 } 6141 6142 return instance._getText(el.childNodes); 6143 }, 6144 6145 /** 6146 * Displays or hide the node instance. 6147 * 6148 * NOTE: This method assume that your node were hidden because of the 6149 * 'aui-hide' css class were being used. This won't manipulate the inline 6150 * `style.display` property. 6151 * 6152 * @method toggle 6153 * @chainable 6154 * @param {Boolean} on Whether to force the toggle. Optional. 6155 * @param {Function} callback A function to run after the visibility change. 6156 * Optional. 6157 */ 6158 toggle: function() { 6159 var instance = this; 6160 6161 instance._toggleView.apply(instance, arguments); 6162 6163 return instance; 6164 }, 6165 6166 /** 6167 * Disables text selection for this element (normalized across browsers). 6168 * 6169 * @method unselectable 6170 * @param noRecurse 6171 * @chainable 6172 */ 6173 unselectable: function(noRecurse) { 6174 var instance = this; 6175 6176 instance.setStyles({ 6177 '-webkit-user-select': CSS_UNSELECTABLE_VALUE, 6178 '-khtml-user-select': CSS_UNSELECTABLE_VALUE, 6179 '-moz-user-select': CSS_UNSELECTABLE_VALUE, 6180 '-ms-user-select': CSS_UNSELECTABLE_VALUE, 6181 '-o-user-select': CSS_UNSELECTABLE_VALUE, 6182 'user-select': CSS_UNSELECTABLE_VALUE 6183 }); 6184 6185 if (A.UA.ie || A.UA.opera) { 6186 _setUnselectable(instance._node, true, noRecurse); 6187 } 6188 6189 return instance; 6190 }, 6191 6192 /** 6193 * Gets or sets the value attribute of the node instance. If the `value` is 6194 * passed it's set the value of the element, otherwise it works as a getter 6195 * for the current value. 6196 * 6197 * Example: 6198 * 6199 * ```
6200 * var input = A.one('#inputId'); 6201 * input.val('Setting new input value'); 6202 * // Alert the value of the input 6203 * alert( input.val() ); 6204 * ``` 6205 * 6206 * @method val 6207 * @param {String} value Value to be set. Optional. 6208 */ 6209 val: function(value) { 6210 var instance = this; 6211 6212 if (isUndefined(value)) { 6213 return instance.get('value'); 6214 } 6215 else { 6216 return instance.set('value', value); 6217 } 6218 }, 6219 6220 /** 6221 * Returns the combined size of the box style for the specified sides. 6222 * 6223 * @method _getBoxStyleAsNumber 6224 * @param {String} sides Can be t, r, b, l or any combination of 6225 * those to represent the top, right, bottom, or left sides. 6226 * @param {String} map An object mapping mapping the "sides" param to the a 6227 * CSS value to retrieve 6228 * @return {Number} 6229 * @private 6230 */ 6231 _getBoxStyleAsNumber: function(sides, map) { 6232 var instance = this; 6233 6234 var sidesArray = sides.match(/\w/g), 6235 value = 0, 6236 side, 6237 sideKey, 6238 i; 6239 6240 for (i = sidesArray.length - 1; i >= 0; i--) { 6241 sideKey = sidesArray[i]; 6242 side = 0; 6243 6244 if (sideKey) { 6245 side = parseFloat(instance.getComputedStyle(map[sideKey])); 6246 side = Math.abs(side); 6247 6248 value += side || 0; 6249 } 6250 } 6251 6252 return value; 6253 }, 6254 6255 /** 6256 * Extracts text content from the passed nodes. 6257 * 6258 * @method _getText 6259 * @private 6260 * @param {Native NodeList} childNodes 6261 */ 6262 _getText: function(childNodes) { 6263 var instance = this; 6264 6265 var length = childNodes.length, 6266 childNode, 6267 str = [], 6268 i; 6269 6270 for (i = 0; i < length; i++) { 6271 childNode = childNodes[i]; 6272 6273 if (childNode && childNode.nodeType !== 8) { 6274 if (childNode.nodeType !== 1) { 6275 str.push(childNode.nodeValue); 6276 } 6277 6278 if (childNode.childNodes) { 6279 str.push(instance._getText(childNode.childNodes)); 6280 } 6281 } 6282 } 6283 6284 return str.join(''); 6285 }, 6286 6287 /** 6288 * Overrides Y.Node._hide. Adds aui-hide to the node's cssClass 6289 * 6290 * @method _hide 6291 * @private 6292 */ 6293 _hide: function() { 6294 var instance = this; 6295 6296 instance.addClass(CSS_HIDE); 6297 6298 return NODE_PROTO_HIDE.apply(instance, arguments); 6299 }, 6300 6301 /** 6302 * The event handler for the "out" function that is fired for events 6303 * attached via the hover method. 6304 * 6305 * @method _hoverOutHandler 6306 * @private 6307 * @param {EventFacade} event 6308 */ 6309 _hoverOutHandler: function(event) { 6310 var instance = this; 6311 6312 var hoverOptions = instance._hoverOptions; 6313 6314 hoverOptions.outTask.delay(hoverOptions.outDelay, event); 6315 }, 6316 6317 /** 6318 * The event handler for the "over" function that is fired for events 6319 * attached via the hover method. 6320 * 6321 * @method _hoverOverHandler 6322 * @private 6323 * @param {EventFacade} event 6324 */ 6325 _hoverOverHandler: function(event) { 6326 var instance = this; 6327 6328 var hoverOptions = instance._hoverOptions; 6329 6330 hoverOptions.overTask.delay(hoverOptions.overDelay, event); 6331 }, 6332 6333 /** 6334 * Cancels the over task, and fires the users custom "out" function for the 6335 * hover method 6336 * 6337 * @method _hoverOverHandler 6338 * @private 6339 * @param {EventFacade} event 6340 */ 6341 _hoverOutTaskFn: function(event) { 6342 var instance = this; 6343 6344 var hoverOptions = instance._hoverOptions; 6345 6346 hoverOptions.overTask.cancel(); 6347 6348 hoverOptions.out.apply(hoverOptions.context || event.currentTarget, arguments); 6349 }, 6350 6351 /** 6352 * Cancels the out task, and fires the users custom "over" function for the 6353 * hover method 6354 * 6355 * @method _hoverOverHandler 6356 * @private 6357 * @param {EventFacade} event 6358 */ 6359 _hoverOverTaskFn: function(event) { 6360 var instance = this; 6361 6362 var hoverOptions = instance._hoverOptions; 6363 6364 hoverOptions.outTask.cancel(); 6365 6366 hoverOptions.over.apply(hoverOptions.context || event.currentTarget, arguments); 6367 }, 6368 6369 /** 6370 * Places a node or html string at a specific location 6371 * 6372 * @method _place 6373 * @private 6374 * @param {Node|String} newNode 6375 * @param {Node} refNode 6376 */ 6377 _place: function(newNode, refNode) { 6378 var instance = this; 6379 6380 var parent = instance.get('parentNode'); 6381 6382 if (parent) { 6383 if (isString(newNode)) { 6384 newNode = ANode.create(newNode); 6385 } 6386 6387 parent.insertBefore(newNode, refNode); 6388 } 6389 6390 return instance; 6391 }, 6392 6393 /** 6394 * Overrides Y.Node._show. Removes aui-hide from the node's cssClass 6395 * 6396 * @method _show 6397 * @private 6398 */ 6399 _show: function() { 6400 var instance = this; 6401 6402 instance.removeClass(CSS_HIDE); 6403 6404 return NODE_PROTO_SHOW.apply(instance, arguments); 6405 }, 6406 6407 _defaultHoverOptions: { 6408 overEventType: 'mouseenter', 6409 outEventType: 'mouseleave', 6410 overDelay: 0, 6411 outDelay: 0, 6412 over: Lang.emptyFn, 6413 out: Lang.emptyFn 6414 } 6415}, true); 6416 6417NODE_PROTO.__isHidden = NODE_PROTO._isHidden; 6418 6419NODE_PROTO._isHidden = function() { 6420 var instance = this; 6421 6422 return NODE_PROTO.__isHidden.call(instance) || instance.hasClass(instance._hideClass || CSS_HIDE); 6423}; 6424 6425/** 6426 * Returns the width of the content, not including the padding, border or 6427 * margin. If a width is passed, the node's overall width is set to that size. 6428 * 6429 * Example: 6430 * 6431 * ``` 6432 * var node = A.one('#nodeId'); 6433 * node.width(); //return content width
6434 * node.width(100); // sets box width 6435 * ``` 6436 * 6437 * @method width 6438 * @return {number} 6439 */ 6440 6441/** 6442 * Returns the height of the content, not including the padding, border or 6443 * margin. If a height is passed, the node's overall height is set to that size. 6444 * 6445 * Example: 6446 * 6447 * ``` 6448 * var node = A.one('#nodeId'); 6449 * node.height(); //return content height 6450 * node.height(100); // sets box height 6451 * ``` 6452 * 6453 * @method height 6454 * @return {number} 6455 */ 6456 6457/** 6458 * Returns the size of the box from inside of the border, which is the 6459 * `offsetWidth` plus the padding on the left and right. 6460 * 6461 * Example: 6462 * 6463 * ``` 6464 * var node = A.one('#nodeId'); 6465 * node.innerWidth(); 6466 * ``` 6467 * 6468 * @method innerWidth 6469 * @return {number} 6470 */ 6471 6472/** 6473 * Returns the size of the box from inside of the border, which is offsetHeight 6474 * plus the padding on the top and bottom. 6475 * 6476 * Example: 6477 * 6478 * ``` 6479 * var node = A.one('#nodeId'); 6480 * node.innerHeight(); 6481 * ``` 6482 * 6483 * @method innerHeight 6484 * @return {number} 6485 */ 6486 6487/** 6488 * Returns the outer width of the box including the border, if true is passed as 6489 * the first argument, the margin is included. 6490 * 6491 * Example: 6492 * 6493 * ``` 6494 * var node = A.one('#nodeId'); 6495 * node.outerWidth(); 6496 * node.outerWidth(true); // includes margin 6497 * ``` 6498 * 6499 * @method outerWidth 6500 * @return {number} 6501 */ 6502 6503/** 6504 * Returns the outer height of the box including the border, if true is passed 6505 * as the first argument, the margin is included. 6506 * 6507 * Example: 6508 * 6509 * ``` 6510 * var node = A.one('#nodeId'); 6511 * node.outerHeight(); 6512 * node.outerHeight(true); // includes margin 6513 * ``` 6514 * 6515 * @method outerHeight 6516 * @return {number} 6517 */ 6518 6519A.each( 6520 ['Height', 'Width'], 6521 function(item, index) { 6522 var sides = index ? 'lr' : 'tb'; 6523 6524 var dimensionType = item.toLowerCase(); 6525 6526 NODE_PROTO[dimensionType] = function(size) { 6527 var instance = this; 6528 6529 var returnValue = instance; 6530 6531 if (isUndefined(size)) { 6532 var node = instance._node; 6533 var dimension; 6534 6535 if (node) { 6536 if ((!node.tagName && node.nodeType === 9) || node.alert) { 6537 dimension = instance.get('region')[dimensionType]; 6538 } 6539 else { 6540 dimension = instance.get('offset' + item); 6541 6542 if (!dimension) { 6543 var originalDisplay = instance.getStyle('display'); 6544 var originalPosition = instance.getStyle('position'); 6545 var originalVisibility = instance.getStyle('visibility'); 6546 6547 instance.setStyles({ 6548 display: 'block !important', 6549 position: 'absolute !important', 6550 visibility: 'hidden !important' 6551 }); 6552 6553 dimension = instance.get('offset' + item); 6554 6555 instance.setStyles({ 6556 display: originalDisplay, 6557 position: originalPosition, 6558 visibility: originalVisibility 6559 }); 6560 } 6561 6562 if (dimension) { 6563 dimension -= (instance.getPadding(sides) + instance.getBorderWidth(sides)); 6564 } 6565 } 6566 } 6567 6568 returnValue = dimension; 6569 } 6570 else { 6571 instance.setStyle(dimensionType, size); 6572 } 6573 6574 return returnValue; 6575 }; 6576 6577 NODE_PROTO['inner' + item] = function() { 6578 var instance = this; 6579 6580 return instance[dimensionType]() + instance.getPadding(sides); 6581 }; 6582 6583 NODE_PROTO['outer' + item] = function(margin) { 6584 var instance = this; 6585 6586 var innerSize = instance['inner' + item](); 6587 var borderSize = instance.getBorderWidth(sides); 6588 6589 var size = innerSize + borderSize; 6590 6591 if (margin) { 6592 size += instance.getMargin(sides); 6593 } 6594 6595 return size; 6596 }; 6597 } 6598); 6599 6600if (!SUPPORT_OPTIONAL_TBODY) { 6601 A.DOM._ADD_HTML = A.DOM.addHTML; 6602 6603 A.DOM.addHTML = function(node, content, where) { 6604 var nodeName = (node.nodeName && node.nodeName.toLowerCase()) || ''; 6605 6606 var tagName = ''; 6607 6608 if (!isUndefined(content)) { 6609 if (isString(content)) { 6610 tagName = (REGEX_TAGNAME.exec(content) || ARRAY_EMPTY_STRINGS)[1]; 6611 } 6612 else if (content.nodeType && content.nodeType === 11 && content.childNodes.length) { // a doc frag 6613 tagName = content.childNodes[0].nodeName; 6614 }
6615 else if (content.nodeName) { // a node 6616 tagName = content.nodeName; 6617 } 6618 6619 tagName = tagName && tagName.toLowerCase(); 6620 } 6621 6622 if (nodeName === 'table' && tagName === 'tr') { 6623 node = node.getElementsByTagName('tbody')[0] || node.appendChild(node.ownerDocument.createElement('tbody')); 6624 6625 var whereNodeName = ((where && where.nodeName) || '').toLowerCase(); 6626 6627 // Assuming if the "where" is a tbody node, 6628 // we're trying to prepend to a table. Attempt to 6629 // grab the first child of the tbody. 6630 if (whereNodeName === 'tbody' && where.childNodes.length > 0) { 6631 where = where.firstChild; 6632 } 6633 } 6634 6635 return A.DOM._ADD_HTML(node, content, where); 6636 }; 6637} 6638 6639/** 6640 * Augments the [YUI3 NodeList](NodeList.html) with more util methods. 6641 * 6642 * Checks the list of [Methods](NodeList.html#methods) available for AUI 6643 * NodeList. 6644 * 6645 * @class A.NodeList 6646 * @constructor 6647 * @uses A.Node 6648 */ 6649ANodeList.importMethod( 6650 NODE_PROTO, [ 6651 'after', 6652 6653 'appendTo', 6654 6655 'attr', 6656 6657 'before', 6658 6659 'empty', 6660 6661 'getX', 6662 6663 'getXY', 6664 6665 'getY', 6666 6667 'hover', 6668 6669 'html', 6670 6671 'innerHeight', 6672 6673 'innerWidth', 6674 6675 'outerHeight', 6676 6677 'outerHTML', 6678 6679 'outerWidth', 6680 6681 'prepend', 6682 6683 'prependTo', 6684 6685 'purge', 6686 6687 'selectText', 6688 6689 'selectable', 6690 6691 'setX', 6692 6693 'setXY', 6694 6695 'setY', 6696 6697 'text', 6698 6699 'toggle', 6700 6701 'unselectable', 6702 6703 'val' 6704 ] 6705); 6706 6707A.mix( 6708 NODELIST_PROTO, { 6709 /** 6710 * See [Node all](Node.html#method_all). 6711 * 6712 * @method all 6713 */ 6714 all: function(selector) { 6715 var instance = this, 6716 newNodeList = [], 6717 nodes = instance._nodes, 6718 length = nodes.length, 6719 subList, 6720 i; 6721 6722 for (i = 0; i < length; i++) { 6723 subList = A.Selector.query(selector, nodes[i]); 6724 6725 if (subList && subList.length) { 6726 newNodeList.push.apply(newNodeList, subList); 6727 } 6728 } 6729 6730 newNodeList = AArray.unique(newNodeList); 6731 6732 return A.all(newNodeList); 6733 }, 6734 6735 /** 6736 * Returns the first element in the node list collection. 6737 * 6738 * @method first 6739 * @return {Node} 6740 */ 6741 first: function() { 6742 var instance = this; 6743 6744 return instance.item(0); 6745 }, 6746 6747 /** 6748 * See [Node getDOMNode](Node.html#method_getDOMNode). 6749 * 6750 * @method getDOM 6751 */ 6752 getDOM: function() { 6753 return ANodeList.getDOMNodes(this); 6754 }, 6755 6756 /** 6757 * Returns the last element in the node list collection. 6758 * 6759 * @method last 6760 * @return {Node} 6761 */ 6762 last: function() { 6763 var instance = this; 6764 6765 return instance.item(instance._nodes.length - 1); 6766 }, 6767 6768 /** 6769 * See [Node one](Node.html#method_one). 6770 * 6771 * @method one 6772 */ 6773 one: function(selector) { 6774 var instance = this, 6775 newNode = null, 6776 nodes = instance._nodes, 6777 length = nodes.length, 6778 i; 6779 6780 for (i = 0; i < length; i++) { 6781 newNode = A.Selector.query(selector, nodes[i], true); 6782 6783 if (newNode) { 6784 newNode = A.one(newNode); 6785 6786 break; 6787 } 6788 } 6789 6790 return newNode; 6791 } 6792 } 6793); 6794 6795NODELIST_PROTO.__filter = NODELIST_PROTO.filter; 6796 6797NODELIST_PROTO.filter = function(value, context) { 6798 var instance = this; 6799 6800 var newNodeList; 6801 6802 if (isFunction(value)) { 6803 var nodes = []; 6804 6805 instance.each( 6806 function(item, index, collection) { 6807 if (value.call(context || item, item, index, collection)) { 6808 nodes.push(item._node); 6809 } 6810 } 6811 ); 6812 6813 newNodeList = A.all(nodes); 6814 } 6815 else { 6816 newNodeList = NODELIST_PROTO.__filter.call(instance, value); 6817 } 6818 6819 return newNodeList; 6820}; 6821 6822A.mix( 6823 ANodeList, { 6824 /** 6825 * Converts the passed `html` into a `NodeList` and returns the result. 6826 * 6827 * @method create 6828 * @param {String} html 6829 * @return {NodeList} 6830 */ 6831 create: function(html) { 6832 var docFrag = A.getDoc().invoke('createDocumentFragment'); 6833 6834 return docFrag.append(html).get('childNodes'); 6835 } 6836 } 6837); 6838 6839A.mix( 6840 A, { 6841 /** 6842 * Gets the body node. Shortcut to `A.one('body')`. 6843 * 6844 * @method getBody 6845 */ 6846 getBody: function() { 6847 var instance = this; 6848 6849 if (!instance._bodyNode) { 6850 instance._bodyNode = A.one(DOC.body); 6851 } 6852 6853 return instance._bodyNode; 6854 }, 6855 6856 /** 6857 * Gets the document node. Shortcut to `A.one(document)`. 6858 * 6859 * @method getDoc 6860 */ 6861 getDoc: function() { 6862 var instance = this; 6863 6864 if (!instance._documentNode) { 6865 instance._documentNode = A.one(DOC); 6866 } 6867 6868 return instance._documentNode; 6869 }, 6870 6871 /** 6872 * Gets the window node. Shortcut to `A.one(window)`. 6873 * 6874 * @method getWin 6875 */ 6876 getWin: function() { 6877 var instance = this; 6878 6879 if (!instance._windowNode) { 6880 instance._windowNode = A.one(WIN); 6881 } 6882 6883 return instance._windowNode; 6884 } 6885 } 6886); 6887 6888 6889}, '3.1.0-deprecated.77', {"requires": ["array-extras", "aui-base-lang", "aui-classnamemanager", "aui-debounce", "node"]}); 6890 6891YUI.add('aui-node-html5', function (A, NAME) { 6892 6893/** 6894 * Provides support for HTML shiv natively on the Alloy DOM methods. The HTML5 6895 * shiv just affects IE. 6896 * 6897 * @module aui-node 6898 * @submodule aui-node-html5 6899 */ 6900 6901if (A.UA.ie) { 6902 /** 6903 * An object that encapsulates util methods for HTML5 shiving. 6904 * 6905 * **What is a "shiv"?** 6906 * 6907 * To the world, a shiv is a slang term for a sharp object used as a 6908 * knife-like weapon. To Internet Explorer, a shiv is a script that, when 6909 * executed, forces the browser to recognize HTML5 elements. 6910 * 6911 * @class A.HTML5 6912 */ 6913 var HTML5 = A.namespace('HTML5'), 6914 DOM_create = A.DOM._create; 6915 6916 if (!HTML5._fragHTML5Shived) { 6917 /** 6918 * A global DocumentFragment already HTML5 shived, for performance 6919 * reasons. (i.e., all nodes and its HTML5 children appended to this 6920 * fragment iherits the styles on IE). 6921 * 6922 * @property _fragHTML5Shived 6923 * @type {DocumentFragment} 6924 * @protected 6925 */ 6926 HTML5._fragHTML5Shived = A.html5shiv( 6927 A.config.doc.createDocumentFragment() 6928 ); 6929 } 6930 6931 A.mix( 6932 HTML5, { 6933 /** 6934 * Receives a `frag` and a HTML content. This method shivs the HTML5 6935 * nodes appended to a Node or fragment which is not on the document 6936 * yet. 6937 * 6938 * @method IECreateFix 6939 * @param {Node|DocumentFragment} frag Fragment to be fixed. 6940 * @param {String} content HTML to be set (using innerHTML) on the 6941 * `frag`. 6942 * @return {Node|DocumentFragment} 6943 */ 6944 IECreateFix: function(frag, content) { 6945 var shivedFrag = HTML5._fragHTML5Shived; 6946
6947 shivedFrag.appendChild(frag); 6948 6949 frag.innerHTML = content; 6950 6951 shivedFrag.removeChild(frag); 6952 6953 return frag; 6954 }, 6955 6956 /** 6957 * AOP listener to the A.DOM._create method. This method intercepts 6958 * all the calls to the A.DOM._create and append the generated 6959 * fragment to [A.HTML._fragHTML5Shived](A.HTML5.html#property__frag 6960 * HTML5Shived), this fixes the IE bug for painting the HTML5 nodes 6961 * on the HTML fragment. 6962 * 6963 * @method _doBeforeCreate 6964 * @param {String} html HTML content 6965 * @param {String} doc 6966 * @param {String} tag 6967 * @protected 6968 * @return {DocumentFragment} 6969 */ 6970 _doBeforeCreate: function(html) { 6971 var createdFrag = DOM_create.apply(this, arguments); 6972 6973 var shivedFrag = HTML5.IECreateFix(createdFrag, html); 6974 6975 return new A.Do.Halt(null, shivedFrag); 6976 } 6977 } 6978 ); 6979 6980 A.Do.before(HTML5._doBeforeCreate, A.DOM, '_create', A.DOM); 6981} 6982/** 6983 * The Node Utility. 6984 * 6985 * @module aui-node 6986 * @submodule aui-node-html5-print 6987 */ 6988 6989var CONFIG = A.config, 6990 DOC = CONFIG.doc, 6991 WIN = CONFIG.win, 6992 UA = A.UA, 6993 IE = UA.ie, 6994 6995 isShivDisabled = function() { 6996 return WIN.AUI_HTML5_IE === false; 6997 }; 6998 6999if (!IE || IE >= 9 || isShivDisabled()) { 7000 return; 7001} 7002 7003var BUFFER_CSS_TEXT = [], 7004 7005 LOCATION = WIN.location, 7006 7007 DOMAIN = LOCATION.protocol + '//' + LOCATION.host, 7008 7009 HTML = DOC.documentElement, 7010 7011 HTML5_ELEMENTS = A.HTML5_ELEMENTS, 7012 HTML5_ELEMENTS_LENGTH = HTML5_ELEMENTS.length, 7013 HTML5_ELEMENTS_LIST = HTML5_ELEMENTS.join('|'), 7014 7015 REGEX_CLONE_NODE_CLEANUP = new RegExp('<(/?):(' + HTML5_ELEMENTS_LIST + ')', 'gi'), 7016 REGEX_ELEMENTS = new RegExp('(' + HTML5_ELEMENTS_LIST + ')', 'gi'), 7017 REGEX_ELEMENTS_FAST = new RegExp('\\b(' + HTML5_ELEMENTS_LIST + ')\\b', 'i'), 7018 7019 REGEX_PRINT_MEDIA = /print|all/, 7020 7021 REGEX_RULE = new RegExp('(^|[^\\n{}]*?\\s)(' + HTML5_ELEMENTS_LIST + ').*?{([^}]*)}', 'gim'), 7022 REGEX_TAG = new RegExp('<(\/*)(' + HTML5_ELEMENTS_LIST + ')', 'gi'), 7023 7024 SELECTOR_REPLACE_RULE = '.' + 'printfix-' + '$1', 7025 7026 STR_EMPTY = '', 7027 7028 STR_URL_DOMAIN = 'url(' + DOMAIN, 7029 7030 TAG_REPLACE_ORIGINAL = '<$1$2', 7031 TAG_REPLACE_FONT = '<$1font'; 7032 7033var html5shiv = A.html5shiv, 7034 // Yes, IE does this wackiness; converting an object 7035 // to a string should never result in undefined, but 7036 // IE's styleSheet object sometimes becomes inaccessible 7037 // after trying to print the second time 7038 isStylesheetDefined = function(obj) { 7039 return obj && (obj + STR_EMPTY !== undefined); 7040 }, 7041 7042 toggleNode = function(node, origNode, prop) { 7043 var state = origNode[prop]; 7044 7045 if (state) { 7046 node.setAttribute(prop, state); 7047 } 7048 else { 7049 node.removeAttribute(prop); 7050 } 7051 }; 7052 7053html5shiv(DOC); 7054 7055var printFix = function() { 7056 var destroy; 7057 7058 var afterPrint = function() { 7059 if (isShivDisabled()) { 7060 destroy(); 7061 } 7062 else { 7063 printFix.onAfterPrint(); 7064 } 7065 }; 7066 7067 var beforePrint = function() { 7068 if (isShivDisabled()) { 7069 destroy(); 7070 } 7071 else { 7072 printFix.onBeforePrint(); 7073 } 7074 }; 7075 7076 destroy = function() { 7077 WIN.detachEvent('onafterprint', afterPrint); 7078 WIN.detachEvent('onbeforeprint', beforePrint); 7079 }; 7080 7081 var init = function() { 7082 WIN.attachEvent('onafterprint', afterPrint); 7083 WIN.attachEvent('onbeforeprint', beforePrint); 7084 }; 7085 7086 init(); 7087 7088 printFix.destroy = destroy; 7089 printFix.init = init; 7090}; 7091 7092A.mix( 7093 printFix, { 7094 /** 7095 * Fires after a print. 7096 * 7097 * @method onAfterPrint 7098 */ 7099 onAfterPrint: function() { 7100 var instance = this; 7101 7102 instance.restoreHTML(); 7103 7104 var styleSheet = instance._getStyleSheet(); 7105 7106 styleSheet.styleSheet.cssText = ''; 7107 }, 7108 7109 /** 7110 * Fires before a print. 7111 * 7112 * @method onBeforePrint 7113 */ 7114 onBeforePrint: function() { 7115 var instance = this; 7116 7117 var styleSheet = instance._getStyleSheet(); 7118 var cssRules = instance._getAllCSSText(); 7119 7120 styleSheet.styleSheet.cssText = instance.parseCSS(cssRules); 7121 7122 instance.writeHTML(); 7123 }, 7124 7125 /** 7126 * Navigates through the CSS joining rules and replacing content. 7127 * 7128 * @method parseCSS 7129 * @param cssText 7130 * @return {String} 7131 */ 7132 parseCSS: function(cssText) { 7133 var css = ''; 7134 var rules = cssText.match(REGEX_RULE); 7135 7136 if (rules) { 7137 css = rules.join('\n').replace(REGEX_ELEMENTS, SELECTOR_REPLACE_RULE); 7138 } 7139 7140 return css; 7141 }, 7142 7143 /** 7144 * Restores the HTML from the `bodyClone` and `bodyEl` attributes. 7145 * 7146 * @method restoreHTML 7147 */ 7148 restoreHTML: function() { 7149 var instance = this; 7150 7151 var bodyClone = instance._getBodyClone(); 7152 var bodyEl = instance._getBodyEl(); 7153 7154 var newNodes = bodyClone.getElementsByTagName('IFRAME'); 7155 var originalNodes = bodyEl.getElementsByTagName('IFRAME'); 7156 7157 var length = originalNodes.length; 7158 7159 // Moving IFRAME nodes back to their original position 7160 if (length === newNodes.length) { 7161 while (length--) { 7162 var newNode = newNodes[length]; 7163 var originalNode = originalNodes[length]; 7164 7165 originalNode.swapNode(newNode); 7166 } 7167 } 7168 7169 bodyClone.innerHTML = ''; 7170 7171 HTML.removeChild(bodyClone); 7172 HTML.appendChild(bodyEl); 7173 }, 7174 7175 /** 7176 * Generates the HTML for print. 7177 * 7178 * @method writeHTML 7179 */ 7180 writeHTML: function() { 7181 var instance = this; 7182 7183 var i = -1; 7184 var j; 7185 7186 var bodyEl = instance._getBodyEl(); 7187 7188 var html5Element; 7189 7190 var cssClass; 7191 7192 var nodeList; 7193 var nodeListLength; 7194 var node; 7195 var buffer = []; 7196 7197 while (++i < HTML5_ELEMENTS_LENGTH) { 7198 html5Element = HTML5_ELEMENTS[i]; 7199 7200 nodeList = DOC.getElementsByTagName(html5Element); 7201 nodeListLength = nodeList.length; 7202 7203 j = -1; 7204 7205 while (++j < nodeListLength) { 7206 node = nodeList[j]; 7207 7208 cssClass = node.className; 7209 7210 if (cssClass.indexOf('printfix-') === -1) { 7211 buffer[0] = 'printfix-' + html5Element; 7212 buffer[1] = cssClass; 7213 7214 node.className = buffer.join(' '); 7215 } 7216 } 7217 } 7218
7219 var docFrag = instance._getDocFrag(); 7220 var bodyClone = instance._getBodyClone(); 7221 7222 docFrag.appendChild(bodyEl); 7223 HTML.appendChild(bodyClone); 7224 7225 bodyClone.className = bodyEl.className; 7226 bodyClone.id = bodyEl.id; 7227 7228 var originalNodes = bodyEl.getElementsByTagName('*'); 7229 var length = originalNodes.length; 7230 7231 // IE will throw a mixed content warning when using https 7232 // and calling clone node if the body contains elements with 7233 // an inline background-image style that is relative to the domain. 7234 if (UA.secure) { 7235 var bodyElStyle = bodyEl.style; 7236 7237 var elStyle; 7238 var backgroundImage; 7239 7240 bodyElStyle.display = 'none'; 7241 7242 for (i = 0; i < length; i++) { 7243 elStyle = originalNodes[i].style; 7244 7245 backgroundImage = elStyle.backgroundImage; 7246 7247 if (backgroundImage && 7248 backgroundImage.indexOf('url
7248(') > -1 && 7249 backgroundImage.indexOf('https') === -1) { 7250 7251 elStyle.backgroundImage = backgroundImage.replace('url(', STR_URL_DOMAIN); 7252 } 7253 } 7254 7255 bodyElStyle.display = ''; 7256 } 7257 7258 var bodyElClone = bodyEl.cloneNode(true); 7259 7260 var newNodes = bodyElClone.getElementsByTagName('*'); 7261 7262 if (length === newNodes.length) { 7263 while (length--) { 7264 var newNode = newNodes[length]; 7265 var newNodeName = newNode.nodeName; 7266 7267 if (newNodeName === 'INPUT' || newNodeName === 'OPTION' || newNodeName === 'IFRAME') { 7268 var originalNode = originalNodes[length]; 7269 var originalNodeName = originalNode.nodeName; 7270 7271 if (originalNodeName === newNodeName) { 7272 var prop = null; 7273 7274 if (newNodeName === 'OPTION') { 7275 prop = 'selected'; 7276 } 7277 else if (newNodeName === 'INPUT' && (newNode.type === 'checkbox' || newNode.type === 7278 'radio')) { 7279 prop = 'checked'; 7280 } 7281 else if (newNodeName === 'IFRAME') { 7282 newNode.src = ''; 7283 } 7284 7285 if (prop !== null) { 7286 toggleNode(newNode, originalNode, prop); 7287 } 7288 } 7289 } 7290 } 7291 } 7292 7293 var bodyHTML = bodyElClone.innerHTML; 7294 7295 bodyHTML = bodyHTML.replace(REGEX_CLONE_NODE_CLEANUP, TAG_REPLACE_ORIGINAL).replace(REGEX_TAG, 7296 TAG_REPLACE_FONT); 7297 7298 bodyClone.innerHTML = bodyHTML; 7299 7300 // Post processing the DOM in order to move IFRAME nodes 7301 7302 newNodes = bodyClone.getElementsByTagName('IFRAME'); 7303 originalNodes = bodyEl.getElementsByTagName('IFRAME'); 7304 7305 length = originalNodes.length; 7306 7307 if (length === newNodes.length) { 7308 while (length--) { 7309 var newNodeIframe = newNodes[length]; 7310 var originalNodeIframe = originalNodes[length]; 7311 7312 // According to quirksmode.org, swapNode is supported on all major IE versions 7313 originalNodeIframe.swapNode(newNodeIframe); 7314 } 7315 } 7316 }, 7317 7318 /** 7319 * Gets all CSS text from all stylesheets. 7320 * 7321 * @method _getAllCSSText 7322 * @protected 7323 * @return {Array} 7324 */ 7325 _getAllCSSText: function() { 7326 var instance = this; 7327 7328 var buffer = []; 7329 var styleSheets = instance._getAllStyleSheets(DOC.styleSheets, 'all'); 7330 var rule; 7331 var cssText; 7332 var styleSheet; 7333 7334 for (var i = 0; styleSheet = styleSheets[i]; i++) { 7335 var rules = styleSheet.rules; 7336 7337 if (rules && rules.length) { 7338 for (var j = 0, ruleLength = rules.length; j < ruleLength; j++) { 7339 rule = rules[j]; 7340 7341 if (!rule.href) { 7342 cssText = instance._getCSSTextFromRule(rule); 7343 7344 buffer.push(cssText); 7345 } 7346 } 7347 } 7348 } 7349 7350 return buffer.join(' '); 7351 }, 7352 7353 /** 7354 * Extracts the CSS text from a rule. 7355 * 7356 * @method _getCSSTextFromRule 7357 * @param rule 7358 * @protected 7359 * @return {String} 7360 */ 7361 _getCSSTextFromRule: function(rule) { 7362 var cssText = ''; 7363 7364 var ruleStyle = rule.style; 7365 var ruleCSSText; 7366 var ruleSelectorText; 7367 7368 if (ruleStyle && (ruleCSSText = ruleStyle.cssText) && (ruleSelectorText = rule.selectorText) && 7369 REGEX_ELEMENTS_FAST.test(ruleSelectorText)) { 7370 BUFFER_CSS_TEXT.length = 0; 7371 7372 BUFFER_CSS_TEXT.push(ruleSelectorText, '{', ruleCSSText, '}'); 7373 7374 cssText = BUFFER_CSS_TEXT.join(' '); 7375 } 7376 7377 return cssText; 7378 }, 7379 7380 /** 7381 * Gets all stylesheets from a page. 7382 * 7383 * @method _getAllStyleSheets 7384 * @param styleSheet, mediaType, level, buffer 7385 * @protected 7386 * @return {Array} 7387 */ 7388 _getAllStyleSheets: function(styleSheet, mediaType, level, buffer) { 7389 var instance = this; 7390 7391 level = level || 1; 7392 7393 buffer = buffer || []; 7394 7395 var i; 7396 7397 if (isStylesheetDefined(styleSheet)) { 7398 var imports = styleSheet.imports; 7399 7400 mediaType = styleSheet.mediaType || mediaType; 7401 7402 if (REGEX_PRINT_MEDIA.test(mediaType)) { 7403 var length; 7404 7405 // IE can crash when trying to access imports more than 3 levels deep 7406 if (level <= 3 && isStylesheetDefined(imports) && imports.length) { 7407 for (i = 0, length = imports.length; i < length; i++) { 7408 instance._getAllStyleSheets(imports[i], mediaType, level + 1, buffer); 7409 } 7410 } 7411 else if (styleSheet.length) { 7412 for (i = 0, length = styleSheet.length; i < length; i++) { 7413 instance._getAllStyleSheets(styleSheet[i], mediaType, level, buffer); 7414 } 7415 } 7416 else { 7417 var rules = styleSheet.rules; 7418 var ruleStyleSheet; 7419 7420 if (rules && rules.length) { 7421 for (i = 0, length = rules.length; i < length; i++) { 7422 ruleStyleSheet = rules[i].styleSheet; 7423 7424 if (ruleStyleSheet) { 7425 instance._getAllStyleSheets(ruleStyleSheet, mediaType, level, buffer); 7426 } 7427 } 7428 } 7429 } 7430 7431 if (!styleSheet.disabled && styleSheet.rules) { 7432 buffer.push(styleSheet); 7433 } 7434 } 7435 } 7436 7437 mediaType = 'all'; 7438 7439 return buffer; 7440 }, 7441 7442 /** 7443 * Gets the `<body>` element. 7444 * 7445 * @method _getBodyEl 7446 * @protected 7447 * @return {Element} 7448 */ 7449 _getBodyEl: function() { 7450 var instance = this; 7451 7452 var bodyEl = instance._bodyEl; 7453 7454 if (!bodyEl) { 7455 bodyEl = DOC.body; 7456 7457 instance._bodyEl = bodyEl; 7458 } 7459 7460 return bodyEl; 7461 }, 7462 7463 /** 7464 * Gets a clone of the `<body>` element. 7465 * 7466 * @method _getBodyClone 7467 * @protected 7468 * @return {Element} 7469 */ 7470 _getBodyClone: function() { 7471 var instance = this; 7472 7473 var bodyClone = instance._bodyClone; 7474 7475 if (!bodyClone) { 7476 bodyClone = DOC.createElement('body'); 7477 7478 instance._bodyClone = bodyClone; 7479 } 7480 7481 return bodyClone; 7482 }, 7483 7484 /** 7485 * Gets a document fragment object. 7486 * 7487 * @method _getDocFrag 7488 * @protected 7489 * @return {DocumentFragment} 7490 */ 7491 _getDocFrag: function() { 7492 var instance = this; 7493 7494 var docFrag = instance._docFrag; 7495 7496 if (!docFrag) { 7497 docFrag = DOC.createDocumentFragment(); 7498 7499 html5shiv(docFrag); 7500 7501 instance._docFrag = docFrag; 7502 } 7503 7504 return docFrag; 7505 }, 7506 7507 /** 7508 * Gets the stylesheet from the DOM. 7509 * 7510 * @method _getStyleSheet 7511 * @protected 7512 * @return {Node} 7513 */ 7514 _getStyleSheet: function() { 7515 var instance = this; 7516 7517 var styleSheet = instance._styleSheet; 7518 7519 if (!styleSheet) { 7520 styleSheet = DOC.createElement('style'); 7521 7522 var head = DOC.documentElement.firstChild; 7523 7524 head.insertBefore(styleSheet, head.firstChild); 7525 7526 styleSheet.media = 'print'; 7527 styleSheet.className = 'printfix'; 7528 7529 instance._styleSheet = styleSheet; 7530 } 7531 7532 return styleSheet; 7533 } 7534 } 7535); 7536 7537A.namespace('HTML5').printFix = printFix; 7538 7539printFix(); 7540 7541 7542}, '3.1.0-deprecated.77', {"requires": ["collection", "aui-node-base"]}); 7543 7544YUI.add('aui-selector', function (A, NAME) { 7545 7546/** 7547 * The Selector Utility. 7548 * 7549 * @module aui-selector 7550 */ 7551 7552var SELECTOR = A.Selector, 7553 7554 CSS_BOOTSTRAP_SR_ONLY = A.getClassName('sr-only'), 7555 CSS_HIDE = A.getClassName('hide'), 7556 REGEX_CLIP_RECT_ZERO = new RegExp(/rect\((0(px)?(,)?(\s)?){4}\)/i), 7557 REGEX_HIDDEN_CLASSNAMES = new RegExp(CSS_HIDE), 7558 REGEX_SR_ONLY_CLASSNAMES = new RegExp(CSS_BOOTSTRAP_SR_ONLY); 7559 7560SELECTOR._isNodeHidden = function(node) { 7561 var width = node.offsetWidth; 7562 var height = node.offsetHeight; 7563 var ignore = node.nodeName.toLowerCase() === 'tr';
7564 var className = node.className; 7565 var nodeStyle = node.style; 7566 7567 var hidden = false; 7568 7569 if (!ignore) { 7570 if (width === 0 && height === 0) { 7571 hidden = true; 7572 } 7573 else if (width > 0 && height > 0) { 7574 hidden = false; 7575 } 7576 } 7577 7578 hidden = hidden || (nodeStyle.display === 'none' || nodeStyle.visibility === 'hidden') || 7579 (nodeStyle.position === 'absolute' && REGEX_CLIP_RECT_ZERO.test(nodeStyle.clip)) || 7580 REGEX_HIDDEN_CLASSNAMES.test(className) || REGEX_SR_ONLY_CLASSNAMES.test(className); 7581 7582 return hidden; 7583}; 7584 7585var testNodeType = function(type) { 7586 return function(node) { 7587 return node.type === type; 7588 }; 7589}; 7590 7591/** 7592 * Augment the [YUI3 Selector](Selector.html) with more util methods. 7593 * 7594 * @class A.Selector 7595 * @uses Selector 7596 * @constructor 7597 */ 7598A.mix( 7599 SELECTOR.pseudos, { 7600 /** 7601 * Checks if the node is a button element or contains `type="button"`. 7602 * 7603 * @method button 7604 * @param node 7605 * @return {Boolean} 7606 */ 7607 button: function(node) { 7608 return node.type === 'button' || node.nodeName.toLowerCase() === 'button'; 7609 }, 7610 7611 /** 7612 * Checks if the node contains `type="checkbox"`. 7613 * 7614 * @method checkbox 7615 * @return {Boolean} 7616 */ 7617 checkbox: testNodeType('checkbox'), 7618 7619 /** 7620 * Checks if the node is checked or not. 7621 * 7622 * @method checked 7623 * @param node 7624 * @return {Boolean} 7625 */ 7626 checked: function(node) { 7627 return node.checked === true; 7628 }, 7629 7630 /** 7631 * Checks if the node is disabled or not. 7632 * 7633 * @method disabled 7634 * @param node 7635 * @return {Boolean} 7636 */ 7637 disabled: function(node) { 7638 return node.disabled === true; 7639 }, 7640 7641 /** 7642 * Checks if the node is empty or not. 7643 * 7644 * @method empty 7645 * @param node 7646 * @return {Boolean} 7647 */ 7648 empty: function(node) { 7649 return !node.firstChild; 7650 }, 7651 7652 /** 7653 * Checks if the node is enabled or not. 7654 * 7655 * @method enabled 7656 * @param node 7657 * @return {Boolean} 7658 */ 7659 enabled: function(node) { 7660 return node.disabled === false && node.type !== 'hidden'; 7661 }, 7662 7663 /** 7664 * Checks if the node contains `type="file"`. 7665 * 7666 * @method file 7667 * @return {Boolean} 7668 */ 7669 file: testNodeType('file'), 7670 7671 /** 7672 * Checks if the node is a header (e.g. `<h1>`, `<h2>`, ...) or not. 7673 * 7674 * @method header 7675 * @param node 7676 * @return {Boolean} 7677 */ 7678 header: function(node) { 7679 return /h\d/i.test(node.nodeName); 7680 }, 7681 7682 /** 7683 * Checks if the node is hidden or not. 7684 * 7685 * @method hidden 7686 * @param node 7687 * @return {Boolean} 7688 */ 7689 hidden: function(node) { 7690 return SELECTOR._isNodeHidden(node); 7691 }, 7692 7693 /** 7694 * Checks if the node contains `type="image"`. 7695 * 7696 * @method image 7697 * @return {Boolean} 7698 */ 7699 image: testNodeType('image'), 7700 7701 /** 7702 * Checks if the node is an input (e.g. `<textarea>`, `<input>`, ...) or not. 7703 * 7704 * @method input 7705 * @param node 7706 * @return {Boolean} 7707 */ 7708 input: function(node) { 7709 return /input|select|textarea|button/i.test(node.nodeName); 7710 }, 7711 7712 /** 7713 * Checks if the node contains a child or not. 7714 * 7715 * @method parent 7716 * @param node 7717 * @return {Boolean} 7718 */ 7719 parent: function(node) { 7720 return !!node.firstChild; 7721 }, 7722 7723 /** 7724 * Checks if the node contains `type="password"`. 7725 * 7726 * @method password 7727 * @return {Boolean} 7728 */ 7729 password: testNodeType('password'), 7730 7731 /** 7732 * Checks if the node contains `type="radio"`. 7733 * 7734 * @method radio 7735 * @return {Boolean} 7736 */ 7737 radio: testNodeType('radio'), 7738 7739 /** 7740 * Checks if the node contains `type="reset"`. 7741 * 7742 * @method reset 7743 * @return {Boolean} 7744 */ 7745 reset: testNodeType('reset'), 7746 7747 /** 7748 * Checks if the node is selected or not. 7749 * 7750 * @method selected 7751 * @param node 7752 * @return {Boolean} 7753 */ 7754 selected: function(node) { 7755 node.parentNode.selectedIndex; 7756 return node.selected === true; 7757 }, 7758 7759 /** 7760 * Checks if the node contains `type="submit"`. 7761 * 7762 * @method submit 7763 * @return {Boolean} 7764 */ 7765 submit: testNodeType('submit'), 7766 7767 /** 7768 * Checks if the node contains `type="text"`. 7769 * 7770 * @method text 7771 * @return {Boolean} 7772 */ 7773 text: testNodeType('text'), 7774 7775 /** 7776 * Checks if the node is visible or not. 7777 * 7778 * @method visible 7779 * @param node 7780 * @return {Boolean} 7781 */ 7782 visible: function(node) { 7783 return !SELECTOR._isNodeHidden(node); 7784 } 7785 } 7786); 7787 7788 7789}, '3.1.0-deprecated.77', {"requires": ["selector-css3", "aui-classnamemanager"]}); 7790 7791YUI.add('aui-timer', function (A, NAME) { 7792 7793/** 7794 * Utility for timing logics used to manage [JavaScript Timer 7795 * Congestion](http://fitzgeraldnick.com/weblog/40/) problems. 7796 * 7797 * @module aui-timer 7798 */ 7799 7800var Lang = A.Lang, 7801 now = Lang.now, 7802 isEmpty = A.Object.isEmpty, 7803 7804 aArray = A.Array; 7805 7806/** 7807 * A base class for Timer. 7808 * 7809 * @class A.Timer 7810 * @constructor 7811 */ 7812var Timer = { 7813 7814 /** 7815 * Cancels repeated action which was set up using `setInterval` function. 7816 * 7817 * @method clearInterval 7818 * @param id 7819 */ 7820 clearInterval: function(id) { 7821 var instance = Timer; 7822 7823 instance.unregister(true, id); 7824 }, 7825 7826 /**
7827 * Clears the delay set by `setTimeout` function. 7828 * 7829 * @method clearTimeout 7830 * @param id 7831 */ 7832 clearTimeout: function(id) { 7833 var instance = Timer; 7834 7835 instance.unregister(false, id); 7836 }, 7837 7838 /** 7839 * Defines the fixed time delay between each interval. 7840 * 7841 * @method intervalTime 7842 * @param newInterval 7843 * @return {Number} 7844 */ 7845 intervalTime: function(newInterval) { 7846 var instance = Timer; 7847 7848 if (arguments.length) { 7849 instance._INTERVAL = newInterval; 7850 } 7851 7852 return instance._INTERVAL; 7853 }, 7854 7855 /** 7856 * Checks if the task is repeatable or not. 7857 * 7858 * @method isRepeatable 7859 * @param task 7860 * @return {Boolean} 7861 */ 7862 isRepeatable: function(task) { 7863 return task.repeats; 7864 }, 7865 7866 /** 7867 * Calls a function after a specified delay. 7868 * 7869 * @method setTimeout 7870 * @param fn 7871 * @param ms 7872 * @param context 7873 */ 7874 setTimeout: function(fn, ms, context) { 7875 var instance = Timer; 7876 7877 var args = aArray(arguments, 3, true); 7878 7879 return instance.register(false, fn, ms, context, args); 7880 }, 7881 7882 /** 7883 * Calls a function repeatedly, with a fixed time delay between each call to 7884 * that function. 7885 * 7886 * @method setInterval 7887 * @param fn 7888 * @param ms 7889 * @param context 7890 */ 7891 setInterval: function(fn, ms, context) { 7892 var instance = Timer; 7893 7894 var args = aArray(arguments, 3, true); 7895 7896 return instance.register(true, fn, ms, context, args); 7897 }, 7898 7899 /** 7900 * Adds a new task to the timer. 7901 * 7902 * @method register 7903 * @param repeats 7904 * @param fn 7905 * @param ms 7906 * @param context 7907 * @param args 7908 */ 7909 register: function(repeats, fn, ms, context, args) { 7910 var instance = Timer; 7911 7912 var id = (++A.Env._uidx); 7913 7914 args = args || []; 7915 7916 args.unshift(fn, context); 7917 7918 instance._TASKS[id] = instance._create( 7919 repeats, instance._getNearestInterval(ms), A.rbind.apply(A, args) 7920 ); 7921 7922 instance._lazyInit(); 7923 7924 return id; 7925 }, 7926 7927 /** 7928 * Runs the task function. 7929 * 7930 * @method run 7931 * @param task 7932 */ 7933 run: function(task) { 7934 task.lastRunTime = now(); 7935 7936 return task.fn(); 7937 }, 7938 7939 /** 7940 * Removes a task from the timer. 7941 * 7942 * @method unregister 7943 * @param repeats 7944 * @param id 7945 */ 7946 unregister: function(repeats, id) { 7947 var instance = Timer; 7948 7949 var tasks = instance._TASKS; 7950 7951 var task = tasks[id]; 7952 7953 instance._lazyDestroy(); 7954 7955 return task && task.repeats === repeats && delete tasks[id]; 7956 }, 7957 7958 /** 7959 * Creates a collection of timer definitions. 7960 * 7961 * @method _create 7962 * @param repeats 7963 * @param ms 7964 * @param fn 7965 * @protected 7966 * @return {Object} 7967 */ 7968 _create: function(repeats, ms, fn) { 7969 return { 7970 fn: fn, 7971 lastRunTime: now(), 7972 next: ms, 7973 repeats: repeats, 7974 timeout: ms 7975 }; 7976 }, 7977 7978 /** 7979 * Subtracts the current time with the last run time. The result of this 7980 * operation is subtracted with the task timeout. 7981 * 7982 * @method _decrementNextRunTime 7983 * @param tasks 7984 * @protected 7985 */ 7986 _decrementNextRunTime: function(task) { 7987 return task.next = task.timeout - (now() - task.lastRunTime); 7988 }, 7989 7990 /** 7991 * Calculates the nearest interval by using the modulus of the argument with 7992 * the interval as reference. 7993 * 7994 * @method _getNearestInterval 7995 * @param num 7996 * @protected 7997 * @return {Number} 7998 */ 7999 _getNearestInterval: function(num) { 8000 var instance = Timer; 8001 8002 var interval = instance._INTERVAL; 8003 8004 var delta = num % interval; 8005 8006 var nearestInterval; 8007 8008 if (delta < interval / 2) { 8009 nearestInterval = num - delta; 8010 } 8011 else { 8012 nearestInterval = num + interval - delta; 8013 } 8014 8015 return nearestInterval; 8016 }, 8017 8018 /** 8019 * Checks if the timer is initialized and empty, then calls the 8020 * `clearTimeout` function using the global interval id. 8021 * 8022 * @method _lazyDestroy 8023 * @protected 8024 */ 8025 _lazyDestroy: function() { 8026 var instance = Timer; 8027 8028 if (instance._initialized && isEmpty(instance._TASKS)) { 8029 clearTimeout(instance._globalIntervalId); 8030 8031 instance._initialized = false;
8032 } 8033 }, 8034 8035 /** 8036 * Checks if the timer is initialized and contains a task, then calls the 8037 * `setTimeout` function and stores the global interval id. 8038 * 8039 * @method _lazyInit 8040 * @protected 8041 */ 8042 _lazyInit: function() { 8043 var instance = Timer; 8044 8045 if (!instance._initialized && !isEmpty(instance._TASKS)) { 8046 instance._lastRunTime = now(); 8047 8048 instance._globalIntervalId = setTimeout( 8049 instance._runner, instance._INTERVAL 8050 ); 8051 8052 instance._initialized = true; 8053 } 8054 }, 8055 8056 /** 8057 * Goes through all pending tasks and initializes its timer or unregisters 8058 * it depending on the task status. 8059 * 8060 * @method _loop 8061 * @param i 8062 * @param pendingTasks 8063 * @param length 8064 * @protected 8065 */ 8066 _loop: function(i, pendingTasks, length) { 8067 var instance = Timer; 8068 8069 var interval = instance._INTERVAL; 8070 var tasks = instance._TASKS; 8071 8072 var halfInterval = interval / 2; 8073 8074 for (var start = now(); i < length && now() - start < 50; i++) { 8075 var taskId = pendingTasks[i]; 8076 var task = tasks[taskId]; 8077 8078 if (task && instance._decrementNextRunTime(task) < halfInterval) { 8079 instance.run(task); 8080 8081 if (instance.isRepeatable(task)) { 8082 instance._resetNextRunTime(task); 8083 } 8084 else { 8085 instance.unregister(false, taskId); 8086 } 8087 } 8088 } 8089 8090 if (instance._initialized) { 8091 if (i < length) { 8092 instance._globalIntervalId = setTimeout(instance._loop, 10); 8093 } 8094 else { 8095 instance._globalIntervalId = setTimeout( 8096 instance._runner, interval 8097 ); 8098 } 8099 } 8100 }, 8101 8102 /** 8103 * Gets the arguments to call the `_loop` method. 8104 * 8105 * @method _runner 8106 * @protected 8107 */ 8108 _runner: function() { 8109 var instance = Timer; 8110 8111 var i = 0; 8112 var pendingTasks = A.Object.keys(instance._TASKS); 8113 var length = pendingTasks.length; 8114 8115 instance._loop(i, pendingTasks, length); 8116 }, 8117 8118 /** 8119 * Resets the next run time. 8120 * 8121 * @method _resetNextRunTime 8122 * @param task 8123 * @protected 8124 */ 8125 _resetNextRunTime: function(task) { 8126 return task.next = task.timeout; 8127 }, 8128 8129 _INTERVAL: 50, 8130 _TASKS: {}, 8131 8132 _lastRunTime: 0, 8133 _globalIntervalId: 0, 8134 _initialized: false 8135}; 8136 8137/** 8138 * Cancels repeated action which was set up using `setInterval` function. 8139 * 8140 * @method A.clearInterval 8141 * @static 8142 * @param id 8143 */ 8144A.clearInterval = Timer.clearInterval; 8145 8146/** 8147 * Clears the delay set by `setTimeout` function. 8148 * 8149 * @method A.clearTimeout 8150 * @static 8151 * @param id 8152 */ 8153A.clearTimeout = Timer.clearTimeout; 8154 8155/** 8156 * Calls a function repeatedly, with a fixed time delay between each call to 8157 * that function. 8158 * 8159 * @method A.setInterval 8160 * @static 8161 * @param fn 8162 * @param ms 8163 * @param context 8164 */ 8165A.setInterval = Timer.setInterval; 8166 8167/** 8168 * Calls a function after a specified delay. 8169 * 8170 * @method A.setTimeout 8171 * @static 8172 * @param fn 8173 * @param ms 8174 * @param context 8175 */ 8176A.setTimeout = Timer.setTimeout; 8177 8178A.Timer = Timer; 8179 8180 8181}, '3.1.0-deprecated.77', {"requires": ["oop"]}); 8182 8183function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 8184 8185/** 8186 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 8187 * 8188 * This library is free software; you can redistribute it and/or modify it under 8189 * the terms of the GNU Lesser General Public License as published by the Free 8190 * Software Foundation; either version 2.1 of the License, or (at your option) 8191 * any later version. 8192 * 8193 * This library is distributed in the hope that it will be useful, but WITHOUT 8194 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 8195 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 8196 * details. 8197 */ 8198 8199/** 8200 * @deprecated As of Athanasius (7.3.x), with no direct replacement 8201 */ 8202YUI.add('liferay-browser-selectors', function (A) { 8203 var REGEX_VERSION_DOT = /\./g; 8204 var YUI3_JS_ENABLED = 'yui3-js-enabled'; 8205 8206 var parseVersionNumber = function parseVersionNumber(str) { 8207 var count = 0; 8208 return parseFloat(str.replace(REGEX_VERSION_DOT, function () { 8209 return count++ == 1 ? '' : '.'; 8210 })); 8211 }; 8212 8213 var DEFAULTS_VERSION = ['0', '0']; 8214 8215 var getVersion = function getVersion(regex, userAgent) { 8216 var version = (userAgent.match(regex) || DEFAULTS_VERSION)[1]; 8217 return parseVersionNumber(version); 8218 }; 8219 8220 var BROWSERS = ['ie', 'opera', 'chrome', 'edge', 'aol', 'camino', 'firefox', 'flock', 'mozilla', 'netscape', 'icab', 'konqueror', 'safari']; 8221 var MAP_OS_SELECTORS = { 8222 macintosh: 'mac', 8223 windows: 'win' 8224 }; 8225 var nav = navigator; 8226 var CONFIG = A.config; 8227 var DOC = CONFIG.doc; 8228 var userAgent = nav.userAgent; 8229 var UA = A.UA; 8230 var OS = UA.os; 8231 var UAX = { 8232 agent: userAgent, 8233 aol: 0, 8234 browser: 0, 8235 camino: 0, 8236 firefox: 0, 8237 flock: 0, 8238 icab: 0, 8239 konqueror: 0, 8240 mozilla: 0, 8241 netscape: 0, 8242 safari: 0 8243 }; 8244 UAX.mac = OS == 'macintosh'; 8245 UAX.rhino = OS == 'rhino'; 8246 UAX.win = OS == 'windows'; 8247 var BrowserSelectors = { 8248 getSelectors: function getSelectors() { 8249 // The methods in this if block only run once across all instances 8250 if (!UA.selectors) { 8251 if (userAgent.indexOf('Edge') !== -1) { 8252 UAX.edge = getVersion(/Edge\/([^\s]*)/, userAgent); 8253 } 8254 8255 if (UA.ie) { 8256 UAX.aol = getVersion(/America Online Browser ([^\s]*);/, userAgent); 8257 var docMode = DOC.documentMode; 8258 8259 if (docMode) { 8260 UA.browser = UA.ie; 8261 UA.ie = docMode; 8262 } 8263 } else if (UA.gecko) { 8264 UAX.netscape = getVersion(/(Netscape|Navigator)\/([^\s]*)/, userAgent); 8265 UAX.flock = getVersion(/Flock\/([^\s]*)/, userAgent); 8266 UAX.camino = getVersion(/Camino\/([^\s]*)/, userAgent); 8267 UAX.firefox = getVersion(/Firefox\/([^\s]*)/, userAgent); 8268 } else if (UA.webkit) { 8269 UAX.safari = getVersion(/Version\/([^\s]*) Safari/, userAgent); 8270 } else { 8271 UAX.icab = getVersion(/iCab(?:\/|\s)?([^\s]*)/, userAgent); 8272 UAX.konqueror = getVersion(/Konqueror\/([^\s]*)/, userAgent); 8273 } 8274 8275 if (!UAX.win && !UAX.mac) { 8276 var linux = /Linux/.test(userAgent); 8277 var sun = /Solaris|SunOS/.test(userAgent); 8278 8279 if (linux) {
8280 UA.os = 'linux'; 8281 UAX.linux = linux; 8282 } else if (sun) { 8283 UA.os = 'sun'; 8284 UAX.sun = sun; 8285 } 8286 } 8287 8288 var touch = UA.touchEnabled; 8289 UAX.touch = touch; 8290 UAX.touchMobile = touch && !!UA.mobile; 8291 A.mix(UA, UAX); 8292 var browserList = []; 8293 var versionMajor = 0; 8294 var browser; 8295 var uaVersionMajor; 8296 var uaVersionMinor; 8297 var version; 8298 var versionObj = { 8299 major: versionMajor, 8300 string: '' 8301 }; 8302 var i = BROWSERS.length; 8303 8304 while (i--) { 8305 browser = BROWSERS[i]; 8306 version = UA[browser]; 8307 8308 if (version > 0) { 8309 versionMajor = parseInt(version, 10); 8310 uaVersionMajor = browser + versionMajor; 8311 uaVersionMinor = browser + version; 8312 8313 if (String(version).indexOf('.') > -1) { 8314 uaVersionMinor = uaVersionMinor.replace(/\.(\d).*/, '-$1'); 8315 } else { 8316 uaVersionMinor += '-0'; 8317 } 8318 8319 browserList.push(browser, uaVersionMajor, uaVersionMinor); 8320 versionObj.string = browser + ''; 8321 versionObj.major = versionMajor; 8322 } 8323 } 8324 8325 UA.version = versionObj; 8326 UA.renderer = ''; 8327 8328 if (UA.ie) { 8329 UA.renderer = 'trident'; 8330 } else if (UA.edge) { 8331 UA.renderer = 'edgeHTML'; 8332 } else if (UA.gecko) { 8333 UA.renderer = 'gecko'; 8334 } else if (UA.webkit) { 8335 UA.renderer = 'webkit'; 8336 } else if (UA.opera) { 8337 UA.renderer = 'presto'; 8338 } 8339 8340 A.UA = UA; 8341 /* 8342 * Browser selectors 8343 */ 8344 8345 var selectors = [UA.renderer, 'js'].concat(browserList); 8346 var osSelector = MAP_OS_SELECTORS[UA.os] || UA.os; 8347 selectors.push(osSelector); 8348 8349 if (UA.mobile) { 8350 selectors.push('mobile'); 8351 } 8352 8353 if (UA.secure) { 8354 selectors.push('secure'); 8355 } 8356 8357 if (UA.touch) { 8358 selectors.push('touch'); 8359 } 8360 8361 UA.selectors = selectors.join(' '); 8362 var svg; 8363 var vml; 8364 vml = !(svg = !!(CONFIG.win.SVGAngle || DOC.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'))); 8365 8366 if (vml) { 8367 var behaviorObj; 8368 var div = DOC.createElement('div'); 8369 div.innerHTML = '<v:shape adj="1"/>'; 8370 behaviorObj = div.firstChild; 8371 behaviorObj.style.behavior = 'url(#default#VML)'; 8372 8373 if (!(behaviorObj && _typeof(behaviorObj.adj) == 'object')) { 8374 vml = false; 8375 } 8376 8377 div = null; 8378 } 8379 8380 YUI._VML = vml; 8381 YUI._SVG = svg; 8382 UA.vml = YUI._VML; 8383 UA.svg = YUI._SVG; 8384 } 8385 8386 return UA.selectors; 8387 }, 8388 run: function run() { 8389 var documentElement = DOC.documentElement; 8390 var selectors = this.getSelectors(); 8391 UA.dir = documentElement.getAttribute('dir') || 'ltr'; 8392 8393 if (documentElement.className.indexOf(UA.dir) === -1) { 8394 selectors += ' ' + UA.dir; 8395 } 8396 8397 if (documentElement.className.indexOf(YUI3_JS_ENABLED) === -1 && selectors.indexOf(YUI3_JS_ENABLED) === -1) { 8398 selectors += ' ' + YUI3_JS_ENABLED; 8399 } 8400 8401 documentElement.className += ' ' + selectors; 8402 } 8403 }; 8404 Liferay.BrowserSelectors = BrowserSelectors; 8405}, '', { 8406 requires: ['yui-base'] 8407}); 8408//# sourceMappingURL=browser_selectors.js.map 8409/** 8410 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 8411 * 8412 * This library is free software; you can redistribute it and/or modify it under 8413 * the terms of the GNU Lesser General Public License as published by the Free 8414 * Software Foundation; either version 2.1 of the License, or (at your option) 8415 * any later version. 8416 * 8417 * This library is distributed in the hope that it will be useful, but WITHOUT 8418 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 8419 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 8420 * details. 8421 */ 8422AUI.add('liferay-form', function (A) { 8423 var AArray = A.Array; 8424 var Lang = A.Lang; 8425 var DEFAULTS_FORM_VALIDATOR = A.config.FormValidator; 8426 var defaultAcceptFiles = DEFAULTS_FORM_VALIDATOR.RULES.acceptFiles; 8427 var TABS_SECTION_STR = 'TabsSection'; 8428 var REGEX_NUMBER = /^[+-]?(\d+)([.|,]\d+)*([eE][+-]?\d+)?$/; 8429 var REGEX_URL = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(https?:\/\/|www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))((.*):(\d*)\/?(.*))?)/; 8430 8431 var acceptFiles = function acceptFiles(val, node, ruleValue) { 8432 if (ruleValue && ruleValue.split(',').includes('*')) { 8433 return true; 8434 } 8435 8436 return defaultAcceptFiles(val, node, ruleValue); 8437 }; 8438 8439 var maxFileSize = function maxFileSize(_val, node, ruleValue) { 8440 var nodeType = node.get('type').toLowerCase(); 8441 8442 if (nodeType === 'file') { 8443 return ruleValue === 0 || node._node.files[0].size <= ruleValue; 8444 } 8445 8446 return true; 8447 }; 8448 8449 var number = function number(val, _node, _ruleValue) { 8450 return REGEX_NUMBER && REGEX_NUMBER.test(val); 8451 }; 8452 8453 var url = function url(val, _node, _ruleValue) { 8454 return REGEX_URL && REGEX_URL.test(val); 8455 }; 8456 8457 A.mix(DEFAULTS_FORM_VALIDATOR.RULES, { 8458 acceptFiles: acceptFiles, 8459 maxFileSize: maxFileSize, 8460 number: number, 8461 url: url 8462 }, true); 8463 A.mix(DEFAULTS_FORM_VALIDATOR.STRINGS, { 8464 DEFAULT: 'Controllare\x20questo\x20campo\x2e', 8465 acceptFiles: 'Inserisci\x20un\x20file\x20con\x20un\x27estensione\x20valida\x20\x28\x7b0\x7d\x29\x2e',
8466 alpha: 'Inserisci\x20solo\x20caratteri\x20alfa\x2e', 8467 alphanum: 'Inserisci\x20solo\x20caratteri\x20alfanumerici\x2e', 8468 date: 'Inserisci\x20una\x20data\x20valida\x2e', 8469 digits: 'Inserisci\x20solo\x20numeri\x2e', 8470 email: 'Inserisci\x20un\x20indirizzo\x20email\x20valido\x2e', 8471 equalTo: 'Inserisci\x20di\x20nuovo\x20lo\x20stesso\x20valore\x2e', 8472 max: 'Inserisci\x20un\x20valore\x20minore\x20di\x20o\x20uguale\x20a\x20\x7b0\x7d\x2e', 8473 maxFileSize: 'Si\x20prega\x20di\x20inserire\x20un\x20file\x20con\x20una\x20dimensione\x20valida\x20non\x20più\x20grande\x20di\x20\x7b0\x7d\x2e', 8474 maxLength: 'Inserisci\x20non\x20più\x20di\x20\x7b0\x7d\x20caratteri\x2e', 8475 min: 'Inserisci\x20un\x20valore\x20più\x20grande\x20di\x20o\x20uguale\x20a\x20\x7b0\x7d\x2e', 8476 minLength: 'Inserisci\x20almeno\x20\x7b0\x7d\x20caratteri\x2e', 8477 number: 'Inserisci\x20un\x20numero\x20valido\x2e', 8478 range: 'Inserisci\x20un\x20valore\x20tra\x20\x7b0\x7d\x20e\x20\x7b1\x7d\x2e', 8479 rangeLength: 'Inserisci\x20un\x20valore\x20con\x20una\x20lunghezza\x20caratteri\x20tra\x20\x7b0\x7d\x20e\x20\x7b1\x7d\x2e', 8480 required: 'Questo\x20campo\x20è\x20obbligatorio\x2e', 8481 url: 'Inserisci\x20un\x20URL\x20valido\x2e' 8482 }, true); 8483 var Form = A.Component.create({ 8484 _INSTANCES: {}, 8485 ATTRS: { 8486 fieldRules: { 8487 setter: function setter(val) { 8488 var instance = this; 8489 8490 instance._processFieldRules(val); 8491 8492 return val; 8493 } 8494 }, 8495 id: {}, 8496 namespace: {}, 8497 onSubmit: { 8498 valueFn: function valueFn() { 8499 var instance = this; 8500 return instance._onSubmit; 8501 } 8502 }, 8503 validateOnBlur: { 8504 validator: Lang.isBoolean, 8505 value: true 8506 } 8507 }, 8508 EXTENDS: A.Base, 8509 get: function get(id) { 8510 var instance = this; 8511 return instance._INSTANCES[id]; 8512 }, 8513 prototype: { 8514 _afterGetFieldsByName: function _afterGetFieldsByName(fieldName) { 8515 var instance = this; 8516 var editorString = 'Editor'; 8517 8518 if (fieldName.lastIndexOf(editorString) === fieldName.length - editorString.length) { 8519 var formNode = instance.formNode; 8520 return new A.Do.AlterReturn('Return editor dom element', formNode.one('#' + fieldName)); 8521 } 8522 }, 8523 _bindForm: function _bindForm() { 8524 var instance = this; 8525 var formNode = instance.formNode; 8526 var formValidator = instance.formValidator; 8527 formValidator.on('submit', A.bind('_onValidatorSubmit', instance)); 8528 formValidator.on('submitError', A.bind('_onSubmitError', instance)); 8529 formNode.delegate(['blur', 'focus'], A.bind('_onFieldFocusChange', instance), 'button,input,select,textarea'); 8530 formNode.delegate(['blur', 'input'], A.bind('_onEditorBlur', instance), 'div[contenteditable="true"]'); 8531 A.Do.after('_afterGetFieldsByName', formValidator, 'getFieldsByName', instance); 8532 }, 8533 _defaultSubmitFn: function _defaultSubmitFn(event) { 8534 var instance = this; 8535 8536 if (!event.stopped) { 8537 submitForm(instance.form); 8538 } 8539 }, 8540 _findRuleIndex: function _findRuleIndex(fieldRules, fieldName, validatorName) { 8541 var ruleIndex = -1; 8542 AArray.some(fieldRules, function (element, index) { 8543 if (element.fieldName === fieldName && element.validatorName === validatorName) { 8544 ruleIndex = index; 8545 return true; 8546 } 8547 }); 8548 return ruleIndex; 8549 }, 8550 _focusInvalidFieldTab: function _focusInvalidFieldTab() { 8551 var instance = this; 8552 var formNode = instance.formNode; 8553 var field = formNode.one('.' + instance.formValidator.get('errorClass')); 8554 8555 if (field) { 8556 var fieldWrapper = field.ancestor('form > fieldset > div'); 8557 var formTabs = formNode.one('.lfr-nav'); 8558 8559 if (fieldWrapper && formTabs) { 8560 var tabs = formTabs.all('.nav-item'); 8561 var tabsNamespace = formTabs.getAttribute('data-tabs-namespace'); 8562 var tabNames = AArray.map(tabs._nodes, function (tab) { 8563 return tab.getAttribute('data-tab-name'); 8564 }); 8565 var fieldWrapperId = fieldWrapper.getAttribute('id').slice(0, -TABS_SECTION_STR.length); 8566 var fieldTabId = AArray.find(tabs._nodes, function (tab) { 8567 return tab.getAttribute('id').indexOf(fieldWrapperId) !== -1; 8568 }); 8569 Liferay.Portal.Tabs.show(tabsNamespace, tabNames, fieldTabId.getAttribute('data-tab-name')); 8570 } 8571 } 8572 }, 8573 _onEditorBlur: function _onEditorBlur(event) { 8574 var instance = this; 8575 var formValidator = instance.formValidator; 8576 formValidator.validateField(event.target); 8577 }, 8578 _onFieldFocusChange: function _onFieldFocusChange(event) { 8579 var row = event.currentTarget.ancestor('.field'); 8580 8581 if (row) { 8582 row.toggleClass('field-focused', event.type === 'focus'); 8583 } 8584 }, 8585 _onSubmit: function _onSubmit(event) { 8586 var instance = this; 8587 event.preventDefault(); 8588 setTimeout(function () { 8589 instance._defaultSubmitFn(event); 8590 }, 0); 8591 }, 8592 _onSubmitError: function _onSubmitError() { 8593 var instance = this; 8594 var collapsiblePanels = instance.formNode.all('.panel-collapse'); 8595 collapsiblePanels.each(function (panel) { 8596 var errorFields = panel.get('children').all('.has-error'); 8597 8598 if (errorFields.size() > 0 && !panel.hasClass('in')) { 8599 var panelNode = panel.getDOM(); 8600 Liferay.CollapseProvider.show({ 8601 panel: panelNode 8602 }); 8603 } 8604 }); 8605 }, 8606 _onValidatorSubmit: function _onValidatorSubmit(event) { 8607 var instance = this; 8608 var onSubmit = instance.get('onSubmit'); 8609 onSubmit.call(instance, event.validator.formEvent); 8610 }, 8611 _processFieldRule: function _processFieldRule(rules, strings, rule) { 8612 var instance = this; 8613 var value = true; 8614 var fieldName = rule.fieldName;
8615 var validatorName = rule.validatorName; 8616 var field = this.formValidator.getField(fieldName); 8617 8618 if (field) { 8619 var fieldNode = field.getDOMNode(); 8620 A.Do.after('_setFieldAttribute', fieldNode, 'setAttribute', instance, fieldName); 8621 A.Do.after('_removeFieldAttribute', fieldNode, 'removeAttribute', instance, fieldName); 8622 } 8623 8624 if ((rule.body || rule.body === 0) && !rule.custom) { 8625 value = rule.body; 8626 } 8627 8628 var fieldRules = rules[fieldName]; 8629 8630 if (!fieldRules) { 8631 fieldRules = {}; 8632 rules[fieldName] = fieldRules; 8633 } 8634 8635 fieldRules[validatorName] = value; 8636 8637 if (rule.custom) { 8638 DEFAULTS_FORM_VALIDATOR.RULES[validatorName] = rule.body; 8639 } 8640 8641 var errorMessage = rule.errorMessage; 8642 8643 if (errorMessage) { 8644 var fieldStrings = strings[fieldName]; 8645 8646 if (!fieldStrings) { 8647 fieldStrings = {}; 8648 strings[fieldName] = fieldStrings; 8649 } 8650 8651 fieldStrings[validatorName] = errorMessage; 8652 } 8653 }, 8654 _processFieldRules: function _processFieldRules(fieldRules) { 8655 var instance = this; 8656 8657 if (!fieldRules) { 8658 fieldRules = instance.get('fieldRules'); 8659 } 8660 8661 var fieldStrings = {}; 8662 var rules = {}; 8663 8664 for (var rule in fieldRules) { 8665 instance._processFieldRule(rules, fieldStrings, fieldRules[rule]); 8666 } 8667 8668 var formValidator = instance.formValidator; 8669 8670 if (formValidator) { 8671 formValidator.set('fieldStrings', fieldStrings); 8672 formValidator.set('rules', rules); 8673 } 8674 }, 8675 _removeFieldAttribute: function _removeFieldAttribute(name, fieldName) { 8676 if (name === 'disabled') { 8677 this.formValidator.validateField(fieldName); 8678 } 8679 }, 8680 _setFieldAttribute: function _setFieldAttribute(name, value, fieldName) { 8681 if (name === 'disabled') { 8682 this.formValidator.resetField(fieldName); 8683 } 8684 }, 8685 _validatable: function _validatable(field) { 8686 var result; 8687 8688 if (field.test(':disabled')) { 8689 result = new A.Do.Halt(); 8690 } 8691 8692 return result; 8693 }, 8694 addRule: function addRule(fieldName, validatorName, errorMessage, body, custom) { 8695 var instance = this; 8696 var fieldRules = instance.get('fieldRules'); 8697 8698 var ruleIndex = instance._findRuleIndex(fieldRules, fieldName, validatorName); 8699 8700 if (ruleIndex == -1) { 8701 fieldRules.push({ 8702 body: body || '', 8703 custom: custom || false, 8704 errorMessage: errorMessage || '', 8705 fieldName: fieldName, 8706 validatorName: validatorName 8707 }); 8708 8709 instance._processFieldRules(fieldRules); 8710 } 8711 }, 8712 initializer: function initializer() { 8713 var instance = this; 8714 var id = instance.get('id'); 8715 var form = document[id]; 8716 var formNode = A.one(form); 8717 instance.form = form; 8718 instance.formNode = formNode; 8719 8720 if (formNode) { 8721 var formValidator = new A.FormValidator({ 8722 boundingBox: formNode, 8723 validateOnBlur: instance.get('validateOnBlur') 8724 }); 8725 A.Do.before('_focusInvalidFieldTab', formValidator, 'focusInvalidField', instance); 8726 A.Do.before('_validatable', formValidator, 'validatable', instance); 8727 instance.formValidator = formValidator; 8728 8729 instance._processFieldRules(); 8730 8731 instance._bindForm(); 8732 } 8733 }, 8734 removeRule: function removeRule(fieldName, validatorName) { 8735 var instance = this; 8736 var fieldRules = instance.get('fieldRules'); 8737 8738 var ruleIndex = instance._findRuleIndex(fieldRules, fieldName, validatorName); 8739 8740 if (ruleIndex != -1) { 8741 var rule = fieldRules[ruleIndex]; 8742 instance.formValidator.resetField(rule.fieldName); 8743 fieldRules.splice(ruleIndex, 1); 8744 8745 instance._processFieldRules(fieldRules); 8746 } 8747 } 8748 }, 8749 8750 /* 8751 * @deprecated As of Mueller (7.2.x), with no direct replacement 8752 */ 8753 register: function register(config) { 8754 var instance = this; 8755 var form = new Liferay.Form(config); 8756 var formName = config.id || config.namespace; 8757 instance._INSTANCES[formName] = form; 8758 Liferay.fire('form:registered', { 8759 form: form, 8760 formName: formName 8761 }); 8762 return form; 8763 } 8764 }); 8765 Liferay.Form = Form; 8766}, '', { 8767 requires: ['aui-base', 'aui-form-validator'] 8768}); 8769//# sourceMappingURL=form.js.map 8770/** 8771 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 8772 * 8773 * This library is free software; you can redistribute it and/or modify it under 8774 * the terms of the GNU Lesser General Public License as published by the Free 8775 * Software Foundation; either version 2.1 of the License, or (at your option) 8776 * any later version. 8777 * 8778 * This library is distributed in the hope that it will be useful, but WITHOUT 8779 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 8780 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 8781 * details. 8782 */ 8783 8784/** 8785 * The Form Placeholders Component. 8786 * 8787 * @deprecated As of Mueller (7.2.x), with no direct replacement 8788 * @module liferay-form-placeholders 8789 */ 8790AUI.add('liferay-form-placeholders', function (A) { 8791 var ANode = A.Node; 8792 var CSS_PLACEHOLDER = 'text-placeholder'; 8793 var MAP_IGNORE_ATTRS = { 8794 id: 1, 8795 name: 1, 8796 type: 1 8797 }; 8798 var SELECTOR_PLACEHOLDER_INPUTS = 'input[placeholder], textarea[placeholder]'; 8799 var STR_BLANK = ''; 8800 var STR_DATA_TYPE_PASSWORD_PLACEHOLDER = 'data-type-password-placeholder'; 8801 var STR_FOCUS = 'focus'; 8802 var STR_PASSWORD = 'password'; 8803 var STR_PLACEHOLDER = 'placeholder'; 8804 var STR_SPACE = ' '; 8805 var STR_TYPE = 'type'; 8806 var Placeholders = A.Component.create({ 8807 EXTENDS: A.Plugin.Base, 8808 NAME: 'placeholders', 8809 NS: STR_PLACEHOLDER, 8810 prototype: { 8811 _initializePasswordNode: function _initializePasswordNode(field) { 8812 var placeholder = ANode.create('<input name="' + field.attr('name') + '_pass_placeholder" type="text" />'); 8813 Liferay.Util.getAttributes(field, function (value, name) { 8814 var result = false;
8815 8816 if (!MAP_IGNORE_ATTRS[name]) { 8817 if (name === 'class') { 8818 value += STR_SPACE + CSS_PLACEHOLDER; 8819 } 8820 8821 placeholder.setAttribute(name, value); 8822 } 8823 8824 return result; 8825 }); 8826 placeholder.val(field.attr(STR_PLACEHOLDER)); 8827 placeholder.attr(STR_DATA_TYPE_PASSWORD_PLACEHOLDER, true); 8828 field.placeBefore(placeholder); 8829 field.hide(); 8830 }, 8831 _removePlaceholders: function _removePlaceholders() { 8832 var instance = this; 8833 var formNode = instance.host.formNode; 8834 var placeholderInputs = formNode.all(SELECTOR_PLACEHOLDER_INPUTS); 8835 placeholderInputs.each(function (item) { 8836 if (item.val() == item.attr(STR_PLACEHOLDER)) { 8837 item.val(STR_BLANK); 8838 } 8839 }); 8840 }, 8841 _toggleLocalizedPlaceholders: function _toggleLocalizedPlaceholders(event, currentTarget) { 8842 var placeholder = currentTarget.attr(STR_PLACEHOLDER); 8843 8844 if (placeholder) { 8845 var value = currentTarget.val(); 8846 8847 if (event.type === STR_FOCUS) { 8848 if (value === placeholder) { 8849 currentTarget.removeClass(CSS_PLACEHOLDER); 8850 } 8851 } else if (!value) { 8852 currentTarget.val(placeholder); 8853 currentTarget.addClass(CSS_PLACEHOLDER); 8854 } 8855 } 8856 }, 8857 _togglePasswordPlaceholders: function _togglePasswordPlaceholders(event, currentTarget) { 8858 var placeholder = currentTarget.attr(STR_PLACEHOLDER); 8859 8860 if (placeholder) { 8861 if (event.type === STR_FOCUS) { 8862 if (currentTarget.hasAttribute(STR_DATA_TYPE_PASSWORD_PLACEHOLDER)) { 8863 currentTarget.hide(); 8864 var passwordField = currentTarget.next(); 8865 passwordField.show(); 8866 setTimeout(function () { 8867 Liferay.Util.focusFormField(passwordField); 8868 }, 0); 8869 } 8870 } else if (currentTarget.attr(STR_TYPE) === STR_PASSWORD) { 8871 var value = currentTarget.val(); 8872 8873 if (!value) { 8874 currentTarget.hide(); 8875 currentTarget.previous().show(); 8876 } 8877 } 8878 } 8879 }, 8880 _togglePlaceholders: function _togglePlaceholders(event) { 8881 var instance = this; 8882 var currentTarget = event.currentTarget; 8883 8884 if (currentTarget.hasAttribute(STR_DATA_TYPE_PASSWORD_PLACEHOLDER) || currentTarget.attr(STR_TYPE) === STR_PASSWORD) { 8885 instance._togglePasswordPlaceholders(event, currentTarget); 8886 } else if (currentTarget.hasClass('language-value')) { 8887 instance._toggleLocalizedPlaceholders(event, currentTarget); 8888 } else { 8889 var placeholder = currentTarget.attr(STR_PLACEHOLDER); 8890 8891 if (placeholder) { 8892 var value = currentTarget.val(); 8893 8894 if (event.type === STR_FOCUS) { 8895 if (value === placeholder) { 8896 currentTarget.val(STR_BLANK); 8897 currentTarget.removeClass(CSS_PLACEHOLDER); 8898 } 8899 } else if (!value) { 8900 currentTarget.val(placeholder); 8901 currentTarget.addClass(CSS_PLACEHOLDER); 8902 } 8903 } 8904 } 8905 }, 8906 initializer: function initializer() { 8907 var instance = this; 8908 var host = instance.get('host'); 8909 var formNode = host.formNode; 8910 8911 if (formNode) { 8912 var placeholderInputs = formNode.all(SELECTOR_PLACEHOLDER_INPUTS); 8913 placeholderInputs.each(function (item) { 8914 if (!item.val()) { 8915 if (item.attr(STR_TYPE) === STR_PASSWORD) { 8916 instance._initializePasswordNode(item); 8917 } else { 8918 item.addClass(CSS_PLACEHOLDER); 8919 item.val(item.attr(STR_PLACEHOLDER)); 8920 } 8921 } 8922 }); 8923 instance.host = host; 8924 instance.beforeHostMethod('_onValidatorSubmit', instance._removePlaceholders, instance); 8925 instance.beforeHostMethod('_onFieldFocusChange', instance._togglePlaceholders, instance); 8926 } 8927 } 8928 } 8929 }); 8930 Liferay.Form.Placeholders = Placeholders; 8931 A.Base.plug(Liferay.Form, Placeholders); 8932}, '', { 8933 requires: ['liferay-form', 'plugin'] 8934}); 8935//# sourceMappingURL=form_placeholders.js.map 8936/** 8937 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 8938 * 8939 * This library is free software; you can redistribute it and/or modify it under 8940 * the terms of the GNU Lesser General Public License as published by the Free 8941 * Software Foundation; either version 2.1 of the License, or (at your option) 8942 * any later version. 8943 * 8944 * This library is distributed in the hope that it will be useful, but WITHOUT 8945 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 8946 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 8947 * details. 8948 */ 8949 8950/** 8951 * The Icon Component. 8952 * 8953 * @deprecated As of Mueller (7.2.x), with no direct replacement 8954 * @module liferay-icon 8955 */ 8956AUI.add('liferay-icon', function (A) { 8957 var _ICON_REGISTRY = {}; 8958 var Icon = { 8959 _forcePost: function _forcePost(event) { 8960 if (!Liferay.SPA || !Liferay.SPA.app) { 8961 Liferay.Util.forcePost(event.currentTarget); 8962 event.preventDefault(); 8963 } 8964 }, 8965 _getConfig: function _getConfig(event) { 8966 return _ICON_REGISTRY[event.currentTarget.attr('id')]; 8967 }, 8968 _handleDocClick: function _handleDocClick(event) { 8969 var instance = this; 8970 8971 var config = instance._getConfig(event); 8972 8973 if (config) { 8974 event.preventDefault(); 8975 8976 if (config.useDialog) { 8977 instance._useDialog(event); 8978 } else { 8979 instance._forcePost(event); 8980 } 8981 } 8982 }, 8983 _handleDocMouseOut: function _handleDocMouseOut(event) { 8984 var instance = this; 8985 8986 var config = instance._getConfig(event); 8987 8988 if (config && config.srcHover) { 8989 instance._onMouseHover(event, config.src); 8990 } 8991 }, 8992 _handleDocMouseOver: function _handleDocMouseOver(event) { 8993 var instance = this; 8994 8995 var config = instance._getConfig(event); 8996 8997 if (config && config.srcHover) { 8998 instance._onMouseHover(event, config.srcHover); 8999 } 9000 }, 9001 _onMouseHover: function _onMouseHover(event, src) { 9002 var img = event.currentTarget.one('img'); 9003 9004 if (img) { 9005 img.attr('src', src); 9006 } 9007 }, 9008 _useDialog: function _useDialog(event) { 9009 Liferay.Util.openInDialog(event, { 9010 dialog: { 9011 destroyOnHide: true 9012 }, 9013 dialogIframe: { 9014 bodyCssClass: 'dialog-with-footer' 9015 } 9016 }); 9017 }, 9018 register: function register(config) { 9019 var instance = this; 9020 var doc = A.one(A.config.doc); 9021 _ICON_REGISTRY[config.id] = config; 9022 9023 if (!instance._docClickHandler) { 9024 instance._docClickHandler = doc.delegate('click', instance._handleDocClick, '.lfr-icon-item', instance); 9025 } 9026 9027 if (!instance._docHoverHandler) { 9028 instance._docHoverHandler = doc.delegate('hover', instance._handleDocMouseOver, instance._handleDocMouseOut, '.lfr-icon-item', instance); 9029 } 9030 9031 Liferay.once('screenLoad', function () { 9032 delete _ICON_REGISTRY[config.id]; 9033 }); 9034 } 9035 }; 9036 Liferay.Icon = Icon; 9037}, '', { 9038 requires: ['aui-base', 'liferay-util-window'] 9039}); 9040//# sourceMappingURL=icon.js.map 9041/** 9042 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 9043 * 9044 * This library is free software; you can redistribute it and/or modify it under 9045 * the terms of the GNU Lesser General Public License as published by the Free 9046 * Software Foundation; either version 2.1 of the License, or (at your option) 9047 * any later version. 9048 * 9049 * This library is distributed in the hope that it will be useful, but WITHOUT 9050 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9051 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 9052 * details. 9053 */ 9054AUI.add('liferay-menu', function (A) { 9055 var Util = Liferay.Util; 9056 var ARIA_ATTR_ROLE = 'role'; 9057 var ATTR_CLASS_NAME = 'className'; 9058 var AUTO = 'auto'; 9059 var CSS_BTN_PRIMARY = 'btn-primary'; 9060 var CSS_EXTENDED = 'lfr-extended'; 9061 var CSS_OPEN = 'open'; 9062 var CSS_PORTLET = '.portlet'; 9063 var DEFAULT_ALIGN_POINTS = ['tl', 'bl']; 9064 var EVENT_CLICK = 'click'; 9065 var PARENT_NODE = 'parentNode'; 9066 var STR_BOTTOM = 'b'; 9067 var STR_LEFT = 'l'; 9068 var STR_LTR = 'ltr'; 9069 var STR_RIGHT = 'r'; 9070 var STR_RTL = 'rtl'; 9071 var STR_TOP = 't'; 9072 var MAP_ALIGN_HORIZONTAL_OVERLAY = { 9073 left: STR_RIGHT, 9074 right: STR_LEFT 9075 }; 9076 var MAP_ALIGN_HORIZONTAL_OVERLAY_RTL = { 9077 left: STR_LEFT, 9078 right: STR_RIGHT 9079 }; 9080 var MAP_ALIGN_HORIZONTAL_TRIGGER = { 9081 left: STR_LEFT, 9082 right: STR_RIGHT 9083 }; 9084 var MAP_ALIGN_HORIZONTAL_TRIGGER_RTL = { 9085 left: STR_RIGHT, 9086 right: STR_LEFT 9087 }; 9088 var MAP_ALIGN_VERTICAL_OVERLAY = { 9089 down: STR_TOP, 9090 up: STR_BOTTOM 9091 }; 9092 var MAP_ALIGN_VERTICAL_TRIGGER = { 9093 down: STR_BOTTOM, 9094 up: STR_TOP 9095 }; 9096 var MAP_LIVE_SEARCH = {}; 9097 var REGEX_DIRECTION = /\bdirection-(down|left|right|up)\b/; 9098 var REGEX_MAX_DISPLAY_ITEMS = /max-display-items-(\d+)/; 9099 var SELECTOR_ANCHOR = 'a'; 9100 var SELECTOR_LIST_ITEM = 'li'; 9101 var SELECTOR_SEARCH_CONTAINER = '.lfr-menu-list-search-container'; 9102 var TPL_MENU = '<div class="open" />'; 9103 9104 var Menu = function Menu() { 9105 var instance = this; 9106 instance._handles = []; 9107 9108 if (!Menu._INSTANCE) { 9109 Menu._INSTANCE = instance; 9110 } 9111 }; 9112 9113 Menu.prototype = { 9114 _closeActiveMenu: function _closeActiveMenu() { 9115 var instance = this; 9116 var menu = instance._activeMenu; 9117 9118 if (menu) { 9119 var handles = instance._handles; 9120 A.Array.invoke(handles, 'detach'); 9121 handles.length = 0;
9122 var overlay = instance._overlay; 9123 9124 if (overlay) { 9125 overlay.hide(); 9126 } 9127 9128 var trigger = instance._activeTrigger; 9129 instance._activeMenu = null; 9130 instance._activeTrigger = null; 9131 9132 if (trigger.hasClass(CSS_EXTENDED)) { 9133 trigger.removeClass(CSS_BTN_PRIMARY); 9134 } else { 9135 trigger.get(PARENT_NODE).removeClass(CSS_OPEN); 9136 var portlet = trigger.ancestor(CSS_PORTLET); 9137 9138 if (portlet) { 9139 portlet.removeClass(CSS_OPEN); 9140 } 9141 } 9142 } 9143 }, 9144 _getAlignPoints: A.cached(function (cssClass) { 9145 var alignPoints = DEFAULT_ALIGN_POINTS; 9146 var defaultOverlayHorizontalAlign = STR_RIGHT; 9147 var defaultTriggerHorizontalAlign = STR_LEFT; 9148 var mapAlignHorizontalOverlay = MAP_ALIGN_HORIZONTAL_OVERLAY; 9149 var mapAlignHorizontalTrigger = MAP_ALIGN_HORIZONTAL_TRIGGER; 9150 var langDir = Liferay.Language.direction[themeDisplay.getLanguageId()] || STR_LTR; 9151 9152 if (langDir === STR_RTL) { 9153 defaultOverlayHorizontalAlign = STR_LEFT; 9154 defaultTriggerHorizontalAlign = STR_RIGHT; 9155 mapAlignHorizontalOverlay = MAP_ALIGN_HORIZONTAL_OVERLAY_RTL; 9156 mapAlignHorizontalTrigger = MAP_ALIGN_HORIZONTAL_TRIGGER_RTL; 9157 } 9158 9159 if (cssClass.indexOf(AUTO) === -1) { 9160 var directionMatch = cssClass.match(REGEX_DIRECTION); 9161 var direction = directionMatch && directionMatch[1] || AUTO; 9162 9163 if (direction != 'down') { 9164 var overlayHorizontal = mapAlignHorizontalOverlay[direction] || defaultOverlayHorizontalAlign; 9165 var overlayVertical = MAP_ALIGN_VERTICAL_OVERLAY[direction] || STR_TOP; 9166 var triggerHorizontal = mapAlignHorizontalTrigger[direction] || defaultTriggerHorizontalAlign; 9167 var triggerVertical = MAP_ALIGN_VERTICAL_TRIGGER[direction] || STR_TOP; 9168 alignPoints = [overlayVertical + overlayHorizontal, triggerVertical + triggerHorizontal]; 9169 } 9170 } 9171 9172 return alignPoints; 9173 }), 9174 _getMenu: function _getMenu(trigger) { 9175 var instance = this; 9176 var overlay = instance._overlay; 9177 9178 if (!overlay) { 9179 var MenuOverlay = A.Component.create({ 9180 AUGMENTS: [A.WidgetCssClass, A.WidgetPosition, A.WidgetStdMod, A.WidgetModality, A.WidgetPositionAlign, A.WidgetPositionConstrain, A.WidgetStack], 9181 CSS_PREFIX: 'overlay', 9182 EXTENDS: A.Widget, 9183 NAME: 'overlay' 9184 }); 9185 overlay = new MenuOverlay({ 9186 align: { 9187 node: trigger, 9188 points: DEFAULT_ALIGN_POINTS 9189 }, 9190 constrain: true, 9191 hideClass: false, 9192 preventOverlap: true, 9193 zIndex: Liferay.zIndex.MENU 9194 }).render(); 9195 Liferay.once('beforeScreenFlip', function () { 9196 overlay.destroy(); 9197 instance._overlay = null; 9198 }); 9199 instance._overlay = overlay; 9200 } else { 9201 overlay.set('align.node', trigger); 9202 } 9203 9204 var listContainer = trigger.getData('menuListContainer'); 9205 var menu = trigger.getData('menu'); 9206 var menuHeight = trigger.getData('menuHeight'); 9207 var liveSearch = menu && MAP_LIVE_SEARCH[menu.guid()]; 9208 9209 if (liveSearch) { 9210 liveSearch.reset(); 9211 } 9212 9213 var listItems; 9214 9215 if (!menu || !listContainer) { 9216 listContainer = trigger.next('ul'); 9217 listItems = listContainer.all(SELECTOR_LIST_ITEM); 9218 menu = A.Node.create(TPL_MENU); 9219 listContainer.placeBefore(menu); 9220 listItems.last().addClass('last'); 9221 menu.append(listContainer); 9222 trigger.setData('menuListContainer', listContainer); 9223 trigger.setData('menu', menu); 9224 9225 instance._setARIARoles(trigger, menu, listContainer); 9226 9227 if (trigger.hasClass('select')) { 9228 listContainer.delegate('click', function (event) { 9229 var selectedListItem = event.currentTarget; 9230 var selectedListItemIcon = selectedListItem.one('i'); 9231 var triggerIcon = trigger.one('i'); 9232 9233 if (selectedListItemIcon && triggerIcon) { 9234 var selectedListItemIconClass = selectedListItemIcon.attr('class'); 9235 triggerIcon.attr('class', selectedListItemIconClass); 9236 } 9237 9238 var selectedListItemMessage = selectedListItem.one('.lfr-icon-menu-text'); 9239 var triggerMessage = trigger.one('.lfr-icon-menu-text'); 9240 9241 if (selectedListItemMessage && triggerMessage) { 9242 triggerMessage.setContent(selectedListItemMessage.text()); 9243 } 9244 }, SELECTOR_LIST_ITEM); 9245 } 9246 } 9247 9248 overlay.setStdModContent(A.WidgetStdMod.BODY, menu); 9249 9250 if (!menuHeight) { 9251 menuHeight = instance._getMenuHeight(trigger, menu, listItems || listContainer.all
9251(SELECTOR_LIST_ITEM)); 9252 trigger.setData('menuHeight', menuHeight); 9253 9254 if (menuHeight !== AUTO) { 9255 listContainer.setStyle('maxHeight', menuHeight); 9256 } 9257 } 9258 9259 instance._getFocusManager(); 9260 9261 return menu; 9262 }, 9263 _getMenuHeight: function _getMenuHeight(trigger, menu, listItems) { 9264 var instance = this; 9265 var cssClass = trigger.attr(ATTR_CLASS_NAME); 9266 var height = AUTO; 9267 9268 if (cssClass.indexOf('lfr-menu-expanded') === -1) { 9269 var params = REGEX_MAX_DISPLAY_ITEMS.exec(cssClass); 9270 var maxDisplayItems = params && parseInt(params[1], 10); 9271 9272 if (maxDisplayItems && listItems.size() > maxDisplayItems) { 9273 instance._getLiveSearch(trigger, trigger.getData('menu')); 9274 9275 height = 0; 9276 var heights = listItems.slice(0, maxDisplayItems).get('offsetHeight'); 9277 9278 for (var i = heights.length - 1; i >= 0; i--) { 9279 height += heights[i]; 9280 } 9281 } 9282 } 9283 9284 return height; 9285 }, 9286 _positionActiveMenu: function _positionActiveMenu() { 9287 var instance = this; 9288 var menu = instance._activeMenu; 9289 var trigger = instance._activeTrigger; 9290 9291 if (menu) { 9292 var cssClass = trigger.attr(ATTR_CLASS_NAME); 9293 var overlay = instance._overlay; 9294 var align = overlay.get('align'); 9295 var listNode = menu.one('ul'); 9296 var listNodeHeight = listNode.get('offsetHeight'); 9297 var listNodeWidth = listNode.get('offsetWidth'); 9298 var modalMask = false; 9299 align.points = instance._getAlignPoints(cssClass); 9300 menu.addClass('lfr-icon-menu-open'); 9301 9302 if (Util.isPhone() || Util.isTablet()) { 9303 overlay.hide(); 9304 modalMask = true; 9305 } 9306 9307 overlay.setAttrs({ 9308 align: align, 9309 centered: false, 9310 height: listNodeHeight, 9311 modal: modalMask, 9312 width: listNodeWidth 9313 }); 9314 9315 if (!Util.isPhone() && !Util.isTablet()) { 9316 var focusManager = overlay.bodyNode.focusManager; 9317 9318 if (focusManager) { 9319 focusManager.focus(0); 9320 } 9321 } 9322 9323 overlay.show(); 9324 9325 if (cssClass.indexOf(CSS_EXTENDED) > -1) { 9326 trigger.addClass(CSS_BTN_PRIMARY); 9327 } else { 9328 trigger.get(PARENT_NODE).addClass(CSS_OPEN); 9329 var portlet = trigger.ancestor(CSS_PORTLET); 9330 9331 if (portlet) { 9332 portlet.addClass(CSS_OPEN); 9333 } 9334 } 9335 } 9336 }, 9337 _setARIARoles: function _setARIARoles(trigger, menu) { 9338 var links = menu.all(SELECTOR_ANCHOR); 9339 var searchContainer = menu.one(SELECTOR_SEARCH_CONTAINER); 9340 var listNode = menu.one('ul'); 9341 var ariaLinksAttr = 'menuitem'; 9342 var ariaListNodeAttr = 'menu'; 9343 9344 if (searchContainer) { 9345 ariaListNodeAttr = 'listbox'; 9346 ariaListNodeAttr = 'option'; 9347 } 9348 9349 listNode.setAttribute(ARIA_ATTR_ROLE, ariaListNodeAttr); 9350 links.set(ARIA_ATTR_ROLE, ariaLinksAttr); 9351 trigger.attr({ 9352 'aria-haspopup': true, 9353 role: 'button' 9354 }); 9355 listNode.setAttribute('aria-labelledby', trigger.guid()); 9356 } 9357 }; 9358 9359 Menu.handleFocus = function (id) { 9360 var node = A.one(id); 9361 9362 if (node) { 9363 node.delegate('mouseenter', A.rbind(Menu._targetLink, node, 'focus'), SELECTOR_LIST_ITEM); 9364 node.delegate('mouseleave', A.rbind(Menu._targetLink, node, 'blur'), SELECTOR_LIST_ITEM); 9365 } 9366 }; 9367 9368 var buffer = []; 9369 9370 Menu.register = function (id) { 9371 var menuNode = document.getElementById(id); 9372 9373 if (menuNode) { 9374 if (!Menu._INSTANCE) { 9375 new Menu(); 9376 } 9377 9378 buffer.push(menuNode); 9379 9380 Menu._registerTask(); 9381 } 9382 }; 9383 9384 Menu._registerTask = A.debounce(function () { 9385 if (buffer.length) { 9386 var nodes = A.all(buffer); 9387 nodes.on(EVENT_CLICK, A.bind('_registerMenu', Menu)); 9388 buffer.length = 0; 9389 } 9390 }, 100); 9391 9392 Menu._targetLink = function (event, action) { 9393 var anchor = event.currentTarget.one(SELECTOR_ANCHOR); 9394 9395 if (anchor) { 9396 anchor[action](); 9397 } 9398 }; 9399 9400 Liferay.provide(Menu, '_getFocusManager', function () { 9401 var menuInstance = Menu._INSTANCE; 9402 var focusManager = menuInstance._focusManager; 9403
9404 if (!focusManager) { 9405 var bodyNode = menuInstance._overlay.bodyNode; 9406 bodyNode.plug(A.Plugin.NodeFocusManager, { 9407 circular: true, 9408 descendants: 'li:not(.hide) a,input', 9409 focusClass: 'focus', 9410 keys: { 9411 next: 'down:40', 9412 previous: 'down:38' 9413 } 9414 }); 9415 bodyNode.on('key', function () { 9416 var activeTrigger = menuInstance._activeTrigger; 9417 9418 if (activeTrigger) { 9419 menuInstance._closeActiveMenu(); 9420 9421 activeTrigger.focus(); 9422 } 9423 }, 'down:27,9'); 9424 focusManager = bodyNode.focusManager; 9425 bodyNode.delegate('mouseenter', function (event) { 9426 if (focusManager.get('focused')) { 9427 focusManager.focus(event.currentTarget.one(SELECTOR_ANCHOR)); 9428 } 9429 }, SELECTOR_LIST_ITEM); 9430 focusManager.after('activeDescendantChange', function (event) { 9431 var descendants = focusManager.get('descendants'); 9432 var selectedItem = descendants.item(event.newVal); 9433 9434 if (selectedItem) { 9435 var overlayList = bodyNode.one('ul'); 9436 9437 if (overlayList) { 9438 overlayList.setAttribute('aria-activedescendant', selectedItem.guid()); 9439 } 9440 } 9441 }); 9442 menuInstance._focusManager = focusManager; 9443 } 9444 9445 focusManager.refresh(); 9446 }, ['node-focusmanager'], true); 9447 Liferay.provide(Menu, '_getLiveSearch', function (_trigger, menu) { 9448 var id = menu.guid(); 9449 var liveSearch = MAP_LIVE_SEARCH[id]; 9450 9451 if (!liveSearch) { 9452 var listNode = menu.one('ul'); 9453 var results = []; 9454 listNode.all('li').each(function (node) { 9455 results.push({ 9456 name: node.one('.taglib-text-icon').text().trim(), 9457 node: node 9458 }); 9459 }); 9460 liveSearch = new Liferay.MenuFilter({ 9461 content: listNode, 9462 minQueryLength: 0, 9463 queryDelay: 0, 9464 resultFilters: 'phraseMatch', 9465 resultTextLocator: 'name', 9466 source: results 9467 }); 9468 liveSearch.get('inputNode').swallowEvent('click'); 9469 MAP_LIVE_SEARCH[id] = liveSearch; 9470 } 9471 }, ['liferay-menu-filter'], true); 9472 Liferay.provide(Menu, '_registerMenu', function (event) { 9473 var menuInstance = Menu._INSTANCE; 9474 var handles = menuInstance._handles; 9475 var trigger = event.currentTarget; 9476 var activeTrigger = menuInstance._activeTrigger; 9477 9478 if (activeTrigger) { 9479 if (activeTrigger != trigger) { 9480 activeTrigger.removeClass(CSS_BTN_PRIMARY); 9481 activeTrigger.get(PARENT_NODE).removeClass(CSS_OPEN); 9482 var portlet = activeTrigger.ancestor(CSS_PORTLET); 9483 9484 if (portlet) { 9485 portlet.removeClass(CSS_OPEN); 9486 } 9487 } else { 9488 menuInstance._closeActiveMenu(); 9489 9490 return; 9491 } 9492 } 9493 9494 if (!trigger.hasClass('disabled')) { 9495 var menu = menuInstance._getMenu(trigger); 9496 9497 menuInstance._activeMenu = menu; 9498 menuInstance._activeTrigger = trigger; 9499 9500 if (!handles.length) { 9501 var listContainer = trigger.getData('menuListContainer'); 9502 A.Event.defineOutside('touchend'); 9503 handles.push(A.getWin().on('resize', A.debounce(menuInstance._positionActiveMenu, 200, menuInstance)), A.getDoc().on(EVENT_CLICK, menuInstance._closeActiveMenu, menuInstance), listContainer.on('touchendoutside', function (event) { 9504 event.preventDefault(); 9505 9506 menuInstance._closeActiveMenu(); 9507 }, menuInstance), Liferay.on('dropdownShow', function (event) { 9508 if (event.src !== 'LiferayMenu') { 9509 menuInstance._closeActiveMenu(); 9510 } 9511 })); 9512 var DDM = A.DD && A.DD.DDM; 9513 9514 if (DDM) { 9515 handles.push(DDM.on('ddm:start', menuInstance._closeActiveMenu, menuInstance)); 9516 } 9517 } 9518 9519 menuInstance._positionActiveMenu(); 9520 9521 Liferay.fire('dropdownShow', { 9522 src: 'LiferayMenu' 9523 }); 9524 event.halt(); 9525 } 9526 }, ['aui-widget-cssclass', 'event-outside', 'event-touch', 'widget', 'widget-modality', 'widget-position', 'widget-position-align', 'widget-position-constrain', 'widget-stack', 'widget-stdmod']); 9527 Liferay.Menu = Menu; 9528}, '', { 9529 requires: ['array-invoke', 'aui-debounce', 'aui-node', 'portal-available-languages'] 9530}); 9531//# sourceMappingURL=menu.js.map 9532/** 9533 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 9534 * 9535 * This library is free software; you can redistribute it and/or modify it under 9536 * the terms of the GNU Lesser General Public License as published by the Free 9537 * Software Foundation; either version 2.1 of the License, or (at your option) 9538 * any later version. 9539 * 9540 * This library is distributed in the hope that it will be useful, but WITHOUT 9541 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9542 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 9543 * details. 9544 */ 9545 9546/** 9547 * @deprecated As of Athanasius (7.3.x), replaced by `Liferay.Util.openToast`. 9548 */ 9549AUI.add('liferay-notice', function (A) { 9550 var ADOM = A.DOM; 9551 var ANode = A.Node; 9552 var Do = A.Do; 9553 var Lang = A.Lang; 9554 var CSS_ALERTS = 'has-alerts'; 9555 var STR_CLICK = 'click'; 9556 var STR_EMPTY = ''; 9557 var STR_HIDE = 'hide'; 9558 var STR_PX = 'px'; 9559 var STR_SHOW = 'show'; 9560 /** 9561 * @deprecated As of Wilberforce (7.0.x) 9562 * 9563 * OPTIONS 9564 * 9565 * Required 9566 * content {string}: The content of the toolbar. 9567 * 9568 * Optional 9569 * animationConfig {Object}: The Transition config, defaults to {easing: 'ease-out', duration: 2, top: '50px'}. If 'left' property is not specified, it will be automatically calculated. 9570 * closeText {string}: Use for the "close" button. Set to false to not have a close button. If set to false but in the provided markup (via content property) there is an element with class "close", a click listener on this element will be added. As result, the notice will be closed.
9571 * noticeClass {string}: A class to add to the notice toolbar. 9572 * timeout {Number}: The timeout in milliseconds, after it the notice will be automatically closed. Set it to -1, or do not add this property to disable this functionality. 9573 * toggleText {object}: The text to use for the "hide" and "show" button. Set to false to not have a hide button. 9574 * type {String}: One of 'warning' or 'notice'. If not set, default notice type will be 'notice' 9575 * useAnimation {boolean}: To animate show/hide of the notice, defaults to true. If useAnimation is set to true, but there is no timeout, 5000 will be used as timeout. 9576 * 9577 * Callbacks 9578 * onClose {function}: Called when the toolbar is closed. 9579 */ 9580 9581 /** 9582 * @deprecated As of Athanasius (7.3.x), replaced by `Liferay.Util.openToast`. 9583 * @module liferay-notice 9584 */ 9585 9586 var Notice = function Notice(options) { 9587 var instance = this; 9588 options = options || {}; 9589 instance._closeText = options.closeText; 9590 instance._node = options.node; 9591 instance._noticeType = options.type || 'notice'; 9592 instance._noticeClass = 'alert-notice'; 9593 instance._onClose = options.onClose; 9594 instance._useCloseButton = true; 9595 9596 if (options.useAnimation) { 9597 instance._noticeClass += ' popup-alert-notice'; 9598 9599 if (!Lang.isNumber(options.timeout)) { 9600 options.timeout = 5000; 9601 } 9602 } 9603 9604 instance._animationConfig = options.animationConfig || { 9605 duration: 2, 9606 easing: 'ease-out', 9607 top: '50px' 9608 }; 9609 instance._useAnimation = options.useAnimation; 9610 instance._timeout = options.timeout; 9611 instance._body = A.getBody(); 9612 instance._useToggleButton = false; 9613 instance._hideText = STR_EMPTY; 9614 instance._showText = STR_EMPTY; 9615 9616 if (options.toggleText !== false) { 9617 instance.toggleText = A.mix(options.toggleText, { 9618 hide: null, 9619 show: null 9620 }); 9621 instance._useToggleButton = true; 9622 } 9623 9624 if (instance._noticeType == 'warning') { 9625 instance._noticeClass = 'alert-danger popup-alert-warning'; 9626 } 9627 9628 if (options.noticeClass) { 9629 instance._noticeClass += ' ' + options.noticeClass; 9630 } 9631 9632 instance._content = options.content || STR_EMPTY; 9633 9634 instance._createHTML(); 9635 9636 return instance._notice; 9637 }; 9638 9639 Notice.prototype = { 9640 _addCloseButton: function _addCloseButton(notice) { 9641 var instance = this; 9642 var closeButton; 9643 9644 if (instance._closeText !== false) { 9645 instance._closeText = instance._closeText || 'Chiudi'; 9646 } else { 9647 instance._useCloseButton = false; 9648 instance._closeText = STR_EMPTY; 9649 } 9650 9651 if (instance._useCloseButton) { 9652 var html = '<button class="btn btn-secondary submit popup-alert-close">' + instance._closeText + '</button>'; 9653 closeButton = notice.append(html); 9654 } else { 9655 closeButton = notice.one('.close'); 9656 } 9657 9658 if (closeButton) { 9659 closeButton.on(STR_CLICK, instance.close, instance); 9660 } 9661 }, 9662 _addToggleButton: function _addToggleButton(notice) { 9663 var instance = this; 9664 9665 if (instance._useToggleButton) { 9666 instance._hideText = instance._toggleText.hide || 'Nascondi'; 9667 instance._showText = instance._toggleText.show || 'Mostra'; 9668 var toggleButton = ANode.create('<a class="toggle-button" href="javascript:;"><span>' + instance._hideText + '</span></a>'); 9669 var toggleSpan = toggleButton.one('span'); 9670 var visible = 0; 9671 var hideText = instance._hideText; 9672 var showText = instance._showText; 9673 toggleButton.on(STR_CLICK, function () { 9674 var text = showText; 9675 9676 if (visible === 0) { 9677 text = hideText; 9678 visible = 1; 9679 } else { 9680 visible = 0; 9681 } 9682 9683 notice.toggle(); 9684 toggleSpan.text(text); 9685 }); 9686 notice.append(toggleButton); 9687 } 9688 }, 9689 _afterNoticeShow: function _afterNoticeShow() { 9690 var instance = this; 9691 9692 instance._preventHide(); 9693 9694 var notice = instance._notice; 9695 9696 if (instance._useAnimation) { 9697 var animationConfig = instance._animationConfig; 9698 var left = animationConfig.left; 9699 var top = animationConfig.top; 9700 9701 if (!left) {
9702 var noticeRegion = ADOM.region(ANode.getDOMNode(notice)); 9703 left = ADOM.winWidth() / 2 - noticeRegion.width / 2; 9704 top = -noticeRegion.height; 9705 animationConfig.left = left + STR_PX; 9706 } 9707 9708 notice.setXY([left, top]); 9709 notice.transition(instance._animationConfig, function () { 9710 instance._hideHandle = A.later(instance._timeout, notice, STR_HIDE); 9711 }); 9712 } else if (instance._timeout > -1) { 9713 instance._hideHandle = A.later(instance._timeout, notice, STR_HIDE); 9714 } 9715 9716 Liferay.fire('noticeShow', { 9717 notice: instance, 9718 useAnimation: instance._useAnimation 9719 }); 9720 }, 9721 _beforeNoticeHide: function _beforeNoticeHide() { 9722 var instance = this; 9723 var returnVal; 9724 9725 if (instance._useAnimation) { 9726 var animationConfig = A.merge(instance._animationConfig, { 9727 top: -instance._notice.get('offsetHeight') + STR_PX 9728 }); 9729 9730 instance._notice.transition(animationConfig, function () { 9731 instance._notice.toggle(false); 9732 }); 9733 9734 returnVal = new Do.Halt(null); 9735 } 9736 9737 Liferay.fire('noticeHide', { 9738 notice: instance, 9739 useAnimation: instance._useAnimation 9740 }); 9741 return returnVal; 9742 }, 9743 _beforeNoticeShow: function _beforeNoticeShow() { 9744 var instance = this; 9745 9746 instance._notice.toggle(true); 9747 }, 9748 _createHTML: function _createHTML() { 9749 var instance = this; 9750 var content = instance._content; 9751 var node = A.one(instance._node); 9752 var notice = node || ANode.create('<div class="alert alert-warning" dynamic="true"></div>'); 9753 9754 if (content) { 9755 notice.html(content); 9756 } 9757 9758 instance._noticeClass.split(' ').forEach(function (item) { 9759 notice.addClass(item); 9760 }); 9761 9762 instance._addCloseButton(notice); 9763 9764 instance._addToggleButton(notice); 9765 9766 if (!node || node && !node.inDoc()) { 9767 instance._body.prepend(notice); 9768 } 9769 9770 instance._body.addClass(CSS_ALERTS); 9771 9772 Do.before(instance._beforeNoticeHide, notice, STR_HIDE, instance); 9773 Do.before(instance._beforeNoticeShow, notice, STR_SHOW, instance); 9774 Do.after(instance._afterNoticeShow, notice, STR_SHOW, instance); 9775 instance._notice = notice; 9776 }, 9777 _preventHide: function _preventHide() { 9778 var instance = this; 9779 9780 if (instance._hideHandle) { 9781 instance._hideHandle.cancel(); 9782 9783 instance._hideHandle = null; 9784 } 9785 }, 9786 close: function close() { 9787 var instance = this; 9788 var notice = instance._notice; 9789 notice.hide(); 9790 9791 instance._body.removeClass(CSS_ALERTS); 9792 9793 if (instance._onClose) { 9794 instance._onClose(); 9795 } 9796 }, 9797 setClosing: function setClosing() { 9798 var instance = this; 9799 var alerts = A.all('.popup-alert-notice, .popup-alert-warning'); 9800 9801 if (alerts.size()) { 9802 instance._useCloseButton = true; 9803 9804 if (!instance._body) { 9805 instance._body = A.getBody(); 9806 } 9807 9808 instance._body.addClass(CSS_ALERTS); 9809 9810 alerts.each(instance._addCloseButton, instance); 9811 } 9812 } 9813 }; 9814 Liferay.Notice = Notice; 9815}, '', { 9816 requires: ['aui-base'] 9817}); 9818//# sourceMappingURL=notice.js.map 9819/** 9820 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 9821 * 9822 * This library is free software; you can redistribute it and/or modify it under 9823 * the terms of the GNU Lesser General Public License as published by the Free 9824 * Software Foundation; either version 2.1 of the License, or (at your option) 9825 * any later version. 9826 * 9827 * This library is distributed in the hope that it will be useful, but WITHOUT 9828 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9829 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 9830 * details. 9831 */ 9832 9833/** 9834 * @deprecated As of Athanasius (7.3.x), with no direct replacement 9835 */ 9836AUI.add('liferay-poller', function (A) { 9837 var AObject = A.Object; 9838 9839 var _browserKey = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER); 9840 9841 var _enabled = false; 9842 var _encryptedUserId = null; 9843 var _supportsComet = false;
9844 var _delayAccessCount = 0; 9845 var _delayIndex = 0; 9846 var _delays = [1, 2, 3, 4, 5, 7, 10]; 9847 9848 var _getEncryptedUserId = function _getEncryptedUserId() { 9849 return _encryptedUserId; 9850 }; 9851 9852 var _frozen = false; 9853 var _locked = false; 9854 9855 var _maxDelay = _delays.length - 1; 9856 9857 var _portletIdsMap = {}; 9858 var _metaData = { 9859 browserKey: _browserKey, 9860 companyId: themeDisplay.getCompanyId(), 9861 portletIdsMap: _portletIdsMap, 9862 startPolling: true 9863 }; 9864 var _customDelay = null; 9865 var _portlets = {}; 9866 var _requestDelay = _delays[0]; 9867 var _sendQueue = []; 9868 var _suspended = false; 9869 var _timerId = null; 9870 9871 var _url = themeDisplay.getPathContext() + '/poller'; 9872 9873 var _receiveChannel = _url + '/receive'; 9874 9875 var _sendChannel = _url + '/send'; 9876 9877 var _closeCurlyBrace = '}'; 9878 var _openCurlyBrace = '{'; 9879 var _escapedCloseCurlyBrace = '[$CLOSE_CURLY_BRACE$]'; 9880 var _escapedOpenCurlyBrace = '[$OPEN_CURLY_BRACE$]'; 9881 9882 var _cancelRequestTimer = function _cancelRequestTimer() { 9883 clearTimeout(_timerId); 9884 _timerId = null; 9885 }; 9886 9887 var _createRequestTimer = function _createRequestTimer() { 9888 _cancelRequestTimer(); 9889 9890 if (_enabled) { 9891 if (Poller.isSupportsComet()) { 9892 _receive(); 9893 } else { 9894 _timerId = setTimeout(_receive, Poller.getDelay()); 9895 } 9896 } 9897 }; 9898 9899 var _freezeConnection = function _freezeConnection() { 9900 _frozen = true; 9901 9902 _cancelRequestTimer(); 9903 }; 9904 9905 var _getReceiveUrl = function _getReceiveUrl() { 9906 return _receiveChannel; 9907 }; 9908 9909 var _getSendUrl = function _getSendUrl() { 9910 return _sendChannel; 9911 }; 9912 9913 var _processResponse = function _processResponse(id, obj) { 9914 var response = JSON.parse(obj.responseText); 9915 var send = false; 9916 9917 if (Array.isArray(response)) { 9918 var meta = response.shift(); 9919 9920 for (var i = 0; i < response.length; i++) { 9921 var chunk = response[i].payload; 9922 var chunkData = chunk.data; 9923 var portletId = chunk.portletId; 9924 var portlet = _portlets[portletId]; 9925 9926 if (portlet) { 9927 var currentPortletId = _portletIdsMap[portletId]; 9928 9929 if (chunkData && currentPortletId) { 9930 chunkData.initialRequest = portlet.initialRequest; 9931 } 9932 9933 portlet.listener.call(portlet.scope || Poller, chunkData, chunk.chunkId); 9934 9935 if (chunkData && chunkData.pollerHintHighConnectivity) { 9936 _requestDelay = _delays[0]; 9937 _delayIndex = 0; 9938 } 9939 9940 if (portlet.initialRequest && currentPortletId) { 9941 send = true; 9942 portlet.initialRequest = false; 9943 } 9944 } 9945 } 9946 9947 if ('startPolling' in _metaData) { 9948 delete _metaData.startPolling; 9949 } 9950 9951 if (send) { 9952 _send(); 9953 } 9954 9955 if (!meta.suspendPolling) { 9956 _thawConnection(); 9957 } else { 9958 _freezeConnection(); 9959 } 9960 } 9961 }; 9962 9963 var _receive = function _receive() { 9964 if (!_suspended && !_frozen) { 9965 _metaData.userId = _getEncryptedUserId(); 9966 _metaData.timestamp = new Date().getTime(); 9967 AObject.each(_portlets, _updatePortletIdsMap); 9968 var requestStr = JSON.stringify([_metaData]); 9969 var body = new URLSearchParams(); 9970 body.append('pollerRequest', requestStr); 9971 Liferay.Util.fetch(_getReceiveUrl(), { 9972 body: body, 9973 method: 'POST' 9974 }).then(function (response) { 9975 return response.text(); 9976 }).then(function (responseText) { 9977 _processResponse(null, { 9978 responseText: responseText 9979 }); 9980 }); 9981 } 9982 }; 9983 9984 var _releaseLock = function _releaseLock() { 9985 _locked = false; 9986 }; 9987 9988 var _sendComplete = function _sendComplete() { 9989 _releaseLock(); 9990 9991 _send(); 9992 }; 9993 9994 var _send = function _send() { 9995 if (_enabled && !_locked && _sendQueue.length && !_suspended && !_frozen) { 9996 _locked = true; 9997 9998 var data = _sendQueue.shift(); 9999 10000 _metaData.userId = _getEncryptedUserId(); 10001 _metaData.timestamp = new Date().getTime(); 10002 AObject.each(_portlets, _updatePortletIdsMap); 10003 var requestStr = JSON.stringify([_metaData].concat(data)); 10004 var body = new URLSearchParams(); 10005 body.append('pollerRequest', requestStr); 10006 Liferay.Util.fetch(_getSendUrl(), { 10007 body: body, 10008 method: 'POST' 10009 }).then(function (response) { 10010 return response.text(); 10011 }).then(_sendComplete); 10012 } 10013 }; 10014 10015 var _thawConnection = function _thawConnection() { 10016 _frozen = false;
10017 10018 _createRequestTimer(); 10019 }; 10020 10021 var _updatePortletIdsMap = function _updatePortletIdsMap(item, index) { 10022 _portletIdsMap[index] = item.initialRequest; 10023 }; 10024 10025 var Poller = { 10026 addListener: function addListener(key, listener, scope) { 10027 _portlets[key] = { 10028 initialRequest: true, 10029 listener: listener, 10030 scope: scope 10031 }; 10032 10033 if (!_enabled) { 10034 _enabled = true; 10035 10036 _receive(); 10037 } 10038 }, 10039 cancelCustomDelay: function cancelCustomDelay() { 10040 _customDelay = null; 10041 }, 10042 getDelay: function getDelay() { 10043 if (_customDelay !== null) { 10044 _requestDelay = _customDelay; 10045 } else if (_delayIndex <= _maxDelay) { 10046 _requestDelay = _delays[_delayIndex]; 10047 _delayAccessCount++; 10048 10049 if (_delayAccessCount == 3) { 10050 _delayIndex++; 10051 _delayAccessCount = 0; 10052 } 10053 } 10054 10055 return _requestDelay * 1000; 10056 }, 10057 getReceiveUrl: _getReceiveUrl, 10058 getSendUrl: _getSendUrl, 10059 init: function init(options) { 10060 var instance = this; 10061 instance.setEncryptedUserId(options.encryptedUserId); 10062 instance.setSupportsComet(options.supportsComet); 10063 }, 10064 isSupportsComet: function isSupportsComet() { 10065 return _supportsComet; 10066 }, 10067 processResponse: _processResponse, 10068 removeListener: function removeListener(key) { 10069 if (key in _portlets) { 10070 delete _portlets[key]; 10071 } 10072 10073 if (AObject.keys(_portlets).length === 0) { 10074 _enabled = false; 10075 10076 _cancelRequestTimer(); 10077 } 10078 }, 10079 resume: function resume() { 10080 _suspended = false; 10081 10082 _createRequestTimer(); 10083 }, 10084 setCustomDelay: function setCustomDelay(delay) { 10085 if (delay === null) { 10086 _customDelay = delay; 10087 } else { 10088 _customDelay = delay / 1000; 10089 } 10090 }, 10091 setDelay: function setDelay(delay) { 10092 _requestDelay = delay / 1000; 10093 }, 10094 setEncryptedUserId: function setEncryptedUserId(encryptedUserId) { 10095 _encryptedUserId = encryptedUserId; 10096 }, 10097 setSupportsComet: function setSupportsComet(supportsComet) { 10098 _supportsComet = supportsComet; 10099 }, 10100 setUrl: function setUrl(url) { 10101 _url = url; 10102 }, 10103 submitRequest: function submitRequest(key, data, chunkId) { 10104 if (!_frozen && key in _portlets) { 10105 for (var i in data) { 10106 if (Object.prototype.hasOwnProperty.call(data, i)) { 10107 var content = data[i]; 10108 10109 if (content.replace) { 10110 content = content.replace(_openCurlyBrace, _escapedOpenCurlyBrace); 10111 content = content.replace(_closeCurlyBrace, _escapedCloseCurlyBrace); 10112 data[i] = content; 10113 } 10114 } 10115 } 10116 10117 var requestData = { 10118 data: data, 10119 portletId: key 10120 }; 10121 10122 if (chunkId) { 10123 requestData.chunkId = chunkId; 10124 } 10125 10126 _sendQueue.push(requestData); 10127 10128 _send(); 10129 } 10130 }, 10131 suspend: function suspend() { 10132 _cancelRequestTimer(); 10133 10134 _suspended = true; 10135 }, 10136 url: _url 10137 }; 10138 A.getWin().on('focus', function () { 10139 _metaData.startPolling = true; 10140 10141 _thawConnection(); 10142 }); 10143 Liferay.Poller = Poller; 10144}, '', { 10145 requires: ['aui-base', 'json'] 10146}); 10147//# sourceMappingURL=poller.js.map 10148YUI.add('async-queue', function (Y, NAME) { 10149 10150/** 10151 * <p>AsyncQueue allows you create a chain of function callbacks executed 10152 * via setTimeout (or synchronously) that are guaranteed to run in order. 10153 * Items in the queue can be promoted or removed. Start or resume the 10154 * execution chain with run(). pause() to temporarily delay execution, or 10155 * stop() to halt and clear the queue.</p> 10156 * 10157 * @module async-queue 10158 */ 10159 10160/** 10161 * <p>A specialized queue class that supports scheduling callbacks to execute 10162 * sequentially, iteratively, even asynchronously.</p> 10163 * 10164 * <p>Callbacks can be function refs or objects with the following keys. Only 10165 * the <code>fn</code> key is required.</p> 10166 * 10167 * <ul> 10168 * <li><code>fn</code> -- The callback function</li> 10169 * <li><code>context</code> -- The execution context for the callbackFn.</li> 10170 * <li><code>args</code> -- Arguments to pass to callbackFn.</li> 10171 * <li><code>timeout</code> -- Millisecond delay before executing callbackFn. 10172 * (Applies to each iterative execution of callback)</li> 10173 * <li><code>iterations</code> -- Number of times to repeat the callback. 10174 * <li><code>until</code> -- Repeat the callback until this function returns 10175 * true. This setting trumps iterations.</li> 10176 * <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from 10177 * executing the next callback in the Queue after 10178 * the callback completes.</li> 10179 * <li><code>id</code> -- Name that can be used to get, promote, get the 10180 * indexOf, or delete this callback.</li> 10181 * </ul> 10182 * 10183 * @class AsyncQueue
10184 * @extends EventTarget 10185 * @constructor 10186 * @param callback* {Function|Object} 0..n callbacks to seed the queue 10187 */ 10188Y.AsyncQueue = function() { 10189 this._init(); 10190 this.add.apply(this, arguments); 10191}; 10192 10193var Queue = Y.AsyncQueue, 10194 EXECUTE = 'execute', 10195 SHIFT = 'shift', 10196 PROMOTE = 'promote', 10197 REMOVE = 'remove', 10198 10199 isObject = Y.Lang.isObject, 10200 isFunction = Y.Lang.isFunction; 10201 10202/** 10203 * <p>Static default values used to populate callback configuration properties. 10204 * Preconfigured defaults include:</p> 10205 * 10206 * <ul> 10207 * <li><code>autoContinue</code>: <code>true</code></li> 10208 * <li><code>iterations</code>: 1</li> 10209 * <li><code>timeout</code>: 10 (10ms between callbacks)</li> 10210 * <li><code>until</code>: (function to run until iterations <= 0)</li> 10211 * </ul> 10212 * 10213 * @property defaults 10214 * @type {Object} 10215 * @static 10216 */ 10217Queue.defaults = Y.mix({ 10218 autoContinue : true, 10219 iterations : 1, 10220 timeout : 10, 10221 until : function () { 10222 this.iterations |= 0; 10223 return this.iterations <= 0; 10224 } 10225}, Y.config.queueDefaults || {}); 10226 10227Y.extend(Queue, Y.EventTarget, { 10228 /** 10229 * Used to indicate the queue is currently executing a callback. 10230 * 10231 * @property _running 10232 * @type {Boolean|Object} true for synchronous callback execution, the 10233 * return handle from Y.later for async callbacks. 10234 * Otherwise false. 10235 * @protected 10236 */ 10237 _running : false, 10238 10239 /** 10240 * Initializes the AsyncQueue instance properties and events. 10241 * 10242 * @method _init 10243 * @protected 10244 */ 10245 _init : function () { 10246 Y.EventTarget.call(this, { prefix: 'queue', emitFacade: true }); 10247 10248 this._q = []; 10249 10250 /** 10251 * Callback defaults for this instance. Static defaults that are not 10252 * overridden are also included. 10253 * 10254 * @property defaults 10255 * @type {Object} 10256 */ 10257 this.defaults = {}; 10258 10259 this._initEvents(); 10260 }, 10261 10262 /** 10263 * Initializes the instance events. 10264 * 10265 * @method _initEvents 10266 * @protected 10267 */ 10268 _initEvents : function () { 10269 this.publish({ 10270 'execute' : { defaultFn : this._defExecFn, emitFacade: true }, 10271 'shift' : { defaultFn : this._defShiftFn, emitFacade: true }, 10272 'add' : { defaultFn : this._defAddFn, emitFacade: true }, 10273 'promote' : { defaultFn : this._defPromoteFn, emitFacade: true }, 10274 'remove' : { defaultFn : this._defRemoveFn, emitFacade: true } 10275 }); 10276 }, 10277 10278 /** 10279 * Returns the next callback needing execution. If a callback is 10280 * configured to repeat via iterations or until, it will be returned until 10281 * the completion criteria is met. 10282 * 10283 * When the queue is empty, null is returned. 10284 * 10285 * @method next 10286 * @return {Function} the callback to execute 10287 */ 10288 next : function () { 10289 var callback; 10290 10291 while (this._q.length) { 10292 callback = this._q[0] = this._prepare(this._q[0]); 10293 if (callback && callback.until()) { 10294 this.fire(SHIFT, { callback: callback }); 10295 callback = null; 10296 } else { 10297 break; 10298 } 10299 } 10300 10301 return callback || null; 10302 }, 10303 10304 /** 10305 * Default functionality for the "shift" event. Shifts the 10306 * callback stored in the event object's <em>callback</em> property from 10307 * the queue if it is the first item. 10308 * 10309 * @method _defShiftFn 10310 * @param e {Event} The event object 10311 * @protected 10312 */ 10313 _defShiftFn : function (e) { 10314 if (this.indexOf(e.callback) === 0) { 10315 this._q.shift(); 10316 } 10317 }, 10318 10319 /** 10320 * Creates a wrapper function to execute the callback using the aggregated 10321 * configuration generated by combining the static AsyncQueue.defaults, the 10322 * instance defaults, and the specified callback settings. 10323 * 10324 * The wrapper function is decorated with the callback configuration as 10325 * properties for runtime modification. 10326 * 10327 * @method _prepare 10328 * @param callback {Object|Function} the raw callback 10329 * @return {Function} a decorated function wrapper to execute the callback 10330 * @protected 10331 */ 10332 _prepare: function (callback) { 10333 if (isFunction(callback) && callback._prepared) { 10334 return callback; 10335 } 10336 10337 var config = Y.merge( 10338 Queue.defaults, 10339 { context : this, args: [], _prepared: true }, 10340 this.defaults, 10341 (isFunction(callback) ? { fn: callback } : callback)), 10342 10343 wrapper = Y.bind(function () { 10344 if (!wrapper._running) { 10345 wrapper.iterations--; 10346 } 10347 if (isFunction(wrapper.fn)) { 10348 wrapper.fn.apply(wrapper.context || Y, 10349 Y.Array(wrapper.args)); 10350 } 10351 }, this); 10352 10353 return Y.mix(wrapper, config); 10354 }, 10355 10356 /** 10357 * Sets the queue in motion. All queued callbacks will be executed in 10358 * order unless pause() or stop() is called or if one of the callbacks is 10359 * configured with autoContinue: false. 10360 * 10361 * @method run 10362 * @return {AsyncQueue} the AsyncQueue instance 10363 * @chainable 10364 */ 10365 run : function () { 10366 var callback, 10367 cont = true; 10368 10369 if (this._executing) { 10370 this._running = true; 10371 return this; 10372 } 10373 10374 for (callback = this.next(); 10375 callback && !this.isRunning(); 10376 callback = this.next()) 10377 { 10378 cont = (callback.timeout < 0) ? 10379 this._execute(callback) : 10380 this._schedule(callback); 10381 10382 // Break to avoid an extra call to next (final-expression of the 10383 // 'for' loop), because the until function of the next callback 10384 // in the queue may return a wrong result if it depends on the 10385 // not-yet-finished work of the previous callback. 10386 if (!cont) { 10387 break; 10388 } 10389 } 10390 10391 if (!callback) { 10392 /** 10393 * Event fired when there is no remaining callback in the running queue. Also fired after stop(). 10394 * @event complete 10395 */ 10396 this.fire('complete'); 10397 } 10398 10399 return this; 10400 }, 10401 10402 /** 10403 * Handles the execution of callbacks. Returns a boolean indicating 10404 * whether it is appropriate to continue running. 10405 * 10406 * @method _execute 10407 * @param callback {Object} the callback object to execute 10408 * @return {Boolean} whether the run loop should continue 10409 * @protected 10410 */ 10411 _execute : function (callback) { 10412 10413 this._running = callback._running = true; 10414 this._executing = callback; 10415 10416 callback.iterations--; 10417 this.fire(EXECUTE, { callback: callback }); 10418 10419 var cont = this._running && callback.autoContinue; 10420 10421 this._running = callback._running = false;
10422 this._executing = false; 10423 10424 return cont; 10425 }, 10426 10427 /** 10428 * Schedules the execution of asynchronous callbacks. 10429 * 10430 * @method _schedule 10431 * @param callback {Object} the callback object to execute 10432 * @return {Boolean} whether the run loop should continue 10433 * @protected 10434 */ 10435 _schedule : function (callback) { 10436 this._running = Y.later(callback.timeout, this, function () { 10437 if (this._execute(callback)) { 10438 this.run(); 10439 } 10440 }); 10441 10442 return false; 10443 }, 10444 10445 /** 10446 * Determines if the queue is waiting for a callback to complete execution. 10447 * 10448 * @method isRunning 10449 * @return {Boolean} true if queue is waiting for a 10450 * from any initiated transactions 10451 */ 10452 isRunning : function () { 10453 return !!this._running; 10454 }, 10455 10456 /** 10457 * Default functionality for the "execute" event. Executes the 10458 * callback function 10459 * 10460 * @method _defExecFn 10461 * @param e {Event} the event object 10462 * @protected 10463 */ 10464 _defExecFn : function (e) { 10465 e.callback(); 10466 }, 10467 10468 /** 10469 * Add any number of callbacks to the end of the queue. Callbacks may be 10470 * provided as functions or objects. 10471 * 10472 * @method add 10473 * @param callback* {Function|Object} 0..n callbacks 10474 * @return {AsyncQueue} the AsyncQueue instance 10475 * @chainable 10476 */ 10477 add : function () { 10478 this.fire('add', { callbacks: Y.Array(arguments,0,true) }); 10479 10480 return this; 10481 }, 10482 10483 /** 10484 * Default functionality for the "add" event. Adds the callbacks 10485 * in the event facade to the queue. Callbacks successfully added to the 10486 * queue are present in the event's <code>added</code> property in the 10487 * after phase. 10488 * 10489 * @method _defAddFn 10490 * @param e {Event} the event object 10491 * @protected 10492 */ 10493 _defAddFn : function(e) { 10494 var _q = this._q, 10495 added = []; 10496 10497 Y.Array.each(e.callbacks, function (c) { 10498 if (isObject(c)) { 10499 _q.push(c); 10500 added.push(c); 10501 } 10502 }); 10503 10504 e.added = added; 10505 }, 10506 10507 /** 10508 * Pause the execution of the queue after the execution of the current 10509 * callback completes. If called from code outside of a queued callback, 10510 * clears the timeout for the pending callback. Paused queue can be 10511 * restarted with q.run() 10512 * 10513 * @method pause 10514 * @return {AsyncQueue} the AsyncQueue instance 10515 * @chainable 10516 */ 10517 pause: function () { 10518 if (this._running && isObject(this._running)) { 10519 this._running.cancel(); 10520 } 10521 10522 this._running = false; 10523 10524 return this; 10525 }, 10526 10527 /** 10528 * Stop and clear the queue after the current execution of the 10529 * current callback completes. 10530 * 10531 * @method stop 10532 * @return {AsyncQueue} the AsyncQueue instance 10533 * @chainable 10534 */ 10535 stop : function () { 10536 10537 this._q = []; 10538 10539 if (this._running && isObject(this._running)) { 10540 this._running.cancel(); 10541 this._running = false; 10542 } 10543 // otherwise don't systematically set this._running to false, because if 10544 // stop has been called from inside a queued callback, the _execute method 10545 // currenty running needs to call run() one more time for the 'complete' 10546 // event to be fired. 10547 10548 // if stop is called from outside a callback, we need to explicitely call 10549 // run() once again to fire the 'complete' event. 10550 if (!this._executing) { 10551 this.run(); 10552 } 10553 10554 return this; 10555 }, 10556 10557 /** 10558 * Returns the current index of a callback. Pass in either the id or 10559 * callback function from getCallback. 10560 * 10561 * @method indexOf 10562 * @param callback {String|Function} the callback or its specified id 10563 * @return {Number} index of the callback or -1 if not found 10564 */ 10565 indexOf : function (callback) { 10566 var i = 0, len = this._q.length, c; 10567 10568 for (; i < len; ++i) { 10569 c = this._q[i]; 10570 if (c === callback || c.id === callback) { 10571 return i; 10572 } 10573 } 10574 10575 return -1; 10576 }, 10577 10578 /** 10579 * Retrieve a callback by its id. Useful to modify the configuration 10580 * while the queue is running. 10581 * 10582 * @method getCallback 10583 * @param id {String} the id assigned to the callback 10584 * @return {Object} the callback object 10585 */ 10586 getCallback : function (id) { 10587 var i = this.indexOf(id); 10588 10589 return (i > -1) ? this._q[i] : null; 10590 }, 10591 10592 /** 10593 * Promotes the named callback to the top of the queue. If a callback is 10594 * currently executing or looping (via until or iterations), the promotion 10595 * is scheduled to occur after the current callback has completed. 10596 * 10597 * @method promote 10598 * @param callback {String|Object} the callback object or a callback's id 10599 * @return {AsyncQueue} the AsyncQueue instance 10600 * @chainable 10601 */ 10602 promote : function (callback) { 10603 var payload = { callback : callback },e; 10604 10605 if (this.isRunning()) { 10606 e = this.after(SHIFT, function () { 10607 this.fire(PROMOTE, payload); 10608 e.detach(); 10609 }, this); 10610 } else { 10611 this.fire(PROMOTE, payload); 10612 } 10613 10614 return this; 10615 }, 10616 10617 /** 10618 * <p>Default functionality for the "promote" event. Promotes the 10619 * named callback to the head of the queue.</p> 10620 * 10621 * <p>The event object will contain a property "callback", which 10622 * holds the id of a callback or the callback object itself.</p> 10623 * 10624 * @method _defPromoteFn 10625 * @param e {Event} the custom event 10626 * @protected 10627 */ 10628 _defPromoteFn : function (e) { 10629 var i = this.indexOf(e.callback), 10630 promoted = (i > -1) ? this._q.splice(i,1)[0] : null; 10631 10632 e.promoted = promoted; 10633 10634 if (promoted) { 10635 this._q.unshift(promoted); 10636 } 10637 }, 10638 10639 /** 10640 * Removes the callback from the queue. If the queue is active, the 10641 * removal is scheduled to occur after the current callback has completed. 10642 * 10643 * @method remove 10644 * @param callback {String|Object} the callback object or a callback's id 10645 * @return {AsyncQueue} the AsyncQueue instance 10646 * @chainable 10647 */ 10648 remove : function (callback) { 10649 var payload = { callback : callback },e; 10650 10651 // Can't return the removed callback because of the deferral until 10652 // current callback is complete 10653 if (this.isRunning()) { 10654 e = this.after(SHIFT, function () { 10655 this.fire(REMOVE, payload); 10656 e.detach(); 10657 },this); 10658 } else { 10659 this.fire(REMOVE, payload); 10660 } 10661 10662 return this; 10663 }, 10664 10665 /** 10666 * <p>Default functionality for the "remove" event. Removes the 10667 * callback from the queue.</p> 10668 * 10669 * <p>The event object will contain a property "callback", which 10670 * holds the id of a callback or the callback object itself.</p> 10671 * 10672 * @method _defRemoveFn 10673 * @param e {Event} the custom event 10674 * @protected 10675 */ 10676 _defRemoveFn : function (e) { 10677 var i = this.indexOf(e.callback); 10678 10679 e.removed = (i > -1) ? this._q.splice(i,1)[0] : null; 10680 }, 10681 10682 /** 10683 * Returns the number of callbacks in the queue. 10684 * 10685 * @method size 10686 * @return {Number} 10687 */ 10688 size : function () { 10689 // next() flushes callbacks that have met their until() criteria and 10690 // therefore shouldn't count since they wouldn't execute anyway. 10691 if (!this.isRunning()) { 10692 this.next(); 10693 } 10694 10695 return this._q.length; 10696 } 10697}); 10698 10699 10700 10701}, 'patched-v3.18.1', {"requires": ["event-custom"]}); 10702 10703YUI.add('base-build', function (Y, NAME) { 10704 10705 /** 10706 * The base-build submodule provides Base.build functionality, which
10707 * can be used to create custom classes, by aggregating extensions onto 10708 * a main class. 10709 * 10710 * @module base 10711 * @submodule base-build 10712 * @for Base 10713 */ 10714 var BaseCore = Y.BaseCore, 10715 Base = Y.Base, 10716 L = Y.Lang, 10717 10718 INITIALIZER = "initializer", 10719 DESTRUCTOR = "destructor", 10720 AGGREGATES = ["_PLUG", "_UNPLUG"], 10721 10722 build; 10723 10724 // Utility function used in `_buildCfg` to aggregate array values into a new 10725 // array from the sender constructor to the receiver constructor. 10726 function arrayAggregator(prop, r, s) { 10727 if (s[prop]) { 10728 r[prop] = (r[prop] || []).concat(s[prop]); 10729 } 10730 } 10731 10732 // Utility function used in `_buildCfg` to aggregate `_ATTR_CFG` array 10733 // values from the sender constructor into a new array on receiver's 10734 // constructor, and clear the cached hash. 10735 function attrCfgAggregator(prop, r, s) { 10736 if (s._ATTR_CFG) { 10737 // Clear cached hash. 10738 r._ATTR_CFG_HASH = null; 10739 10740 arrayAggregator.apply(null, arguments); 10741 } 10742 } 10743 10744 // Utility function used in `_buildCfg` to aggregate ATTRS configs from one 10745 // the sender constructor to the receiver constructor. 10746 function attrsAggregator(prop, r, s) { 10747 BaseCore.modifyAttrs(r, s.ATTRS); 10748 } 10749 10750 Base._build = function(name, main, extensions, px, sx, cfg) { 10751 10752 var build = Base._build, 10753 10754 builtClass = build._ctor(main, cfg), 10755 buildCfg = build._cfg(main, cfg, extensions), 10756 10757 _mixCust = build._mixCust, 10758 10759 dynamic = builtClass._yuibuild.dynamic, 10760 10761 i, l, extClass, extProto, 10762 initializer, 10763 destructor; 10764 10765 // Augment/Aggregate 10766 for (i = 0, l = extensions.length; i < l; i++) { 10767 extClass = extensions[i]; 10768 10769 extProto = extClass.prototype; 10770 10771 initializer = extProto[INITIALIZER]; 10772 destructor = extProto[DESTRUCTOR]; 10773 delete extProto[INITIALIZER]; 10774 delete extProto[DESTRUCTOR]; 10775 10776 // Prototype, old non-displacing augment 10777 Y.mix(builtClass, extClass, true, null, 1); 10778 10779 // Custom Statics 10780 _mixCust(builtClass, extClass, buildCfg); 10781 10782 if (initializer) { 10783 extProto[INITIALIZER] = initializer; 10784 } 10785 10786 if (destructor) { 10787 extProto[DESTRUCTOR] = destructor; 10788 } 10789 10790 builtClass._yuibuild.exts.push(extClass); 10791 } 10792 10793 if (px) { 10794 Y.mix(builtClass.prototype, px, true); 10795 } 10796 10797 if (sx) { 10798 Y.mix(builtClass, build._clean(sx, buildCfg), true); 10799 _mixCust(builtClass, sx, buildCfg); 10800 } 10801 10802 builtClass.prototype.hasImpl = build._impl; 10803 10804 if (dynamic) { 10805 builtClass.NAME = name; 10806 builtClass.prototype.constructor = builtClass; 10807 10808 // Carry along the reference to `modifyAttrs()` from `main`. 10809 builtClass.modifyAttrs = main.modifyAttrs; 10810 } 10811 10812 return builtClass; 10813 }; 10814 10815 build = Base._build; 10816 10817 Y.mix(build, { 10818 10819 _mixCust: function(r, s, cfg) { 10820 10821 var aggregates, 10822 custom, 10823 statics, 10824 aggr, 10825 l, 10826 i; 10827 10828 if (cfg) { 10829 aggregates = cfg.aggregates; 10830 custom = cfg.custom; 10831 statics = cfg.statics; 10832 } 10833 10834 if (statics) { 10835 Y.mix(r, s, true, statics); 10836 } 10837 10838 if (aggregates) { 10839 for (i = 0, l = aggregates.length; i < l; i++) { 10840 aggr = aggregates[i]; 10841 if (!r.hasOwnProperty(aggr) && s.hasOwnProperty(aggr)) { 10842 r[aggr] = L.isArray(s[aggr]) ? [] : {}; 10843 } 10844 Y.aggregate(r, s, true, [aggr]); 10845 } 10846 } 10847 10848 if (custom) { 10849 for (i in custom) { 10850 if (custom.hasOwnProperty(i)) { 10851 custom[i](i, r, s); 10852 } 10853 } 10854 } 10855 10856 }, 10857 10858 _tmpl: function(main) { 10859 10860 function BuiltClass() { 10861 BuiltClass.superclass.constructor.apply(this, arguments); 10862 } 10863 Y.extend(BuiltClass, main); 10864 10865 return BuiltClass; 10866 }, 10867 10868 _impl : function(extClass) { 10869 var classes = this._getClasses(), i, l, cls, exts, ll, j; 10870 for (i = 0, l = classes.length; i < l; i++) { 10871 cls = classes[i]; 10872 if (cls._yuibuild) { 10873 exts = cls._yuibuild.exts; 10874 ll = exts.length; 10875 10876 for (j = 0; j < ll; j++) { 10877 if (exts[j] === extClass) { 10878 return true; 10879 } 10880 } 10881 } 10882 } 10883 return false;
10884 }, 10885 10886 _ctor : function(main, cfg) { 10887 10888 var dynamic = (cfg && false === cfg.dynamic) ? false : true, 10889 builtClass = (dynamic) ? build._tmpl(main) : main, 10890 buildCfg = builtClass._yuibuild; 10891 10892 if (!buildCfg) { 10893 buildCfg = builtClass._yuibuild = {}; 10894 } 10895 10896 buildCfg.id = buildCfg.id || null; 10897 buildCfg.exts = buildCfg.exts || []; 10898 buildCfg.dynamic = dynamic; 10899 10900 return builtClass; 10901 }, 10902 10903 _cfg : function(main, cfg, exts) { 10904 var aggr = [], 10905 cust = {}, 10906 statics = [], 10907 buildCfg, 10908 cfgAggr = (cfg && cfg.aggregates), 10909 cfgCustBuild = (cfg && cfg.custom), 10910 cfgStatics = (cfg && cfg.statics), 10911 c = main, 10912 i, 10913 l; 10914 10915 // Prototype Chain 10916 while (c && c.prototype) { 10917 buildCfg = c._buildCfg; 10918 if (buildCfg) { 10919 if (buildCfg.aggregates) { 10920 aggr = aggr.concat(buildCfg.aggregates); 10921 } 10922 if (buildCfg.custom) { 10923 Y.mix(cust, buildCfg.custom, true); 10924 } 10925 if (buildCfg.statics) { 10926 statics = statics.concat(buildCfg.statics); 10927 } 10928 } 10929 c = c.superclass ? c.superclass.constructor : null; 10930 } 10931 10932 // Exts 10933 if (exts) { 10934 for (i = 0, l = exts.length; i < l; i++) { 10935 c = exts[i]; 10936 buildCfg = c._buildCfg; 10937 if (buildCfg) { 10938 if (buildCfg.aggregates) { 10939 aggr = aggr.concat(buildCfg.aggregates); 10940 } 10941 if (buildCfg.custom) { 10942 Y.mix(cust, buildCfg.custom, true); 10943 } 10944 if (buildCfg.statics) { 10945 statics = statics.concat(buildCfg.statics); 10946 } 10947 } 10948 } 10949 } 10950 10951 if (cfgAggr) { 10952 aggr = aggr.concat(cfgAggr); 10953 } 10954 10955 if (cfgCustBuild) { 10956 Y.mix(cust, cfg.cfgBuild, true); 10957 } 10958 10959 if (cfgStatics) { 10960 statics = statics.concat(cfgStatics); 10961 } 10962 10963 return { 10964 aggregates: aggr, 10965 custom: cust, 10966 statics: statics 10967 }; 10968 }, 10969 10970 _clean : function(sx, cfg) { 10971 var prop, i, l, sxclone = Y.merge(sx), 10972 aggregates = cfg.aggregates, 10973 custom = cfg.custom; 10974 10975 for (prop in custom) { 10976 if (sxclone.hasOwnProperty(prop)) { 10977 delete sxclone[prop]; 10978 } 10979 } 10980 10981 for (i = 0, l = aggregates.length; i < l; i++) { 10982 prop = aggregates[i]; 10983 if (sxclone.hasOwnProperty(prop)) { 10984 delete sxclone[prop]; 10985 } 10986 } 10987 10988 return sxclone; 10989 } 10990 }); 10991 10992 /** 10993 * <p> 10994 * Builds a custom constructor function (class) from the 10995 * main function, and array of extension functions (classes) 10996 * provided. The NAME field for the constructor function is 10997 * defined by the first argument passed in. 10998 * </p> 10999 * <p> 11000 * The cfg object supports the following properties 11001 * </p> 11002 * <dl> 11003 * <dt>dynamic <boolean></dt> 11004 * <dd> 11005 * <p>If true (default), a completely new class 11006 * is created which extends the main class, and acts as the 11007 * host on which the extension classes are augmented.</p> 11008 * <p>If false, the extensions classes are augmented directly to 11009 * the main class, modifying the main class' prototype.</p> 11010 * </dd> 11011 * <dt>aggregates <String[]></dt> 11012 * <dd>An array of static property names, which will get aggregated 11013 * on to the built class, in addition to the default properties build 11014 * will always aggregate as defined by the main class' static _buildCfg 11015 * property. 11016 * </dd> 11017 * </dl> 11018 * 11019 * @method build 11020 * @deprecated Use the more convenient Base.create and Base.mix methods instead 11021 * @static 11022 * @param {Function} name The name of the new class. Used to define the NAME property for the new class. 11023 * @param {Function} main The main class on which to base the built class 11024 * @param {Function[]} extensions The set of extension classes which will be 11025 * augmented/aggregated to the built class. 11026 * @param {Object} cfg Optional. Build configuration for the class (see description). 11027 * @return {Function} A custom class, created from the provided main and extension classes 11028 */ 11029 Base.build = function(name, main, extensions, cfg) { 11030 return build(name, main, extensions, null, null, cfg); 11031 }; 11032 11033 /** 11034 * Creates a new class (constructor function) which extends the base class passed in as the second argument, 11035 * and mixes in the array of extensions provided. 11036 * 11037 * Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend). 11038 * 11039 * Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend). 11040 * 11041 * **NOTE FOR COMPONENT DEVELOPERS**: Both the `base` class, and `extensions` can define static a `_buildCfg` 11042 * property, which acts as class creation meta-data, and drives how special static properties from the base 11043 * class, or extensions should be copied, aggregated or (custom) mixed into the newly created class. 11044 * 11045 * The `_buildCfg` property is a hash with 3 supported properties: `statics`, `aggregates` and `custom`, e.g: 11046 * 11047 * // If the Base/Main class is the thing introducing the property: 11048 * 11049 * MyBaseClass._buildCfg = { 11050 * 11051 * // Static properties/methods to copy (Alias) to the built class. 11052 * statics: ["CopyThisMethod", "CopyThisProperty"], 11053 * 11054 * // Static props to aggregate onto the built class. 11055 * aggregates: ["AggregateThisProperty"], 11056 * 11057 * // Static properties which need custom handling (e.g. deep merge etc.) 11058 * custom: { 11059 * "CustomProperty" : function(property, Receiver, Supplier) { 11060 * ... 11061 * var triggers = Receiver.CustomProperty.triggers; 11062 * Receiver.CustomProperty.triggers = triggers.concat(Supplier.CustomProperty.triggers); 11063 * ... 11064 * } 11065 * } 11066 * }; 11067 * 11068 * MyBaseClass.CopyThisMethod = function() {...}; 11069 * MyBaseClass.CopyThisProperty = "foo"; 11070 * MyBaseClass.AggregateThisProperty = {...}; 11071 * MyBaseClass.CustomProperty = { 11072 * triggers: [...] 11073 * } 11074 * 11075 * // Or, if the Extension is the thing introducing the property: 11076 * 11077 * MyExtension._buildCfg = { 11078 * statics : ... 11079 * aggregates : ... 11080 * custom : ... 11081 * } 11082 * 11083 * This way, when users pass your base or extension class to `Y.Base.create` or `Y.Base.mix`, they don't need to 11084 * know which properties need special handling. `Y.Base` has a buildCfg which defines `ATTRS` for custom mix handling 11085 * (to protect the static config objects), and `Y.Widget` has a buildCfg which specifies `HTML_PARSER` for 11086 * straight up aggregation. 11087 * 11088 * @method create 11089 * @static 11090 * @param {String} name The name of the newly created class. Used to define the NAME property for the new class. 11091 * @param {Function} main The base class which the new class should extend. 11092 * This class needs to be Base or a class derived from base (e.g. Widget). 11093 * @param {Function[]} extensions The list of extensions which will be mixed into the built class. 11094 * @param {Object} px The set of prototype properties/methods to add to the built class. 11095 * @param {Object} sx The set of static properties/methods to add to the built class. 11096 * @return {Function} The newly created class. 11097 */ 11098 Base.create = function(name, base, extensions, px, sx) { 11099 return build(name, base, extensions, px, sx); 11100 }; 11101 11102 /** 11103 * <p>Mixes in a list of extensions to an existing class.</p> 11104 * @method mix 11105 * @static 11106 * @param {Function} main The existing class into which the extensions should be mixed. 11107 * The class needs to be Base or a class derived from Base (e.g. Widget) 11108 * @param {Function[]} extensions The set of extension classes which will mixed into the existing main class. 11109 * @return {Function} The modified main class, with extensions mixed in. 11110 */ 11111 Base.mix = function(main, extensions) { 11112 11113 if (main._CACHED_CLASS_DATA) { 11114 main._CACHED_CLASS_DATA = null; 11115 } 11116 11117 return build(null, main, extensions, null, null, {dynamic:false}); 11118 }; 11119 11120 /** 11121 * The build configuration for the Base class. 11122 * 11123 * Defines the static fields which need to be aggregated when the Base class 11124 * is used as the main class passed to the 11125 * <a href="#method_Base.build">Base.build</a> method. 11126 * 11127 * @property _buildCfg 11128 * @type Object 11129 * @static 11130 * @final 11131 * @private 11132 */ 11133 BaseCore._buildCfg = { 11134 aggregates: AGGREGATES.concat(), 11135 11136 custom: { 11137 ATTRS : attrsAggregator, 11138 _ATTR_CFG : attrCfgAggregator, 11139 _NON_ATTRS_CFG: arrayAggregator 11140 } 11141 }; 11142 11143 // Makes sure Base and BaseCore use separate `_buildCfg` objects. 11144 Base._buildCfg = { 11145 aggregates: AGGREGATES.concat(), 11146 11147 custom: { 11148 ATTRS : attrsAggregator, 11149 _ATTR_CFG : attrCfgAggregator, 11150 _NON_ATTRS_CFG: arrayAggregator 11151 } 11152 }; 11153 11154 11155}, 'patched-v3.18.1', {"requires": ["base-base"]}); 11156 11157YUI.add('cookie', function (Y, NAME) { 11158 11159/** 11160 * Utilities for cookie management 11161 * @module cookie 11162 */ 11163 11164 //shortcuts 11165 var L = Y.Lang, 11166 O = Y.Object, 11167 NULL = null, 11168 11169 //shortcuts to functions 11170 isString = L.isString, 11171 isObject = L.isObject, 11172 isUndefined = L.isUndefined, 11173 isFunction = L.isFunction, 11174 encode = encodeURIComponent, 11175 decode = decodeURIComponent, 11176 11177 //shortcut to document 11178 doc = Y.config.doc; 11179 11180 /* 11181 * Throws an error message. 11182 */ 11183 function error(message){ 11184 throw new TypeError(message); 11185 } 11186 11187 /* 11188 * Checks the validity of a cookie name. 11189 */ 11190 function validateCookieName(name){ 11191 if (!isString(name) || name === ""){ 11192 error("Cookie name must be a non-empty string."); 11193 } 11194 } 11195 11196 /* 11197 * Checks the validity of a subcookie name. 11198 */ 11199 function validateSubcookieName(subName){ 11200 if (!isString(subName) || subName === ""){ 11201 error("Subcookie name must be a non-empty string."); 11202 } 11203 } 11204 11205 /** 11206 * Cookie utility. 11207 * @class Cookie 11208 * @static 11209 */ 11210 Y.Cookie = { 11211 11212 //------------------------------------------------------------------------- 11213 // Private Methods 11214 //------------------------------------------------------------------------- 11215 11216 /** 11217 * Creates a cookie string that can be assigned into document.cookie. 11218 * @param {String} name The name of the cookie. 11219 * @param {String} value The value of the cookie. 11220 * @param {Boolean} encodeValue True to encode the value, false to leave as-is. 11221 * @param {Object} options (Optional) Options for the cookie. 11222 * @return {String} The formatted cookie string.
11223 * @method _createCookieString 11224 * @private 11225 * @static 11226 */ 11227 _createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ { 11228 11229 options = options || {}; 11230 11231 var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value), 11232 expires = options.expires, 11233 path = options.path, 11234 domain = options.domain; 11235 11236 11237 if (isObject(options)){ 11238 //expiration date 11239 if (expires instanceof Date){ 11240 text += "; expires=" + expires.toUTCString(); 11241 } 11242 11243 //path 11244 if (isString(path) && path !== ""){ 11245 text += "; path=" + path; 11246 } 11247 11248 //domain 11249 if (isString(domain) && domain !== ""){ 11250 text += "; domain=" + domain; 11251 } 11252 11253 //secure 11254 if (options.secure === true){ 11255 text += "; secure"; 11256 } 11257 } 11258 11259 return text; 11260 }, 11261 11262 /** 11263 * Formats a cookie value for an object containing multiple values. 11264 * @param {Object} hash An object of key-value pairs to create a string for. 11265 * @return {String} A string suitable for use as a cookie value. 11266 * @method _createCookieHashString 11267 * @private 11268 * @static 11269 */ 11270 _createCookieHashString : function (hash /*:Object*/) /*:String*/ { 11271 if (!isObject(hash)){ 11272 error("Cookie._createCookieHashString(): Argument must be an object."); 11273 } 11274 11275 var text /*:Array*/ = []; 11276 11277 O.each(hash, function(value, key){ 11278 if (!isFunction(value) && !isUndefined(value)){ 11279 text.push(encode(key) + "=" + encode(String(value))); 11280 } 11281 }); 11282 11283 return text.join("&"); 11284 }, 11285 11286 /** 11287 * Parses a cookie hash string into an object. 11288 * @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2). 11289 * @return {Object} An object containing entries for each cookie value. 11290 * @method _parseCookieHash 11291 * @private 11292 * @static 11293 */ 11294 _parseCookieHash : function (text) { 11295 11296 var hashParts = text.split("&"), 11297 hashPart = NULL, 11298 hash = {}; 11299 11300 if (text.length){ 11301 for (var i=0, len=hashParts.length; i < len; i++){ 11302 hashPart = hashParts[i].split("="); 11303 hash[decode(hashPart[0])] = decode(hashPart[1]); 11304 } 11305 } 11306 11307 return hash; 11308 }, 11309 11310 /** 11311 * Parses a cookie string into an object representing all accessible cookies. 11312 * @param {String} text The cookie string to parse. 11313 * @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true. 11314 * @param {Object} options (Optional) Contains settings for loading the cookie. 11315 * @return {Object} An object containing entries for each accessible cookie. 11316 * @method _parseCookieString 11317 * @private 11318 * @static 11319 */ 11320 _parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/, options /*:Object*/) /*:Object*/ { 11321 11322 var cookies /*:Object*/ = {}; 11323 11324 if (isString(text) && text.length > 0) { 11325 11326 var decodeValue = (shouldDecode === false ? function(s){return s;} : decode), 11327 cookieParts = text.split(/;\s/g), 11328 cookieName = NULL, 11329 cookieValue = NULL, 11330 cookieNameValue = NULL; 11331 11332 for (var i=0, len=cookieParts.length; i < len; i++){ 11333 //check for normally-formatted cookie (name-value) 11334 cookieNameValue = cookieParts[i].match(/([^=]+)=/i); 11335 if (cookieNameValue instanceof Array){ 11336 try { 11337 cookieName = decode(cookieNameValue[1]); 11338 cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1)); 11339 } catch (ex){ 11340 //intentionally ignore the cookie - the encoding is wrong 11341 } 11342 } else { 11343 //means the cookie does not have an "=", so treat it as a boolean flag 11344 cookieName = decode(cookieParts[i]); 11345 cookieValue = ""; 11346 } 11347 // don't overwrite an already loaded cookie if set by option 11348 if (!isUndefined(options) && options.reverseCookieLoa
11348ding) { 11349 if (isUndefined(cookies[cookieName])) { 11350 cookies[cookieName] = cookieValue; 11351 } 11352 } else { 11353 cookies[cookieName] = cookieValue; 11354 } 11355 } 11356 11357 } 11358 11359 return cookies; 11360 }, 11361 11362 /** 11363 * Sets the document object that the cookie utility uses for setting 11364 * cookies. This method is necessary to ensure that the cookie utility 11365 * unit tests can pass even when run on a domain instead of locally. 11366 * This method should not be used otherwise; you should use 11367 * <code>Y.config.doc</code> to change the document that the cookie 11368 * utility uses for everyday purposes. 11369 * @param {Object} newDoc The object to use as the document. 11370 * @method _setDoc 11371 * @private 11372 */ 11373 _setDoc: function(newDoc){ 11374 doc = newDoc; 11375 }, 11376 11377 //------------------------------------------------------------------------- 11378 // Public Methods 11379 //------------------------------------------------------------------------- 11380 11381 /** 11382 * Determines if the cookie with the given name exists. This is useful for 11383 * Boolean cookies (those that do not follow the name=value convention). 11384 * @param {String} name The name of the cookie to check. 11385 * @return {Boolean} True if the cookie exists, false if not. 11386 * @method exists 11387 * @static 11388 */ 11389 exists: function(name) { 11390 11391 validateCookieName(name); //throws error 11392 11393 var cookies = this._parseCookieString(doc.cookie, true); 11394 11395 return cookies.hasOwnProperty(name); 11396 }, 11397 11398 /** 11399 * Returns the cookie value for the given name. 11400 * @param {String} name The name of the cookie to retrieve. 11401 * @param {Function|Object} options (Optional) An object containing one or more 11402 * cookie options: raw (true/false), reverseCookieLoading (true/false) 11403 * and converter (a function). 11404 * The converter function is run on the value before returning it. The 11405 * function is not used if the cookie doesn't exist. The function can be 11406 * passed instead of the options object for backwards compatibility. When 11407 * raw is set to true, the cookie value is not URI decoded. 11408 * @return {Any} If no converter is specified, returns a string or null if 11409 * the cookie doesn't exist. If the converter is specified, returns the value 11410 * returned from the converter or null if the cookie doesn't exist. 11411 * @method get 11412 * @static 11413 */ 11414 get : function (name, options) { 11415 11416 validateCookieName(name); //throws error 11417 11418 var cookies, 11419 cookie, 11420 converter; 11421 11422 //if options is a function, then it's the converter 11423 if (isFunction(options)) { 11424 converter = options; 11425 options = {}; 11426 } else if (isObject(options)) { 11427 converter = options.converter; 11428 } else { 11429 options = {}; 11430 } 11431 11432 cookies = this._parseCookieString(doc.cookie, !options.raw, options); 11433 cookie = cookies[name]; 11434 11435 //should return null, not undefined if the cookie doesn't exist 11436 if (isUndefined(cookie)) { 11437 return NULL; 11438 } 11439 11440 if (!isFunction(converter)){ 11441 return cookie; 11442 } else { 11443 return converter(cookie); 11444 } 11445 }, 11446 11447 /** 11448 * Returns the value of a subcookie. 11449 * @param {String} name The name of the cookie to retrieve. 11450 * @param {String} subName The name of the subcookie to retrieve. 11451 * @param {Function} converter (Optional) A function to run on the value before returning 11452 * it. The function is not used if the cookie doesn't exist. 11453 * @param {Object} options (Optional) Containing one or more settings for cookie parsing. 11454 * @return {Any} If the cookie doesn't exist, null is returned. If the subcookie 11455 * doesn't exist, null if also returned. If no converter is specified and the 11456 * subcookie exists, a string is returned. If a converter is specified and the 11457 * subcookie exists, the value returned from the converter is returned. 11458 * @method getSub 11459 * @static 11460 */ 11461 getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/, options /*:Object*/) /*:Variant*/ { 11462
11463 var hash /*:Variant*/ = this.getSubs(name, options); 11464 11465 if (hash !== NULL) { 11466 11467 validateSubcookieName(subName); //throws error 11468 11469 if (isUndefined(hash[subName])){ 11470 return NULL; 11471 } 11472 11473 if (!isFunction(converter)){ 11474 return hash[subName]; 11475 } else { 11476 return converter(hash[subName]); 11477 } 11478 } else { 11479 return NULL; 11480 } 11481 11482 }, 11483 11484 /** 11485 * Returns an object containing name-value pairs stored in the cookie with the given name. 11486 * @param {String} name The name of the cookie to retrieve. 11487 * @param {Object} options (Optional) Containing one or more settings for cookie parsing. 11488 * @return {Object} An object of name-value pairs if the cookie with the given name 11489 * exists, null if it does not. 11490 * @method getSubs 11491 * @static 11492 */ 11493 getSubs : function (name /*:String*/, options /*:Object*/) { 11494 11495 validateCookieName(name); //throws error 11496 11497 var cookies = this._parseCookieString(doc.cookie, false, options); 11498 if (isString(cookies[name])){ 11499 return this._parseCookieHash(cookies[name]); 11500 } 11501 return NULL; 11502 }, 11503 11504 /** 11505 * Removes a cookie from the machine by setting its expiration date to 11506 * sometime in the past. 11507 * @param {String} name The name of the cookie to remove. 11508 * @param {Object} options (Optional) An object containing one or more 11509 * cookie options: path (a string), domain (a string), 11510 * and secure (true/false). The expires option will be overwritten 11511 * by the method. 11512 * @return {String} The created cookie string. 11513 * @method remove 11514 * @static 11515 */ 11516 remove : function (name, options) { 11517 11518 validateCookieName(name); //throws error 11519 11520 //set options 11521 options = Y.merge(options || {}, { 11522 expires: new Date(0) 11523 }); 11524 11525 //set cookie 11526 return this.set(name, "", options); 11527 }, 11528 11529 /** 11530 * Removes a sub cookie with a given name. 11531 * @param {String} name The name of the cookie in which the subcookie exists. 11532 * @param {String} subName The name of the subcookie to remove. 11533 * @param {Object} options (Optional) An object containing one or more 11534 * cookie options: path (a string), domain (a string), expires (a Date object), 11535 * removeIfEmpty (true/false), and secure (true/false). This must be the same 11536 * settings as the original subcookie. 11537 * @return {String} The created cookie string. 11538 * @method removeSub 11539 * @static 11540 */ 11541 removeSub : function(name, subName, options) { 11542 11543 validateCookieName(name); //throws error 11544 11545 validateSubcookieName(subName); //throws error 11546 11547 options = options || {}; 11548 11549 //get all subcookies for this cookie 11550 var subs = this.getSubs(name); 11551 11552 //delete the indicated subcookie 11553 if (isObject(subs) && subs.hasOwnProperty(subName)){ 11554 delete subs[subName]; 11555 11556 if (!options.removeIfEmpty) { 11557 //reset the cookie 11558 11559 return this.setSubs(name, subs, options); 11560 } else { 11561 //reset the cookie if there are subcookies left, else remove 11562 for (var key in subs){ 11563 if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){ 11564 return this.setSubs(name, subs, options); 11565 } 11566 } 11567 11568 return this.remove(name, options); 11569 } 11570 } else { 11571 return ""; 11572 } 11573 11574 }, 11575 11576 /** 11577 * Sets a cookie with a given name and value. 11578 * @param {String} name The name of the cookie to set. 11579 * @param {Any} value The value to set for the cookie. 11580 * @param {Object}
11580 options (Optional) An object containing one or more 11581 * cookie options: path (a string), domain (a string), expires (a Date object), 11582 * secure (true/false), and raw (true/false). Setting raw to true indicates 11583 * that the cookie should not be URI encoded before being set. 11584 * @return {String} The created cookie string. 11585 * @method set 11586 * @static 11587 */ 11588 set : function (name, value, options) { 11589 11590 validateCookieName(name); //throws error 11591 11592 if (isUndefined(value)){ 11593 error("Cookie.set(): Value cannot be undefined."); 11594 } 11595 11596 options = options || {}; 11597 11598 var text = this._createCookieString(name, value, !options.raw, options); 11599 doc.cookie = text; 11600 return text; 11601 }, 11602 11603 /** 11604 * Sets a sub cookie with a given name to a particular value. 11605 * @param {String} name The name of the cookie to set. 11606 * @param {String} subName The name of the subcookie to set. 11607 * @param {Any} value The value to set. 11608 * @param {Object} options (Optional) An object containing one or more 11609 * cookie options: path (a string), domain (a string), expires (a Date object), 11610 * and secure (true/false). 11611 * @return {String} The created cookie string. 11612 * @method setSub 11613 * @static 11614 */ 11615 setSub : function (name, subName, value, options) { 11616 11617 validateCookieName(name); //throws error 11618 11619 validateSubcookieName(subName); //throws error 11620 11621 if (isUndefined(value)){ 11622 error("Cookie.setSub(): Subcookie value cannot be undefined."); 11623 } 11624 11625 var hash = this.getSubs(name); 11626 11627 if (!isObject(hash)){ 11628 hash = {}; 11629 } 11630 11631 hash[subName] = value; 11632 11633 return this.setSubs(name, hash, options); 11634 11635 }, 11636 11637 /** 11638 * Sets a cookie with a given name to contain a hash of name-value pairs. 11639 * @param {String} name The name of the cookie to set. 11640 * @param {Object} value An object containing name-value pairs. 11641 * @param {Object} options (Optional) An object containing one or more 11642 * cookie options: path (a string), domain (a string), expires (a Date object), 11643 * and secure (true/false). 11644 * @return {String} The created cookie string. 11645 * @method setSubs 11646 * @static 11647 */ 11648 setSubs : function (name, value, options) { 11649 11650 validateCookieName(name); //throws error 11651 11652 if (!isObject(value)){ 11653 error("Cookie.setSubs(): Cookie value must be an object."); 11654 } 11655 11656 var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options); 11657 doc.cookie = text; 11658 return text; 11659 } 11660 11661 }; 11662 11663 11664}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 11665 11666YUI.add('event-touch', function (Y, NAME) { 11667 11668/** 11669Adds touch event facade normalization properties (touches, changedTouches, targetTouches etc.) to the DOM event facade. Adds 11670touch events to the DOM events whitelist. 11671 11672@example 11673 YUI().use('event-touch', function (Y) { 11674 Y.one('#myDiv').on('touchstart', function(e) { 11675 ... 11676 }); 11677 }); 11678@module event 11679@submodule event-touch 11680 */ 11681var SCALE = "scale", 11682 ROTATION = "rotation", 11683 IDENTIFIER = "identifier", 11684 win = Y.config.win, 11685 GESTURE_MAP = {}; 11686 11687/** 11688 * Adds touch event facade normalization properties to the DOM event facade 11689 * 11690 * @method _touch 11691 * @for DOMEventFacade 11692 * @private 11693 * @param ev {Event} the DOM event 11694 * @param currentTarget {HTMLElement} the element the listener was attached to 11695 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event 11696 */ 11697Y.DOMEventFacade.prototype._touch = function(e, currentTarget, wrapper) { 11698 11699 var i,l, etCached, et,touchCache; 11700 11701 11702 if (e.touches) { 11703 11704 /** 11705 * Array of individual touch events for touch points that are still in 11706 * contact with the touch surface. 11707 * 11708 * @property touches 11709 * @type {DOMEventFacade[]} 11710 */ 11711 this.touches = []; 11712 touchCache = {}; 11713 11714 for (i = 0, l = e.touches.length; i < l; ++i) { 11715 et = e.touches[i]; 11716 touchCache[Y.stamp(et)] = this.touches[i] = new Y.DOMEventFacade(et, currentTarget, wrapper); 11717 } 11718 } 11719 11720 if (e.targetTouches) { 11721 11722 /** 11723 * Array of individual touch events still in contact with the touch 11724 * surface and whose `touchstart` event occurred inside the same taregt 11725 * element as the current target element. 11726 * 11727 * @property targetTouches 11728 * @type {DOMEventFacade[]} 11729 */ 11730 this.targetTouches = []; 11731 11732 for (i = 0, l = e.targetTouches.length; i < l; ++i) { 11733 et = e.targetTouches[i]; 11734 etCached = touchCache && touchCache[Y.stamp(et, true)]; 11735 11736 this.targetTouches[i] = etCached || new Y.DOMEventFacade(et, currentTarget, wrapper); 11737 11738 } 11739 } 11740 11741 if (e.changedTouches) { 11742 11743 /** 11744 An array of event-specific touch events. 11745 11746 For `touchstart`, the touch points that became active with the current 11747 event. 11748 11749 For `touchmove`, the touch points that have changed since the last 11750 event. 11751 11752 For `touchend`, the touch points that have been removed from the touch 11753 surface. 11754 11755 @property changedTouches 11756 @type {DOMEventFacade[]} 11757 **/ 11758 this.changedTouches = []; 11759 11760 for (i = 0, l = e.changedTouches.length; i < l; ++i) { 11761 et = e.changedTouches[i]; 11762 etCached = touchCache && touchCache[Y.stamp(et, true)]; 11763 11764 this.changedTouches[i] = etCached || new Y.DOMEventFacade(et, currentTarget, wrapper); 11765 11766 } 11767 } 11768 11769 if (SCALE in e) { 11770 this[SCALE] = e[SCALE]; 11771 } 11772 11773 if (ROTATION in e) { 11774 this[ROTATION] = e[ROTATION]; 11775 } 11776 11777 if (IDENTIFIER in e) { 11778 this[IDENTIFIER] = e[IDENTIFIER]; 11779 } 11780}; 11781 11782//Adding MSPointer events to whitelisted DOM Events. MSPointer event payloads 11783//have the same properties as mouse events. 11784if (Y.Node.DOM_EVENTS) { 11785 Y.mix(Y.Node.DOM_EVENTS, { 11786 touchstart:1, 11787 touchmove:1, 11788 touchend:1, 11789 touchcancel:1, 11790 gesturestart:1, 11791 gesturechange:1, 11792 gestureend:1, 11793 MSPointerDown:1, 11794 MSPointerUp:1, 11795 MSPointerMove:1, 11796 MSPointerCancel:1, 11797 pointerdown:1, 11798 pointerup:1, 11799 pointermove:1, 11800 pointercancel:1 11801 }); 11802} 11803
11804//Add properties to Y.EVENT.GESTURE_MAP based on feature detection. 11805if ((win && ("ontouchstart" in win)) && !(Y.UA.chrome && Y.UA.chrome < 6)) { 11806 GESTURE_MAP.start = ["touchstart", "mousedown"]; 11807 GESTURE_MAP.end = ["touchend", "mouseup"]; 11808 GESTURE_MAP.move = ["touchmove", "mousemove"]; 11809 GESTURE_MAP.cancel = ["touchcancel", "mousecancel"]; 11810} 11811 11812else if (win && win.PointerEvent) { 11813 GESTURE_MAP.start = "pointerdown"; 11814 GESTURE_MAP.end = "pointerup"; 11815 GESTURE_MAP.move = "pointermove"; 11816 GESTURE_MAP.cancel = "pointercancel"; 11817} 11818 11819else if (win && ("msPointerEnabled" in win.navigator)) { 11820 GESTURE_MAP.start = "MSPointerDown"; 11821 GESTURE_MAP.end = "MSPointerUp"; 11822 GESTURE_MAP.move = "MSPointerMove"; 11823 GESTURE_MAP.cancel = "MSPointerCancel"; 11824} 11825 11826else { 11827 GESTURE_MAP.start = "mousedown"; 11828 GESTURE_MAP.end = "mouseup"; 11829 GESTURE_MAP.move = "mousemove"; 11830 GESTURE_MAP.cancel = "mousecancel"; 11831} 11832 11833/** 11834 * A object literal with keys "start", "end", and "move". The value for each key is a 11835 * string representing the event for that environment. For touch environments, the respective 11836 * values are "touchstart", "touchend" and "touchmove". Mouse and MSPointer environments are also 11837 * supported via feature detection. 11838 * 11839 * @property _GESTURE_MAP 11840 * @type Object 11841 * @static 11842 */ 11843Y.Event._GESTURE_MAP = GESTURE_MAP; 11844 11845 11846}, 'patched-v3.18.1', {"requires": ["node-base"]}); 11847 11848YUI.add('overlay', function (Y, NAME) { 11849 11850/** 11851 * Provides a basic Overlay widget, with Standard Module content support. The Overlay widget 11852 * provides Page XY positioning support, alignment and centering support along with basic 11853 * stackable support (z-index and shimming). 11854 * 11855 * @module overlay 11856 */ 11857 11858/** 11859 * A basic Overlay Widget, which can be positioned based on Page XY co-ordinates and is stackable (z-index support). 11860 * It also provides alignment and centering support and uses a standard module format for it's content, with header, 11861 * body and footer section support. 11862 * 11863 * @class Overlay 11864 * @constructor 11865 * @extends Widget 11866 * @uses WidgetStdMod 11867 * @uses WidgetPosition 11868 * @uses WidgetStack 11869 * @uses WidgetPositionAlign 11870 * @uses WidgetPositionConstrain 11871 * @param {Object} object The user configuration for the instance. 11872 */ 11873Y.Overlay = Y.Base.create("overlay", Y.Widget, [Y.WidgetStdMod, Y.WidgetPosition, Y.WidgetStack, Y.WidgetPositionAlign, Y.WidgetPositionConstrain]); 11874 11875 11876}, 'patched-v3.18.1', { 11877 "requires": [ 11878 "widget", 11879 "widget-stdmod", 11880 "widget-position", 11881 "widget-position-align", 11882 "widget-stack", 11883 "widget-position-constrain" 11884 ], 11885 "skinnable": true 11886}); 11887 11888YUI.add('querystring-stringify', function (Y, NAME) { 11889 11890/** 11891 * Provides Y.QueryString.stringify method for converting objects to Query Strings. 11892 * 11893 * @module querystring 11894 * @submodule querystring-stringify 11895 */ 11896 11897var QueryString = Y.namespace("QueryString"), 11898 stack = [], 11899 L = Y.Lang; 11900 11901/** 11902 * Provides Y.QueryString.escape method to be able to override default encoding 11903 * method. This is important in cases where non-standard delimiters are used, if 11904 * the delimiters would not normally be handled properly by the builtin 11905 * (en|de)codeURIComponent functions. 11906 * Default: encodeURIComponent 11907 * 11908 * @method escape 11909 * @for QueryString 11910 * @static 11911 **/ 11912QueryString.escape = encodeURIComponent; 11913 11914/** 11915 * <p>Converts an arbitrary value to a Query String representation.</p> 11916 * 11917 * <p>Objects with cyclical references will trigger an exception.</p> 11918 * 11919 * @method stringify 11920 * @for QueryString 11921 * @public 11922 * @param obj {Any} any arbitrary value to convert to query string 11923 * @param cfg {Object} (optional) Configuration object. The three 11924 * supported configurations are: 11925 * <ul><li>sep: When defined, the value will be used as the key-value 11926 * separator. The default value is "&".</li> 11927 * <li>eq: When defined, the value will be used to join the key to 11928 * the value. The default value is "=".</li> 11929 * <li>arrayKey: When set to true, the key of an array will have the 11930 * '[]' notation appended to the key. The default value is false. 11931 * </li></ul> 11932 * @param name {String} (optional) Name of the current key, for handling children recursively. 11933 * @static 11934 */ 11935QueryString.stringify = function (obj, c, name) { 11936 var begin, end, i, l, n, s, 11937 sep = c && c.sep ? c.sep : "&", 11938 eq = c && c.eq ? c.eq : "=", 11939 aK = c && c.arrayKey ? c.arrayKey : false;
11940 11941 if (L.isNull(obj) || L.isUndefined(obj) || L.isFunction(obj)) { 11942 return name ? QueryString.escape(name) + eq : ''; 11943 } 11944 11945 if (L.isBoolean(obj) || Object.prototype.toString.call(obj) === '[object Boolean]') { 11946 obj =+ obj; 11947 } 11948 11949 if (L.isNumber(obj) || L.isString(obj)) { 11950 return QueryString.escape(name) + eq + QueryString.escape(obj); 11951 } 11952 11953 if (L.isArray(obj)) { 11954 s = []; 11955 name = aK ? name + '[]' : name; 11956 l = obj.length; 11957 for (i = 0; i < l; i++) { 11958 s.push( QueryString.stringify(obj[i], c, name) ); 11959 } 11960 11961 return s.join(sep); 11962 } 11963 // now we know it's an object. 11964 11965 // Check for cyclical references in nested objects 11966 for (i = stack.length - 1; i >= 0; --i) { 11967 if (stack[i] === obj) { 11968 throw new Error("QueryString.stringify. Cyclical reference"); 11969 } 11970 } 11971 11972 stack.push(obj); 11973 s = []; 11974 begin = name ? name + '[' : ''; 11975 end = name ? ']' : ''; 11976 for (i in obj) { 11977 if (obj.hasOwnProperty(i)) { 11978 n = begin + i + end; 11979 s.push(QueryString.stringify(obj[i], c, n)); 11980 } 11981 } 11982 11983 stack.pop(); 11984 s = s.join(sep); 11985 if (!s && name) { 11986 return name + "="; 11987 } 11988 11989 return s; 11990}; 11991 11992 11993}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 11994 11995YUI.add('widget-child', function (Y, NAME) { 11996 11997/** 11998 * Extension enabling a Widget to be a child of another Widget. 11999 * 12000 * @module widget-child 12001 */ 12002 12003var Lang = Y.Lang; 12004 12005/** 12006 * Widget extension providing functionality enabling a Widget to be a 12007 * child of another Widget. 12008 * 12009 * @class WidgetChild 12010 * @param {Object} config User configuration object. 12011*/ 12012function Child() { 12013 12014 // Widget method overlap 12015 Y.after(this._syncUIChild, this, "syncUI"); 12016 Y.after(this._bindUIChild, this, "bindUI"); 12017 12018} 12019 12020Child.ATTRS = { 12021 12022 /** 12023 * @attribute selected 12024 * @type Number 12025 * @default 0 12026 * 12027 * @description Number indicating if the Widget is selected. Possible 12028 * values are: 12029 * <dl> 12030 * <dt>0</dt> <dd>(Default) Not selected</dd> 12031 * <dt>1</dt> <dd>Fully selected</dd> 12032 * <dt>2</dt> <dd>Partially selected</dd> 12033 * </dl> 12034 */ 12035 selected: { 12036 value: 0, 12037 validator: Lang.isNumber 12038 }, 12039 12040 12041 /** 12042 * @attribute index 12043 * @type Number 12044 * @readOnly 12045 * 12046 * @description Number representing the Widget's ordinal position in its 12047 * parent Widget. 12048 */ 12049 index: { 12050 readOnly: true, 12051 getter: function () { 12052 12053 var parent = this.get("parent"), 12054 index = -1; 12055 12056 if (parent) { 12057 index = parent.indexOf(this); 12058 } 12059 12060 return index; 12061 12062 } 12063 }, 12064 12065 12066 /** 12067 * @attribute parent 12068 * @type Widget 12069 * @readOnly 12070 * 12071 * @description Retrieves the parent of the Widget in the object hierarchy. 12072 */ 12073 parent: { 12074 readOnly: true 12075 }, 12076 12077 12078 /** 12079 * @attribute depth 12080 * @type Number 12081 * @default -1 12082 * @readOnly 12083 * 12084 * @description Number representing the depth of this Widget relative to 12085 * the root Widget in the object heirarchy. 12086 */ 12087 depth: { 12088 readOnly: true, 12089 getter: function () { 12090 12091 var parent = this.get("parent"), 12092 root = this.get("root"), 12093 depth = -1; 12094 12095 while (parent) { 12096 12097 depth = (depth + 1); 12098 12099 if (parent == root) { 12100 break; 12101 } 12102 12103 parent = parent.get("parent"); 12104 12105 } 12106 12107 return depth; 12108 12109 } 12110 }, 12111 12112 /** 12113 * @attribute root 12114 * @type Widget 12115 * @readOnly 12116 * 12117 * @description Returns the root Widget in the object hierarchy. If the 12118 * ROOT_TYPE property is set, the search for the root Widget will be 12119 * constrained to parent Widgets of the specified type. 12120 */ 12121 root: { 12122 readOnly: true, 12123 getter: function () { 12124 12125 var getParent = function (child) { 12126 12127 var parent = child.get("parent"), 12128 FnRootType = child.ROOT_TYPE, 12129 criteria = parent; 12130 12131 if (FnRootType) { 12132 criteria = (parent && Y.instanceOf(parent, FnRootType)); 12133 } 12134 12135 return (criteria ? getParent(parent) : child); 12136 12137 }; 12138 12139 return getParent(this); 12140 12141 } 12142 } 12143 12144}; 12145 12146Child.prototype = { 12147 12148 /** 12149 * Constructor reference used to determine the root of a Widget-based 12150 * object tree. 12151 * <p> 12152 * Currently used to control the behavior of the <code>root</code> 12153 * attribute so that recursing up the object heirarchy can be constrained 12154 * to a specific type of Widget. Widget authors should set this property 12155 * to the constructor function for a given Widget implementation. 12156 * </p> 12157 * 12158 * @property ROOT_TYPE 12159 * @type Object 12160 */ 12161 ROOT_TYPE: null, 12162 12163 /** 12164 * Returns the node on which to bind delegate listeners. 12165 * 12166 * Override of Widget's implementation of _getUIEventNode() to ensure that 12167 * all event listeners are bound to the Widget's topmost DOM element. 12168 * This ensures that the firing of each type of Widget UI event (click, 12169 * mousedown, etc.) is facilitated by a single, top-level, delegated DOM 12170 * event listener. 12171 * 12172 * @method _getUIEventNode 12173 * @for Widget 12174 * @protected 12175 */ 12176 _getUIEventNode: function () { 12177 var root = this.get("root"), 12178 returnVal; 12179 12180 if (root) { 12181 returnVal = root.get("boundingBox"); 12182 } 12183 12184 return returnVal; 12185 }, 12186 12187 /** 12188 * @method next
12189 * @description Returns the Widget's next sibling. 12190 * @param {Boolean} circular Boolean indicating if the parent's first child 12191 * should be returned if the child has no next sibling. 12192 * @return {Widget} Widget instance. 12193 */ 12194 next: function (circular) { 12195 12196 var parent = this.get("parent"), 12197 sibling; 12198 12199 if (parent) { 12200 sibling = parent.item((this.get("index")+1)); 12201 } 12202 12203 if (!sibling && circular) { 12204 sibling = parent.item(0); 12205 } 12206 12207 return sibling; 12208 12209 }, 12210 12211 12212 /** 12213 * @method previous 12214 * @description Returns the Widget's previous sibling. 12215 * @param {Boolean} circular Boolean indicating if the parent's last child 12216 * should be returned if the child has no previous sibling. 12217 * @return {Widget} Widget instance. 12218 */ 12219 previous: function (circular) { 12220 12221 var parent = this.get("parent"), 12222 index = this.get("index"), 12223 sibling; 12224 12225 if (parent && index > 0) { 12226 sibling = parent.item([(index-1)]); 12227 } 12228 12229 if (!sibling && circular) { 12230 sibling = parent.item((parent.size() - 1)); 12231 } 12232 12233 return sibling; 12234 12235 }, 12236 12237 12238 // Override of Y.WidgetParent.remove() 12239 // Sugar implementation allowing a child to remove itself from its parent. 12240 remove: function (index) { 12241 12242 var parent, 12243 removed; 12244 12245 if (Lang.isNumber(index)) { 12246 removed = Y.WidgetParent.prototype.remove.apply(this, arguments); 12247 } 12248 else { 12249 12250 parent = this.get("parent"); 12251 12252 if (parent) { 12253 removed = parent.remove(this.get("index")); 12254 } 12255 12256 } 12257 12258 return removed; 12259 12260 }, 12261 12262 12263 /** 12264 * @method isRoot 12265 * @description Determines if the Widget is the root Widget in the 12266 * object hierarchy. 12267 * @return {Boolean} Boolean indicating if Widget is the root Widget in the 12268 * object hierarchy. 12269 */ 12270 isRoot: function () { 12271 return (this == this.get("root")); 12272 }, 12273 12274 12275 /** 12276 * @method ancestor 12277 * @description Returns the Widget instance at the specified depth. 12278 * @param {number} depth Number representing the depth of the ancestor. 12279 * @return {Widget} Widget instance. 12280 */ 12281 ancestor: function (depth) { 12282 12283 var root = this.get("root"), 12284 parent; 12285 12286 if (this.get("depth") > depth) { 12287 12288 parent = this.get("parent"); 12289 12290 while (parent != root && parent.get("depth") > depth) { 12291 parent = parent.get("parent"); 12292 } 12293 12294 } 12295 12296 return parent; 12297 12298 }, 12299 12300 12301 /** 12302 * Updates the UI to reflect the <code>selected</code> attribute value. 12303 * 12304 * @method _uiSetChildSelected 12305 * @protected 12306 * @param {number} selected The selected value to be reflected in the UI. 12307 */ 12308 _uiSetChildSelected: function (selected) { 12309 12310 var box = this.get("boundingBox"), 12311 sClassName = this.getClassName("selected"); 12312 12313 if (selected === 0) { 12314 box.removeClass(sClassName); 12315 } 12316 else { 12317 box.addClass(sClassName); 12318 } 12319 12320 }, 12321 12322 12323 /** 12324 * Default attribute change listener for the <code>selected</code> 12325 * attribute, responsible for updating the UI, in response to 12326 * attribute changes. 12327 * 12328 * @method _afterChildSelectedChange 12329 * @protected 12330 * @param {EventFacade} event The event facade for the attribute change. 12331 */ 12332 _afterChildSelectedChange: function (event) { 12333 this._uiSetChildSelected(event.newVal); 12334 }, 12335 12336 12337 /** 12338 * Synchronizes the UI to match the WidgetChild state. 12339 * <p> 12340 * This method is invoked after bindUI is invoked for the Widget class 12341 * using YUI's aop infrastructure. 12342 * </p> 12343 * 12344 * @method _syncUIChild 12345 * @protected 12346 */ 12347 _syncUIChild: function () { 12348 this._uiSetChildSelected(this.get("selected")); 12349 }, 12350 12351 12352 /** 12353 * Binds event listeners responsible for updating the UI state in response 12354 * to WidgetChild related state changes. 12355 * <p> 12356 * This method is invoked after bindUI is invoked for the Widget class
12357 * using YUI's aop infrastructure. 12358 * </p> 12359 * @method _bindUIChild 12360 * @protected 12361 */ 12362 _bindUIChild: function () { 12363 this.after("selectedChange", this._afterChildSelectedChange); 12364 } 12365 12366}; 12367 12368Y.WidgetChild = Child; 12369 12370 12371}, 'patched-v3.18.1', {"requires": ["base-build", "widget"]}); 12372 12373YUI.add('widget-position-align', function (Y, NAME) { 12374 12375/** 12376Provides extended/advanced XY positioning support for Widgets, through an 12377extension. 12378 12379It builds on top of the `widget-position` module, to provide alignment and 12380centering support. Future releases aim to add constrained and fixed positioning 12381support. 12382 12383@module widget-position-align 12384**/ 12385var Lang = Y.Lang, 12386 12387 ALIGN = 'align', 12388 ALIGN_ON = 'alignOn', 12389 12390 VISIBLE = 'visible', 12391 BOUNDING_BOX = 'boundingBox', 12392 12393 OFFSET_WIDTH = 'offsetWidth', 12394 OFFSET_HEIGHT = 'offsetHeight', 12395 REGION = 'region', 12396 VIEWPORT_REGION = 'viewportRegion'; 12397 12398/** 12399Widget extension, which can be used to add extended XY positioning support to 12400the base Widget class, through the `Base.create` method. 12401 12402**Note:** This extension requires that the `WidgetPosition` extension be added 12403to the Widget (before `WidgetPositionAlign`, if part of the same extension list 12404passed to `Base.build`). 12405 12406@class WidgetPositionAlign 12407@param {Object} config User configuration object. 12408@constructor 12409**/ 12410function PositionAlign (config) {} 12411 12412PositionAlign.ATTRS = { 12413 12414 /** 12415 The alignment configuration for this widget. 12416 12417 The `align` attribute is used to align a reference point on the widget, with 12418 the reference point on another `Node`, or the viewport. The object which 12419 `align` expects has the following properties: 12420 12421 * __`node`__: The `Node` to which the widget is to be aligned. If set to 12422 `null`, or not provided, the widget is aligned to the viewport. 12423 12424 * __`points`__: A two element Array, defining the two points on the widget 12425 and `Node`/viewport which are to be aligned. The first element is the 12426 point on the widget, and the second element is the point on the 12427 `Node`/viewport. Supported alignment points are defined as static 12428 properties on `WidgetPositionAlign`. 12429 12430 @example Aligns the top-right corner of the widget with the top-left corner 12431 of the viewport: 12432 12433 myWidget.set('align', { 12434 points: [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.TL] 12435 }); 12436 12437 @attribute align 12438 @type Object 12439 @default null 12440 **/ 12441 align: { 12442 value: null 12443 }, 12444 12445 /** 12446 A convenience Attribute, which can be used as a shortcut for the `align` 12447 Attribute. 12448 12449 If set to `true`, the widget is centered in the viewport. If set to a `Node` 12450 reference or valid selector String, the widget will be centered within the 12451 `Node`. If set to `false`, no center positioning is applied. 12452 12453 @attribute centered 12454 @type Boolean|Node 12455 @default false 12456 **/ 12457 centered: { 12458 setter : '_setAlignCenter', 12459 lazyAdd:false, 12460 value :false 12461 }, 12462 12463 /** 12464 An Array of Objects corresponding to the `Node`s and events that will cause 12465 the alignment of this widget to be synced to the DOM. 12466 12467 The `alignOn` Attribute is expected to be an Array of Objects with the 12468 following properties: 12469 12470 * __`eventName`__: The String event name to listen for. 12471 12472 * __`node`__: The optional `Node` that will fire the event, it can be a 12473 `Node` reference or a selector String. This will default to the widget's 12474 `boundingBox`. 12475 12476 @example Sync this widget's alignment on window resize: 12477 12478 myWidget.set('alignOn', [ 12479 { 12480 node : Y.one('win'), 12481 eventName: 'resize' 12482 } 12483 ]); 12484 12485 @attribute alignOn 12486 @type Array 12487 @default [] 12488 **/ 12489 alignOn: { 12490 value : [], 12491 validator: Y.Lang.isArray 12492 } 12493}; 12494 12495/** 12496Constant used to specify the top-left corner for alignment 12497 12498@property TL 12499@type String 12500@value 'tl' 12501@static 12502**/ 12503PositionAlign.TL = 'tl'; 12504 12505/** 12506Constant used to specify the top-right corner for alignment 12507 12508@property TR
12509@type String 12510@value 'tr' 12511@static 12512**/ 12513PositionAlign.TR = 'tr'; 12514 12515/** 12516Constant used to specify the bottom-left corner for alignment 12517 12518@property BL 12519@type String 12520@value 'bl' 12521@static 12522**/ 12523PositionAlign.BL = 'bl'; 12524 12525/** 12526Constant used to specify the bottom-right corner for alignment 12527 12528@property BR 12529@type String 12530@value 'br' 12531@static 12532**/ 12533PositionAlign.BR = 'br'; 12534 12535/** 12536Constant used to specify the top edge-center point for alignment 12537 12538@property TC 12539@type String 12540@value 'tc' 12541@static 12542**/ 12543PositionAlign.TC = 'tc'; 12544 12545/** 12546Constant used to specify the right edge, center point for alignment 12547 12548@property RC 12549@type String 12550@value 'rc' 12551@static 12552**/ 12553PositionAlign.RC = 'rc'; 12554 12555/** 12556Constant used to specify the bottom edge, center point for alignment 12557 12558@property BC 12559@type String 12560@value 'bc' 12561@static 12562**/ 12563PositionAlign.BC = 'bc'; 12564 12565/** 12566Constant used to specify the left edge, center point for alignment 12567 12568@property LC 12569@type String 12570@value 'lc' 12571@static 12572**/ 12573PositionAlign.LC = 'lc'; 12574 12575/** 12576Constant used to specify the center of widget/node/viewport for alignment 12577 12578@property CC 12579@type String 12580@value 'cc' 12581@static 12582*/ 12583PositionAlign.CC = 'cc'; 12584 12585PositionAlign.prototype = { 12586 // -- Protected Properties ------------------------------------------------- 12587 12588 12589 initializer : function() { 12590 if (!this._posNode) { 12591 Y.error('WidgetPosition needs to be added to the Widget, ' + 12592 'before WidgetPositionAlign is added'); 12593 } 12594 12595 Y.after(this._bindUIPosAlign, this, 'bindUI'); 12596 Y.after(this._syncUIPosAlign, this, 'syncUI'); 12597 }, 12598 12599 /** 12600 Holds the alignment-syncing event handles. 12601 12602 @property _posAlignUIHandles 12603 @type Array 12604 @default null 12605 @protected 12606 **/ 12607 _posAlignUIHandles: null, 12608 12609 // -- Lifecycle Methods ---------------------------------------------------- 12610 12611 destructor: function () { 12612 this._detachPosAlignUIHandles(); 12613 }, 12614 12615 /** 12616 Bind event listeners responsible for updating the UI state in response to 12617 the widget's position-align related state changes. 12618 12619 This method is invoked after `bindUI` has been invoked for the `Widget` 12620 class using the AOP infrastructure. 12621 12622 @method _bindUIPosAlign 12623 @protected 12624 **/ 12625 _bindUIPosAlign: function () { 12626 this.after('alignChange', this._afterAlignChange); 12627 this.after('alignOnChange', this._afterAlignOnChange); 12628 this.after('visibleChange', this._syncUIPosAlign); 12629 }, 12630 12631 /** 12632 Synchronizes the current `align` Attribute value to the DOM. 12633 12634 This method is invoked after `syncUI` has been invoked for the `Widget` 12635 class using the AOP infrastructure. 12636 12637 @method _syncUIPosAlign 12638 @protected 12639 **/ 12640 _syncUIPosAlign: function () { 12641 var align = this.get(ALIGN); 12642 12643 this._uiSetVisiblePosAlign(this.get(VISIBLE)); 12644 12645 if (align) { 12646 this._uiSetAlign(align.node, align.points); 12647 } 12648 }, 12649 12650 // -- Public Methods ------------------------------------------------------- 12651 12652 /** 12653 Aligns this widget to the provided `Node` (or viewport) using the provided 12654 points. This method can be invoked with no arguments which will cause the 12655 widget's current `align` Attribute value to be synced to the DOM. 12656 12657 @example Aligning to the top-left corner of the `<body>`: 12658 12659 myWidget.align('body', 12660 [Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.TR]); 12661 12662 @method align 12663 @param {Node|String|null} [node] A reference (or selector String) for the 12664 `Node` which with the widget is to be aligned. If null is passed in, the 12665 widget will be aligned with the viewport. 12666 @param {Array[2]} [points] A two item array specifying the points on the 12667 widget and `Node`/viewport which will to be aligned. The first entry is 12668 the point on the widget, and the second entry is the point on the 12669 `Node`/viewport. Valid point references are defined as static constants on 12670 the `WidgetPositionAlign` extension. 12671 @chainable 12672 **/ 12673 align: function (node, points) { 12674 if (arguments.length) { 12675 // Set the `align` Attribute. 12676 this.set(ALIGN, {
12677 node : node, 12678 points: points 12679 }); 12680 } else { 12681 // Sync the current `align` Attribute value to the DOM. 12682 this._syncUIPosAlign(); 12683 } 12684 12685 return this; 12686 }, 12687 12688 /** 12689 Centers the widget in the viewport, or if a `Node` is passed in, it will 12690 be centered to that `Node`. 12691 12692 @method centered 12693 @param {Node|String} [node] A `Node` reference or selector String defining 12694 the `Node` which the widget should be centered. If a `Node` is not passed 12695 in, then the widget will be centered to the viewport. 12696 @chainable 12697 **/ 12698 centered: function (node) { 12699 return this.align(node, [PositionAlign.CC, PositionAlign.CC]); 12700 }, 12701 12702 // -- Protected Methods ---------------------------------------------------- 12703 12704 /** 12705 Returns coordinates realative to the passed `Node` alignment. 12706 12707 @method _getAlignToXY 12708 @param {Node} 'Node' The node to align to. 12709 @param {Array} [point] The node alignment points. 12710 @param {Number} 'Node' x coordinate. 12711 @param {Number} 'Node' y coordinate. 12712 @return {Array} the coordinates. 12713 @private 12714 **/ 12715 _getAlignToXY: function (node, point, x, y) { 12716 var xy; 12717 12718 switch (point) { 12719 case PositionAlign.TL: 12720 xy = [x, y]; 12721 break; 12722 12723 case PositionAlign.TR: 12724 xy = [ 12725 x - node.get(OFFSET_WIDTH), 12726 y 12727 ]; 12728 break; 12729 12730 case PositionAlign.BL: 12731 xy = [ 12732 x, 12733 y - node.get(OFFSET_HEIGHT) 12734 ]; 12735 break; 12736 12737 case PositionAlign.BR: 12738 xy = [ 12739 x - node.get(OFFSET_WIDTH), 12740 y - node.get(OFFSET_HEIGHT) 12741 ]; 12742 break; 12743 12744 case PositionAlign.TC: 12745 xy = [ 12746 x - (node.get(OFFSET_WIDTH) / 2), 12747 y 12748 ]; 12749 break; 12750 12751 case PositionAlign.BC: 12752 xy = [ 12753 x - (node.get(OFFSET_WIDTH) / 2), 12754 y - node.get(OFFSET_HEIGHT) 12755 ]; 12756 break; 12757 12758 case PositionAlign.LC: 12759 xy = [ 12760 x, 12761 y - (node.get(OFFSET_HEIGHT) / 2) 12762 ]; 12763 break; 12764 12765 case PositionAlign.RC: 12766 xy = [ 12767 x - node.get(OFFSET_WIDTH), 12768 y - (node.get(OFFSET_HEIGHT) / 2) 12769 ]; 12770 break; 12771 12772 case PositionAlign.CC: 12773 xy = [ 12774 x - (node.get(OFFSET_WIDTH) / 2), 12775 y - (node.get(OFFSET_HEIGHT) / 2) 12776 ]; 12777 break; 12778 12779 default: 12780 break; 12781 12782 } 12783 12784 return xy; 12785 }, 12786 12787 /** 12788 Returns `Widget` alignment coordinates realative to the given `Node`. 12789 12790 @method _getAlignedXY 12791 @param {Node|String|null} [node] The node to align to, or null to indicate 12792 the viewport. 12793 @param {Array} points The alignment points. 12794 @return {Array} the coordinates. 12795 @protected 12796 **/ 12797 _getAlignedXY: function (node, points) { 12798 if ( ! Lang.isArray(points) || points.length !== 2) { 12799 Y.error('align: Invalid Points Arguments'); 12800 return; 12801 } 12802 12803 var nodeRegion = this._getRegion(node), nodePoint, xy; 12804 12805 if ( ! nodeRegion) { 12806 // No-op, nothing to align to. 12807 return; 12808 } 12809 12810 nodePoint = points[1]; 12811 12812 // TODO: Optimize KWeight - Would lookup table help? 12813 switch (nodePoint) { 12814 case PositionAlign.TL: 12815 xy = [nodeRegion.left, nodeRegion.top]; 12816 break; 12817 12818 case PositionAlign.TR: 12819 xy = [nodeRegion.right, nodeRegion.top]; 12820 break; 12821 12822 case PositionAlign.BL: 12823 xy = [nodeRegion.left, nodeRegion.bottom]; 12824 break; 12825 12826 case PositionAlign.BR: 12827 xy = [nodeRegion.right, nodeRegion.bottom]; 12828 break; 12829 12830 case PositionAlign.TC: 12831 xy = [ 12832 nodeRegion.left + Math.floor(nodeRegion.width / 2), 12833 nodeRegion.top 12834 ]; 12835 break; 12836 12837 case PositionAlign.BC: 12838 xy = [ 12839 nodeRegion.left + Math.floor(nodeRegion.width / 2), 12840 nodeRegion.bottom 12841 ]; 12842 break; 12843 12844 case PositionAlign.LC: 12845 xy = [ 12846 nodeRegion.left, 12847 nodeRegion.top + Math.floor(nodeRegion.height / 2) 12848 ]; 12849 break; 12850 12851 case PositionAlign.RC: 12852 xy = [ 12853 nodeRegion.right, 12854 nodeRegion.top + Math.floor(nodeRegion.height / 2) 12855 ]; 12856 break; 12857 12858 case PositionAlign.CC: 12859 xy = [ 12860 nodeRegion.left + Math.floor(nodeRegion.width / 2), 12861 nodeRegion.top + Math.floor(nodeRegion.height / 2) 12862 ]; 12863 break; 12864 12865 default: 12866 break; 12867 12868 } 12869 12870 return this._getAlignToXY(this._posNode, points[0], xy[0], xy[1]); 12871 }, 12872 12873 /** 12874 Default setter for `center` Attribute changes. Sets up the appropriate 12875 value, and passes it through the to the align attribute. 12876 12877 @method _setAlignCenter 12878 @param {Boolean|Node} val The Attribute value being set. 12879 @return {Boolean|Node} the value passed in. 12880 @protected 12881 **/ 12882 _setAlignCenter: function (val) { 12883 if (val) { 12884 this.set(ALIGN, { 12885 node : val === true ? null : val, 12886 points: [PositionAlign.CC, PositionAlign.CC] 12887 }); 12888 } 12889 12890 return val; 12891 }, 12892 12893 /** 12894 Updates the UI to reflect the `align` value passed in. 12895 12896 **Note:** See the `align` Attribute documentation, for the Object structure 12897 expected. 12898 12899 @method _uiSetAlign 12900 @param {Node|String|null} [node] The node to align to, or null to indicate 12901 the viewport. 12902 @param {Array} points The alignment points. 12903 @protected 12904 **/ 12905 _uiSetAlign: function (node, points) { 12906 var xy = this._getAlignedXY(node, points); 12907 12908 if (xy) { 12909 this._doAlign(xy); 12910 } 12911 }, 12912 12913 /** 12914 Attaches or detaches alignment-syncing event handlers based on the widget's 12915 `visible` Attribute state. 12916 12917 @method _uiSetVisiblePosAlign 12918 @param {Boolean} visible The current value of the widget's `visible` 12919 Attribute. 12920 @protected 12921 **/ 12922 _uiSetVisiblePosAlign: function (visible) { 12923 if (visible) { 12924 this._attachPosAlignUIHandles(); 12925 } else { 12926 this._detachPosAlignUIHandles(); 12927 } 12928 }, 12929 12930 /** 12931 Attaches the alignment-syncing event handlers. 12932 12933 @method _attachPosAlignUIHandles 12934 @protected 12935 **/ 12936 _attachPosAlignUIHandles: function () { 12937 if (this._posAlignUIHandles) { 12938 // No-op if we have already setup the event handlers. 12939 return; 12940 } 12941 12942 var bb = this.get(BOUNDING_BOX), 12943 syncAlign = Y.bind(this._syncUIPosAlign, this), 12944 handles = []; 12945 12946 Y.Array.each(this.get(ALIGN_ON), function (o) { 12947 var event = o.eventName, 12948 node = Y.one(o.node) || bb; 12949 12950 if (event) { 12951 handles.push(node.on(event, syncAlign)); 12952 } 12953 }); 12954 12955 this._posAlignUIHandles = handles; 12956 }, 12957 12958 /** 12959 Detaches the alignment-syncing event handlers. 12960 12961 @method _detachPosAlignUIHandles 12962 @protected 12963 **/ 12964 _detachPosAlignUIHandles: function () { 12965 var handles = this._posAlignUIHandles; 12966 if (handles) { 12967 new Y.EventHandle(handles).detach(); 12968 this._posAlignUIHandles = null; 12969 } 12970 }, 12971 12972 // -- Private Methods ------------------------------------------------------ 12973 12974 /** 12975 Helper method, used to align the given point on the widget, with the XY page 12976 coordinates provided. 12977 12978 @method _doAlign 12979 @param {Array} xy XY page coordinates to align to. 12980 @private 12981 **/ 12982 _doAlign: function(xy) { 12983 if (xy) { 12984 this.move(xy); 12985 } 12986 }, 12987 12988 /** 12989 Returns the region of the passed-in `Node`, or the viewport region if 12990 calling with passing in a `Node`. 12991 12992 @method _getRegion 12993 @param {Node} [node] The node to get the region of. 12994 @return {Object} The node's region. 12995 @private 12996 **/ 12997 _getRegion: function (node) { 12998 var nodeRegion; 12999 13000 if ( ! node) { 13001 nodeRegion = this._posNode.get(VIEWPORT_REGION); 13002 } else { 13003 node = Y.Node.one(node); 13004 if (node) { 13005 nodeRegion = node.get(REGION); 13006 } 13007 } 13008 13009 return nodeRegion; 13010 }, 13011 13012 // -- Protected Event Handlers --------------------------------------------- 13013 13014 /** 13015 Handles `alignChange` events by updating the UI in response to `align` 13016 Attribute changes. 13017 13018 @method _afterAlignChange 13019 @param {EventFacade} e 13020 @protected 13021 **/ 13022 _afterAlignChange: function (e) { 13023 var align = e.newVal; 13024 if (align) { 13025 this._uiSetAlign(align.node, align.points); 13026 } 13027 }, 13028 13029 /** 13030 Handles `alignOnChange` events by updating the alignment-syncing event 13031 handlers. 13032 13033 @method _afterAlignOnChange 13034 @param {EventFacade} e 13035 @protected 13036 **/ 13037 _afterAlignOnChange: function(e) { 13038 this._detachPosAlignUIHandles(); 13039 13040 if (this.get(VISIBLE)) { 13041 this._attachPosAlignUIHandles(); 13042 } 13043 } 13044}; 13045 13046Y.WidgetPositionAlign = PositionAlign; 13047 13048 13049}, 'patched-v3.18.1', {"requires": ["widget-position"]}); 13050 13051YUI.add('widget-position-constrain', function (Y, NAME) { 13052 13053/** 13054 * Provides constrained xy positioning support for Widgets, through an extension. 13055 * 13056 * It builds on top of the widget-position module, to provide constrained positioning support. 13057 * 13058 * @module widget-position-constrain 13059 */ 13060var CONSTRAIN = "constrain", 13061 CONSTRAIN_XYCHANGE = "constrain|xyChange", 13062 CONSTRAIN_CHANGE = "constrainChange", 13063 13064 PREVENT_OVERLAP = "preventOverlap", 13065 ALIGN = "align", 13066 13067 EMPTY_STR = "", 13068 13069 BINDUI = "bindUI", 13070 13071 XY = "xy", 13072 X_COORD = "x", 13073 Y_COORD = "y", 13074 13075 Node = Y.Node, 13076 13077 VIEWPORT_REGION = "viewportRegion", 13078 REGION = "region", 13079 13080 PREVENT_OVERLAP_MAP; 13081 13082/** 13083 * A widget extension, which can be used to add constrained xy positioning support to the base Widget class, 13084 * through the <a href="Base.html#method_build">Base.build</a> method. This extension requires that 13085 * the WidgetPosition extension be added to the Widget (before WidgetPositionConstrain, if part of the same 13086 * extension list passed to Base.build). 13087 * 13088 * @class WidgetPositionConstrain 13089 * @param {Object} User configuration object 13090 */ 13091function PositionConstrain(config) {} 13092 13093/** 13094 * Static property used to define the default attribute 13095 * configuration introduced by WidgetPositionConstrain. 13096 * 13097 * @property ATTRS 13098 * @type Object 13099 * @static 13100 */ 13101PositionConstrain.ATTRS = { 13102 13103 /** 13104 * @attribute constrain 13105 * @type boolean | Node 13106 * @default null
13107 * @description The node to constrain the widget's bounding box to, when setting xy. Can also be 13108 * set to true, to constrain to the viewport. 13109 */ 13110 constrain : { 13111 value: null, 13112 setter: "_setConstrain" 13113 }, 13114 13115 /** 13116 * @attribute preventOverlap 13117 * @type boolean 13118 * @description If set to true, and WidgetPositionAlign is also added to the Widget, 13119 * constrained positioning will attempt to prevent the widget's bounding box from overlapping 13120 * the element to which it has been aligned, by flipping the orientation of the alignment 13121 * for corner based alignments 13122 */ 13123 preventOverlap : { 13124 value:false 13125 } 13126}; 13127 13128/** 13129 * @property _PREVENT_OVERLAP 13130 * @static 13131 * @protected 13132 * @type Object 13133 * @description The set of positions for which to prevent 13134 * overlap. 13135 */ 13136PREVENT_OVERLAP_MAP = PositionConstrain._PREVENT_OVERLAP = { 13137 x: { 13138 "tltr": 1, 13139 "blbr": 1, 13140 "brbl": 1, 13141 "trtl": 1 13142 }, 13143 y : { 13144 "trbr": 1, 13145 "tlbl": 1, 13146 "bltl": 1, 13147 "brtr": 1 13148 } 13149}; 13150 13151PositionConstrain.prototype = { 13152 13153 initializer : function() { 13154 if (!this._posNode) { 13155 Y.error("WidgetPosition needs to be added to the Widget, before WidgetPositionConstrain is added"); 13156 } 13157 Y.after(this._bindUIPosConstrained, this, BINDUI); 13158 }, 13159 13160 /** 13161 * Calculates the constrained positions for the XY positions provided, using 13162 * the provided node argument is passed in. If no node value is passed in, the value of 13163 * the "constrain" attribute is used. 13164 * 13165 * @method getConstrainedXY 13166 * @param {Array} xy The xy values to constrain 13167 * @param {Node | boolean} node Optional. The node to constrain to, or true for the viewport 13168 * @return {Array} The constrained xy values 13169 */ 13170 getConstrainedXY : function(xy, node) { 13171 node = node || this.get(CONSTRAIN); 13172 13173 var constrainingRegion = this._getRegion((node === true) ? null : node), 13174 nodeRegion = this._posNode.get(REGION); 13175 13176 return [ 13177 this._constrain(xy[0], X_COORD, nodeRegion, constrainingRegion), 13178 this._constrain(xy[1], Y_COORD, nodeRegion, constrainingRegion) 13179 ]; 13180 }, 13181 13182 /** 13183 * Constrains the widget's bounding box to a node (or the viewport). If xy or node are not 13184 * passed in, the current position and the value of "constrain" will be used respectively. 13185 * 13186 * The widget's position will be changed to the constrained position. 13187 * 13188 * @method constrain 13189 * @param {Array} xy Optional. The xy values to constrain 13190 * @param {Node | boolean} node Optional. The node to constrain to, or true for the viewport 13191 */ 13192 constrain : function(xy, node) { 13193 var currentXY, 13194 constrainedXY, 13195 constraint = node || this.get(CONSTRAIN); 13196 13197 if (constraint) { 13198 currentXY = xy || this.get(XY); 13199 constrainedXY = this.getConstrainedXY(currentXY, constraint); 13200 13201 if (constrainedXY[0] !== currentXY[0] || constrainedXY[1] !== currentXY[1]) { 13202 this.set(XY, constrainedXY, { constrained:true }); 13203 } 13204 } 13205 }, 13206 13207 /** 13208 * The setter implementation for the "constrain" attribute. 13209 * 13210 * @method _setConstrain 13211 * @protected 13212 * @param {Node | boolean} val The attribute value 13213 */ 13214 _setConstrain : function(val) { 13215 return (val === true) ? val : Node.one(val); 13216 }, 13217 13218 /** 13219 * The method which performs the actual constrain calculations for a given axis ("x" or "y") based 13220 * on the regions provided. 13221 * 13222 * @method _constrain 13223 * @protected 13224 * 13225 * @param {Number} val The value to constrain 13226 * @param {String} axis The axis to use for constrainment 13227 * @param {Region} nodeRegion The region of the node to constrain 13228 * @param {Region} constrainingRegion The region of the node (or viewport) to constrain to 13229 * 13230 * @return {Number} The constrained value 13231 */ 13232 _constrain: function(val, axis, nodeRegion, constrainingRegion) { 13233 if (constrainingRegion) { 13234 13235 if (this.get(PREVENT_OVERLAP)) { 13236 val = this._preventOverlap(val, axis, nodeRegion, constrainingRegion); 13237 } 13238 13239 var x = (axis == X_COORD), 13240 13241 regionSize = (x) ? constrainingRegion.width : constrainingRegion.height, 13242 nodeSize = (x) ? nodeRegion.width : nodeRegion.height, 13243 minConstraint = (x) ? constrainingRegion.left : constrainingRegion.top, 13244 maxConstraint = (x) ? constrainingRegion.right - nodeSize : constrainingRegion.bottom - nodeSize; 13245 13246 if (val < minConstraint || val > maxConstraint) { 13247 if (nodeSize < regionSize) { 13248 if (val < minConstraint) { 13249 val = minConstraint; 13250 } else if (val > maxConstraint) { 13251 val = maxConstraint; 13252 } 13253 } else { 13254 val = minConstraint; 13255 } 13256 } 13257 } 13258 13259 return val; 13260 }, 13261 13262 /** 13263 * The method which performs the preventOverlap calculations for a given axis ("x" or "y") based 13264 * on the value and regions provided. 13265 * 13266 * @method _preventOverlap 13267 * @protected 13268 * 13269 * @param {Number} val The value being constrain 13270 * @param {String} axis The axis to being constrained 13271 * @param {Region} nodeRegion The region of the node being constrained 13272 * @param {Region} constrainingRegion The region of the node (or viewport) we need to constrain to 13273 * 13274 * @return {Number} The constrained value 13275 */ 13276 _preventOverlap : function(val, axis, nodeRegion, constrainingRegion) { 13277 13278 var align = this.get(ALIGN), 13279 x = (axis === X_COORD), 13280 nodeSize, 13281 alignRegion, 13282 nearEdge, 13283 farEdge, 13284 spaceOnNearSide, 13285 spaceOnFarSide; 13286 13287 if (align && align.points && PREVENT_OVERLAP_MAP[axis][align.points.join(EMPTY_STR)]) { 13288 13289 alignRegion = this._getRegion(align.node); 13290 13291 if (alignRegion) { 13292 nodeSize = (x) ? nodeRegion.width : nodeRegion.height; 13293 nearEdge = (x) ? alignRegion.left : alignRegion.top; 13294 farEdge = (x) ? alignRegion.right : alignRegion.bottom; 13295 spaceOnNearSide = (x) ? alignRegion.left - constrainingRegion.left : alignRegion.top - constrainingRegion.top; 13296 spaceOnFarSide = (x) ? constrainingRegion.right - alignRegion.right : constrainingRegion.bottom - alignRegion.bottom; 13297 } 13298 13299 if (val > nearEdge) { 13300 if (spaceOnFarSide < nodeSize && spaceOnNearSide > nodeSize) { 13301 val = nearEdge - nodeSize; 13302 } 13303 } else { 13304 if (spaceOnNearSide < nodeSize && spaceOnFarSide > nodeSize) { 13305 val = farEdge; 13306 } 13307 } 13308 } 13309 13310 return val; 13311 }, 13312 13313 /** 13314 * Binds event listeners responsible for updating the UI state in response to 13315 * Widget constrained positioning related state changes. 13316 * <p> 13317 * This method is invoked after bindUI is invoked for the Widget class
13318 * using YUI's aop infrastructure. 13319 * </p> 13320 * 13321 * @method _bindUIPosConstrained 13322 * @protected 13323 */ 13324 _bindUIPosConstrained : function() { 13325 this.after(CONSTRAIN_CHANGE, this._afterConstrainChange); 13326 this._enableConstraints(this.get(CONSTRAIN)); 13327 }, 13328 13329 /** 13330 * After change listener for the "constrain" attribute, responsible 13331 * for updating the UI, in response to attribute changes. 13332 * 13333 * @method _afterConstrainChange 13334 * @protected 13335 * @param {EventFacade} e The event facade 13336 */ 13337 _afterConstrainChange : function(e) { 13338 this._enableConstraints(e.newVal); 13339 }, 13340 13341 /** 13342 * Updates the UI if enabling constraints, and sets up the xyChange event listeners 13343 * to constrain whenever the widget is moved. Disabling constraints removes the listeners. 13344 * 13345 * @method _enableConstraints 13346 * @private 13347 * @param {boolean} enable Enable or disable constraints 13348 */ 13349 _enableConstraints : function(enable) { 13350 if (enable) { 13351 this.constrain(); 13352 this._cxyHandle = this._cxyHandle || this.on(CONSTRAIN_XYCHANGE, this._constrainOnXYChange); 13353 } else if (this._cxyHandle) { 13354 this._cxyHandle.detach(); 13355 this._cxyHandle = null; 13356 } 13357 }, 13358 13359 /** 13360 * The on change listener for the "xy" attribute. Modifies the event facade'
13360s 13361 * newVal property with the constrained XY value. 13362 * 13363 * @method _constrainOnXYChange 13364 * @protected 13365 * @param {EventFacade} e The event facade for the attribute change 13366 */ 13367 _constrainOnXYChange : function(e) { 13368 if (!e.constrained) { 13369 e.newVal = this.getConstrainedXY(e.newVal); 13370 } 13371 }, 13372 13373 /** 13374 * Utility method to normalize region retrieval from a node instance, 13375 * or the viewport, if no node is provided. 13376 * 13377 * @method _getRegion 13378 * @private 13379 * @param {Node} node Optional. 13380 */ 13381 _getRegion : function(node) { 13382 var region; 13383 if (!node) { 13384 region = this._posNode.get(VIEWPORT_REGION); 13385 } else { 13386 node = Node.one(node); 13387 if (node) { 13388 region = node.get(REGION); 13389 } 13390 } 13391 return region; 13392 } 13393}; 13394 13395Y.WidgetPositionConstrain = PositionConstrain; 13396 13397 13398}, 'patched-v3.18.1', {"requires": ["widget-position"]}); 13399 13400YUI.add('widget-position', function (Y, NAME) { 13401 13402/** 13403 * Provides basic XY positioning support for Widgets, though an extension 13404 * 13405 * @module widget-position 13406 */ 13407 var Lang = Y.Lang, 13408 Widget = Y.Widget, 13409 13410 XY_COORD = "xy", 13411 13412 POSITION = "position", 13413 POSITIONED = "positioned", 13414 BOUNDING_BOX = "boundingBox", 13415 RELATIVE = "relative", 13416 13417 RENDERUI = "renderUI", 13418 BINDUI = "bindUI", 13419 SYNCUI = "syncUI", 13420 13421 UI = Widget.UI_SRC, 13422 13423 XYChange = "xyChange"; 13424 13425 /** 13426 * Widget extension, which can be used to add positioning support to the base Widget class, 13427 * through the <a href="Base.html#method_build">Base.build</a> method. 13428 * 13429 * @class WidgetPosition 13430 * @param {Object} config User configuration object 13431 */ 13432 function Position(config) { 13433 } 13434 13435 /** 13436 * Static property used to define the default attribute 13437 * configuration introduced by WidgetPosition. 13438 * 13439 * @property ATTRS 13440 * @static 13441 * @type Object 13442 */ 13443 Position.ATTRS = { 13444 13445 /** 13446 * @attribute x 13447 * @type number 13448 * @default 0 13449 * 13450 * @description Page X co-ordinate for the widget. This attribute acts as a facade for the 13451 * xy attribute. Changes in position can be monitored by listening for xyChange events. 13452 */ 13453 x: { 13454 setter: function(val) { 13455 this._setX(val); 13456 }, 13457 getter: function() { 13458 return this._getX(); 13459 }, 13460 lazyAdd:false 13461 }, 13462 13463 /** 13464 * @attribute y 13465 * @type number 13466 * @default 0 13467 * 13468 * @description Page Y co-ordinate for the widget. This attribute acts as a facade for the 13469 * xy attribute. Changes in position can be monitored by listening for xyChange events. 13470 */ 13471 y: { 13472 setter: function(val) { 13473 this._setY(val); 13474 }, 13475 getter: function() { 13476 return this._getY(); 13477 }, 13478 lazyAdd: false 13479 }, 13480 13481 /** 13482 * @attribute xy 13483 * @type Array 13484 * @default [0,0] 13485 * 13486 * @description Page XY co-ordinate pair for the widget. 13487 */ 13488 xy: { 13489 value:[0,0], 13490 validator: function(val) { 13491 return this._validateXY(val); 13492 } 13493 } 13494 }; 13495 13496 /** 13497 * Default class used to mark the boundingBox of a positioned widget. 13498 * 13499 * @property POSITIONED_CLASS_NAME
13500 * @type String 13501 * @default "yui-widget-positioned" 13502 * @static 13503 */ 13504 Position.POSITIONED_CLASS_NAME = Widget.getClassName(POSITIONED); 13505 13506 Position.prototype = { 13507 13508 initializer : function() { 13509 this._posNode = this.get(BOUNDING_BOX); 13510 13511 // WIDGET METHOD OVERLAP 13512 Y.after(this._renderUIPosition, this, RENDERUI); 13513 Y.after(this._syncUIPosition, this, SYNCUI); 13514 Y.after(this._bindUIPosition, this, BINDUI); 13515 }, 13516 13517 /** 13518 * Creates/Initializes the DOM to support xy page positioning. 13519 * <p> 13520 * This method in invoked after renderUI is invoked for the Widget class 13521 * using YUI's aop infrastructure. 13522 * </p> 13523 * @method _renderUIPosition 13524 * @protected 13525 */ 13526 _renderUIPosition : function() { 13527 this._posNode.addClass(Position.POSITIONED_CLASS_NAME); 13528 }, 13529 13530 /** 13531 * Synchronizes the UI to match the Widgets xy page position state. 13532 * <p> 13533 * This method in invoked after syncUI is invoked for the Widget class 13534 * using YUI's aop infrastructure. 13535 * </p> 13536 * @method _syncUIPosition 13537 * @protected 13538 */ 13539 _syncUIPosition : function() { 13540 var posNode = this._posNode; 13541 if (posNode.getStyle(POSITION) === RELATIVE) { 13542 this.syncXY(); 13543 } 13544 this._uiSetXY(this.get(XY_COORD)); 13545 }, 13546 13547 /** 13548 * Binds event listeners responsible for updating the UI state in response to 13549 * Widget position related state changes. 13550 * <p> 13551 * This method in invoked after bindUI is invoked for the Widget class 13552 * using YUI's aop infrastructure. 13553 * </p> 13554 * @method _bindUIPosition 13555 * @protected 13556 */ 13557 _bindUIPosition :function() { 13558 this.after(XYChange, this._afterXYChange); 13559 }, 13560 13561 /** 13562 * Moves the Widget to the specified page xy co-ordinate position. 13563 * 13564 * @method move 13565 * 13566 * @param {Number|Number[]} x The new x position or [x, y] values passed 13567 * as an array to support simple pass through of Node.getXY results 13568 * @param {Number} [y] The new y position 13569 */ 13570 move: function () { 13571 var args = arguments, 13572 coord = (Lang.isArray(args[0])) ? args[0] : [args[0], args[1]]; 13573 this.set(XY_COORD, coord); 13574 }, 13575 13576 /** 13577 * Synchronizes the Panel's "xy", "x", and "y" properties with the 13578 * Widget's position in the DOM. 13579 * 13580 * @method syncXY 13581 */ 13582 syncXY : function () { 13583 this.set(XY_COORD, this._posNode.getXY(), {src: UI}); 13584 }, 13585 13586 /** 13587 * Default validator for the XY attribute 13588 * 13589 * @method _validateXY 13590 * @protected 13591 * @param {Array} val The XY page co-ordinate value which is being set. 13592 * @return {boolean} true if valid, false if not. 13593 */ 13594 _validateXY : function(val) { 13595 return (Lang.isArray(val) && Lang.isNumber(val[0]) && Lang.isNumber(val[1])); 13596 }, 13597 13598 /** 13599 * Default setter for the X attribute. The setter passes the X value through 13600 * to the XY attribute, which is the sole store for the XY state. 13601 * 13602 * @method _setX 13603 * @protected 13604 * @param {Number} val The X page co-ordinate value 13605 */ 13606 _setX : function(val) { 13607 this.set(XY_COORD, [val, this.get(XY_COORD)[1]]); 13608 }, 13609 13610 /** 13611 * Default setter for the Y attribute. The setter passes the Y value through 13612 * to the XY attribute, which is the sole store for the XY state. 13613 * 13614 * @method _setY 13615 * @protected 13616 * @param {Number} val The Y page co-ordinate value 13617 */ 13618 _setY : function(val) { 13619 this.set(XY_COORD, [this.get(XY_COORD)[0], val]); 13620 }, 13621 13622 /** 13623 * Default getter for the X attribute. The value is retrieved from 13624 * the XY attribute, which is the sole store for the XY state. 13625 * 13626 * @method _getX 13627 * @protected 13628 * @return {Number} The X page co-ordinate value 13629 */ 13630 _getX : function() { 13631 return this.get(XY_COORD)[0]; 13632 }, 13633 13634 /** 13635 * Default getter for the Y attribute. The value is retrieved from 13636 * the XY attribute, which is the sole store for the XY state. 13637 * 13638 * @method _getY 13639 * @protected 13640 * @return {Number} The Y page co-ordinate value 13641 */ 13642 _getY : function() { 13643 return this.get(XY_COORD)[1]; 13644 }, 13645 13646 /** 13647 * Default attribute change listener for the xy attribute, responsible 13648 * for updating the UI, in response to attribute changes. 13649 * 13650 * @method _afterXYChange 13651 * @protected 13652 * @param {EventFacade} e The event facade for the attribute change 13653 */ 13654 _afterXYChange : function(e) { 13655 if (e.src != UI) { 13656 this._uiSetXY(e.newVal); 13657 } 13658 }, 13659 13660 /** 13661 * Updates the UI to reflect the XY page co-ordinates passed in. 13662 * 13663 * @method _uiSetXY 13664 * @protected 13665 * @param {String} val The XY page co-ordinates value to be reflected in the UI 13666 */ 13667 _uiSetXY : function(val) { 13668 this._posNode.setXY(val); 13669 } 13670 }; 13671
13672 Y.WidgetPosition = Position; 13673 13674 13675}, 'patched-v3.18.1', {"requires": ["base-build", "node-screen", "widget"]}); 13676 13677YUI.add('widget-stack', function (Y, NAME) { 13678 13679/** 13680 * Provides stackable (z-index) support for Widgets through an extension. 13681 * 13682 * @module widget-stack 13683 */ 13684 var L = Y.Lang, 13685 UA = Y.UA, 13686 Node = Y.Node, 13687 Widget = Y.Widget, 13688 13689 ZINDEX = "zIndex", 13690 SHIM = "shim", 13691 VISIBLE = "visible", 13692 13693 BOUNDING_BOX = "boundingBox", 13694 13695 RENDER_UI = "renderUI", 13696 BIND_UI = "bindUI", 13697 SYNC_UI = "syncUI", 13698 13699 OFFSET_WIDTH = "offsetWidth", 13700 OFFSET_HEIGHT = "offsetHeight", 13701 PARENT_NODE = "parentNode", 13702 FIRST_CHILD = "firstChild", 13703 OWNER_DOCUMENT = "ownerDocument", 13704 13705 WIDTH = "width", 13706 HEIGHT = "height", 13707 PX = "px", 13708 13709 // HANDLE KEYS 13710 SHIM_DEFERRED = "shimdeferred", 13711 SHIM_RESIZE = "shimresize", 13712 13713 // Events 13714 VisibleChange = "visibleChange", 13715 WidthChange = "widthChange", 13716 HeightChange = "heightChange", 13717 ShimChange = "shimChange", 13718 ZIndexChange = "zIndexChange", 13719 ContentUpdate = "contentUpdate", 13720 13721 // CSS 13722 STACKED = "stacked"; 13723 13724 /** 13725 * Widget extension, which can be used to add stackable (z-index) support to the 13726 * base Widget class along with a shimming solution, through the 13727 * <a href="Base.html#method_build">Base.build</a> method. 13728 * 13729 * @class WidgetStack 13730 * @param {Object} User configuration object 13731 */ 13732 function Stack(config) {} 13733 13734 // Static Properties 13735 /** 13736 * Static property used to define the default attribute 13737 * configuration introduced by WidgetStack. 13738 * 13739 * @property ATTRS 13740 * @type Object 13741 * @static 13742 */ 13743 Stack.ATTRS = { 13744 /** 13745 * @attribute shim 13746 * @type boolean 13747 * @default false, for all browsers other than IE6, for which a shim is enabled by default. 13748 * 13749 * @description Boolean flag to indicate whether or not a shim should be added to the Widgets 13750 * boundingBox, to protect it from select box bleedthrough. 13751 */ 13752 shim: { 13753 value: (UA.ie == 6) 13754 }, 13755 13756 /** 13757 * @attribute zIndex 13758 * @type number 13759 * @default 0 13760 * @description The z-index to apply to the Widgets boundingBox. Non-numerical values for 13761 * zIndex will be converted to 0 13762 */ 13763 zIndex: { 13764 value : 0, 13765 setter: '_setZIndex' 13766 } 13767 }; 13768 13769 /** 13770 * The HTML parsing rules for the WidgetStack class. 13771 * 13772 * @property HTML_PARSER 13773 * @static 13774 * @type Object 13775 */ 13776 Stack.HTML_PARSER = { 13777 zIndex: function (srcNode) { 13778 return this._parseZIndex(srcNode); 13779 } 13780 }; 13781 13782 /** 13783 * Default class used to mark the shim element 13784 * 13785 * @property SHIM_CLASS_NAME
13786 * @type String 13787 * @static 13788 * @default "yui3-widget-shim" 13789 */ 13790 Stack.SHIM_CLASS_NAME = Widget.getClassName(SHIM); 13791 13792 /** 13793 * Default class used to mark the boundingBox of a stacked widget. 13794 * 13795 * @property STACKED_CLASS_NAME 13796 * @type String 13797 * @static 13798 * @default "yui3-widget-stacked" 13799 */ 13800 Stack.STACKED_CLASS_NAME = Widget.getClassName(STACKED); 13801 13802 /** 13803 * Default markup template used to generate the shim element. 13804 * 13805 * @property SHIM_TEMPLATE 13806 * @type String 13807 * @static 13808 */ 13809 Stack.SHIM_TEMPLATE = '<iframe class="' + Stack.SHIM_CLASS_NAME + '" frameborder="0" title="Widget Stacking Shim" src="javascript:false" tabindex="-1" role="presentation"></iframe>'; 13810 13811 Stack.prototype = { 13812 13813 initializer : function() { 13814 this._stackNode = this.get(BOUNDING_BOX); 13815 this._stackHandles = {}; 13816 13817 // WIDGET METHOD OVERLAP 13818 Y.after(this._renderUIStack, this, RENDER_UI); 13819 Y.after(this._syncUIStack, this, SYNC_UI); 13820 Y.after(this._bindUIStack, this, BIND_UI); 13821 }, 13822 13823 /** 13824 * Synchronizes the UI to match the Widgets stack state. This method in 13825 * invoked after syncUI is invoked for the Widget class using YUI's aop infrastructure. 13826 * 13827 * @method _syncUIStack 13828 * @protected 13829 */ 13830 _syncUIStack: function() { 13831 this._uiSetShim(this.get(SHIM)); 13832 this._uiSetZIndex(this.get(ZINDEX)); 13833 }, 13834 13835 /** 13836 * Binds event listeners responsible for updating the UI state in response to 13837 * Widget stack related state changes. 13838 * <p> 13839 * This method is invoked after bindUI is invoked for the Widget class 13840 * using YUI's aop infrastructure. 13841 * </p> 13842 * @method _bindUIStack 13843 * @protected 13844 */ 13845 _bindUIStack: function() { 13846 this.after(ShimChange, this._afterShimChange); 13847 this.after(ZIndexChange, this._afterZIndexChange); 13848 }, 13849 13850 /** 13851 * Creates/Initializes the DOM to support stackability. 13852 * <p> 13853 * This method in invoked after renderUI is invoked for the Widget class 13854 * using YUI's aop infrastructure. 13855 * </p> 13856 * @method _renderUIStack 13857 * @protected 13858 */ 13859 _renderUIStack: function() { 13860 this._stackNode.addClass(Stack.STACKED_CLASS_NAME); 13861 }, 13862 13863 /** 13864 Parses a `zIndex` attribute value from this widget's `srcNode`. 13865 13866 @method _parseZIndex 13867 @param {Node} srcNode The node to parse a `zIndex` value from. 13868 @return {Mixed} The parsed `zIndex` value. 13869 @protected 13870 **/ 13871 _parseZIndex: function (srcNode) { 13872 var zIndex; 13873 13874 // Prefers how WebKit handles `z-index` which better matches the 13875 // spec: 13876 // 13877 // * http://www.w3.org/TR/CSS2/visuren.html#z-index 13878 // * https://bugs.webkit.org/show_bug.cgi?id=15562 13879 // 13880 // When a node isn't rendered in the document, and/or when a 13881 // node is not positioned, then it doesn't have a context to derive 13882 // a valid `z-index` value from. 13883 if (!srcNode.inDoc() || srcNode.getStyle('position') === 'static') { 13884 zIndex = 'auto'; 13885 } else { 13886 // Uses `getComputedStyle()` because it has greater accuracy in 13887 // more browsers than `getStyle()` does for `z-index`. 13888 zIndex = srcNode.getComputedStyle('zIndex'); 13889 } 13890 13891 // This extension adds a stacking context to widgets, therefore a 13892 // `srcNode` witout a stacking context (i.e. "auto") will return 13893 // `null` from this DOM parser. This way the widget's default or 13894 // user provided value for `zIndex` will be used. 13895 return zIndex === 'auto' ? null : zIndex; 13896 }, 13897 13898 /** 13899 * Default setter for zIndex attribute changes. Normalizes zIndex values to 13900 * numbers, converting non-numerical values to 0. 13901 * 13902 * @method _setZIndex 13903 * @protected 13904 * @param {String | Number} zIndex 13905 * @return {Number} Normalized zIndex 13906 */ 13907 _setZIndex: function(zIndex) { 13908 if (L.isString(zIndex)) { 13909 zIndex = parseInt(zIndex, 10); 13910 } 13911 if (!L.isNumber(zIndex)) { 13912 zIndex = 0; 13913 } 13914 return zIndex; 13915 }, 13916 13917 /** 13918 * Default attribute change listener for the shim attribute, responsible 13919 * for updating the UI, in response to attribute changes. 13920 * 13921 * @method _afterShimChange 13922 * @protected 13923 * @param {EventFacade} e The event facade for the attribute change 13924 */ 13925 _afterShimChange : function(e) { 13926 this._uiSetShim(e.newVal); 13927 }, 13928 13929 /** 13930 * Default attribute change listener for the zIndex attribute, responsible 13931 * for updating the UI, in response to attribute changes. 13932 * 13933 * @method _afterZIndexChange 13934 * @protected 13935 * @param {EventFacade} e The event facade for the attribute change 13936 */ 13937 _afterZIndexChange : function(e) { 13938 this._uiSetZIndex(e.newVal); 13939 }, 13940 13941 /** 13942 * Updates the UI to reflect the zIndex value passed in. 13943 * 13944 * @method _uiSetZIndex 13945 * @protected 13946 * @param {number} zIndex The zindex to be reflected in the UI 13947 */ 13948 _uiSetZIndex: function (zIndex) { 13949 this._stackNode.setStyle(ZINDEX, zIndex); 13950 }, 13951 13952 /** 13953 * Updates the UI to enable/disable the shim. If the widget is not currently visible, 13954 * creation of the shim is deferred until it is made visible, for performance reasons. 13955 * 13956 * @method _uiSetShim 13957 * @protected 13958 * @param {boolean} enable If true, creates/renders the shim, if false, removes it. 13959 */ 13960 _uiSetShim: function (enable) { 13961 if (enable) { 13962 // Lazy creation 13963 if (this.get(VISIBLE)) { 13964 this._renderShim(); 13965 } else { 13966 this._renderShimDeferred(); 13967 } 13968 13969 // Eagerly attach resize handlers 13970 // 13971 // Required because of Event stack behavior, commit ref: cd8dddc 13972 // Should be revisted after Ticket #2531067 is resolved. 13973 if (UA.ie == 6) { 13974 this._addShimResizeHandlers(); 13975 } 13976 } else { 13977 this._destroyShim(); 13978 } 13979 }, 13980 13981 /** 13982 * Sets up change handlers for the visible attribute, to defer shim creation/rendering 13983 * until the Widget is made visible. 13984 * 13985 * @method _renderShimDeferred 13986 * @private 13987 */ 13988 _renderShimDeferred : function() { 13989 13990 this._stackHandles[SHIM_DEFERRED] = this._stackHandles[SHIM_DEFERRED] || []; 13991 13992 var handles = this._stackHandles[SHIM_DEFERRED], 13993 createBeforeVisible = function(e) { 13994 if (e.newVal) { 13995 this._renderShim(); 13996 } 13997 }; 13998 13999 handles.push(this.on(VisibleChange, createBeforeVisible)); 14000 // Depending how how Ticket #2531067 is resolved, a reversal of 14001 // commit ref: cd8dddc could lead to a more elagent solution, with 14002 // the addition of this line here: 14003 // 14004 // handles.push(this.after(VisibleChange, this.sizeShim)); 14005 }, 14006 14007 /** 14008 * Sets up event listeners to resize the shim when the size of the Widget changes. 14009 * <p> 14010 * NOTE: This method is only used for IE6 currently, since IE6 doesn't support a way to 14011 * resize the shim purely through CSS, when the Widget does not have an explicit width/height 14012 * set. 14013 * </p> 14014 * @method _addShimResizeHandlers 14015 * @private 14016 */ 14017 _addShimResizeHandlers : function() { 14018 14019 this._stackHandles[SHIM_RESIZE] = this._stackHandles[SHIM_RESIZE] || []; 14020 14021 var sizeShim = this.sizeShim, 14022 handles = this._stackHandles[SHIM_RESIZE]; 14023 14024 handles.push(this.after(VisibleChange, sizeShim)); 14025 handles.push(this.after(WidthChange, sizeShim)); 14026 handles.push(this.after(HeightChange, sizeShim)); 14027 handles.push(this.after(ContentUpdate, sizeShim)); 14028 }, 14029 14030 /** 14031 * Detaches any handles stored for the provided key 14032 * 14033 * @method _detachStackHandles 14034 * @param String handleKey The key defining the group of handles which should be detached 14035 * @private 14036 */ 14037 _detachStackHandles : function(handleKey) { 14038 var handles = this._stackHandles[handleKey], 14039 handle; 14040 14041 if (handles && handles.length > 0) { 14042 while((handle = handles.pop())) { 14043 handle.detach(); 14044 } 14045 } 14046 }, 14047 14048 /** 14049 * Creates the shim element and adds it to the DOM 14050 * 14051 * @method _renderShim 14052 * @private 14053 */ 14054 _renderShim : function() { 14055 var shimEl = this._shimNode, 14056 stackEl = this._stackNode; 14057 14058 if (!shimEl) { 14059 shimEl = this._shimNode = this._getShimTemplate(); 14060 stackEl.insertBefore(shimEl, stackEl.get(FIRST_CHILD)); 14061 14062 this._detachStackHandles(SHIM_DEFERRED); 14063 this.sizeShim(); 14064 } 14065 }, 14066 14067 /** 14068 * Removes the shim from the DOM, and detaches any related event 14069 * listeners. 14070 * 14071 * @method _destroyShim 14072 * @private 14073 */ 14074 _destroyShim : function() { 14075 if (this._shimNode) { 14076 this._shimNode.get(PARENT_NODE).removeChild(this._shimNode); 14077 this._shimNode = null; 14078 14079 this._detachStackHandles(SHIM_DEFERRED); 14080 this._detachStackHandles(SHIM_RESIZE); 14081 } 14082 }, 14083 14084 /** 14085 * For IE6, synchronizes the size and position of iframe shim to that of 14086 * Widget bounding box which it is protecting. For all other browsers, 14087 * this method does not do anything. 14088 * 14089 * @method sizeShim 14090 */ 14091 sizeShim: function () { 14092 var shim = this._shimNode, 14093 node = this._stackNode; 14094 14095 if (shim && UA.ie === 6 && this.get(VISIBLE)) { 14096 shim.setStyle(WIDTH, node.get(OFFSET_WIDTH) + PX); 14097 shim.setStyle(HEIGHT, node.get(OFFSET_HEIGHT) + PX); 14098 } 14099 }, 14100 14101 /** 14102 * Creates a cloned shim node, using the SHIM_TEMPLATE html template, for use on a new instance. 14103 * 14104 * @method _getShimTemplate 14105 * @private 14106 * @return {Node} node A new shim Node instance. 14107 */ 14108 _getShimTemplate : function() { 14109 return Node.create(Stack.SHIM_TEMPLATE, this._stackNode.get(OWNER_DOCUMENT)); 14110 } 14111 }; 14112
14113 Y.WidgetStack = Stack; 14114 14115 14116}, 'patched-v3.18.1', {"requires": ["base-build", "widget"], "skinnable": true}); 14117
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.