PageSourceSearch

https://wiedza.pkn.pl/html/js/aui/event-base/event-base.js?t=1544454314000

js pkn.pl collected 2026-10-02 04:28:18 UTC 40,938 bytes, 1,356 lines download raw bytes

1/*
2Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3Code licensed under the BSD License:
4http://developer.yahoo.com/yui/license.html
5version: 3.4.0
6build: nightly
7*/
8(function () {
9var GLOBAL_ENV = YUI.Env;
10
11if (!GLOBAL_ENV._ready) {
12    GLOBAL_ENV._ready = function() {
13        GLOBAL_ENV.DOMReady = true;
14        GLOBAL_ENV.remove(YUI.config.doc, 'DOMContentLoaded', GLOBAL_ENV._ready);
15    };
16
17    GLOBAL_ENV.add(YUI.config.doc, 'DOMContentLoaded', GLOBAL_ENV._ready);
18}
19})();
20YUI.add('event-base', function(Y) {
21
22/*
23 * DOM event listener abstraction layer
24 * @module event
25 * @submodule event-base
26 */
27
28/**
29 * The domready event fires at the moment the browser's DOM is
30 * usable. In most cases, this is before images are fully
31 * downloaded, allowing you to provide a more responsive user
32 * interface.
33 *
34 * In YUI 3, domready subscribers will be notified immediately if
35 * that moment has already passed when the subscription is created.
36 *
37 * One exception is if the yui.js file is dynamically injected into
38 * the page.  If this is done, you must tell the YUI instance that
39 * you did this in order for DOMReady (and window load events) to
40 * fire normally.  That configuration option is 'injected' -- set
41 * it to true if the yui.js script is not included inline.
42 *
43 * This method is part of the 'event-ready' module, which is a
44 * submodule of 'event'.
45 *
46 * @event domready
47 * @for YUI
48 */
49Y.publish('domready', {
50    fireOnce: true,
51    async: true
52});
53
54if (YUI.Env.DOMReady) {
55    Y.fire('domready');
56} else {
57    Y.Do.before(function() { Y.fire('domready'); }, YUI.Env, '_ready');
58}
59
60/**
61 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
62 * events.
63 * @module event
64 * @submodule event-base
65 */
66
67/**
68 * Wraps a DOM event, properties requiring browser abstraction are
69 * fixed here.  Provids a security layer when required.
70 * @class DOMEventFacade
71 * @param ev {Event} the DOM event
72 * @param currentTarget {HTMLElement} the element the listener was attached to
73 * @param wrapper {Event.Custom} the custom event wrapper for this DOM event
74 */
75
76    var ua = Y.UA,
77
78    EMPTY = {},
79
80    /**
81     * webkit key remapping required for Safari < 3.1
82     * @property webkitKeymap
83     * @private
84     */
85    webkitKeymap = {
86        63232: 38, // up
87        63233: 40, // down
88        63234: 37, // left
89        63235: 39, // right
90        63276: 33, // page up
91        63277: 34, // page down
92        25:     9, // SHIFT-TAB (Safari provides a different key code in
93                   // this case, even though the shiftKey modifier is set)
94        63272: 46, // delete
95        63273: 36, // home
96        63275: 35  // end
97    },
98
99    /**
100     * Returns a wrapped node.  Intended to be used on event targets,
101     * so it will return the node's parent if the target is a text
102     * node.
103     *
104     * If accessing a property of the node throws an error, this is
105     * probably the anonymous div wrapper Gecko adds inside text
106     * nodes.  This likely will only occur when attempting to access
107     * the relatedTarget.  In this case, we now return null because
108     * the anonymous div is completely useless and we do not know
109     * what the related target was because we can't even get to
110     * the element's parent node.
111     *
112     * @method resolve
113     * @private
114     */
115    resolve = function(n) {
116        if (!n) {
117            return n;
118        }
119        try {
120            if (n && 3 == n.nodeType) {
121                n = n.parentNode;
122            }
123        } catch(e) {
124            return null;
125        }
126
127        return Y.one(n);
128    },
129
130    DOMEventFacade = function(ev, currentTarget, wrapper) {
131        this._event = ev;
132        this._currentTarget = currentTarget;
133        this._wrapper = wrapper || EMPTY;
134
135        // if not lazy init
136        this.init();
137    };
138
139Y.extend(DOMEventFacade, Object, {
140
141    init: function() {
142
143        var e = this._event,
144            overrides = this._wrapper.overrides,
145            x = e.pageX,
146            y = e.pageY,
147            c,
148            currentTarget = this._currentTarget;
149
150        this.altKey   = e.altKey;
151        this.ctrlKey  = e.ctrlKey;
152        this.metaKey  = e.metaKey;
153        this.shiftKey = e.shiftKey;
154        this.type     = (overrides && overrides.type) || e.type;
155        this.clientX  = e.clientX;
156        this.clientY  = e.clientY;
157
158        this.pageX = x;
159        this.pageY = y;
160
161        c = e.keyCode || e.charCode;
162
163        if (ua.webkit && (c in webkitKeymap)) {
164            c = webkitKeymap[c];
165        }
166
167        this.keyCode = c;
168        this.charCode = c;
169        this.which = e.which || e.charCode || c;
170        // this.button = e.button;
171        this.button = this.which;
172
173        this.target = resolve(e.target);
174        this.currentTarget = resolve(currentTarget);
175        this.relatedTarget = resolve(e.relatedTarget);
176
177        if (e.type == "mousewheel" || e.type == "DOMMouseScroll") {
178            this.wheelDelta = (e.detail) ? (e.detail * -1) : Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1);
179        }
180
181        if (this._touch) {
182            this._touch(e, currentTarget, this._wrapper);
183        }
184    },
185
186    stopPropagation: function() {
187        this._event.stopPropagation();
188        this._wrapper.stopped = 1;
189        this.stopped = 1;
190    },
191
192    stopImmediatePropagation: function() {
193        var e = this._event;
194        if (e.stopImmediatePropagation) {
195            e.stopImmediatePropagation();
196        } else {
197            this.stopPropagation();
198        }
199        this._wrapper.stopped = 2;
200        this.stopped = 2;
201    },
202
203    preventDefault: function(returnValue) {
204        var e = this._event;
205        e.preventDefault();
206        e.returnValue = returnValue || false;
207        this._wrapper.prevented = 1;
208        this.prevented = 1;
209    },
210
211    halt: function(immediate) {
212        if (immediate) {
213            this.stopImmediatePropagation();
214        } else {
215            this.stopPropagation();
216        }
217
218        this.preventDefault();
219    }
220
221});
222
223DOMEventFacade.resolve = resolve;
224Y.DOM2EventFacade = DOMEventFacade;
225Y.DOMEventFacade = DOMEventFacade;
226
227    /**
228     * The native event
229     * @property _event
230     * @type {Native DOM Event}
231     * @private
232     */
233
234    /**
235    The name of the event (e.g. "click")
236
237    @property type
238    @type {String}
239    **/
240
241    /**
242    `true` if the "alt" or "option" key is pressed.
243
244    @property altKey
245    @type {Boolean}
246    **/
247
248    /**
249    `true` if the shift key is pressed.
250
251    @property shiftKey
252    @type {Boolean}
253    **/
254
255    /**
256    `true` if the "Windows" key on a Windows keyboard, "command" key on an
257    Apple keyboard, or "meta" key on other keyboards is pressed.
258
259    @property metaKey
260    @type {Boolean}
261    **/
262
263    /**
264    `true` if the "Ctrl" or "control" key is pressed.
265
266    @property ctrlKey
267    @type {Boolean}
268    **/
269
270    /**
271     * The X location of the event on the page (including scroll)
272     * @property pageX
273     * @type {Number}
274     */
275
276    /**
277     * The Y location of the event on the page (including scroll)
278     * @property pageY
279     * @type {Number}
280     */
281
282    /**
283     * The X location of the event in the viewport
284     * @property clientX
285     * @type {Number}
286     */
287
288    /**
289     * The Y location of the event in the viewport
290     * @property clientY
291     * @type {Number}
292     */
293
294    /**
295     * The keyCode for key events.  Uses charCode if keyCode is not available
296     * @property keyCode
297     * @type {Number}
298     */
299
300    /**
301     * The charCode for key events.  Same as keyCode
302     * @property charCode
303     * @type {Number}
304     */
305
306    /**
307     * The button that was pushed. 1 for left click, 2 for middle click, 3 for
308     * right click.  This is only reliably populated on `mouseup` events.
309     * @property button
310     * @type {Number}
311     */
312
313    /**
314     * The button that was pushed.  Same as button.
315     * @property which
316     * @type {Number}
317     */
318
319    /**
320     * Node reference for the targeted element
321     * @property target
322     * @type {Node}
323     */
324
325    /**
326     * Node reference for the element that the listener was attached to.
327     * @property currentTarget
328     * @type {Node}
329     */
330
331    /**
332     * Node reference to the relatedTarget
333     * @property relatedTarget
334     * @type {Node}
335     */
336
337    /**
338     * Number representing the direction and velocity of the movement of the mousewheel.
339     * Negative is down, the higher the number, the faster.  Applies to the mousewheel event.
340     * @property wheelDelta
341     * @type {Number}
342     */
343
344    /**
345     * Stops the propagation to the next bubble target
346     * @method stopPropagation
347     */
348
349    /**
350     * Stops the propagation to the next bubble target and
351     * prevents any additional listeners from being exectued
352     * on the current target.
353     * @method stopImmediatePropagation
354     */
355
356    /**
357     * Prevents the event's default behavior
358     * @method preventDefault
359     * @param returnValue {string} sets the returnValue of the event to this value
360     * (rather than the default false value).  This can be used to add a customized
361     * confirmation query to the beforeunload event).
362     */
363
364    /**
365     * Stops the event propagation and prevents the default
366     * event behavior.
367     * @method halt
368     * @param immediate {boolean} if true additional listeners
369     * on the current target will not be executed
370     */
371(function() {
372/**
373 * The event utility provides functions to add and remove event listeners,
374 * event cleansing.  It also tries to automatically remove listeners it
375 * registers during the unload event.
376 * @module event
377 * @main event
378 * @submodule event-base
379 */
380
381/**
382 * The event utility provides functions to add and remove event listeners,
383 * event cleansing.  It also tries to automatically remove listeners it
384 * registers during the unload event.
385 *
386 * @class Event
387 * @static
388 */
389
390Y.Env.evt.dom_wrappers = {};
391Y.Env.evt.dom_map = {};
392
393var _eventenv = Y.Env.evt,
394    config = Y.config,
395    win = config.win,
396    add = YUI.Env.add,
397    remove = YUI.Env.remove,
398
399    onLoad = function() {
400        YUI.Env.windowLoaded = true;
401        Y.Event._load();
402        remove(win, "load", onLoad);
403    },
404
405    onUnload = function() {
406        Y.Event._unload();
407    },
408
409    EVENT_READY = 'domready',
410
411    COMPAT_ARG = '~yui|2|compat~',
412
413    shouldIterate = function(o) {
414        try {
415            return (o && typeof o !== "string" && Y.Lang.isNumber(o.length) &&
416                    !o.tagName && !o.alert);
417        } catch(ex) {
418            return false;
419        }
420
421    },
422
423    // aliases to support DOM event subscription clean up when the last
424    // subscriber is detached. deleteAndClean overrides the DOM event's wrapper
425    // CustomEvent _delete method.
426    _ceProtoDelete = Y.CustomEvent.prototype._delete,
427    _deleteAndClean = function(s) {
428        var ret = _ceProtoDelete.apply(this, arguments);
429
430        if (!this.subCount && !this.afterCount) {
431            Y.Event._clean(this);
432        }
433
434        return ret;
435    },
436
437Event = function() {
438
439    /**
440     * True after the onload event has fired
441     * @property _loadComplete
442     * @type boolean
443     * @static
444     * @private
445     */
446    var _loadComplete =  false,
447
448    /**
449     * The number of times to poll after window.onload.  This number is
450     * increased if additional late-bound handlers are requested after
451     * the page load.
452     * @property _retryCount
453     * @static
454     * @private
455     */
456    _retryCount = 0,
457
458    /**
459     * onAvailable listeners
460     * @property _avail
461     * @static
462     * @private
463     */
464    _avail = [],
465
466    /**
467     * Custom event wrappers for DOM events.  Key is
468     * 'event:' + Element uid stamp + event type
469     * @property _wrappers
470     * @type Y.Event.Custom
471     * @static
472     * @private
473     */
474    _wrappers = _eventenv.dom_wrappers,
475
476    _windowLoadKey = null,
477
478    /**
479     * Custom event wrapper map DOM events.  Key is
480     * Element uid stamp.  Each item is a hash of custom event
481     * wrappers as provided in the _wrappers collection.  This
482     * provides the infrastructure for getListeners.
483     * @property _el_events
484     * @static
485     * @private
486     */
487    _el_events = _eventenv.dom_map;
488
489    return {
490
491        /**
492         * The number of times we should look for elements that are not
493         * in the DOM at the time the event is requested after the document
494         * has been loaded.  The default is 1000@amp;40 ms, so it will poll
495         * for 40 seconds or until all outstanding handlers are bound
496         * (whichever comes first).
497         * @property POLL_RETRYS
498         * @type int
499         * @static
500         * @final
501         */
502        POLL_RETRYS: 1000,
503
504        /**
505         * The poll interval in milliseconds
506         * @property POLL_INTERVAL
507         * @type int
508         * @static
509         * @final
510         */
511        POLL_INTERVAL: 40,
512
513        /**
514         * addListener/removeListener can throw errors in unexpected scenarios.
515         * These errors are suppressed, the method returns false, and this property
516         * is set
517         * @property lastError
518         * @static
519         * @type Error
520         */
521        lastError: null,
522
523
524        /**
525         * poll handle
526         * @property _interval
527         * @static
528         * @private
529         */
530        _interval: null,
531
532        /**
533         * document readystate poll handle
534         * @property _dri
535         * @static
536         * @private
537         */
538         _dri: null,
539
540        /**
541         * True when the document is initially usable
542         * @property DOMReady
543         * @type boolean
544         * @static
545         */
546        DOMReady: false,
547
548        /**
549         * @method startInterval
550         * @static
551         * @private
552         */
553        startInterval: function() {
554            if (!Event._interval) {
555Event._interval = setInterval(Event._poll, Event.POLL_INTERVAL);
556            }
557        },
558
559        /**
560         * Executes the supplied callback when the item with the supplied
561         * id is found.  This is meant to be used to execute behavior as
562         * soon as possible as the page loads.  If you use this after the
563         * initial page load it will poll for a fixed time for the element.
564         * The number of times it will poll and the frequency are
565         * configurable.  By default it will poll for 10 seconds.
566         *
567         * <p>The callback is executed with a single parameter:
568         * the custom object parameter, if provided.</p>
569         *
570         * @method onAvailable
571         *
572         * @param {string||string[]}   id the id of the element, or an array
573         * of ids to look for.
574         * @param {function} fn what to execute when the element is found.
575         * @param {object}   p_obj an optional object to be passed back as
576         *                   a parameter to fn.
577         * @param {boolean|object}  p_override If set to true, fn will execute
578         *                   in the context of p_obj, if set to an object it
579         *                   will execute in the context of that object
580         * @param checkContent {boolean} check child node readiness (onContentReady)
581         * @static
582         * @deprecated Use Y.on("available")
583         */
584        // @TODO fix arguments
585        onAvailable: function(id, fn, p_obj, p_override, checkContent, compat) {
586
587            var a = Y.Array(id), i, availHandle;
588
589
590            for (i=0; i<a.length; i=i+1) {
591                _avail.push({
592                    id:         a[i],
593                    fn:         fn,
594                    obj:        p_obj,
595                    override:   p_override,
596                    checkReady: checkContent,
597                    compat:     compat
598                });
599            }
600            _retryCount = this.POLL_RETRYS;
601
602            // We want the first test to be immediate, but async
603            setTimeout(Event._poll, 0);
604
605            availHandle = new Y.EventHandle({
606
607                _delete: function() {
608                    // set by the event system for lazy DOM listeners
609                    if (availHandle.handle) {
610                        availHandle.handle.detach();
611                        return;
612                    }
613
614                    var i, j;
615
616                    // otherwise try to remove the onAvailable listener(s)
617                    for (i = 0; i < a.length; i++) {
618                        for (j = 0; j < _avail.length; j++) {
619                            if (a[i] === _avail[j].id) {
620                                _avail.splice(j, 1);
621                            }
622                        }
623                    }
624                }
625
626            });
627
628            return availHandle;
629        },
630
631        /**
632         * Works the same way as onAvailable, but additionally checks the
633         * state of sibling elements to determine if the content of the
634         * available element is safe to modify.
635         *
636         * <p>The callback is executed with a single parameter:
637         * the custom object parameter, if provided.</p>
638         *
639         * @method onContentReady
640         *
641         * @param {string}   id the id of the element to look for.
642         * @param {function} fn what to execute when the element is ready.
643         * @param {object}   obj an optional object to be passed back as
644         *                   a parameter to fn.
645         * @param {boolean|object}  override If set to true, fn will execute
646         *                   in the context of p_obj.  If an object, fn will
647         *                   exectute in the context of that object
648         *
649         * @static
650         * @deprecated Use Y.on("contentready")
651         */
652        // @TODO fix arguments
653        onContentReady: function(id, fn, obj, override, compat) {
654            return Event.onAvailable(id, fn, obj, override, true, compat);
655        },
656
657        /**
658         * Adds an event listener
659         *
660         * @method attach
661         *
662         * @param {String}   type     The type of event to append
663         * @param {Function} fn        The method the event invokes
664         * @param {String|HTMLElement|Array|NodeList} el An id, an element
665         *  reference, or a collection of ids and/or elements to assign the
666         *  listener to.
667         * @param {Object}   context optional context object
668         * @param {Boolean|object}  args 0..n arguments to pass to the callback
669         * @return {EventHandle} an object to that can be used to detach the listener
670         *
671         * @static
672         */
673
674        attach: function(type, fn, el, context) {
675            return Event._attach(Y.Array(arguments, 0, true));
676        },
677
678        _createWrapper: function (el, type, capture, compat, facade) {
679
680            var cewrapper,
681                ek  = Y.stamp(el),
682                key = 'event:' + ek + type;
683
684            if (false === facade) {
685                key += 'native';
686            }
687            if (capture) {
688                key += 'capture';
689            }
690
691
692            cewrapper = _wrappers[key];
693
694
695            if (!cewrapper) {
696                // create CE wrapper
697                cewrapper = Y.publish(key, {
698                    silent: true,
699                    bubbles: false,
700                    contextFn: function() {
701                        if (compat) {
702                            return cewrapper.el;
703                        } else {
704                            cewrapper.nodeRef = cewrapper.nodeRef || Y.one(cewrapper.el);
705                            return cewrapper.nodeRef;
706                        }
707                    }
708                });
709
710                cewrapper.overrides = {};
711
712                // for later removeListener calls
713                cewrapper.el = el;
714                cewrapper.key = key;
715                cewrapper.domkey = ek;
716                cewrapper.type = type;
717                cewrapper.fn = function(e) {
718                    cewrapper.fire(Event.getEvent(e, el, (compat || (false === facade))));
719                };
720                cewrapper.capture = capture;
721
722                if (el == win && type == "load") {
723                    // window load happens once
724                    cewrapper.fireOnce = true;
725                    _windowLoadKey = key;
726                }
727                cewrapper._delete = _deleteAndClean;
728
729                _wrappers[key] = cewrapper;
730                _el_events[ek] = _el_events[ek] || {};
731                _el_events[ek][key] = cewrapper;
732
733                add(el, type, cewrapper.fn, capture);
734            }
735
736            return cewrapper;
737
738        },
739
740        _attach: function(args, conf) {
741
742            var compat,
743                handles, oEl, cewrapper, context,
744                fireNow = false, ret,
745                type = args[0],
746                fn = args[1],
747                el = args[2] || win,
748                facade = conf && conf.facade,
749                capture = conf && conf.capture,
750                overrides = conf && conf.overrides;
751
752            if (args[args.length-1] === COMPAT_ARG) {
753                compat = true;
754            }
755
756            if (!fn || !fn.call) {
757// throw new TypeError(type + " attach call failed, callback undefined");
758                return false;
759            }
760
761            // The el argument can be an array of elements or element ids.
762            if (shouldIterate(el)) {
763
764                handles=[];
765
766                Y.each(el, function(v, k) {
767                    args[2] = v;
768                    handles.push(Event._attach(args.slice(), conf));
769                });
770
771                // return (handles.length === 1) ? handles[0] : handles;
772                return new Y.EventHandle(handles);
773
774            // If the el argument is a string, we assume it is
775            // actually the id of the element.  If the page is loaded
776            // we convert el to the actual element, otherwise we
777            // defer attaching the event until the element is
778            // ready
779            } else if (Y.Lang.isString(el)) {
780
781                // oEl = (compat) ? Y.DOM.byId(el) : Y.Selector.query(el);
782
783                if (compat) {
784                    oEl = Y.DOM.byId(el);
785                } else {
786
787                    oEl = Y.Selector.query(el);
788
789                    switch (oEl.length) {
790                        case 0:
791                            oEl = null;
792                            break;
793                        case 1:
794                            oEl = oEl[0];
795                            break;
796                        default:
797                            args[2] = oEl;
798                            return Event._attach(args, conf);
799                    }
800                }
801
802                if (oEl) {
803
804                    el = oEl;
805
806                // Not found = defer adding the event until the element is available
807                } else {
808
809                    ret = Event.onAvailable(el, function() {
810
811                        ret.handle = Event._attach(args, conf);
812
813                    }, Event, true, false, compat);
814
815                    return ret;
816
817                }
818            }
819
820            // Element should be an html element or node
821            if (!el) {
822                return false;
823            }
824
825            if (Y.Node && Y.instanceOf(el, Y.Node)) {
826                el = Y.Node.getDOMNode(el);
827            }
828
829            cewrapper = Event._createWrapper(el, type, capture, compat, facade);
830            if (overrides) {
831                Y.mix(cewrapper.overrides, overrides);
832            }
833
834            if (el == win && type == "load") {
835
836                // if the load is complete, fire immediately.
837                // all subscribers, including the current one
838                // will be notified.
839                if (YUI.Env.windowLoaded) {
840                    fireNow = true;
841                }
842            }
843
844            if (compat) {
845                args.pop();
846            }
847
848            context = args[3];
849
850            // set context to the Node if not specified
851            // ret = cewrapper.on.apply(cewrapper, trimmedArgs);
852            ret = cewrapper._on(fn, context, (args.length > 4) ? args.slice(4) : null);
853
854            if (fireNow) {
855                cewrapper.fire();
856            }
857
858            return ret;
859
860        },
861
862        /**
863         * Removes an event listener.  Supports the signature the event was bound
864         * with, but the preferred way to remove listeners is using the handle
865         * that is returned when using Y.on
866         *
867         * @method detach
868         *
869         * @param {String} type the type of event to remove.
870         * @param {Function} fn the method the event invokes.  If fn is
871         * undefined, then all event handlers for the type of event are
872         * removed.
873         * @param {String|HTMLElement|Array|NodeList|EventHandle} el An
874         * event handle, an id, an element reference, or a collection
875         * of ids and/or elements to remove the listener from.
876         * @return {boolean} true if the unbind was successful, false otherwise.
877         * @static
878         */
879        detach: function(type, fn, el, obj) {
880
881            var args=Y.Array(arguments, 0, true), compat, l, ok, i,
882                id, ce;
883
884            if (args[args.length-1] === COMPAT_ARG) {
885                compat = true;
886                // args.pop();
887            }
888
889            if (type && type.detach) {
890                return type.detach();
891            }
892
893            // The el argument can be a string
894            if (typeof el == "string") {
895
896                // el = (compat) ? Y.DOM.byId(el) : Y.all(el);
897                if (compat) {
898                    el = Y.DOM.byId(el);
899                } else {
900                    el = Y.Selector.query(el);
901                    l = el.length;
902                    if (l < 1) {
903                        el = null;
904                    } else if (l == 1) {
905                        el = el[0];
906                    }
907                }
908                // return Event.detach.apply(Event, args);
909            }
910
911            if (!el) {
912                return false;
913            }
914
915            if (el.detach) {
916                args.splice(2, 1);
917                return el.detach.apply(el, args);
918            // The el argument can be an array of elements or element ids.
919            } else if (shouldIterate(el)) {
920                ok = true;
921                for (i=0, l=el.length; i<l; ++i) {
922                    args[2] = el[i];
923                    ok = ( Y.Event.detach.apply(Y.Event, args) && ok );
924                }
925
926                return ok;
927            }
928
929            if (!type || !fn || !fn.call) {
930                return Event.purgeElement(el, false, type);
931            }
932
933            id = 'event:' + Y.stamp(el) + type;
934            ce = _wrappers[id];
935
936            if (ce) {
937                return ce.detach(fn);
938            } else {
939                return false;
940            }
941
942        },
943
944        /**
945         * Finds the event in the window object, the caller's arguments, or
946         * in the arguments of another method in the callstack.  This is
947         * executed automatically for events registered through the event
948         * manager, so the implementer should not normally need to execute
949         * this function at all.
950         * @method getEvent
951         * @param {Event} e the event parameter from the handler
952         * @param {HTMLElement} el the element the listener was attached to
953         * @return {Event} the event
954         * @static
955         */
956        getEvent: function(e, el, noFacade) {
957            var ev = e || win.event;
958
959            return (noFacade) ? ev :
960                new Y.DOMEventFacade(ev, el, _wrappers['event:' + Y.stamp(el) + e.type]);
961        },
962
963        /**
964         * Generates an unique ID for the element if it does not already
965         * have one.
966         * @method generateId
967         * @param el the element to create the id for
968         * @return {string} the resulting id of the element
969         * @static
970         */
971        generateId: function(el) {
972            return Y.DOM.generateID(el);
973        },
974
975        /**
976         * We want to be able to use getElementsByTagName as a collection
977         * to attach a group of events to.  Unfortunately, different
978         * browsers return different types of collections.  This function
979         * tests to determine if the object is array-like.  It will also
980         * fail if the object is an array, but is empty.
981         * @method _isValidCollection
982         * @param o the object to test
983         * @return {boolean} true if the object is array-like and populated
984         * @deprecated was not meant to be used directly
985         * @static
986         * @private
987         */
988        _isValidCollection: shouldIterate,
989
990        /**
991         * hook up any deferred listeners
992         * @method _load
993         * @static
994         * @private
995         */
996        _load: function(e) {
997            if (!_loadComplete) {
998                _loadComplete = true;
999
1000                // Just in case DOMReady did not go off for some reason
1001                // E._ready();
1002                if (Y.fire) {
1003                    Y.fire(EVENT_READY);
1004                }
1005
1006                // Available elements may not have been detected before the
1007                // window load event fires. Try to find them now so that the
1008                // the user is more likely to get the onAvailable notifications
1009                // before the window load notification
1010                Event._poll();
1011            }
1012        },
1013
1014        /**
1015         * Polling function that runs before the onload event fires,
1016         * attempting to attach to DOM Nodes as soon as they are
1017         * available
1018         * @method _poll
1019         * @static
1020         * @private
1021         */
1022        _poll: function() {
1023            if (Event.locked) {
1024                return;
1025            }
1026
1027            if (Y.UA.ie && !YUI.Env.DOMReady) {
1028                // Hold off if DOMReady has not fired and check current
1029                // readyState to protect against the IE operation aborted
1030                // issue.
1031                Event.startInterval();
1032                return;
1033            }
1034
1035            Event.locked = true;
1036
1037            // keep trying until after the page is loaded.  We need to
1038            // check the page load state prior to trying to bind the
1039            // elements so that we can be certain all elements have been
1040            // tested appropriately
1041            var i, len, item, el, notAvail, executeItem,
1042                tryAgain = !_loadComplete;
1043
1044            if (!tryAgain) {
1045                tryAgain = (_retryCount > 0);
1046            }
1047
1048            // onAvailable
1049            notAvail = [];
1050
1051            executeItem = function (el, item) {
1052                var context, ov = item.override;
1053                if (item.compat) {
1054                    if (item.override) {
1055                        if (ov === true) {
1056                            context = item.obj;
1057                        } else {
1058                            context = ov;
1059                        }
1060                    } else {
1061                        context = el;
1062                    }
1063                    item.fn.call(context, item.obj);
1064                } else {
1065                    context = item.obj || Y.one(el);
1066                    item.fn.apply(context, (Y.Lang.isArray(ov)) ? ov : []);
1067                }
1068            };
1069
1070            // onAvailable
1071            for (i=0,len=_avail.length; i<len; ++i) {
1072                item = _avail[i];
1073                if (item && !item.checkReady) {
1074
1075                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
1076                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
1077
1078                    if (el) {
1079                        executeItem(el, item);
1080                        _avail[i] = null;
1081                    } else {
1082                        notAvail.push(item);
1083                    }
1084                }
1085            }
1086
1087            // onContentReady
1088            for (i=0,len=_avail.length; i<len; ++i) {
1089                item = _avail[i];
1090                if (item && item.checkReady) {
1091
1092                    // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id);
1093                    el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true);
1094
1095                    if (el) {
1096                        // The element is available, but not necessarily ready
1097                        // @todo should we test parentNode.nextSibling?
1098                        if (_loadComplete || (el.get && el.get('nextSibling')) || el.nextSibling) {
1099                            executeItem(el, item);
1100                            _avail[i] = null;
1101                        }
1102                    } else {
1103                        notAvail.push(item);
1104                    }
1105                }
1106            }
1107
1108            _retryCount = (notAvail.length === 0) ? 0 : _retryCount - 1;
1109
1110            if (tryAgain) {
1111                // we may need to strip the nulled out items here
1112                Event.startInterval();
1113            } else {
1114                clearInterval(Event._interval);
1115                Event._interval = null;
1116            }
1117
1118            Event.locked = false;
1119
1120            return;
1121
1122        },
1123
1124        /**
1125         * Removes all listeners attached to the given element via addListener.
1126         * Optionally, the node's children can also be purged.
1127         * Optionally, you can specify a specific type of event to remove.
1128         * @method purgeElement
1129         * @param {HTMLElement} el the element to purge
1130         * @param {boolean} recurse recursively purge this element's children
1131         * as well.  Use with caution.
1132         * @param {string} type optional type of listener to purge. If
1133         * left out, all listeners will be removed
1134         * @static
1135         */
1136        purgeElement: function(el, recurse, type) {
1137            // var oEl = (Y.Lang.isString(el)) ? Y.one(el) : el,
1138            var oEl = (Y.Lang.isString(el)) ?  Y.Selector.query(el, null, true) : el,
1139                lis = Event.getListeners(oEl, type), i, len, children, child;
1140
1141            if (recurse && oEl) {
1142                lis = lis || [];
1143                children = Y.Selector.query('*', oEl);
1144                i = 0;
1145                len = children.length;
1146                for (; i < len; ++i) {
1147                    child = Event.getListeners(children[i], type);
1148                    if (child) {
1149                        lis = lis.concat(child);
1150                    }
1151                }
1152            }
1153
1154            if (lis) {
1155                for (i = 0, len = lis.length; i < len; ++i) {
1156                    lis[i].detachAll();
1157                }
1158            }
1159
1160        },
1161
1162        /**
1163         * Removes all object references and the DOM proxy subscription for
1164         * a given event for a DOM node.
1165         *
1166         * @method _clean
1167         * @param wrapper {CustomEvent} Custom event proxy for the DOM
1168         *                  subscription
1169         * @private
1170         * @static
1171         * @since 3.4.0
1172         */
1173        _clean: function (wrapper) {
1174            var key    = wrapper.key,
1175                domkey = wrapper.domkey;
1176
1177            remove(wrapper.el, wrapper.type, wrapper.fn, wrapper.capture);
1178            delete _wrappers[key];
1179            delete Y._yuievt.events[key];
1180            if (_el_events[domkey]) {
1181                delete _el_events[domkey][key];
1182                if (!Y.Object.size(_el_events[domkey])) {
1183                    delete _el_events[domkey];
1184                }
1185            }
1186        },
1187
1188        /**
1189         * Returns all listeners attached to the given element via addListener.
1190         * Optionally, you can specify a specific type of event to return.
1191         * @method getListeners
1192         * @param el {HTMLElement|string} the element or element id to inspect
1193         * @param type {string} optional type of listener to return. If
1194         * left out, all listeners will be returned
1195         * @return {CustomEvent} the custom event wrapper for the DOM event(s)
1196         * @static
1197         */
1198        getListeners: function(el, type) {
1199            var ek = Y.stamp(el, true), evts = _el_events[ek],
1200                results=[] , key = (type) ? 'event:' + ek + type : null,
1201                adapters = _eventenv.plugins;
1202
1203            if (!evts) {
1204                return null;
1205            }
1206
1207            if (key) {
1208                // look for synthetic events
1209                if (adapters[type] && adapters[type].eventDef) {
1210                    key += '_synth';
1211                }
1212
1213                if (evts[key]) {
1214                    results.push(evts[key]);
1215                }
1216
1217                // get native events as well
1218                key += 'native';
1219                if (evts[key]) {
1220                    results.push(evts[key]);
1221                }
1222
1223            } else {
1224                Y.each(evts, function(v, k) {
1225                    results.push(v);
1226                });
1227            }
1228
1229            return (results.length) ? results : null;
1230        },
1231
1232        /**
1233         * Removes all listeners registered by pe.event.  Called
1234         * automatically during the unload event.
1235         * @method _unload
1236         * @static
1237         * @private
1238         */
1239        _unload: function(e) {
1240            Y.each(_wrappers, function(v, k) {
1241                if (v.type == 'unload') {
1242                    v.fire(e);
1243                }
1244                v.detachAll();
1245            });
1246            remove(win, "unload", onUnload);
1247        },
1248
1249        /**
1250         * Adds a DOM event directly without the caching, cleanup, context adj, etc
1251         *
1252         * @method nativeAdd
1253         * @param {HTMLElement} el      the element to bind the handler to
1254         * @param {string}      type   the type of event handler
1255         * @param {function}    fn      the callback to invoke
1256         * @param {boolen}      capture capture or bubble phase
1257         * @static
1258         * @private
1259         */
1260        nativeAdd: add,
1261
1262        /**
1263         * Basic remove listener
1264         *
1265         * @method nativeRemove
1266         * @param {HTMLElement} el      the element to bind the handler to
1267         * @param {string}      type   the type of event handler
1268         * @param {function}    fn      the callback to invoke
1269         * @param {boolen}      capture capture or bubble phase
1270         * @static
1271         * @private
1272         */
1273        nativeRemove: remove
1274    };
1275
1276}();
1277
1278Y.Event = Event;
1279
1280if (config.injected || YUI.Env.windowLoaded) {
1281    onLoad();
1282} else {
1283    add(win, "load", onLoad);
1284}
1285
1286// Process onAvailable/onContentReady items when when the DOM is ready in IE
1287if (Y.UA.ie) {
1288    Y.on(EVENT_READY, Event._poll);
1289}
1290
1291add(win, "unload", onUnload);
1292
1293Event.Custom = Y.CustomEvent;
1294Event.Subscriber = Y.Subscriber;
1295Event.Target = Y.EventTarget;
1296Event.Handle = Y.EventHandle;
1297Event.Facade = Y.EventFacade;
1298
1299Event._poll();
1300
1301})();
1302
1303/**
1304 * DOM event listener abstraction layer
1305 * @module event
1306 * @submodule event-base
1307 */
1308
1309/**
1310 * Executes the callback as soon as the specified element
1311 * is detected in the DOM.  This function expects a selector
1312 * string for the element(s) to detect.  If you already have
1313 * an element reference, you don't need this event.
1314 * @event available
1315 * @param type {string} 'available'
1316 * @param fn {function} the callback function to execute.
1317 * @param el {string} an selector for the element(s) to attach
1318 * @param context optional argument that specifies what 'this' refers to.
1319 * @param args* 0..n additional arguments to pass on to the callback function.
1320 * These arguments will be added after the event object.
1321 * @return {EventHandle} the detach handle
1322 * @for YUI
1323 */
1324Y.Env.evt.plugins.available = {
1325    on: function(type, fn, id, o) {
1326        var a = arguments.length > 4 ?  Y.Array(arguments, 4, true) : null;
1327        return Y.Event.onAvailable.call(Y.Event, id, fn, o, a);
1328    }
1329};
1330
1331/**
1332 * Executes the callback as soon as the specified element
1333 * is detected in the DOM with a nextSibling property
1334 * (indicating that the element's children are available).
1335 * This function expects a selector
1336 * string for the element(s) to detect.  If you already have
1337 * an element reference, you don't need this event.
1338 * @event contentready
1339 * @param type {string} 'contentready'
1340 * @param fn {function} the callback function to execute.
1341 * @param el {string} an selector for the element(s) to attach.
1342 * @param context optional argument that specifies what 'this' refers to.
1343 * @param args* 0..n additional arguments to pass on to the callback function.
1344 * These arguments will be added after the event object.
1345 * @return {EventHandle} the detach handle
1346 * @for YUI
1347 */
1348Y.Env.evt.plugins.contentready = {
1349    on: function(type, fn, id, o) {
1350        var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null;
1351        return Y.Event.onContentReady.call(Y.Event, id, fn, o, a);
1352    }
1353};
1354
1355
1356}, '3.4.0' ,{requires:['event-custom-base']});

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.