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