src/cm/media/js/lib/yui/yui_3.0.0b1/build/event-custom/event-custom-debug.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0b1
       
     6 build: 1163
       
     7 */
       
     8 YUI.add('event-custom', function(Y) {
       
     9 
       
    10 Y.Env.evt = {
       
    11     handles: {},
       
    12     plugins: {}
       
    13 };
       
    14 
       
    15 (function() {
       
    16 
       
    17 /**
       
    18  * Allows for the insertion of methods that are executed before or after
       
    19  * a specified method
       
    20  * @class Do
       
    21  * @static
       
    22  */
       
    23 
       
    24 var BEFORE = 0,
       
    25     AFTER = 1;
       
    26 
       
    27 Y.Do = {
       
    28 
       
    29     /**
       
    30      * Cache of objects touched by the utility
       
    31      * @property objs
       
    32      * @static
       
    33      */
       
    34     objs: {},
       
    35 
       
    36     /**
       
    37      * Execute the supplied method before the specified function
       
    38      * @method before
       
    39      * @param fn {Function} the function to execute
       
    40      * @param obj the object hosting the method to displace
       
    41      * @param sFn {string} the name of the method to displace
       
    42      * @param c The execution context for fn
       
    43      * @return {string} handle for the subscription
       
    44      * @static
       
    45      */
       
    46     before: function(fn, obj, sFn, c) {
       
    47         // Y.log('Do before: ' + sFn, 'info', 'event');
       
    48         var f = fn, a;
       
    49         if (c) {
       
    50             a = [fn, c].concat(Y.Array(arguments, 4, true));
       
    51             f = Y.rbind.apply(Y, a);
       
    52         }
       
    53 
       
    54         return this._inject(BEFORE, f, obj, sFn);
       
    55     },
       
    56 
       
    57     /**
       
    58      * Execute the supplied method after the specified function
       
    59      * @method after
       
    60      * @param fn {Function} the function to execute
       
    61      * @param obj the object hosting the method to displace
       
    62      * @param sFn {string} the name of the method to displace
       
    63      * @param c The execution context for fn
       
    64      * @return {string} handle for the subscription
       
    65      * @static
       
    66      */
       
    67     after: function(fn, obj, sFn, c) {
       
    68         var f = fn, a;
       
    69         if (c) {
       
    70             a = [fn, c].concat(Y.Array(arguments, 4, true));
       
    71             f = Y.rbind.apply(Y, a);
       
    72         }
       
    73 
       
    74         return this._inject(AFTER, f, obj, sFn);
       
    75     },
       
    76 
       
    77     /**
       
    78      * Execute the supplied method after the specified function
       
    79      * @method _inject
       
    80      * @param when {string} before or after
       
    81      * @param fn {Function} the function to execute
       
    82      * @param obj the object hosting the method to displace
       
    83      * @param sFn {string} the name of the method to displace
       
    84      * @param c The execution context for fn
       
    85      * @return {string} handle for the subscription
       
    86      * @private
       
    87      * @static
       
    88      */
       
    89     _inject: function(when, fn, obj, sFn) {
       
    90 
       
    91         // object id
       
    92         var id = Y.stamp(obj), o, sid;
       
    93 
       
    94         if (! this.objs[id]) {
       
    95             // create a map entry for the obj if it doesn't exist
       
    96             this.objs[id] = {};
       
    97         }
       
    98 
       
    99         o = this.objs[id];
       
   100 
       
   101         if (! o[sFn]) {
       
   102             // create a map entry for the method if it doesn't exist
       
   103             o[sFn] = new Y.Do.Method(obj, sFn);
       
   104 
       
   105             // re-route the method to our wrapper
       
   106             obj[sFn] = 
       
   107                 function() {
       
   108                     return o[sFn].exec.apply(o[sFn], arguments);
       
   109                 };
       
   110         }
       
   111 
       
   112         // subscriber id
       
   113         sid = id + Y.stamp(fn) + sFn;
       
   114 
       
   115         // register the callback
       
   116         o[sFn].register(sid, fn, when);
       
   117 
       
   118         return new Y.EventHandle(o[sFn], sid);
       
   119 
       
   120     },
       
   121 
       
   122     /**
       
   123      * Detach a before or after subscription
       
   124      * @method detach
       
   125      * @param handle {string} the subscription handle
       
   126      */
       
   127     detach: function(handle) {
       
   128 
       
   129         if (handle.detach) {
       
   130             handle.detach();
       
   131         }
       
   132 
       
   133     },
       
   134 
       
   135     _unload: function(e, me) {
       
   136 
       
   137     }
       
   138 };
       
   139 
       
   140 //////////////////////////////////////////////////////////////////////////
       
   141 
       
   142 /**
       
   143  * Wrapper for a displaced method with aop enabled
       
   144  * @class Do.Method
       
   145  * @constructor
       
   146  * @param obj The object to operate on
       
   147  * @param sFn The name of the method to displace
       
   148  */
       
   149 Y.Do.Method = function(obj, sFn) {
       
   150     this.obj = obj;
       
   151     this.methodName = sFn;
       
   152     this.method = obj[sFn];
       
   153     // this.before = [];
       
   154     // this.after = [];
       
   155     this.before = {};
       
   156     this.after = {};
       
   157 };
       
   158 
       
   159 /**
       
   160  * Register a aop subscriber
       
   161  * @method register
       
   162  * @param sid {string} the subscriber id
       
   163  * @param fn {Function} the function to execute
       
   164  * @param when {string} when to execute the function
       
   165  */
       
   166 Y.Do.Method.prototype.register = function (sid, fn, when) {
       
   167     if (when) {
       
   168         // this.after.push(fn);
       
   169         this.after[sid] = fn;
       
   170     } else {
       
   171         // this.before.push(fn);
       
   172         this.before[sid] = fn;
       
   173     }
       
   174 };
       
   175 
       
   176 /**
       
   177  * Unregister a aop subscriber
       
   178  * @method delete
       
   179  * @param sid {string} the subscriber id
       
   180  * @param fn {Function} the function to execute
       
   181  * @param when {string} when to execute the function
       
   182  */
       
   183 Y.Do.Method.prototype._delete = function (sid) {
       
   184     // Y.log('Y.Do._delete: ' + sid, 'info', 'Event');
       
   185     delete this.before[sid];
       
   186     delete this.after[sid];
       
   187 };
       
   188 
       
   189 /**
       
   190  * Execute the wrapped method
       
   191  * @method exec
       
   192  */
       
   193 Y.Do.Method.prototype.exec = function () {
       
   194 
       
   195     var args = Y.Array(arguments, 0, true), 
       
   196         i, ret, newRet, 
       
   197         bf = this.before,
       
   198         af = this.after,
       
   199         prevented = false;
       
   200 
       
   201     // execute before
       
   202     for (i in bf) {
       
   203         if (bf.hasOwnProperty(i)) {
       
   204             ret = bf[i].apply(this.obj, args);
       
   205             if (ret) {
       
   206                 switch (ret.constructor) {
       
   207                     case Y.Do.Halt:
       
   208                         return ret.retVal;
       
   209                     case Y.Do.AlterArgs:
       
   210                         args = ret.newArgs;
       
   211                         break;
       
   212                     case Y.Do.Prevent:
       
   213                         prevented = true;
       
   214                         break;
       
   215                     default:
       
   216                 }
       
   217             }
       
   218         }
       
   219     }
       
   220 
       
   221     // execute method
       
   222     if (!prevented) {
       
   223         ret = this.method.apply(this.obj, args);
       
   224     }
       
   225 
       
   226     // execute after methods.
       
   227     for (i in af) {
       
   228         if (af.hasOwnProperty(i)) {
       
   229             newRet = af[i].apply(this.obj, args);
       
   230             // Stop processing if a Halt object is returned
       
   231             if (newRet && newRet.constructor == Y.Do.Halt) {
       
   232                 return newRet.retVal;
       
   233             // Check for a new return value
       
   234             } else if (newRet && newRet.constructor == Y.Do.AlterReturn) {
       
   235                 ret = newRet.newRetVal;
       
   236             }
       
   237         }
       
   238     }
       
   239 
       
   240     return ret;
       
   241 };
       
   242 
       
   243 //////////////////////////////////////////////////////////////////////////
       
   244 
       
   245 
       
   246 /**
       
   247  * Return an AlterArgs object when you want to change the arguments that
       
   248  * were passed into the function.  An example would be a service that scrubs
       
   249  * out illegal characters prior to executing the core business logic.
       
   250  * @class Do.AlterArgs
       
   251  */
       
   252 Y.Do.AlterArgs = function(msg, newArgs) {
       
   253     this.msg = msg;
       
   254     this.newArgs = newArgs;
       
   255 };
       
   256 
       
   257 /**
       
   258  * Return an AlterReturn object when you want to change the result returned
       
   259  * from the core method to the caller
       
   260  * @class Do.AlterReturn
       
   261  */
       
   262 Y.Do.AlterReturn = function(msg, newRetVal) {
       
   263     this.msg = msg;
       
   264     this.newRetVal = newRetVal;
       
   265 };
       
   266 
       
   267 /**
       
   268  * Return a Halt object when you want to terminate the execution
       
   269  * of all subsequent subscribers as well as the wrapped method
       
   270  * if it has not exectued yet.
       
   271  * @class Do.Halt
       
   272  */
       
   273 Y.Do.Halt = function(msg, retVal) {
       
   274     this.msg = msg;
       
   275     this.retVal = retVal;
       
   276 };
       
   277 
       
   278 /**
       
   279  * Return a Prevent object when you want to prevent the wrapped function
       
   280  * from executing, but want the remaining listeners to execute
       
   281  * @class Do.Prevent
       
   282  */
       
   283 Y.Do.Prevent = function(msg) {
       
   284     this.msg = msg;
       
   285 };
       
   286 
       
   287 /**
       
   288  * Return an Error object when you want to terminate the execution
       
   289  * of all subsequent method calls.
       
   290  * @class Do.Error
       
   291  * @deprecated use Y.Do.Halt or Y.Do.Prevent
       
   292  */
       
   293 Y.Do.Error = Y.Do.Halt;
       
   294 
       
   295 //////////////////////////////////////////////////////////////////////////
       
   296 
       
   297 // Y["Event"] && Y.Event.addListener(window, "unload", Y.Do._unload, Y.Do);
       
   298 
       
   299 })();
       
   300 (function() {
       
   301 
       
   302 /**
       
   303  * Wraps and protects a custom event for use when emitFacade is set to true.
       
   304  * @class EventFacade
       
   305  * @param e {Event} the custom event
       
   306  * @param currentTarget {HTMLElement} the element the listener was attached to
       
   307  */
       
   308 
       
   309 /*
       
   310 var PROPS = {
       
   311     details: 1,
       
   312     type: 1,
       
   313     target: 1,
       
   314     currentTarget: 1,
       
   315     stopPropagation: 2,
       
   316     stopImmediatePropagation: 2,
       
   317     preventDefault: 2,
       
   318     halt: 2
       
   319 };
       
   320 
       
   321 Y.EventFacade = function(e, currentTarget) {
       
   322     if (e) {
       
   323         Y.Object.each(PROPS, function(v, k) {
       
   324             //this[k] = (v == 2) ? e[k].apply(e, arguments) : e[k];
       
   325             var val = e[k];
       
   326             if (val) {
       
   327                 this[k] = (v == 2) ? function() {
       
   328                     if (val) {
       
   329                         val.apply(e, arguments);
       
   330                     }
       
   331                 } : val;
       
   332             } else {
       
   333                 console.log('missing ' + k);
       
   334             }
       
   335         });
       
   336     }
       
   337 };
       
   338 */
       
   339 
       
   340 Y.EventFacade = function(e, currentTarget) {
       
   341 
       
   342     e = e || {};
       
   343 
       
   344     /**
       
   345      * The arguments passed to fire 
       
   346      * @property details
       
   347      * @type Array
       
   348      */
       
   349     this.details = e.details;
       
   350 
       
   351     /**
       
   352      * The event type
       
   353      * @property type
       
   354      * @type string
       
   355      */
       
   356     this.type = e.type;
       
   357 
       
   358     //////////////////////////////////////////////////////
       
   359 
       
   360     /**
       
   361      * Node reference for the targeted eventtarget
       
   362      * @propery target
       
   363      * @type Node
       
   364      */
       
   365     this.target = e.target;
       
   366 
       
   367     /**
       
   368      * Node reference for the element that the listener was attached to.
       
   369      * @propery currentTarget
       
   370      * @type Node
       
   371      */
       
   372     this.currentTarget = currentTarget;
       
   373 
       
   374     /**
       
   375      * Node reference to the relatedTarget
       
   376      * @propery relatedTarget
       
   377      * @type Node
       
   378      */
       
   379     this.relatedTarget = e.relatedTarget;
       
   380     
       
   381     /**
       
   382      * Stops the propagation to the next bubble target
       
   383      * @method stopPropagation
       
   384      */
       
   385     this.stopPropagation = function() {
       
   386         e.stopPropagation();
       
   387     };
       
   388 
       
   389     /**
       
   390      * Stops the propagation to the next bubble target and
       
   391      * prevents any additional listeners from being exectued
       
   392      * on the current target.
       
   393      * @method stopImmediatePropagation
       
   394      */
       
   395     this.stopImmediatePropagation = function() {
       
   396         e.stopImmediatePropagation();
       
   397     };
       
   398 
       
   399     /**
       
   400      * Prevents the event's default behavior
       
   401      * @method preventDefault
       
   402      */
       
   403     this.preventDefault = function() {
       
   404         e.preventDefault();
       
   405     };
       
   406 
       
   407     /**
       
   408      * Stops the event propagation and prevents the default
       
   409      * event behavior.
       
   410      * @method halt
       
   411      * @param immediate {boolean} if true additional listeners
       
   412      * on the current target will not be executed
       
   413      */
       
   414     this.halt = function(immediate) {
       
   415         e.halt(immediate);
       
   416     };
       
   417 
       
   418 };
       
   419 
       
   420 })();
       
   421 
       
   422 /**
       
   423  * Custom event engine, DOM event listener abstraction layer, synthetic DOM 
       
   424  * events.
       
   425  * @module event-custom
       
   426  */
       
   427 
       
   428 /**
       
   429  * Return value from all subscribe operations
       
   430  * @class EventHandle
       
   431  * @constructor
       
   432  * @param evt {CustomEvent} the custom event
       
   433  * @param sub {Subscriber} the subscriber
       
   434  */
       
   435 
       
   436 // var onsubscribeType = "_event:onsub",
       
   437 var AFTER = 'after', 
       
   438     CONFIGS = [
       
   439         'broadcast',
       
   440         'bubbles',
       
   441         'context',
       
   442         'contextFn',
       
   443         'configured',
       
   444         'currentTarget',
       
   445         'defaultFn',
       
   446         'details',
       
   447         'emitFacade',
       
   448         'fireOnce',
       
   449         'host',
       
   450         'preventable',
       
   451         'preventedFn',
       
   452         'queuable',
       
   453         'silent',
       
   454         'stoppedFn',
       
   455         'target',
       
   456         'type'
       
   457     ],
       
   458 
       
   459     FACADE = new Y.EventFacade(),
       
   460 
       
   461     FACADE_KEYS = Y.Object.keys(FACADE),
       
   462 
       
   463     YUI3_SIGNATURE = 9,
       
   464     YUI_LOG = 'yui:log';
       
   465 
       
   466 Y.EventHandle = function(evt, sub) {
       
   467 
       
   468     /**
       
   469      * The custom event
       
   470      * @type CustomEvent
       
   471      */
       
   472     this.evt = evt;
       
   473 
       
   474     /**
       
   475      * The subscriber object
       
   476      * @type Subscriber
       
   477      */
       
   478     this.sub = sub;
       
   479 };
       
   480 
       
   481 Y.EventHandle.prototype = {
       
   482 
       
   483     /**
       
   484      * Detaches this subscriber
       
   485      * @method detach
       
   486      */
       
   487     detach: function() {
       
   488         if (this.evt) {
       
   489             // Y.log('EventHandle.detach: ' + this.sub, 'info', 'Event');
       
   490             this.evt._delete(this.sub);
       
   491         }
       
   492     }
       
   493 };
       
   494 
       
   495 /**
       
   496  * The CustomEvent class lets you define events for your application
       
   497  * that can be subscribed to by one or more independent component.
       
   498  *
       
   499  * @param {String}  type The type of event, which is passed to the callback
       
   500  *                  when the event fires
       
   501  * @param o configuration object
       
   502  * @class CustomEvent
       
   503  * @constructor
       
   504  */
       
   505 Y.CustomEvent = function(type, o) {
       
   506 
       
   507     // if (arguments.length > 2) {
       
   508 // this.log('CustomEvent context and silent are now in the config', 'warn', 'Event');
       
   509     // }
       
   510 
       
   511     o = o || {};
       
   512 
       
   513     this.id = Y.stamp(this);
       
   514 
       
   515     /**
       
   516      * The type of event, returned to subscribers when the event fires
       
   517      * @property type
       
   518      * @type string
       
   519      */
       
   520     this.type = type;
       
   521 
       
   522     /**
       
   523      * The context the the event will fire from by default.  Defaults to the YUI
       
   524      * instance.
       
   525      * @property context
       
   526      * @type object
       
   527      */
       
   528     this.context = Y;
       
   529 
       
   530     this.logSystem = (type == YUI_LOG);
       
   531 
       
   532     /**
       
   533      * If 0, this event does not broadcast.  If 1, the YUI instance is notified
       
   534      * every time this event fires.  If 2, the YUI instance and the YUI global
       
   535      * (if event is enabled on the global) are notified every time this event
       
   536      * fires.
       
   537      * @property broadcast
       
   538      * @type int
       
   539      */
       
   540     // this.broadcast = 0;
       
   541 
       
   542     /**
       
   543      * By default all custom events are logged in the debug build, set silent
       
   544      * to true to disable debug outpu for this event.
       
   545      * @property silent
       
   546      * @type boolean
       
   547      */
       
   548     this.silent = this.logSystem;
       
   549 
       
   550     // this.queuable = false;
       
   551 
       
   552     /**
       
   553      * The subscribers to this event
       
   554      * @property subscribers
       
   555      * @type Subscriber{}
       
   556      */
       
   557     this.subscribers = {};
       
   558 
       
   559     /*
       
   560      * The publisher has configured this event
       
   561      * @property configured
       
   562      * @type boolean
       
   563      * @default true
       
   564      */
       
   565     // this.configured = true;
       
   566 
       
   567     /**
       
   568      * 'After' subscribers
       
   569      * @property afters
       
   570      * @type Subscriber{}
       
   571      */
       
   572     this.afters = {};
       
   573 
       
   574     /**
       
   575      * This event has fired if true
       
   576      *
       
   577      * @property fired
       
   578      * @type boolean
       
   579      * @default false;
       
   580      */
       
   581     // this.fired = false;
       
   582 
       
   583     /**
       
   584      * This event should only fire one time if true, and if
       
   585      * it has fired, any new subscribers should be notified
       
   586      * immediately.
       
   587      *
       
   588      * @property fireOnce
       
   589      * @type boolean
       
   590      * @default false;
       
   591      */
       
   592     // this.fireOnce = false;
       
   593 
       
   594     /**
       
   595      * Flag for stopPropagation that is modified during fire()
       
   596      * 1 means to stop propagation to bubble targets.  2 means
       
   597      * to also stop additional subscribers on this target.
       
   598      * @property stopped
       
   599      * @type int
       
   600      */
       
   601     // this.stopped = 0;
       
   602 
       
   603     /**
       
   604      * Flag for preventDefault that is modified during fire().
       
   605      * if it is not 0, the default behavior for this event
       
   606      * @property prevented
       
   607      * @type int
       
   608      */
       
   609     // this.prevented = 0;
       
   610 
       
   611     /**
       
   612      * Specifies the host for this custom event.  This is used
       
   613      * to enable event bubbling
       
   614      * @property host
       
   615      * @type EventTarget
       
   616      */
       
   617     // this.host = null;
       
   618 
       
   619     /**
       
   620      * The default function to execute after event listeners
       
   621      * have fire, but only if the default action was not
       
   622      * prevented.
       
   623      * @property defaultFn
       
   624      * @type Function
       
   625      */
       
   626     // this.defaultFn = null;
       
   627 
       
   628     /**
       
   629      * The function to execute if a subscriber calls
       
   630      * stopPropagation or stopImmediatePropagation
       
   631      * @property stoppedFn
       
   632      * @type Function
       
   633      */
       
   634     // this.stoppedFn = null;
       
   635 
       
   636     /**
       
   637      * The function to execute if a subscriber calls
       
   638      * preventDefault
       
   639      * @property preventedFn
       
   640      * @type Function
       
   641      */
       
   642     // this.preventedFn = null;
       
   643 
       
   644     /**
       
   645      * Specifies whether or not this event's default function
       
   646      * can be cancelled by a subscriber by executing preventDefault() 
       
   647      * on the event facade 
       
   648      * @property preventable 
       
   649      * @type boolean 
       
   650      * @default true
       
   651      */
       
   652     this.preventable = true;
       
   653 
       
   654     /**
       
   655      * Specifies whether or not a subscriber can stop the event propagation
       
   656      * via stopPropagation(), stopImmediatePropagation(), or halt()
       
   657      * @property bubbles
       
   658      * @type boolean
       
   659      * @default true
       
   660      */
       
   661     this.bubbles = true;
       
   662 
       
   663     /**
       
   664      * Supports multiple options for listener signatures in order to
       
   665      * port YUI 2 apps.
       
   666      * @property signature
       
   667      * @type int
       
   668      * @default 9
       
   669      */
       
   670     this.signature = YUI3_SIGNATURE;
       
   671 
       
   672     // this.hasSubscribers = false;
       
   673 
       
   674     // this.hasAfters = false;
       
   675 
       
   676     /**
       
   677      * If set to true, the custom event will deliver an EventFacade object
       
   678      * that is similar to a DOM event object.
       
   679      * @property emitFacade
       
   680      * @type boolean
       
   681      * @default false
       
   682      */
       
   683     // this.emitFacade = false;
       
   684 
       
   685     this.applyConfig(o, true);
       
   686 
       
   687     // this.log("Creating " + this.type);
       
   688 
       
   689 };
       
   690 
       
   691 Y.CustomEvent.prototype = {
       
   692 
       
   693     _YUI_EVENT: true,
       
   694 
       
   695     /**
       
   696      * Apply configuration properties.  Only applies the CONFIG whitelist
       
   697      * @method applyConfig
       
   698      * @param o hash of properties to apply
       
   699      * @param force {boolean} if true, properties that exist on the event 
       
   700      * will be overwritten.
       
   701      */
       
   702     applyConfig: function(o, force) {
       
   703         if (o) {
       
   704             Y.mix(this, o, force, CONFIGS);
       
   705         }
       
   706     },
       
   707 
       
   708     _on: function(fn, context, args, when) {
       
   709 
       
   710         if (!fn) {
       
   711             Y.error("Invalid callback for CE: " + this.type);
       
   712         }
       
   713 
       
   714         var s = new Y.Subscriber(fn, context, args, when);
       
   715 
       
   716         if (this.fireOnce && this.fired) {
       
   717             Y.later(0, this, this._notify, s);
       
   718         }
       
   719 
       
   720         if (when == AFTER) {
       
   721             this.afters[s.id] = s;
       
   722             this.hasAfters = true;
       
   723         } else {
       
   724             this.subscribers[s.id] = s;
       
   725             this.hasSubscribers = true;
       
   726         }
       
   727 
       
   728         return new Y.EventHandle(this, s);
       
   729 
       
   730     },
       
   731 
       
   732     /**
       
   733      * Listen for this event
       
   734      * @method subscribe
       
   735      * @param {Function} fn        The function to execute
       
   736      * @return {EventHandle|EventTarget} unsubscribe handle or a
       
   737      * chainable event target depending on the 'chain' config.
       
   738      * @deprecated use on
       
   739      */
       
   740     subscribe: function(fn, context) {
       
   741         var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
       
   742         return this._on(fn, context, a, true);
       
   743     },
       
   744 
       
   745     /**
       
   746      * Listen for this event
       
   747      * @method on
       
   748      * @param {Function} fn        The function to execute
       
   749      * @return {EventHandle|EventTarget} unsubscribe handle or a
       
   750      * chainable event target depending on the 'chain' config.
       
   751      */
       
   752     on: function(fn, context) {
       
   753         var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
       
   754         return this._on(fn, context, a, true);
       
   755     },
       
   756 
       
   757     /**
       
   758      * Listen for this event after the normal subscribers have been notified and
       
   759      * the default behavior has been applied.  If a normal subscriber prevents the 
       
   760      * default behavior, it also prevents after listeners from firing.
       
   761      * @method after
       
   762      * @param {Function} fn        The function to execute
       
   763      * @return {EventHandle|EventTarget} unsubscribe handle or a
       
   764      * chainable event target depending on the 'chain' config.
       
   765      */
       
   766     after: function(fn, context) {
       
   767         var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
       
   768         return this._on(fn, context, a, AFTER);
       
   769     },
       
   770 
       
   771     /**
       
   772      * Detach listeners.
       
   773      * @method detach 
       
   774      * @param {Function} fn  The subscribed function to remove, if not supplied
       
   775      *                       all will be removed
       
   776      * @param {Object}   context The context object passed to subscribe.
       
   777      * @return {boolean|EventTarget} returns a chainable event target
       
   778      * or a boolean for legacy detach support.
       
   779      */
       
   780     detach: function(fn, context) {
       
   781 
       
   782         // if arg[0] typeof unsubscribe handle
       
   783         if (fn && fn.detach) {
       
   784             return fn.detach();
       
   785         }
       
   786 
       
   787         if (!fn) {
       
   788             return this.unsubscribeAll();
       
   789         }
       
   790 
       
   791         var found = false, subs = this.subscribers, i, s;
       
   792 
       
   793         for (i in subs) {
       
   794             if (subs.hasOwnProperty(i)) {
       
   795                 s = subs[i];
       
   796                 if (s && s.contains(fn, context)) {
       
   797                     this._delete(s);
       
   798                     found = true;
       
   799                 }
       
   800             }
       
   801         }
       
   802 
       
   803         return found;
       
   804     },
       
   805 
       
   806     /**
       
   807      * Detach listeners.
       
   808      * @method unsubscribe
       
   809      * @param {Function} fn  The subscribed function to remove, if not supplied
       
   810      *                       all will be removed
       
   811      * @param {Object}   context The context object passed to subscribe.
       
   812      * @return {boolean|EventTarget} returns a chainable event target
       
   813      * or a boolean for legacy detach support.
       
   814      * @deprecated use detach
       
   815      */
       
   816     unsubscribe: function() {
       
   817         return this.detach.apply(this, arguments);
       
   818     },
       
   819 
       
   820     _getFacade: function() {
       
   821 
       
   822         var ef = this._facade, o, args = this.details, o2;
       
   823 
       
   824         if (!ef) {
       
   825             ef = new Y.EventFacade(this, this.currentTarget);
       
   826         }
       
   827 
       
   828         // if the first argument is an object literal, apply the
       
   829         // properties to the event facade
       
   830         o = args && args[0];
       
   831 
       
   832         if (Y.Lang.isObject(o, true)) {
       
   833 
       
   834             o2 = {};
       
   835 
       
   836             // protect the event facade properties
       
   837             Y.mix(o2, ef, true, FACADE_KEYS);
       
   838 
       
   839             // mix the data
       
   840             Y.mix(ef, o, true);
       
   841 
       
   842             // restore ef
       
   843             Y.mix(ef, o2, true, FACADE_KEYS);
       
   844         }
       
   845 
       
   846         // update the details field with the arguments
       
   847         // ef.type = this.type;
       
   848         ef.details = this.details;
       
   849         ef.target = this.target;
       
   850         ef.currentTarget = this.currentTarget;
       
   851         ef.stopped = 0;
       
   852         ef.prevented = 0;
       
   853 
       
   854         this._facade = ef;
       
   855 
       
   856         return this._facade;
       
   857     },
       
   858 
       
   859     /**
       
   860      * Notify a single subscriber
       
   861      * @method _notify
       
   862      * @param s {Subscriber} the subscriber
       
   863      * @param args {Array} the arguments array to apply to the listener
       
   864      * @private
       
   865      */
       
   866     _notify: function(s, args, ef) {
       
   867 
       
   868         this.log(this.type + "->" + ": " +  s);
       
   869 
       
   870         var ret;
       
   871 
       
   872         // emit an EventFacade if this is that sort of event
       
   873         if (this.emitFacade) {
       
   874 
       
   875             // @TODO object literal support to fire makes it possible for
       
   876             // config info to be passed if we wish.
       
   877             
       
   878             if (!ef) {
       
   879                 ef = this._getFacade(args);
       
   880 
       
   881                 if (Y.Lang.isObject(args[0])) {
       
   882                     args[0] = ef;
       
   883                 } else {
       
   884                     args.unshift(ef);
       
   885                 }
       
   886             }
       
   887         }
       
   888 
       
   889         ret = s.notify(args, this);
       
   890 
       
   891         if (false === ret || this.stopped > 1) {
       
   892             this.log(this.type + " cancelled by subscriber");
       
   893             return false;
       
   894         }
       
   895 
       
   896         return true;
       
   897     },
       
   898 
       
   899     /**
       
   900      * Logger abstraction to centralize the application of the silent flag
       
   901      * @method log
       
   902      * @param msg {string} message to log
       
   903      * @param cat {string} log category
       
   904      */
       
   905     log: function(msg, cat) {
       
   906         if (!this.silent) {
       
   907             Y.log(this.id + ': ' + msg, cat || "info", "event");
       
   908         }
       
   909     },
       
   910 
       
   911     /**
       
   912      * Notifies the subscribers.  The callback functions will be executed
       
   913      * from the context specified when the event was created, and with the 
       
   914      * following parameters:
       
   915      *   <ul>
       
   916      *   <li>The type of event</li>
       
   917      *   <li>All of the arguments fire() was executed with as an array</li>
       
   918      *   <li>The custom object (if any) that was passed into the subscribe() 
       
   919      *       method</li>
       
   920      *   </ul>
       
   921      * @method fire 
       
   922      * @param {Object*} arguments an arbitrary set of parameters to pass to 
       
   923      *                            the handler.
       
   924      * @return {boolean} false if one of the subscribers returned false, 
       
   925      *                   true otherwise
       
   926      */
       
   927     fire: function() {
       
   928 
       
   929         var es = Y.Env._eventstack,
       
   930             subs, s, args, i, ef, q, queue, ce, hasSub,
       
   931             ret = true, events;
       
   932 
       
   933         // @TODO find a better way to short circuit this.  
       
   934         // if (!this.broadcast && !this.defaultFn && !this.hasSubscribers && !this.hasAfters) {
       
   935         //     return true;
       
   936         // }
       
   937 
       
   938         if (es) {
       
   939 
       
   940             // queue this event if the current item in the queue bubbles
       
   941             // if (b && this.queuable && this.type != es.next.type) {
       
   942             if (this.queuable && this.type != es.next.type) {
       
   943 
       
   944                 this.log('queue ' + this.type);
       
   945 
       
   946                 es.queue.push([this, arguments]);
       
   947                 return true;
       
   948             }
       
   949 
       
   950         } else {
       
   951 
       
   952             Y.Env._eventstack = {
       
   953                // id of the first event in the stack
       
   954                id: this.id,
       
   955                next: this,
       
   956                silent: this.silent,
       
   957                logging: (this.type === YUI_LOG),
       
   958                stopped: 0,
       
   959                prevented: 0,
       
   960                queue: []
       
   961             };
       
   962 
       
   963             es = Y.Env._eventstack;
       
   964         }
       
   965 
       
   966         if (this.fireOnce && this.fired) {
       
   967 
       
   968             this.log('fireOnce event: ' + this.type + ' already fired');
       
   969 
       
   970         } else {
       
   971 
       
   972             args = Y.Array(arguments, 0, true);
       
   973 
       
   974             this.stopped = 0;
       
   975             this.prevented = 0;
       
   976             this.target = this.target || this.host;
       
   977 
       
   978             events = new Y.EventTarget({
       
   979                 fireOnce: true,
       
   980                 context: this.host
       
   981             });
       
   982 
       
   983             this.events = events;
       
   984 
       
   985             if (this.preventedFn) {
       
   986                 events.on('prevented', this.preventedFn);
       
   987             }
       
   988 
       
   989             if (this.stoppedFn) {
       
   990                 events.on('stopped', this.stoppedFn);
       
   991             }
       
   992 
       
   993             this.currentTarget = this.host || this.currentTarget;
       
   994 
       
   995             this.fired = true;
       
   996             this.details = args.slice(); // original arguments in the details
       
   997 
       
   998             // this.log("Firing " + this  + ", " + "args: " + args);
       
   999             this.log("Firing " + this.type);
       
  1000 
       
  1001             hasSub = false;
       
  1002             es.lastLogState = es.logging;
       
  1003             ef = null;
       
  1004 
       
  1005             if (this.emitFacade) {
       
  1006 
       
  1007                 // this.fire({
       
  1008                 //   foo: 1
       
  1009                 //   bar: 2
       
  1010                 // }
       
  1011                 // this.fire({
       
  1012                 //   bar: 2
       
  1013                 // } // foo is still 1 unless we create a new facade
       
  1014                 this._facade = null;
       
  1015 
       
  1016                 ef = this._getFacade(args);
       
  1017 
       
  1018                 if (Y.Lang.isObject(args[0])) {
       
  1019                     args[0] = ef;
       
  1020                 } else {
       
  1021                     args.unshift(ef);
       
  1022                 }
       
  1023             }
       
  1024 
       
  1025             if (this.hasSubscribers) {
       
  1026                 subs = Y.merge(this.subscribers);
       
  1027 
       
  1028                 for (i in subs) {
       
  1029                     if (subs.hasOwnProperty(i)) {
       
  1030 
       
  1031                         if (!hasSub) {
       
  1032                             es.logging = (es.logging || (this.type === YUI_LOG));
       
  1033                             hasSub = true;
       
  1034                         }
       
  1035 
       
  1036                         // stopImmediatePropagation
       
  1037                         if (this.stopped == 2) {
       
  1038                             break;
       
  1039                         }
       
  1040 
       
  1041                         s = subs[i];
       
  1042                         if (s && s.fn) {
       
  1043                             ret = this._notify(s, args, ef);
       
  1044                             if (false === ret) {
       
  1045                                 this.stopped = 2;
       
  1046                             }
       
  1047                         }
       
  1048                     }
       
  1049                 }
       
  1050             }
       
  1051 
       
  1052             es.logging = (es.lastLogState);
       
  1053 
       
  1054             // bubble if this is hosted in an event target and propagation has not been stopped
       
  1055             if (this.bubbles && this.host && !this.stopped) {
       
  1056                 es.stopped = 0;
       
  1057                 es.prevented = 0;
       
  1058                 ret = this.host.bubble(this);
       
  1059 
       
  1060                 this.stopped = Math.max(this.stopped, es.stopped);
       
  1061                 this.prevented = Math.max(this.prevented, es.prevented);
       
  1062 
       
  1063             }
       
  1064 
       
  1065             // execute the default behavior if not prevented
       
  1066             if (this.defaultFn && !this.prevented) {
       
  1067                 this.defaultFn.apply(this.host || this, args);
       
  1068             }
       
  1069 
       
  1070             // broadcast listeners are fired as discreet events on the
       
  1071             // YUI instance and potentially the YUI global.
       
  1072             if (!this.stopped && this.broadcast) {
       
  1073 
       
  1074                 if (this.host !== Y) {
       
  1075                     Y.fire.apply(Y, args);
       
  1076                 }
       
  1077 
       
  1078                 if (this.broadcast == 2) {
       
  1079                     Y.Global.fire.apply(Y.Global, args);
       
  1080                 }
       
  1081             }
       
  1082 
       
  1083             // process after listeners.  If the default behavior was
       
  1084             // prevented, the after events don't fire.
       
  1085             if (this.hasAfters && !this.prevented && this.stopped < 2) {
       
  1086                 subs = Y.merge(this.afters);
       
  1087                 for (i in subs) {
       
  1088                     if (subs.hasOwnProperty(i)) {
       
  1089 
       
  1090                         if (!hasSub) {
       
  1091                             es.logging = (es.logging || (this.type === YUI_LOG));
       
  1092                             hasSub = true;
       
  1093                         }
       
  1094 
       
  1095                         // stopImmediatePropagation
       
  1096                         if (this.stopped == 2) {
       
  1097                             break;
       
  1098                         }
       
  1099 
       
  1100                         s = subs[i];
       
  1101                         if (s && s.fn) {
       
  1102                             ret = this._notify(s, args, ef);
       
  1103                             if (false === ret) {
       
  1104                                 this.stopped = 2;
       
  1105                             }
       
  1106                         }
       
  1107                     }
       
  1108                 }
       
  1109             }
       
  1110         }
       
  1111 
       
  1112         if (es.id === this.id) {
       
  1113 // console.log('clearing stack: ' + es.id + ', ' + this);
       
  1114 
       
  1115 // reset propragation properties while processing the rest of the queue
       
  1116 
       
  1117 // process queued events
       
  1118             queue = es.queue;
       
  1119 
       
  1120             while (queue.length) {
       
  1121                 // q[0] = the event, q[1] = arguments to fire
       
  1122                 q = queue.pop(); 
       
  1123                 ce = q[0];
       
  1124 
       
  1125 // Y.log('firing queued event ' + ce.type + ', from ' + this);
       
  1126                 es.stopped = 0;
       
  1127                 es.prevented = 0;
       
  1128                 
       
  1129 // set up stack to allow the next item to be processed
       
  1130                 es.next = ce;
       
  1131 
       
  1132                 ret = ce.fire.apply(ce, q[1]);
       
  1133             }
       
  1134 
       
  1135             Y.Env._eventstack = null;
       
  1136         } 
       
  1137 
       
  1138         return (ret !== false);
       
  1139     },
       
  1140 
       
  1141     /**
       
  1142      * Removes all listeners
       
  1143      * @method unsubscribeAll
       
  1144      * @return {int} The number of listeners unsubscribed
       
  1145      * @deprecated use detachAll
       
  1146      */
       
  1147     unsubscribeAll: function() {
       
  1148         return this.detachAll.apply(this, arguments);
       
  1149     },
       
  1150 
       
  1151     /**
       
  1152      * Removes all listeners
       
  1153      * @method detachAll
       
  1154      * @return {int} The number of listeners unsubscribed
       
  1155      */
       
  1156     detachAll: function() {
       
  1157         var subs = this.subscribers, i, l=0;
       
  1158         for (i in subs) {
       
  1159             if (subs.hasOwnProperty(i)) {
       
  1160                 this._delete(subs[i]);
       
  1161                 l++;
       
  1162             }
       
  1163         }
       
  1164 
       
  1165         this.subscribers={};
       
  1166 
       
  1167         return l;
       
  1168     },
       
  1169 
       
  1170     /**
       
  1171      * @method _delete
       
  1172      * @param subscriber object
       
  1173      * @private
       
  1174      */
       
  1175     _delete: function(s) {
       
  1176 
       
  1177         if (s) {
       
  1178             delete s.fn;
       
  1179             delete s.context;
       
  1180             delete this.subscribers[s.id];
       
  1181             delete this.afters[s.id];
       
  1182         }
       
  1183 
       
  1184     },
       
  1185 
       
  1186     /**
       
  1187      * @method toString
       
  1188      */
       
  1189     toString: function() {
       
  1190          return this.type;
       
  1191     },
       
  1192 
       
  1193     /**
       
  1194      * Stop propagation to bubble targets
       
  1195      * @method stopPropagation
       
  1196      */
       
  1197     stopPropagation: function() {
       
  1198         this.stopped = 1;
       
  1199         Y.Env._eventstack.stopped = 1;
       
  1200         this.events.fire('stopped', this);
       
  1201     },
       
  1202 
       
  1203     /**
       
  1204      * Stops propagation to bubble targets, and prevents any remaining
       
  1205      * subscribers on the current target from executing.
       
  1206      * @method stopImmediatePropagation
       
  1207      */
       
  1208     stopImmediatePropagation: function() {
       
  1209         this.stopped = 2;
       
  1210         Y.Env._eventstack.stopped = 2;
       
  1211         this.events.fire('stopped', this);
       
  1212     },
       
  1213 
       
  1214     /**
       
  1215      * Prevents the execution of this event's defaultFn
       
  1216      * @method preventDefault
       
  1217      */
       
  1218     preventDefault: function() {
       
  1219         if (this.preventable) {
       
  1220             this.prevented = 1;
       
  1221             Y.Env._eventstack.prevented = 1;
       
  1222 
       
  1223             this.events.fire('prevented', this);
       
  1224         }
       
  1225     },
       
  1226 
       
  1227     /**
       
  1228      * Stops the event propagation and prevents the default
       
  1229      * event behavior.
       
  1230      * @method halt
       
  1231      * @param immediate {boolean} if true additional listeners
       
  1232      * on the current target will not be executed
       
  1233      */
       
  1234     halt: function(immediate) {
       
  1235         if (immediate) {
       
  1236             this.stopImmediatePropagation();
       
  1237         } else {
       
  1238             this.stopPropagation();
       
  1239         }
       
  1240         this.preventDefault();
       
  1241     }
       
  1242 
       
  1243 };
       
  1244 
       
  1245 /////////////////////////////////////////////////////////////////////
       
  1246 
       
  1247 /**
       
  1248  * Stores the subscriber information to be used when the event fires.
       
  1249  * @param {Function} fn       The wrapped function to execute
       
  1250  * @param {Object}   context  The value of the keyword 'this' in the listener
       
  1251  * @param {Array} args*       0..n additional arguments to supply the listener
       
  1252  *
       
  1253  * @class Subscriber
       
  1254  * @constructor
       
  1255  */
       
  1256 Y.Subscriber = function(fn, context, args) {
       
  1257 
       
  1258     /**
       
  1259      * The callback that will be execute when the event fires
       
  1260      * This is wrapped by Y.rbind if obj was supplied.
       
  1261      * @property fn
       
  1262      * @type Function
       
  1263      */
       
  1264     this.fn = fn;
       
  1265 
       
  1266     /**
       
  1267      * Optional 'this' keyword for the listener
       
  1268      * @property context
       
  1269      * @type Object
       
  1270      */
       
  1271     this.context = context;
       
  1272 
       
  1273     /**
       
  1274      * Unique subscriber id
       
  1275      * @property id
       
  1276      * @type String
       
  1277      */
       
  1278     this.id = Y.stamp(this);
       
  1279 
       
  1280     /*
       
  1281      * }
       
  1282      * fn bound to obj with additional arguments applied via Y.rbind
       
  1283      * @property wrappedFn
       
  1284      * @type Function
       
  1285      */
       
  1286     // this.wrappedFn = fn;
       
  1287 
       
  1288     /**
       
  1289      * Additional arguments to propagate to the subscriber
       
  1290      * @property args
       
  1291      * @type Array
       
  1292      */
       
  1293     this.args = args;
       
  1294 
       
  1295     /**
       
  1296      * Custom events for a given fire transaction.
       
  1297      * @property events
       
  1298      * @type {EventTarget}
       
  1299      */
       
  1300     this.events = null;
       
  1301     
       
  1302     // if (context) {
       
  1303     //     this.wrappedFn = Y.rbind.apply(Y, args);
       
  1304     // }
       
  1305     
       
  1306 
       
  1307 };
       
  1308 
       
  1309 Y.Subscriber.prototype = {
       
  1310 
       
  1311     _notify: function(c, args, ce) {
       
  1312         var a = this.args, ret;
       
  1313         switch (ce.signature) {
       
  1314             case 0:
       
  1315                 ret = this.fn.call(c, ce.type, args, c);
       
  1316                 break;
       
  1317             case 1:
       
  1318                 ret = this.fn.call(c, args[0] || null, c);
       
  1319                 break;
       
  1320             default:
       
  1321                 if (a || args) {
       
  1322                     args = args || [];
       
  1323                     a = (a) ? args.concat(a) : args;
       
  1324                     ret = this.fn.apply(c, a);
       
  1325                 } else {
       
  1326                     ret = this.fn.call(c);
       
  1327                 }
       
  1328         }
       
  1329 
       
  1330         return ret;
       
  1331     },
       
  1332 
       
  1333     /**
       
  1334      * Executes the subscriber.
       
  1335      * @method notify
       
  1336      * @param args {Array} Arguments array for the subscriber
       
  1337      * @param ce {CustomEvent} The custom event that sent the notification
       
  1338      */
       
  1339     notify: function(args, ce) {
       
  1340         var c = this.context,
       
  1341             ret = true;
       
  1342 
       
  1343         if (!c) {
       
  1344             c = (ce.contextFn) ? ce.contextFn() : ce.context;
       
  1345         }
       
  1346 
       
  1347         // Ease debugging by only catching errors if we will not re-throw
       
  1348         // them.
       
  1349         if (Y.config.throwFail) {
       
  1350             ret = this._notify(c, args, ce);
       
  1351         } else {
       
  1352             try {
       
  1353                 ret = this._notify(c, args, ce);
       
  1354             } catch(e) {
       
  1355                 Y.error(this + ' failed: ' + e.message, e);
       
  1356             }
       
  1357         }
       
  1358 
       
  1359         return ret;
       
  1360     },
       
  1361 
       
  1362     /**
       
  1363      * Returns true if the fn and obj match this objects properties.
       
  1364      * Used by the unsubscribe method to match the right subscriber.
       
  1365      *
       
  1366      * @method contains
       
  1367      * @param {Function} fn the function to execute
       
  1368      * @param {Object} context optional 'this' keyword for the listener
       
  1369      * @return {boolean} true if the supplied arguments match this 
       
  1370      *                   subscriber's signature.
       
  1371      */
       
  1372     contains: function(fn, context) {
       
  1373         if (context) {
       
  1374             return ((this.fn == fn) && this.context == context);
       
  1375         } else {
       
  1376             return (this.fn == fn);
       
  1377         }
       
  1378     },
       
  1379 
       
  1380     /**
       
  1381      * @method toString
       
  1382      */
       
  1383     toString: function() {
       
  1384         return "Subscriber " + this.id;
       
  1385     }
       
  1386 };
       
  1387 
       
  1388 // FACADE = new Y.EventFacade(new Y.CustomEvent('x'));
       
  1389 (function() {
       
  1390 
       
  1391 /**
       
  1392  * EventTarget provides the implementation for any object to
       
  1393  * publish, subscribe and fire to custom events, and also
       
  1394  * alows other EventTargets to target the object with events
       
  1395  * sourced from the other object.
       
  1396  * EventTarget is designed to be used with Y.augment to wrap 
       
  1397  * EventCustom in an interface that allows events to be listened to 
       
  1398  * and fired by name.  This makes it possible for implementing code to
       
  1399  * subscribe to an event that either has not been created yet, or will
       
  1400  * not be created at all.
       
  1401  * @class EventTarget
       
  1402  * @param opts a configuration object
       
  1403  * @config emitFacade {boolean} if true, all events will emit event 
       
  1404  * facade payloads by default (default false)
       
  1405  * @config prefix {string} the prefix to apply to non-prefixed event names 
       
  1406  * @config chain {boolean} if true, on/after/detach return the host to allow 
       
  1407  * chaining, otherwise they return an EventHandle (default false)
       
  1408  */
       
  1409 
       
  1410 var L = Y.Lang,
       
  1411     PREFIX_DELIMITER = ':',
       
  1412     CATEGORY_DELIMITER = '|',
       
  1413     AFTER_PREFIX = '~AFTER~',
       
  1414 
       
  1415     /**
       
  1416      * If the instance has a prefix attribute and the
       
  1417      * event type is not prefixed, the instance prefix is
       
  1418      * applied to the supplied type.
       
  1419      * @method _getType
       
  1420      * @private
       
  1421      */
       
  1422     _getType = Y.cached(function(type, pre) {
       
  1423 
       
  1424         if (!pre || !L.isString(type) || type.indexOf(PREFIX_DELIMITER) > -1) {
       
  1425             return type;
       
  1426         } 
       
  1427 
       
  1428         return pre + PREFIX_DELIMITER + type;
       
  1429     }),
       
  1430 
       
  1431     /**
       
  1432      * Returns an array with the detach key (if provided),
       
  1433      * and the prefixed event name from _getType
       
  1434      * Y.on('detachcategory, menu:click', fn)
       
  1435      * @method _parseType
       
  1436      * @private
       
  1437      */
       
  1438     _parseType = Y.cached(function(type, pre) {
       
  1439 
       
  1440         var t = type, detachcategory, after, i, full_t;
       
  1441 
       
  1442         if (!L.isString(t)) {
       
  1443             return t;
       
  1444         } 
       
  1445         
       
  1446         i = t.indexOf(AFTER_PREFIX);
       
  1447 
       
  1448         if (i > -1) {
       
  1449             after = true;
       
  1450             t = t.substr(AFTER_PREFIX.length);
       
  1451             // Y.log(t);
       
  1452         }
       
  1453 
       
  1454         // parts = t.split(DETACH_PREFIX_SPLITTER);
       
  1455         // if (parts.length > 1) {
       
  1456         //     detachcategory = parts[0];
       
  1457         //     t = parts[1];
       
  1458         //     if (t == '*') {
       
  1459         //          t = null;
       
  1460         //     }
       
  1461         // }
       
  1462         
       
  1463         i = t.indexOf(CATEGORY_DELIMITER);
       
  1464         if (i > -1) {
       
  1465             detachcategory = t.substr(0, (i));
       
  1466             t = t.substr(i+1);
       
  1467             if (t == '*') {
       
  1468                 t = null;
       
  1469             }
       
  1470         }
       
  1471 
       
  1472         full_t = _getType(t, pre);
       
  1473 
       
  1474         return [detachcategory, full_t, after, t];
       
  1475     }),
       
  1476 
       
  1477     ET = function(opts) {
       
  1478 
       
  1479         // console.log('EventTarget constructor executed: ' + this._yuid);
       
  1480 
       
  1481         var o = (L.isObject(opts)) ? opts : {};
       
  1482 
       
  1483         this._yuievt = {
       
  1484 
       
  1485             id: Y.guid(),
       
  1486 
       
  1487             events: {},
       
  1488 
       
  1489             targets: {},
       
  1490 
       
  1491             config: o,
       
  1492 
       
  1493             chain: ('chain' in o) ? o.chain : Y.config.chain,
       
  1494 
       
  1495             defaults: {
       
  1496                 context: o.context || this, 
       
  1497                 host: this,
       
  1498                 emitFacade: o.emitFacade,
       
  1499                 fireOnce: o.fireOnce,
       
  1500                 queuable: o.queuable,
       
  1501                 broadcast: o.broadcast,
       
  1502                 bubbles: ('bubbles' in o) ? o.bubbles : true
       
  1503             }
       
  1504         };
       
  1505 
       
  1506     };
       
  1507 
       
  1508 
       
  1509 ET.prototype = {
       
  1510 
       
  1511     /**
       
  1512      * Subscribe to a custom event hosted by this object
       
  1513      * @method on 
       
  1514      * @param type    {string}   The type of the event
       
  1515      * @param fn {Function} The callback
       
  1516      * @return the event target or a detach handle per 'chain' config
       
  1517      */
       
  1518     on: function(type, fn, context, x) {
       
  1519 
       
  1520         var parts = _parseType(type, this._yuievt.config.prefix), f, c, args, ret, ce,
       
  1521             detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype,
       
  1522             Node = Y.Node, n;
       
  1523 
       
  1524         if (L.isObject(type, true)) {
       
  1525 
       
  1526             f = fn; 
       
  1527             c = context; 
       
  1528             args = Y.Array(arguments, 0, true);
       
  1529             ret = {};
       
  1530             after = type._after;
       
  1531             delete type._after;
       
  1532 
       
  1533             Y.each(type, function(v, k) {
       
  1534 
       
  1535                 if (v) {
       
  1536                     f = v.fn || ((Y.Lang.isFunction(v)) ? v : f);
       
  1537                     c = v.context || c;
       
  1538                 }
       
  1539 
       
  1540                 args[0] = (after) ? AFTER_PREFIX + k : k;
       
  1541                 args[1] = f;
       
  1542                 args[2] = c;
       
  1543 
       
  1544                 ret[k] = this.on.apply(this, args); 
       
  1545 
       
  1546             }, this);
       
  1547 
       
  1548             return (this._yuievt.chain) ? this : ret;
       
  1549 
       
  1550         } else if (L.isFunction(type)) {
       
  1551             return Y.Do.before.apply(Y.Do, arguments);
       
  1552         }
       
  1553 
       
  1554         detachcategory = parts[0];
       
  1555         after = parts[2];
       
  1556         shorttype = parts[3];
       
  1557 
       
  1558 
       
  1559         // extra redirection so we catch adaptor events too.  take a look at this.
       
  1560         if (Node && (this instanceof Node) && (shorttype in Node.DOM_EVENTS)) {
       
  1561             args = Y.Array(arguments, 0, true);
       
  1562             args.splice(2, 0, Node.getDOMNode(this));
       
  1563             return Y.on.apply(Y, args);
       
  1564         }
       
  1565 
       
  1566         type = parts[1];
       
  1567 
       
  1568         if (this instanceof YUI) {
       
  1569             adapt = Y.Env.evt.plugins[type];
       
  1570             args  = Y.Array(arguments, 0, true);
       
  1571             args[0] = shorttype;
       
  1572             // check for the existance of an event adaptor
       
  1573             if (adapt && adapt.on) {
       
  1574                 n = args[2];
       
  1575                 Y.log('Using adaptor for ' + shorttype + ', ' + n, 'info', 'event');
       
  1576                 if (Node && n && (n instanceof Node)) {
       
  1577                     args[2] = Node.getDOMNode(n);
       
  1578                 }
       
  1579                 handle = adapt.on.apply(Y, args);
       
  1580             // check to see if the target is an EventTarget.  If so,
       
  1581             // delegate to it (the EventTarget should handle whether
       
  1582             // or not the prefix was included);
       
  1583             // } else if (o && !(o instanceof YUI) && o.getEvent) {
       
  1584             //     a = Y.Array(arguments, 0, true);
       
  1585             //     a.splice(2, 1);
       
  1586             //     return o.on.apply(o, a);
       
  1587             // } else if ((!type) || (!adapt && type.indexOf(':') == -1)) {
       
  1588             } else if ((!type) || (!adapt && Node && (shorttype in Node.DOM_EVENTS))) {
       
  1589                 handle = Y.Event._attach(args);
       
  1590             }
       
  1591 
       
  1592         } 
       
  1593 
       
  1594         if (!handle) {
       
  1595 
       
  1596             // Y.log('parts: ' + parts);
       
  1597             ce     = this._yuievt.events[type] || this.publish(type);
       
  1598             // args   = Y.Array(arguments, 1, true);
       
  1599             // f = (after) ? ce.after : ce.on;
       
  1600             // handle = f.apply(ce, args);
       
  1601 
       
  1602             handle = ce._on(fn, context, (arguments.length > 3) ? Y.Array(arguments, 3, true) : null, (after) ? 'after' : true);
       
  1603         }
       
  1604 
       
  1605         if (detachcategory) {
       
  1606 
       
  1607             store[detachcategory] = store[detachcategory] || {};
       
  1608             store[detachcategory][type] = store[detachcategory][type] || [];
       
  1609             store[detachcategory][type].push(handle);
       
  1610 
       
  1611             // Y.log('storing: ' + key);
       
  1612         }
       
  1613 
       
  1614         return (this._yuievt.chain) ? this : handle;
       
  1615 
       
  1616     },
       
  1617 
       
  1618     /**
       
  1619      * subscribe to an event
       
  1620      * @method subscribe
       
  1621      * @deprecated use on
       
  1622      */
       
  1623     subscribe: function() {
       
  1624         return this.on.apply(this, arguments);
       
  1625     },
       
  1626 
       
  1627     /**
       
  1628      * Detach one or more listeners the from the specified event
       
  1629      * @method detach 
       
  1630      * @param type {string|Object}   Either the handle to the subscriber or the 
       
  1631      *                        type of event.  If the type
       
  1632      *                        is not specified, it will attempt to remove
       
  1633      *                        the listener from all hosted events.
       
  1634      * @param fn   {Function} The subscribed function to unsubscribe, if not
       
  1635      *                          supplied, all subscribers will be removed.
       
  1636      * @param context  {Object}   The custom object passed to subscribe.  This is
       
  1637      *                        optional, but if supplied will be used to
       
  1638      *                        disambiguate multiple listeners that are the same
       
  1639      *                        (e.g., you subscribe many object using a function
       
  1640      *                        that lives on the prototype)
       
  1641      * @return {EventTarget} the host
       
  1642      */
       
  1643     detach: function(type, fn, context) {
       
  1644 
       
  1645         var parts = _parseType(type, this._yuievt.config.prefix), 
       
  1646         detachcategory = L.isArray(parts) ? parts[0] : null,
       
  1647         shorttype = (parts) ? parts[3] : null,
       
  1648         handle, adapt, store = Y.Env.evt.handles, cat, args,
       
  1649         evts = this._yuievt.events, ce, i, ret = true,
       
  1650 
       
  1651         keyDetacher = function(lcat, ltype) {
       
  1652             var handles = lcat[ltype];
       
  1653             if (handles) {
       
  1654                 while (handles.length) {
       
  1655                     handle = handles.pop();
       
  1656                     handle.detach();
       
  1657                 }
       
  1658             }
       
  1659         };
       
  1660 
       
  1661         if (detachcategory) {
       
  1662 
       
  1663             cat = store[detachcategory];
       
  1664             type = parts[1];
       
  1665 
       
  1666             if (cat) {
       
  1667                 if (type) {
       
  1668                     keyDetacher(cat, type);
       
  1669                 } else {
       
  1670                     for (i in cat) {
       
  1671                         if (cat.hasOwnProperty(i)) {
       
  1672                             keyDetacher(cat, i);
       
  1673                         }
       
  1674                     }
       
  1675                 }
       
  1676 
       
  1677                 return (this._yuievt.chain) ? this : true;
       
  1678             }
       
  1679 
       
  1680         // If this is an event handle, use it to detach
       
  1681         } else if (L.isObject(type) && type.detach) {
       
  1682             ret = type.detach();
       
  1683             return (this._yuievt.chain) ? this : true;
       
  1684         // extra redirection so we catch adaptor events too.  take a look at this.
       
  1685         } else if (Y.Node && (this instanceof Y.Node) && ((!shorttype) || (shorttype in Y.Node.DOM_EVENTS))) {
       
  1686             args = Y.Array(arguments, 0, true);
       
  1687             args[2] = Y.Node.getDOMNode(this);
       
  1688             return Y.detach.apply(Y, args);
       
  1689         }
       
  1690 
       
  1691         adapt = Y.Env.evt.plugins[shorttype];
       
  1692 
       
  1693         // The YUI instance handles DOM events and adaptors
       
  1694         if (this instanceof YUI) {
       
  1695             args = Y.Array(arguments, 0, true);
       
  1696             // use the adaptor specific detach code if
       
  1697             if (adapt && adapt.detach) {
       
  1698                 return adapt.detach.apply(Y, args);
       
  1699             // DOM event fork
       
  1700             } else if (!type || (!adapt && type.indexOf(':') == -1)) {
       
  1701                 args[0] = type;
       
  1702                 return Y.Event.detach.apply(Y.Event, args);
       
  1703             }
       
  1704         }
       
  1705 
       
  1706         if (type) {
       
  1707             ce = evts[type];
       
  1708             if (ce) {
       
  1709                 return ce.detach(fn, context);
       
  1710             }
       
  1711         } else {
       
  1712             for (i in evts) {
       
  1713                 if (evts.hasOwnProperty(i)) {
       
  1714                     ret = ret && evts[i].detach(fn, context);
       
  1715                 }
       
  1716             }
       
  1717             return ret;
       
  1718         }
       
  1719 
       
  1720         return (this._yuievt.chain) ? this : false;
       
  1721     },
       
  1722 
       
  1723     /**
       
  1724      * detach a listener
       
  1725      * @method unsubscribe
       
  1726      * @deprecated use detach
       
  1727      */
       
  1728     unsubscribe: function() {
       
  1729         return this.detach.apply(this, arguments);
       
  1730     },
       
  1731     
       
  1732     /**
       
  1733      * Removes all listeners from the specified event.  If the event type
       
  1734      * is not specified, all listeners from all hosted custom events will
       
  1735      * be removed.
       
  1736      * @method detachAll
       
  1737      * @param type {string}   The type, or name of the event
       
  1738      */
       
  1739     detachAll: function(type) {
       
  1740         type = _getType(type, this._yuievt.config.prefix);
       
  1741         return this.detach(type);
       
  1742     },
       
  1743 
       
  1744     /**
       
  1745      * Removes all listeners from the specified event.  If the event type
       
  1746      * is not specified, all listeners from all hosted custom events will
       
  1747      * be removed.
       
  1748      * @method unsubscribeAll
       
  1749      * @param type {string}   The type, or name of the event
       
  1750      * @deprecated use detachAll
       
  1751      */
       
  1752     unsubscribeAll: function() {
       
  1753         return this.detachAll.apply(this, arguments);
       
  1754     },
       
  1755 
       
  1756     /**
       
  1757      * Creates a new custom event of the specified type.  If a custom event
       
  1758      * by that name already exists, it will not be re-created.  In either
       
  1759      * case the custom event is returned. 
       
  1760      *
       
  1761      * @method publish
       
  1762      *
       
  1763      * @param type {string} the type, or name of the event
       
  1764      * @param opts {object} optional config params.  Valid properties are:
       
  1765      *
       
  1766      *  <ul>
       
  1767      *    <li>
       
  1768      *   'broadcast': whether or not the YUI instance and YUI global are notified when the event is fired (false)
       
  1769      *    </li>
       
  1770      *    <li>
       
  1771      *   'bubbles': whether or not this event bubbles (true)
       
  1772      *    </li>
       
  1773      *    <li>
       
  1774      *   'context': the default execution context for the listeners (this)
       
  1775      *    </li>
       
  1776      *    <li>
       
  1777      *   'defaultFn': the default function to execute when this event fires if preventDefault was not called
       
  1778      *    </li>
       
  1779      *    <li>
       
  1780      *   'emitFacade': whether or not this event emits a facade (false)
       
  1781      *    </li>
       
  1782      *    <li>
       
  1783      *   'prefix': the prefix for this targets events, e.g., 'menu' in 'menu:click' 
       
  1784      *    </li>
       
  1785      *    <li>
       
  1786      *   'fireOnce': if an event is configured to fire once, new subscribers after
       
  1787      *   the fire will be notified immediately.
       
  1788      *    </li>
       
  1789      *    <li>
       
  1790      *   'preventable': whether or not preventDefault() has an effect (true)
       
  1791      *    </li>
       
  1792      *    <li>
       
  1793      *   'preventedFn': a function that is executed when preventDefault is called
       
  1794      *    </li>
       
  1795      *    <li>
       
  1796      *   'queuable': whether or not this event can be queued during bubbling (false)
       
  1797      *    </li>
       
  1798      *    <li>
       
  1799      *   'silent': if silent is true, debug messages are not provided for this event.
       
  1800      *    </li>
       
  1801      *    <li>
       
  1802      *   'stoppedFn': a function that is executed when stopPropagation is called
       
  1803      *    </li>
       
  1804      *    <li>
       
  1805      *   'type': the event type (valid option if not provided as the first parameter to publish)
       
  1806      *    </li>
       
  1807      *  </ul>
       
  1808      *
       
  1809      *  @return {Event.Custom} the custom event
       
  1810      *
       
  1811      */
       
  1812     publish: function(type, opts) {
       
  1813         // this._yuievt.config.prefix
       
  1814 
       
  1815         type = _getType(type, this._yuievt.config.prefix);
       
  1816 
       
  1817         var events, ce, ret, o;
       
  1818 
       
  1819         if (L.isObject(type)) {
       
  1820             ret = {};
       
  1821             Y.each(type, function(v, k) {
       
  1822                 ret[k] = this.publish(k, v || opts); 
       
  1823             }, this);
       
  1824 
       
  1825             return ret;
       
  1826         }
       
  1827 
       
  1828         events = this._yuievt.events; 
       
  1829         ce = events[type];
       
  1830 
       
  1831         //if (ce && !ce.configured) {
       
  1832         if (ce) {
       
  1833 // ce.log("publish applying new config to published event: '"+type+"' exists", 'info', 'event');
       
  1834             if (opts) {
       
  1835                 ce.applyConfig(opts, true);
       
  1836             }
       
  1837 
       
  1838         } else {
       
  1839             o = (opts) ?  Y.mix(opts, this._yuievt.defaults) : this._yuievt.defaults;
       
  1840             // apply defaults
       
  1841 
       
  1842             ce = new Y.CustomEvent(type, o);
       
  1843 
       
  1844             events[type] = ce;
       
  1845 
       
  1846         }
       
  1847 
       
  1848         // make sure we turn the broadcast flag off if this
       
  1849         // event was published as a result of bubbling
       
  1850         if (opts instanceof Y.CustomEvent) {
       
  1851             events[type].broadcast = false;
       
  1852         }
       
  1853 
       
  1854         return events[type];
       
  1855     },
       
  1856 
       
  1857     /**
       
  1858      * Registers another EventTarget as a bubble target.  Bubble order
       
  1859      * is determined by the order registered.  Multiple targets can
       
  1860      * be specified.
       
  1861      * @method addTarget
       
  1862      * @param o {EventTarget} the target to add
       
  1863      */
       
  1864     addTarget: function(o) {
       
  1865         this._yuievt.targets[Y.stamp(o)] = o;
       
  1866         this._yuievt.hasTargets = true;
       
  1867     },
       
  1868 
       
  1869     /**
       
  1870      * Removes a bubble target
       
  1871      * @method removeTarget
       
  1872      * @param o {EventTarget} the target to remove
       
  1873      */
       
  1874     removeTarget: function(o) {
       
  1875         delete this._yuievt.targets[Y.stamp(o)];
       
  1876     },
       
  1877 
       
  1878    /**
       
  1879      * Fire a custom event by name.  The callback functions will be executed
       
  1880      * from the context specified when the event was created, and with the 
       
  1881      * following parameters.
       
  1882      *
       
  1883      * If the custom event object hasn't been created, then the event hasn't 
       
  1884      * been published and it has no subscribers.  For performance sake, we 
       
  1885      * immediate exit in this case.  This means the event won't bubble, so 
       
  1886      * if the intention is that a bubble target be notified, the event must 
       
  1887      * be published on this object first.
       
  1888      *
       
  1889      * @method fire
       
  1890      * @param type {String|Object} The type of the event, or an object that contains
       
  1891      * a 'type' property.
       
  1892      * @param arguments {Object*} an arbitrary set of parameters to pass to 
       
  1893      * the handler.
       
  1894      * @return {boolean} the return value from Event.Custom.fire
       
  1895      *                   
       
  1896      */
       
  1897     fire: function(type) {
       
  1898 
       
  1899         var typeIncluded = L.isString(type),
       
  1900             t = (typeIncluded) ? type : (type && type.type),
       
  1901             ce, a, ret;
       
  1902 
       
  1903         t = _getType(t, this._yuievt.config.prefix);
       
  1904         ce = this.getEvent(t);
       
  1905 
       
  1906         // this event has not been published or subscribed to
       
  1907         if (!ce) {
       
  1908             
       
  1909             // if this object has bubble targets, we need to publish the
       
  1910             // event in order for it to bubble.
       
  1911             if (this._yuievt.hasTargets) {
       
  1912                 // ce = this.publish(t);
       
  1913                 // ce.details = Y.Array(arguments, (typeIncluded) ? 1 : 0, true);
       
  1914                 
       
  1915                 a = (typeIncluded) ? arguments : Y.Array(arguments, 0, true).unshift(t);
       
  1916                 return this.bubble(null, a, this);
       
  1917             }
       
  1918 
       
  1919             // otherwise there is nothing to be done
       
  1920             ret = true;
       
  1921 
       
  1922         } else {
       
  1923 
       
  1924             a = Y.Array(arguments, (typeIncluded) ? 1 : 0, true);
       
  1925             ret = ce.fire.apply(ce, a);
       
  1926 
       
  1927             // clear target for next fire()
       
  1928             ce.target = null;
       
  1929         }
       
  1930 
       
  1931         return (this._yuievt.chain) ? this : ret;
       
  1932     },
       
  1933 
       
  1934     /**
       
  1935      * Returns the custom event of the provided type has been created, a
       
  1936      * falsy value otherwise
       
  1937      * @method getEvent
       
  1938      * @param type {string} the type, or name of the event
       
  1939      * @return {Event.Custom} the custom event or null
       
  1940      */
       
  1941     getEvent: function(type) {
       
  1942         type = _getType(type, this._yuievt.config.prefix);
       
  1943         var e = this._yuievt.events;
       
  1944         return (e && type in e) ? e[type] : null;
       
  1945     },
       
  1946 
       
  1947     /**
       
  1948      * Propagate an event
       
  1949      * @method bubble
       
  1950      * @param evt {Event.Custom} the custom event to propagate
       
  1951      * @return {boolean} the aggregated return value from Event.Custom.fire
       
  1952      */
       
  1953     bubble: function(evt, args, target) {
       
  1954 
       
  1955         var targs = this._yuievt.targets, ret = true,
       
  1956             t, type, ce, i;
       
  1957 
       
  1958         if (!evt || ((!evt.stopped) && targs)) {
       
  1959 
       
  1960             // Y.log('Bubbling ' + evt.type);
       
  1961             for (i in targs) {
       
  1962                 if (targs.hasOwnProperty(i)) {
       
  1963                     t = targs[i]; 
       
  1964                     type = evt && evt.type;
       
  1965                     ce = t.getEvent(type); 
       
  1966                         
       
  1967                     // if this event was not published on the bubble target,
       
  1968                     // publish it with sensible default properties
       
  1969                     if (!ce) {
       
  1970 
       
  1971                         // publish the event on the bubble target using this event
       
  1972                         // for its configuration
       
  1973                         // ce = t.publish(type, evt);
       
  1974 
       
  1975                         // set the host and context appropriately
       
  1976                         // ce.context = (evt.host === evt.context) ? t : evt.context;
       
  1977                         // ce.host = t;
       
  1978 
       
  1979                         // clear handlers if specified on this event
       
  1980                         // ce.defaultFn = null;
       
  1981                         // ce.preventedFn = null;
       
  1982                         // ce.stoppedFn = null;
       
  1983 
       
  1984                         if (t._yuievt.hasTargets) {
       
  1985                             t.bubble.call(t, evt, args, target);
       
  1986                         }
       
  1987 
       
  1988                     } else {
       
  1989 
       
  1990                         ce.target = target || (evt && evt.target) || this;
       
  1991 
       
  1992                         ce.currentTarget = t;
       
  1993 
       
  1994                         ret = ret && ce.fire.apply(ce, args || evt.details);
       
  1995 
       
  1996                         // stopPropagation() was called
       
  1997                         if (ce.stopped) {
       
  1998                             break;
       
  1999                         }
       
  2000                     }
       
  2001                 }
       
  2002             }
       
  2003         }
       
  2004 
       
  2005         return ret;
       
  2006     },
       
  2007 
       
  2008     /**
       
  2009      * Subscribe to a custom event hosted by this object.  The
       
  2010      * supplied callback will execute after any listeners add
       
  2011      * via the subscribe method, and after the default function,
       
  2012      * if configured for the event, has executed.
       
  2013      * @method after
       
  2014      * @param type    {string}   The type of the event
       
  2015      * @param fn {Function} The callback
       
  2016      * @return the event target or a detach handle per 'chain' config
       
  2017      */
       
  2018     after: function(type, fn) {
       
  2019 
       
  2020         var a = Y.Array(arguments, 0, true);
       
  2021 
       
  2022         switch (L.type(type)) {
       
  2023             case 'function':
       
  2024                 return Y.Do.after.apply(Y.Do, arguments);
       
  2025             case 'object':
       
  2026                 a[0]._after = true;
       
  2027                 break;
       
  2028             default:
       
  2029                 a[0] = AFTER_PREFIX + type;
       
  2030         }
       
  2031 
       
  2032         return this.on.apply(this, a);
       
  2033 
       
  2034     },
       
  2035 
       
  2036     /**
       
  2037      * Executes the callback before a DOM event, custom event
       
  2038      * or method.  If the first argument is a function, it
       
  2039      * is assumed the target is a method.  For DOM and custom
       
  2040      * events, this is an alias for Y.on.
       
  2041      *
       
  2042      * For DOM and custom events:
       
  2043      * type, callback, context, 1-n arguments
       
  2044      *  
       
  2045      * For methods:
       
  2046      * callback, object (method host), methodName, context, 1-n arguments
       
  2047      *
       
  2048      * @method before
       
  2049      * @return detach handle
       
  2050      * @deprecated use the on method
       
  2051      */
       
  2052     before: function() { 
       
  2053         return this.on.apply(this, arguments);
       
  2054     }
       
  2055 
       
  2056 };
       
  2057 
       
  2058 Y.EventTarget = ET;
       
  2059 
       
  2060 // make Y an event target
       
  2061 Y.mix(Y, ET.prototype, false, false, { 
       
  2062     bubbles: false 
       
  2063 });
       
  2064 
       
  2065 ET.call(Y);
       
  2066 
       
  2067 YUI.Env.globalEvents = YUI.Env.globalEvents || new ET();
       
  2068 
       
  2069 /**
       
  2070  * Hosts YUI page level events.  This is where events bubble to
       
  2071  * when the broadcast config is set to 2.  This property is
       
  2072  * only available if the custom event module is loaded.
       
  2073  * @property Global
       
  2074  * @type EventTarget
       
  2075  * @for YUI
       
  2076  */
       
  2077 Y.Global = YUI.Env.globalEvents;
       
  2078 
       
  2079 // @TODO implement a global namespace function on Y.Global?
       
  2080 
       
  2081 })();
       
  2082 
       
  2083 
       
  2084 }, '3.0.0b1' ,{requires:['oop']});