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