PageSourceSearch

https://www.provincia.terni.it/portal/combo?browserId=chrome&minif…/aui/widget-stack/widget-stack.js

js provincia.terni.it collected 2026-10-02 12:10:56 UTC 396,178 bytes, 14,117 lines download raw bytes

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>&nbsp;';
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 &lt;= 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 &quot;shift&quot; 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 &quot;execute&quot; 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 &quot;add&quot; 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 &quot;promote&quot; event.  Promotes the
10619     * named callback to the head of the queue.</p>
10620     *
10621     * <p>The event object will contain a property &quot;callback&quot;, 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 &quot;remove&quot; event.  Removes the
10667     * callback from the queue.</p>
10668     *
10669     * <p>The event object will contain a property &quot;callback&quot;, 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 &#60;boolean&#62;</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 &#60;String[]&#62;</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.