2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('event-custom-base', function (Y, NAME) {
11 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
13 * @module event-custom
23 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
25 * @module event-custom
26 * @submodule event-custom-base
30 * Allows for the insertion of methods that are executed before or after
42 * Cache of objects touched by the utility
45 * @deprecated Since 3.6.0. The `_yuiaop` property on the AOP'd object
46 * replaces the role of this property, but is considered to be private, and
47 * is only mentioned to provide a migration path.
49 * If you have a use case which warrants migration to the _yuiaop property,
50 * please file a ticket to let us know what it's used for and we can see if
51 * we need to expose hooks for that functionality more formally.
56 * <p>Execute the supplied method before the specified function. Wrapping
57 * function may optionally return an instance of the following classes to
58 * further alter runtime behavior:</p>
60 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
61 * <dd>Immediatly stop execution and return
62 * <code>returnValue</code>. No other wrapping functions will be
64 * <dt></code>Y.Do.AlterArgs(message, newArgArray)</code></dt>
65 * <dd>Replace the arguments that the original function will be
67 * <dt></code>Y.Do.Prevent(message)</code></dt>
68 * <dd>Don't execute the wrapped function. Other before phase
69 * wrappers will be executed.</dd>
73 * @param fn {Function} the function to execute
74 * @param obj the object hosting the method to displace
75 * @param sFn {string} the name of the method to displace
76 * @param c The execution context for fn
77 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
78 * when the event fires.
79 * @return {string} handle for the subscription
82 before: function(fn, obj, sFn, c) {
83 // Y.log('Do before: ' + sFn, 'info', 'event');
86 a = [fn, c].concat(Y.Array(arguments, 4, true));
87 f = Y.rbind.apply(Y, a);
90 return this._inject(DO_BEFORE, f, obj, sFn);
94 * <p>Execute the supplied method after the specified function. Wrapping
95 * function may optionally return an instance of the following classes to
96 * further alter runtime behavior:</p>
98 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt>
99 * <dd>Immediatly stop execution and return
100 * <code>returnValue</code>. No other wrapping functions will be
102 * <dt></code>Y.Do.AlterReturn(message, returnValue)</code></dt>
103 * <dd>Return <code>returnValue</code> instead of the wrapped
104 * method's original return value. This can be further altered by
105 * other after phase wrappers.</dd>
108 * <p>The static properties <code>Y.Do.originalRetVal</code> and
109 * <code>Y.Do.currentRetVal</code> will be populated for reference.</p>
112 * @param fn {Function} the function to execute
113 * @param obj the object hosting the method to displace
114 * @param sFn {string} the name of the method to displace
115 * @param c The execution context for fn
116 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber
117 * @return {string} handle for the subscription
120 after: function(fn, obj, sFn, c) {
123 a = [fn, c].concat(Y.Array(arguments, 4, true));
124 f = Y.rbind.apply(Y, a);
127 return this._inject(DO_AFTER, f, obj, sFn);
131 * Execute the supplied method before or after the specified function.
132 * Used by <code>before</code> and <code>after</code>.
135 * @param when {string} before or after
136 * @param fn {Function} the function to execute
137 * @param obj the object hosting the method to displace
138 * @param sFn {string} the name of the method to displace
139 * @param c The execution context for fn
140 * @return {string} handle for the subscription
144 _inject: function(when, fn, obj, sFn) {
146 var id = Y.stamp(obj), o, sid;
149 // create a map entry for the obj if it doesn't exist, to hold overridden methods
156 // create a map entry for the method if it doesn't exist
157 o[sFn] = new Y.Do.Method(obj, sFn);
159 // re-route the method to our wrapper
160 obj[sFn] = function() {
161 return o[sFn].exec.apply(o[sFn], arguments);
166 sid = id + Y.stamp(fn) + sFn;
168 // register the callback
169 o[sFn].register(sid, fn, when);
171 return new Y.EventHandle(o[sFn], sid);
175 * Detach a before or after subscription.
178 * @param handle {string} the subscription handle
181 detach: function(handle) {
190 //////////////////////////////////////////////////////////////////////////
193 * Contains the return value from the wrapped method, accessible
194 * by 'after' event listeners.
196 * @property originalRetVal
202 * Contains the current state of the return value, consumable by
203 * 'after' event listeners, and updated if an after subscriber
204 * changes the return value generated by the wrapped function.
206 * @property currentRetVal
211 //////////////////////////////////////////////////////////////////////////
214 * Wrapper for a displaced method with aop enabled
217 * @param obj The object to operate on
218 * @param sFn The name of the method to displace
220 DO.Method = function(obj, sFn) {
222 this.methodName = sFn;
223 this.method = obj[sFn];
229 * Register a aop subscriber
231 * @param sid {string} the subscriber id
232 * @param fn {Function} the function to execute
233 * @param when {string} when to execute the function
235 DO.Method.prototype.register = function (sid, fn, when) {
237 this.after[sid] = fn;
239 this.before[sid] = fn;
244 * Unregister a aop subscriber
246 * @param sid {string} the subscriber id
247 * @param fn {Function} the function to execute
248 * @param when {string} when to execute the function
250 DO.Method.prototype._delete = function (sid) {
251 // Y.log('Y.Do._delete: ' + sid, 'info', 'Event');
252 delete this.before[sid];
253 delete this.after[sid];
257 * <p>Execute the wrapped method. All arguments are passed into the wrapping
258 * functions. If any of the before wrappers return an instance of
259 * <code>Y.Do.Halt</code> or <code>Y.Do.Prevent</code>, neither the wrapped
260 * function nor any after phase subscribers will be executed.</p>
262 * <p>The return value will be the return value of the wrapped function or one
263 * provided by a wrapper function via an instance of <code>Y.Do.Halt</code> or
264 * <code>Y.Do.AlterReturn</code>.
267 * @param arg* {any} Arguments are passed to the wrapping and wrapped functions
268 * @return {any} Return value of wrapped function unless overwritten (see above)
270 DO.Method.prototype.exec = function () {
272 var args = Y.Array(arguments, 0, true),
280 if (bf.hasOwnProperty(i)) {
281 ret = bf[i].apply(this.obj, args);
283 switch (ret.constructor) {
300 ret = this.method.apply(this.obj, args);
303 DO.originalRetVal = ret;
304 DO.currentRetVal = ret;
306 // execute after methods.
308 if (af.hasOwnProperty(i)) {
309 newRet = af[i].apply(this.obj, args);
310 // Stop processing if a Halt object is returned
311 if (newRet && newRet.constructor === DO.Halt) {
312 return newRet.retVal;
313 // Check for a new return value
314 } else if (newRet && newRet.constructor === DO.AlterReturn) {
315 ret = newRet.newRetVal;
316 // Update the static retval state
317 DO.currentRetVal = ret;
325 //////////////////////////////////////////////////////////////////////////
328 * Return an AlterArgs object when you want to change the arguments that
329 * were passed into the function. Useful for Do.before subscribers. An
330 * example would be a service that scrubs out illegal characters prior to
331 * executing the core business logic.
332 * @class Do.AlterArgs
334 * @param msg {String} (optional) Explanation of the altered return value
335 * @param newArgs {Array} Call parameters to be used for the original method
336 * instead of the arguments originally passed in.
338 DO.AlterArgs = function(msg, newArgs) {
340 this.newArgs = newArgs;
344 * Return an AlterReturn object when you want to change the result returned
345 * from the core method to the caller. Useful for Do.after subscribers.
346 * @class Do.AlterReturn
348 * @param msg {String} (optional) Explanation of the altered return value
349 * @param newRetVal {any} Return value passed to code that invoked the wrapped
352 DO.AlterReturn = function(msg, newRetVal) {
354 this.newRetVal = newRetVal;
358 * Return a Halt object when you want to terminate the execution
359 * of all subsequent subscribers as well as the wrapped method
360 * if it has not exectued yet. Useful for Do.before subscribers.
363 * @param msg {String} (optional) Explanation of why the termination was done
364 * @param retVal {any} Return value passed to code that invoked the wrapped
367 DO.Halt = function(msg, retVal) {
369 this.retVal = retVal;
373 * Return a Prevent object when you want to prevent the wrapped function
374 * from executing, but want the remaining listeners to execute. Useful
375 * for Do.before subscribers.
378 * @param msg {String} (optional) Explanation of why the termination was done
380 DO.Prevent = function(msg) {
385 * Return an Error object when you want to terminate the execution
386 * of all subsequent method calls.
389 * @param msg {String} (optional) Explanation of the altered return value
390 * @param retVal {any} Return value passed to code that invoked the wrapped
392 * @deprecated use Y.Do.Halt or Y.Do.Prevent
397 //////////////////////////////////////////////////////////////////////////
400 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
402 * @module event-custom
403 * @submodule event-custom-base
407 // var onsubscribeType = "_event:onsub",
408 var YArray = Y.Array,
434 CONFIGS_HASH = YArray.hash(CONFIGS),
436 nativeSlice = Array.prototype.slice,
441 mixConfigs = function(r, s, ov) {
445 if (CONFIGS_HASH[p] && (ov || !(p in r))) {
454 * The CustomEvent class lets you define events for your application
455 * that can be subscribed to by one or more independent component.
457 * @param {String} type The type of event, which is passed to the callback
458 * when the event fires.
459 * @param {object} defaults configuration object.
465 * The type of event, returned to subscribers when the event fires
471 * By default all custom events are logged in the debug build, set silent
472 * to true to disable debug outpu for this event.
477 Y.CustomEvent = function(type, defaults) {
479 this._kds = Y.CustomEvent.keepDeprecatedSubs;
484 this.silent = this.logSystem = (type === YUI_LOG);
488 * The subscribers to this event
489 * @property subscribers
490 * @type Subscriber {}
495 * 'After' subscribers
497 * @type Subscriber {}
500 this.subscribers = {};
505 mixConfigs(this, defaults, true);
510 * Static flag to enable population of the <a href="#property_subscribers">`subscribers`</a>
511 * and <a href="#property_subscribers">`afters`</a> properties held on a `CustomEvent` instance.
513 * These properties were changed to private properties (`_subscribers` and `_afters`), and
514 * converted from objects to arrays for performance reasons.
516 * Setting this property to true will populate the deprecated `subscribers` and `afters`
517 * properties for people who may be using them (which is expected to be rare). There will
518 * be a performance hit, compared to the new array based implementation.
520 * If you are using these deprecated properties for a use case which the public API
521 * does not support, please file an enhancement request, and we can provide an alternate
522 * public implementation which doesn't have the performance cost required to maintiain the
523 * properties as objects.
525 * @property keepDeprecatedSubs
532 Y.CustomEvent.keepDeprecatedSubs = false;
534 Y.CustomEvent.mixConfigs = mixConfigs;
536 Y.CustomEvent.prototype = {
538 constructor: Y.CustomEvent,
541 * Monitor when an event is attached or detached.
543 * @property monitored
548 * If 0, this event does not broadcast. If 1, the YUI instance is notified
549 * every time this event fires. If 2, the YUI instance and the YUI global
550 * (if event is enabled on the global) are notified every time this event
552 * @property broadcast
557 * Specifies whether this event should be queued when the host is actively
558 * processing an event. This will effect exectution order of the callbacks
559 * for the various events.
566 * This event has fired if true
574 * An array containing the arguments the custom event
575 * was last fired with.
576 * @property firedWith
581 * This event should only fire one time if true, and if
582 * it has fired, any new subscribers should be notified
591 * fireOnce listeners will fire syncronously unless async
599 * Flag for stopPropagation that is modified during fire()
600 * 1 means to stop propagation to bubble targets. 2 means
601 * to also stop additional subscribers on this target.
607 * Flag for preventDefault that is modified during fire().
608 * if it is not 0, the default behavior for this event
609 * @property prevented
614 * Specifies the host for this custom event. This is used
615 * to enable event bubbling
621 * The default function to execute after event listeners
622 * have fire, but only if the default action was not
624 * @property defaultFn
629 * The function to execute if a subscriber calls
630 * stopPropagation or stopImmediatePropagation
631 * @property stoppedFn
636 * The function to execute if a subscriber calls
638 * @property preventedFn
643 * The subscribers to this event
644 * @property _subscribers
645 * @type Subscriber []
650 * 'After' subscribers
652 * @type Subscriber []
657 * If set to true, the custom event will deliver an EventFacade object
658 * that is similar to a DOM event object.
659 * @property emitFacade
665 * Supports multiple options for listener signatures in order to
667 * @property signature
671 signature : YUI3_SIGNATURE,
674 * The context the the event will fire from by default. Defaults to the YUI
682 * Specifies whether or not this event's default function
683 * can be cancelled by a subscriber by executing preventDefault()
684 * on the event facade
685 * @property preventable
692 * Specifies whether or not a subscriber can stop the event propagation
693 * via stopPropagation(), stopImmediatePropagation(), or halt()
695 * Events can only bubble if emitFacade is true.
704 * Returns the number of subscribers for this event as the sum of the on()
705 * subscribers and after() subscribers.
710 hasSubs: function(when) {
713 subs = this._subscribers,
714 afters = this._afters,
726 subs = sib._subscribers;
727 afters = sib._afters;
739 return (when === 'after') ? a : s;
746 * Monitor the event state for the subscribed event. The first parameter
747 * is what should be monitored, the rest are the normal parameters when
748 * subscribing to an event.
750 * @param what {string} what to monitor ('detach', 'attach', 'publish').
751 * @return {EventHandle} return value from the monitor event subscription.
753 monitor: function(what) {
754 this.monitored = true;
755 var type = this.id + '|' + this.type + '_' + what,
756 args = nativeSlice.call(arguments, 0);
758 return this.host.on.apply(this.host, args);
762 * Get all of the subscribers to this event and any sibling event
764 * @return {Array} first item is the on subscribers, second the after.
766 getSubs: function() {
768 var sibling = this.sibling,
769 subs = this._subscribers,
770 afters = this._afters,
775 siblingSubs = sibling._subscribers;
776 siblingAfters = sibling._afters;
781 subs = subs.concat(siblingSubs);
783 subs = siblingSubs.concat();
787 subs = subs.concat();
795 afters = afters.concat(siblingAfters);
797 afters = siblingAfters.concat();
801 afters = afters.concat();
807 return [subs, afters];
811 * Apply configuration properties. Only applies the CONFIG whitelist
812 * @method applyConfig
813 * @param o hash of properties to apply.
814 * @param force {boolean} if true, properties that exist on the event
815 * will be overwritten.
817 applyConfig: function(o, force) {
818 mixConfigs(this, o, force);
822 * Create the Subscription for subscribing function, context, and bound
823 * arguments. If this is a fireOnce event, the subscriber is immediately
827 * @param fn {Function} Subscription callback
828 * @param [context] {Object} Override `this` in the callback
829 * @param [args] {Array} bound arguments that will be passed to the callback after the arguments generated by fire()
830 * @param [when] {String} "after" to slot into after subscribers
831 * @return {EventHandle}
834 _on: function(fn, context, args, when) {
836 if (!fn) { this.log('Invalid callback for CE: ' + this.type); }
838 var s = new Y.Subscriber(fn, context, args, when),
841 if (this.fireOnce && this.fired) {
843 firedWith = this.firedWith;
845 // It's a little ugly for this to know about facades,
846 // but given the current breakup, not much choice without
847 // moving a whole lot of stuff around.
848 if (this.emitFacade && this._addFacadeToArgs) {
849 this._addFacadeToArgs(firedWith);
853 setTimeout(Y.bind(this._notify, this, s, firedWith), 0);
855 this._notify(s, firedWith);
859 if (when === AFTER) {
863 this._afters.push(s);
865 if (!this._subscribers) {
866 this._subscribers = [];
868 this._subscribers.push(s);
872 if (when === AFTER) {
873 this.afters[s.id] = s;
875 this.subscribers[s.id] = s;
879 return new Y.EventHandle(this, s);
883 * Listen for this event
885 * @param {Function} fn The function to execute.
886 * @return {EventHandle} Unsubscribe handle.
887 * @deprecated use on.
889 subscribe: function(fn, context) {
890 Y.log('ce.subscribe deprecated, use "on"', 'warn', 'deprecated');
891 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
892 return this._on(fn, context, a, true);
896 * Listen for this event
898 * @param {Function} fn The function to execute.
899 * @param {object} context optional execution context.
900 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
901 * when the event fires.
902 * @return {EventHandle} An object with a detach method to detch the handler(s).
904 on: function(fn, context) {
905 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
907 if (this.monitored && this.host) {
908 this.host._monitor('attach', this, {
912 return this._on(fn, context, a, true);
916 * Listen for this event after the normal subscribers have been notified and
917 * the default behavior has been applied. If a normal subscriber prevents the
918 * default behavior, it also prevents after listeners from firing.
920 * @param {Function} fn The function to execute.
921 * @param {object} context optional execution context.
922 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber
923 * when the event fires.
924 * @return {EventHandle} handle Unsubscribe handle.
926 after: function(fn, context) {
927 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null;
928 return this._on(fn, context, a, AFTER);
934 * @param {Function} fn The subscribed function to remove, if not supplied
935 * all will be removed.
936 * @param {Object} context The context object passed to subscribe.
937 * @return {int} returns the number of subscribers unsubscribed.
939 detach: function(fn, context) {
940 // unsubscribe handle
941 if (fn && fn.detach) {
947 subs = this._subscribers,
948 afters = this._afters;
951 for (i = subs.length; i >= 0; i--) {
953 if (s && (!fn || fn === s.fn)) {
954 this._delete(s, subs, i);
961 for (i = afters.length; i >= 0; i--) {
963 if (s && (!fn || fn === s.fn)) {
964 this._delete(s, afters, i);
975 * @method unsubscribe
976 * @param {Function} fn The subscribed function to remove, if not supplied
977 * all will be removed.
978 * @param {Object} context The context object passed to subscribe.
979 * @return {int|undefined} returns the number of subscribers unsubscribed.
980 * @deprecated use detach.
982 unsubscribe: function() {
983 return this.detach.apply(this, arguments);
987 * Notify a single subscriber
989 * @param {Subscriber} s the subscriber.
990 * @param {Array} args the arguments array to apply to the listener.
993 _notify: function(s, args, ef) {
995 this.log(this.type + '->' + 'sub: ' + s.id);
999 ret = s.notify(args, this);
1001 if (false === ret || this.stopped > 1) {
1002 this.log(this.type + ' cancelled by subscriber');
1010 * Logger abstraction to centralize the application of the silent flag
1012 * @param {string} msg message to log.
1013 * @param {string} cat log category.
1015 log: function(msg, cat) {
1016 if (!this.silent) { Y.log(this.id + ': ' + msg, cat || 'info', 'event'); }
1020 * Notifies the subscribers. The callback functions will be executed
1021 * from the context specified when the event was created, and with the
1022 * following parameters:
1024 * <li>The type of event</li>
1025 * <li>All of the arguments fire() was executed with as an array</li>
1026 * <li>The custom object (if any) that was passed into the subscribe()
1030 * @param {Object*} arguments an arbitrary set of parameters to pass to
1032 * @return {boolean} false if one of the subscribers returned false,
1038 // push is the fastest way to go from arguments to arrays
1039 // for most browsers currently
1040 // http://jsperf.com/push-vs-concat-vs-slice/2
1043 args.push.apply(args, arguments);
1045 return this._fire(args);
1049 * Private internal implementation for `fire`, which is can be used directly by
1050 * `EventTarget` and other event module classes which have already converted from
1051 * an `arguments` list to an array, to avoid the repeated overhead.
1055 * @param {Array} args The array of arguments passed to be passed to handlers.
1056 * @return {boolean} false if one of the subscribers returned false, true otherwise.
1058 _fire: function(args) {
1060 if (this.fireOnce && this.fired) {
1061 this.log('fireOnce event: ' + this.type + ' already fired');
1065 // this doesn't happen if the event isn't published
1066 // this.host._monitor('fire', this.type, args);
1070 if (this.fireOnce) {
1071 this.firedWith = args;
1074 if (this.emitFacade) {
1075 return this.fireComplex(args);
1077 return this.fireSimple(args);
1083 * Set up for notifying subscribers of non-emitFacade events.
1085 * @method fireSimple
1086 * @param args {Array} Arguments passed to fire()
1087 * @return Boolean false if a subscriber returned false
1090 fireSimple: function(args) {
1093 if (this.hasSubs()) {
1094 var subs = this.getSubs();
1095 this._procSubs(subs[0], args);
1096 this._procSubs(subs[1], args);
1098 if (this.broadcast) {
1099 this._broadcast(args);
1101 return this.stopped ? false : true;
1104 // Requires the event-custom-complex module for full funcitonality.
1105 fireComplex: function(args) {
1106 this.log('Missing event-custom-complex needed to emit a facade for: ' + this.type);
1107 args[0] = args[0] || {};
1108 return this.fireSimple(args);
1112 * Notifies a list of subscribers.
1115 * @param subs {Array} List of subscribers
1116 * @param args {Array} Arguments passed to fire()
1118 * @return Boolean false if a subscriber returns false or stops the event
1119 * propagation via e.stopPropagation(),
1120 * e.stopImmediatePropagation(), or e.halt()
1123 _procSubs: function(subs, args, ef) {
1126 for (i = 0, l = subs.length; i < l; i++) {
1129 if (false === this._notify(s, args, ef)) {
1132 if (this.stopped === 2) {
1142 * Notifies the YUI instance if the event is configured with broadcast = 1,
1143 * and both the YUI instance and Y.Global if configured with broadcast = 2.
1145 * @method _broadcast
1146 * @param args {Array} Arguments sent to fire()
1149 _broadcast: function(args) {
1150 if (!this.stopped && this.broadcast) {
1152 var a = args.concat();
1153 a.unshift(this.type);
1155 if (this.host !== Y) {
1159 if (this.broadcast === 2) {
1160 Y.Global.fire.apply(Y.Global, a);
1166 * Removes all listeners
1167 * @method unsubscribeAll
1168 * @return {int} The number of listeners unsubscribed.
1169 * @deprecated use detachAll.
1171 unsubscribeAll: function() {
1172 return this.detachAll.apply(this, arguments);
1176 * Removes all listeners
1178 * @return {int} The number of listeners unsubscribed.
1180 detachAll: function() {
1181 return this.detach();
1185 * Deletes the subscriber from the internal store of on() and after()
1189 * @param s subscriber object.
1190 * @param subs (optional) on or after subscriber array
1191 * @param index (optional) The index found.
1194 _delete: function(s, subs, i) {
1198 subs = (when === AFTER) ? this._afters : this._subscribers;
1202 i = YArray.indexOf(subs, s, 0);
1204 if (s && subs[i] === s) {
1210 if (when === AFTER) {
1211 delete this.afters[s.id];
1213 delete this.subscribers[s.id];
1217 if (this.monitored && this.host) {
1218 this.host._monitor('detach', this, {
1230 * Stores the subscriber information to be used when the event fires.
1231 * @param {Function} fn The wrapped function to execute.
1232 * @param {Object} context The value of the keyword 'this' in the listener.
1233 * @param {Array} args* 0..n additional arguments to supply the listener.
1238 Y.Subscriber = function(fn, context, args, when) {
1241 * The callback that will be execute when the event fires
1242 * This is wrapped by Y.rbind if obj was supplied.
1249 * Optional 'this' keyword for the listener
1253 this.context = context;
1256 * Unique subscriber id
1263 * Additional arguments to propagate to the subscriber
1272 * Custom events for a given fire transaction.
1274 * @type {EventTarget}
1276 // this.events = null;
1279 * This listener only reacts to the event once
1282 // this.once = false;
1286 Y.Subscriber.prototype = {
1287 constructor: Y.Subscriber,
1289 _notify: function(c, args, ce) {
1290 if (this.deleted && !this.postponed) {
1291 if (this.postponed) {
1293 delete this.context;
1295 delete this.postponed;
1299 var a = this.args, ret;
1300 switch (ce.signature) {
1302 ret = this.fn.call(c, ce.type, args, c);
1305 ret = this.fn.call(c, args[0] || null, c);
1310 a = (a) ? args.concat(a) : args;
1311 ret = this.fn.apply(c, a);
1313 ret = this.fn.call(c);
1325 * Executes the subscriber.
1327 * @param args {Array} Arguments array for the subscriber.
1328 * @param ce {CustomEvent} The custom event that sent the notification.
1330 notify: function(args, ce) {
1331 var c = this.context,
1335 c = (ce.contextFn) ? ce.contextFn() : ce.context;
1338 // only catch errors if we will not re-throw them.
1339 if (Y.config && Y.config.throwFail) {
1340 ret = this._notify(c, args, ce);
1343 ret = this._notify(c, args, ce);
1345 Y.error(this + ' failed: ' + e.message, e);
1353 * Returns true if the fn and obj match this objects properties.
1354 * Used by the unsubscribe method to match the right subscriber.
1357 * @param {Function} fn the function to execute.
1358 * @param {Object} context optional 'this' keyword for the listener.
1359 * @return {boolean} true if the supplied arguments match this
1360 * subscriber's signature.
1362 contains: function(fn, context) {
1364 return ((this.fn === fn) && this.context === context);
1366 return (this.fn === fn);
1370 valueOf : function() {
1376 * Return value from all subscribe operations
1377 * @class EventHandle
1379 * @param {CustomEvent} evt the custom event.
1380 * @param {Subscriber} sub the subscriber.
1382 Y.EventHandle = function(evt, sub) {
1393 * The subscriber object
1401 Y.EventHandle.prototype = {
1402 batch: function(f, c) {
1403 f.call(c || this, this);
1404 if (Y.Lang.isArray(this.evt)) {
1405 Y.Array.each(this.evt, function(h) {
1406 h.batch.call(c || h, f);
1412 * Detaches this subscriber
1414 * @return {int} the number of detached listeners
1416 detach: function() {
1417 var evt = this.evt, detached = 0, i;
1419 // Y.log('EventHandle.detach: ' + this.sub, 'info', 'Event');
1420 if (Y.Lang.isArray(evt)) {
1421 for (i = 0; i < evt.length; i++) {
1422 detached += evt[i].detach();
1425 evt._delete(this.sub);
1435 * Monitor the event state for the subscribed event. The first parameter
1436 * is what should be monitored, the rest are the normal parameters when
1437 * subscribing to an event.
1439 * @param what {string} what to monitor ('attach', 'detach', 'publish').
1440 * @return {EventHandle} return value from the monitor event subscription.
1442 monitor: function(what) {
1443 return this.evt.monitor.apply(this.evt, arguments);
1448 * Custom event engine, DOM event listener abstraction layer, synthetic DOM
1450 * @module event-custom
1451 * @submodule event-custom-base
1455 * EventTarget provides the implementation for any object to
1456 * publish, subscribe and fire to custom events, and also
1457 * alows other EventTargets to target the object with events
1458 * sourced from the other object.
1459 * EventTarget is designed to be used with Y.augment to wrap
1460 * EventCustom in an interface that allows events to be listened to
1461 * and fired by name. This makes it possible for implementing code to
1462 * subscribe to an event that either has not been created yet, or will
1463 * not be created at all.
1464 * @class EventTarget
1465 * @param opts a configuration object
1466 * @config emitFacade {boolean} if true, all events will emit event
1467 * facade payloads by default (default false)
1468 * @config prefix {String} the prefix to apply to non-prefixed event names
1472 PREFIX_DELIMITER = ':',
1473 CATEGORY_DELIMITER = '|',
1474 AFTER_PREFIX = '~AFTER~',
1475 WILD_TYPE_RE = /(.*?)(:)(.*?)/,
1477 _wildType = Y.cached(function(type) {
1478 return type.replace(WILD_TYPE_RE, "*$2$3");
1482 * If the instance has a prefix attribute and the
1483 * event type is not prefixed, the instance prefix is
1484 * applied to the supplied type.
1488 _getType = function(type, pre) {
1490 if (!pre || !type || type.indexOf(PREFIX_DELIMITER) > -1) {
1494 return pre + PREFIX_DELIMITER + type;
1498 * Returns an array with the detach key (if provided),
1499 * and the prefixed event name from _getType
1500 * Y.on('detachcategory| menu:click', fn)
1501 * @method _parseType
1504 _parseType = Y.cached(function(type, pre) {
1506 var t = type, detachcategory, after, i;
1508 if (!L.isString(t)) {
1512 i = t.indexOf(AFTER_PREFIX);
1516 t = t.substr(AFTER_PREFIX.length);
1519 i = t.indexOf(CATEGORY_DELIMITER);
1522 detachcategory = t.substr(0, (i));
1529 // detach category, full type with instance prefix, is this an after listener, short type
1530 return [detachcategory, (pre) ? _getType(t, pre) : t, after, t];
1533 ET = function(opts) {
1535 var etState = this._yuievt,
1539 etState = this._yuievt = {
1540 events: {}, // PERF: Not much point instantiating lazily. We're bound to have events
1541 targets: null, // PERF: Instantiate lazily, if user actually adds target,
1546 chain: Y.config.chain
1550 etConfig = etState.config;
1553 mixConfigs(etConfig, opts, true);
1555 if (opts.chain !== undefined) {
1556 etState.chain = opts.chain;
1560 etConfig.prefix = opts.prefix;
1570 * Listen to a custom event hosted by this object one time.
1571 * This is the equivalent to <code>on</code> except the
1572 * listener is immediatelly detached when it is executed.
1574 * @param {String} type The name of the event
1575 * @param {Function} fn The callback to execute in response to the event
1576 * @param {Object} [context] Override `this` object in callback
1577 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
1578 * @return {EventHandle} A subscription handle capable of detaching the
1582 var handle = this.on.apply(this, arguments);
1583 handle.batch(function(hand) {
1585 hand.sub.once = true;
1592 * Listen to a custom event hosted by this object one time.
1593 * This is the equivalent to <code>after</code> except the
1594 * listener is immediatelly detached when it is executed.
1596 * @param {String} type The name of the event
1597 * @param {Function} fn The callback to execute in response to the event
1598 * @param {Object} [context] Override `this` object in callback
1599 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
1600 * @return {EventHandle} A subscription handle capable of detaching that
1603 onceAfter: function() {
1604 var handle = this.after.apply(this, arguments);
1605 handle.batch(function(hand) {
1607 hand.sub.once = true;
1614 * Takes the type parameter passed to 'on' and parses out the
1615 * various pieces that could be included in the type. If the
1616 * event type is passed without a prefix, it will be expanded
1617 * to include the prefix one is supplied or the event target
1618 * is configured with a default prefix.
1620 * @param {String} type the type
1621 * @param {String} [pre=this._yuievt.config.prefix] the prefix
1623 * @return {Array} an array containing:
1624 * * the detach category, if supplied,
1625 * * the prefixed event type,
1626 * * whether or not this is an after listener,
1627 * * the supplied event type
1629 parseType: function(type, pre) {
1630 return _parseType(type, pre || this._yuievt.config.prefix);
1634 * Subscribe a callback function to a custom event fired by this object or
1635 * from an object that bubbles its events to this object.
1637 * Callback functions for events published with `emitFacade = true` will
1638 * receive an `EventFacade` as the first argument (typically named "e").
1639 * These callbacks can then call `e.preventDefault()` to disable the
1640 * behavior published to that event's `defaultFn`. See the `EventFacade`
1641 * API for all available properties and methods. Subscribers to
1642 * non-`emitFacade` events will receive the arguments passed to `fire()`
1643 * after the event name.
1645 * To subscribe to multiple events at once, pass an object as the first
1646 * argument, where the key:value pairs correspond to the eventName:callback,
1647 * or pass an array of event names as the first argument to subscribe to
1648 * all listed events with the same callback.
1650 * Returning `false` from a callback is supported as an alternative to
1651 * calling `e.preventDefault(); e.stopPropagation();`. However, it is
1652 * recommended to use the event methods whenever possible.
1655 * @param {String} type The name of the event
1656 * @param {Function} fn The callback to execute in response to the event
1657 * @param {Object} [context] Override `this` object in callback
1658 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
1659 * @return {EventHandle} A subscription handle capable of detaching that
1662 on: function(type, fn, context) {
1664 var yuievt = this._yuievt,
1665 parts = _parseType(type, yuievt.config.prefix), f, c, args, ret, ce,
1666 detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype,
1667 Node = Y.Node, n, domevent, isArr;
1669 // full name, args, detachcategory, after
1670 this._monitor('attach', parts[1], {
1676 if (L.isObject(type)) {
1678 if (L.isFunction(type)) {
1679 return Y.Do.before.apply(Y.Do, arguments);
1684 args = nativeSlice.call(arguments, 0);
1687 if (L.isArray(type)) {
1691 after = type._after;
1694 Y.each(type, function(v, k) {
1696 if (L.isObject(v)) {
1697 f = v.fn || ((L.isFunction(v)) ? v : f);
1701 var nv = (after) ? AFTER_PREFIX : '';
1703 args[0] = nv + ((isArr) ? v : k);
1707 ret.push(this.on.apply(this, args));
1711 return (yuievt.chain) ? this : new Y.EventHandle(ret);
1714 detachcategory = parts[0];
1716 shorttype = parts[3];
1718 // extra redirection so we catch adaptor events too. take a look at this.
1719 if (Node && Y.instanceOf(this, Node) && (shorttype in Node.DOM_EVENTS)) {
1720 args = nativeSlice.call(arguments, 0);
1721 args.splice(2, 0, Node.getDOMNode(this));
1722 // Y.log("Node detected, redirecting with these args: " + args);
1723 return Y.on.apply(Y, args);
1728 if (Y.instanceOf(this, YUI)) {
1730 adapt = Y.Env.evt.plugins[type];
1731 args = nativeSlice.call(arguments, 0);
1732 args[0] = shorttype;
1737 if (Y.instanceOf(n, Y.NodeList)) {
1738 n = Y.NodeList.getDOMNodes(n);
1739 } else if (Y.instanceOf(n, Node)) {
1740 n = Node.getDOMNode(n);
1743 domevent = (shorttype in Node.DOM_EVENTS);
1745 // Captures both DOM events and event plugins.
1751 // check for the existance of an event adaptor
1753 Y.log('Using adaptor for ' + shorttype + ', ' + n, 'info', 'event');
1754 handle = adapt.on.apply(Y, args);
1755 } else if ((!type) || domevent) {
1756 handle = Y.Event._attach(args);
1762 ce = yuievt.events[type] || this.publish(type);
1763 handle = ce._on(fn, context, (arguments.length > 3) ? nativeSlice.call(arguments, 3) : null, (after) ? 'after' : true);
1765 // TODO: More robust regex, accounting for category
1766 if (type.indexOf("*:") !== -1) {
1767 this._hasSiblings = true;
1771 if (detachcategory) {
1772 store[detachcategory] = store[detachcategory] || {};
1773 store[detachcategory][type] = store[detachcategory][type] || [];
1774 store[detachcategory][type].push(handle);
1777 return (yuievt.chain) ? this : handle;
1782 * subscribe to an event
1784 * @deprecated use on
1786 subscribe: function() {
1787 Y.log('EventTarget subscribe() is deprecated, use on()', 'warn', 'deprecated');
1788 return this.on.apply(this, arguments);
1792 * Detach one or more listeners the from the specified event
1794 * @param type {string|Object} Either the handle to the subscriber or the
1795 * type of event. If the type
1796 * is not specified, it will attempt to remove
1797 * the listener from all hosted events.
1798 * @param fn {Function} The subscribed function to unsubscribe, if not
1799 * supplied, all subscribers will be removed.
1800 * @param context {Object} The custom object passed to subscribe. This is
1801 * optional, but if supplied will be used to
1802 * disambiguate multiple listeners that are the same
1803 * (e.g., you subscribe many object using a function
1804 * that lives on the prototype)
1805 * @return {EventTarget} the host
1807 detach: function(type, fn, context) {
1809 var evts = this._yuievt.events,
1812 isNode = Node && (Y.instanceOf(this, Node));
1814 // detachAll disabled on the Y instance.
1815 if (!type && (this !== Y)) {
1817 if (evts.hasOwnProperty(i)) {
1818 evts[i].detach(fn, context);
1822 Y.Event.purgeElement(Node.getDOMNode(this));
1828 var parts = _parseType(type, this._yuievt.config.prefix),
1829 detachcategory = L.isArray(parts) ? parts[0] : null,
1830 shorttype = (parts) ? parts[3] : null,
1831 adapt, store = Y.Env.evt.handles, detachhost, cat, args,
1834 keyDetacher = function(lcat, ltype, host) {
1835 var handles = lcat[ltype], ce, i;
1837 for (i = handles.length - 1; i >= 0; --i) {
1838 ce = handles[i].evt;
1839 if (ce.host === host || ce.el === host) {
1840 handles[i].detach();
1846 if (detachcategory) {
1848 cat = store[detachcategory];
1850 detachhost = (isNode) ? Y.Node.getDOMNode(this) : this;
1854 keyDetacher(cat, type, detachhost);
1857 if (cat.hasOwnProperty(i)) {
1858 keyDetacher(cat, i, detachhost);
1866 // If this is an event handle, use it to detach
1867 } else if (L.isObject(type) && type.detach) {
1870 // extra redirection so we catch adaptor events too. take a look at this.
1871 } else if (isNode && ((!shorttype) || (shorttype in Node.DOM_EVENTS))) {
1872 args = nativeSlice.call(arguments, 0);
1873 args[2] = Node.getDOMNode(this);
1874 Y.detach.apply(Y, args);
1878 adapt = Y.Env.evt.plugins[shorttype];
1880 // The YUI instance handles DOM events and adaptors
1881 if (Y.instanceOf(this, YUI)) {
1882 args = nativeSlice.call(arguments, 0);
1883 // use the adaptor specific detach code if
1884 if (adapt && adapt.detach) {
1885 adapt.detach.apply(Y, args);
1888 } else if (!type || (!adapt && Node && (type in Node.DOM_EVENTS))) {
1890 Y.Event.detach.apply(Y.Event, args);
1896 ce = evts[parts[1]];
1898 ce.detach(fn, context);
1906 * @method unsubscribe
1907 * @deprecated use detach
1909 unsubscribe: function() {
1910 Y.log('EventTarget unsubscribe() is deprecated, use detach()', 'warn', 'deprecated');
1911 return this.detach.apply(this, arguments);
1915 * Removes all listeners from the specified event. If the event type
1916 * is not specified, all listeners from all hosted custom events will
1919 * @param type {String} The type, or name of the event
1921 detachAll: function(type) {
1922 return this.detach(type);
1926 * Removes all listeners from the specified event. If the event type
1927 * is not specified, all listeners from all hosted custom events will
1929 * @method unsubscribeAll
1930 * @param type {String} The type, or name of the event
1931 * @deprecated use detachAll
1933 unsubscribeAll: function() {
1934 Y.log('EventTarget unsubscribeAll() is deprecated, use detachAll()', 'warn', 'deprecated');
1935 return this.detachAll.apply(this, arguments);
1939 * Creates a new custom event of the specified type. If a custom event
1940 * by that name already exists, it will not be re-created. In either
1941 * case the custom event is returned.
1945 * @param type {String} the type, or name of the event
1946 * @param opts {object} optional config params. Valid properties are:
1950 * 'broadcast': whether or not the YUI instance and YUI global are notified when the event is fired (false)
1953 * 'bubbles': whether or not this event bubbles (true)
1954 * Events can only bubble if emitFacade is true.
1957 * 'context': the default execution context for the listeners (this)
1960 * 'defaultFn': the default function to execute when this event fires if preventDefault was not called
1963 * 'emitFacade': whether or not this event emits a facade (false)
1966 * 'prefix': the prefix for this targets events, e.g., 'menu' in 'menu:click'
1969 * 'fireOnce': if an event is configured to fire once, new subscribers after
1970 * the fire will be notified immediately.
1973 * 'async': fireOnce event listeners will fire synchronously if the event has already
1974 * fired unless async is true.
1977 * 'preventable': whether or not preventDefault() has an effect (true)
1980 * 'preventedFn': a function that is executed when preventDefault is called
1983 * 'queuable': whether or not this event can be queued during bubbling (false)
1986 * 'silent': if silent is true, debug messages are not provided for this event.
1989 * 'stoppedFn': a function that is executed when stopPropagation is called
1993 * 'monitored': specifies whether or not this event should send notifications about
1994 * when the event has been attached, detached, or published.
1997 * 'type': the event type (valid option if not provided as the first parameter to publish)
2001 * @return {CustomEvent} the custom event
2004 publish: function(type, opts) {
2007 etState = this._yuievt,
2008 etConfig = etState.config,
2009 pre = etConfig.prefix;
2011 if (typeof type === "string") {
2013 type = _getType(type, pre);
2015 ret = this._publish(type, etConfig, opts);
2019 Y.each(type, function(v, k) {
2021 k = _getType(k, pre);
2023 ret[k] = this._publish(k, etConfig, v || opts);
2032 * Returns the fully qualified type, given a short type string.
2033 * That is, returns "foo:bar" when given "bar" if "foo" is the configured prefix.
2035 * NOTE: This method, unlike _getType, does no checking of the value passed in, and
2036 * is designed to be used with the low level _publish() method, for critical path
2037 * implementations which need to fast-track publish for performance reasons.
2039 * @method _getFullType
2041 * @param {String} type The short type to prefix
2042 * @return {String} The prefixed type, if a prefix is set, otherwise the type passed in
2044 _getFullType : function(type) {
2046 var pre = this._yuievt.config.prefix;
2049 return pre + PREFIX_DELIMITER + type;
2056 * The low level event publish implementation. It expects all the massaging to have been done
2057 * outside of this method. e.g. the `type` to `fullType` conversion. It's designed to be a fast
2058 * path publish, which can be used by critical code paths to improve performance.
2062 * @param {String} fullType The prefixed type of the event to publish.
2063 * @param {Object} etOpts The EventTarget specific configuration to mix into the published event.
2064 * @param {Object} ceOpts The publish specific configuration to mix into the published event.
2065 * @return {CustomEvent} The published event. If called without `etOpts` or `ceOpts`, this will
2066 * be the default `CustomEvent` instance, and can be configured independently.
2068 _publish : function(fullType, etOpts, ceOpts) {
2071 etState = this._yuievt,
2072 etConfig = etState.config,
2073 host = etConfig.host,
2074 context = etConfig.context,
2075 events = etState.events;
2077 ce = events[fullType];
2079 // PERF: Hate to pull the check out of monitor, but trying to keep critical path tight.
2080 if ((etConfig.monitored && !ce) || (ce && ce.monitored)) {
2081 this._monitor('publish', fullType, {
2088 ce = events[fullType] = new Y.CustomEvent(fullType, etOpts);
2092 ce.context = context;
2097 mixConfigs(ce, ceOpts, true);
2104 * This is the entry point for the event monitoring system.
2105 * You can monitor 'attach', 'detach', 'fire', and 'publish'.
2106 * When configured, these events generate an event. click ->
2107 * click_attach, click_detach, click_publish -- these can
2108 * be subscribed to like other events to monitor the event
2109 * system. Inividual published events can have monitoring
2110 * turned on or off (publish can't be turned off before it
2111 * it published) by setting the events 'monitor' config.
2114 * @param what {String} 'attach', 'detach', 'fire', or 'publish'
2115 * @param eventType {String|CustomEvent} The prefixed name of the event being monitored, or the CustomEvent object.
2116 * @param o {Object} Information about the event interaction, such as
2117 * fire() args, subscription category, publish config
2120 _monitor: function(what, eventType, o) {
2121 var monitorevt, ce, type;
2124 if (typeof eventType === "string") {
2126 ce = this.getEvent(eventType, true);
2129 type = eventType.type;
2132 if ((this._yuievt.config.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
2133 monitorevt = type + '_' + what;
2135 this.fire.call(this, monitorevt, o);
2141 * Fire a custom event by name. The callback functions will be executed
2142 * from the context specified when the event was created, and with the
2143 * following parameters.
2145 * The first argument is the event type, and any additional arguments are
2146 * passed to the listeners as parameters. If the first of these is an
2147 * object literal, and the event is configured to emit an event facade,
2148 * that object is mixed into the event facade and the facade is provided
2149 * in place of the original object.
2151 * If the custom event object hasn't been created, then the event hasn't
2152 * been published and it has no subscribers. For performance sake, we
2153 * immediate exit in this case. This means the event won't bubble, so
2154 * if the intention is that a bubble target be notified, the event must
2155 * be published on this object first.
2158 * @param type {String|Object} The type of the event, or an object that contains
2159 * a 'type' property.
2160 * @param arguments {Object*} an arbitrary set of parameters to pass to
2161 * the handler. If the first of these is an object literal and the event is
2162 * configured to emit an event facade, the event facade will replace that
2163 * parameter after the properties the object literal contains are copied to
2165 * @return {Boolean} True if the whole lifecycle of the event went through,
2166 * false if at any point the event propagation was halted.
2168 fire: function(type) {
2170 var typeIncluded = (typeof type === "string"),
2171 argCount = arguments.length,
2173 yuievt = this._yuievt,
2174 etConfig = yuievt.config,
2175 pre = etConfig.prefix,
2181 if (typeIncluded && argCount <= 3) {
2183 // PERF: Try to avoid slice/iteration for the common signatures
2186 if (argCount === 2) {
2187 args = [arguments[1]]; // fire("foo", {})
2188 } else if (argCount === 3) {
2189 args = [arguments[1], arguments[2]]; // fire("foo", {}, opts)
2191 args = []; // fire("foo")
2195 args = nativeSlice.call(arguments, ((typeIncluded) ? 1 : 0));
2198 if (!typeIncluded) {
2199 t = (type && type.type);
2203 t = _getType(t, pre);
2206 ce = yuievt.events[t];
2208 if (this._hasSiblings) {
2209 ce2 = this.getSibling(t, ce);
2212 ce = this.publish(t);
2216 // PERF: trying to avoid function call, since this is a critical path
2217 if ((etConfig.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) {
2218 this._monitor('fire', (ce || t), {
2223 // this event has not been published or subscribed to
2225 if (yuievt.hasTargets) {
2226 return this.bubble({ type: t }, args, this);
2229 // otherwise there is nothing to be done
2237 ret = ce._fire(args);
2240 return (yuievt.chain) ? this : ret;
2243 getSibling: function(type, ce) {
2246 // delegate to *:type events if there are subscribers
2247 if (type.indexOf(PREFIX_DELIMITER) > -1) {
2248 type = _wildType(type);
2249 ce2 = this.getEvent(type, true);
2251 ce2.applyConfig(ce);
2252 ce2.bubbles = false;
2261 * Returns the custom event of the provided type has been created, a
2262 * falsy value otherwise
2264 * @param type {String} the type, or name of the event
2265 * @param prefixed {String} if true, the type is prefixed already
2266 * @return {CustomEvent} the custom event or null
2268 getEvent: function(type, prefixed) {
2272 pre = this._yuievt.config.prefix;
2273 type = (pre) ? _getType(type, pre) : type;
2275 e = this._yuievt.events;
2276 return e[type] || null;
2280 * Subscribe to a custom event hosted by this object. The
2281 * supplied callback will execute after any listeners add
2282 * via the subscribe method, and after the default function,
2283 * if configured for the event, has executed.
2286 * @param {String} type The name of the event
2287 * @param {Function} fn The callback to execute in response to the event
2288 * @param {Object} [context] Override `this` object in callback
2289 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
2290 * @return {EventHandle} A subscription handle capable of detaching the
2293 after: function(type, fn) {
2295 var a = nativeSlice.call(arguments, 0);
2297 switch (L.type(type)) {
2299 return Y.Do.after.apply(Y.Do, arguments);
2301 // YArray.each(a[0], function(v) {
2302 // v = AFTER_PREFIX + v;
2309 a[0] = AFTER_PREFIX + type;
2312 return this.on.apply(this, a);
2317 * Executes the callback before a DOM event, custom event
2318 * or method. If the first argument is a function, it
2319 * is assumed the target is a method. For DOM and custom
2320 * events, this is an alias for Y.on.
2322 * For DOM and custom events:
2323 * type, callback, context, 0-n arguments
2326 * callback, object (method host), methodName, context, 0-n arguments
2329 * @return detach handle
2331 before: function() {
2332 return this.on.apply(this, arguments);
2339 // make Y an event target
2340 Y.mix(Y, ET.prototype);
2341 ET.call(Y, { bubbles: false });
2343 YUI.Env.globalEvents = YUI.Env.globalEvents || new ET();
2346 * Hosts YUI page level events. This is where events bubble to
2347 * when the broadcast config is set to 2. This property is
2348 * only available if the custom event module is loaded.
2353 Y.Global = YUI.Env.globalEvents;
2355 // @TODO implement a global namespace function on Y.Global?
2358 `Y.on()` can do many things:
2361 <li>Subscribe to custom events `publish`ed and `fire`d from Y</li>
2362 <li>Subscribe to custom events `publish`ed with `broadcast` 1 or 2 and
2363 `fire`d from any object in the YUI instance sandbox</li>
2364 <li>Subscribe to DOM events</li>
2365 <li>Subscribe to the execution of a method on any object, effectively
2366 treating that method as an event</li>
2369 For custom event subscriptions, pass the custom event name as the first argument
2370 and callback as the second. The `this` object in the callback will be `Y` unless
2371 an override is passed as the third argument.
2373 Y.on('io:complete', function () {
2374 Y.MyApp.updateStatus('Transaction complete');
2377 To subscribe to DOM events, pass the name of a DOM event as the first argument
2378 and a CSS selector string as the third argument after the callback function.
2379 Alternately, the third argument can be a `Node`, `NodeList`, `HTMLElement`,
2380 array, or simply omitted (the default is the `window` object).
2382 Y.on('click', function (e) {
2385 // proceed with ajax form submission
2386 var url = this.get('action');
2390 The `this` object in DOM event callbacks will be the `Node` targeted by the CSS
2391 selector or other identifier.
2393 `on()` subscribers for DOM events or custom events `publish`ed with a
2394 `defaultFn` can prevent the default behavior with `e.preventDefault()` from the
2395 event object passed as the first parameter to the subscription callback.
2397 To subscribe to the execution of an object method, pass arguments corresponding to the call signature for
2398 <a href="../classes/Do.html#methods_before">`Y.Do.before(...)`</a>.
2400 NOTE: The formal parameter list below is for events, not for function
2401 injection. See `Y.Do.before` for that signature.
2404 @param {String} type DOM or custom event name
2405 @param {Function} fn The callback to execute in response to the event
2406 @param {Object} [context] Override `this` object in callback
2407 @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
2408 @return {EventHandle} A subscription handle capable of detaching the
2415 Listen for an event one time. Equivalent to `on()`, except that
2416 the listener is immediately detached when executed.
2418 See the <a href="#methods_on">`on()` method</a> for additional subscription
2423 @param {String} type DOM or custom event name
2424 @param {Function} fn The callback to execute in response to the event
2425 @param {Object} [context] Override `this` object in callback
2426 @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
2427 @return {EventHandle} A subscription handle capable of detaching the
2433 Listen for an event one time. Equivalent to `once()`, except, like `after()`,
2434 the subscription callback executes after all `on()` subscribers and the event's
2435 `defaultFn` (if configured) have executed. Like `after()` if any `on()` phase
2436 subscriber calls `e.preventDefault()`, neither the `defaultFn` nor the `after()`
2437 subscribers will execute.
2439 The listener is immediately detached when executed.
2441 See the <a href="#methods_on">`on()` method</a> for additional subscription
2446 @param {String} type The custom event name
2447 @param {Function} fn The callback to execute in response to the event
2448 @param {Object} [context] Override `this` object in callback
2449 @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
2450 @return {EventHandle} A subscription handle capable of detaching the
2456 Like `on()`, this method creates a subscription to a custom event or to the
2457 execution of a method on an object.
2459 For events, `after()` subscribers are executed after the event's
2460 `defaultFn` unless `e.preventDefault()` was called from an `on()` subscriber.
2462 See the <a href="#methods_on">`on()` method</a> for additional subscription
2465 NOTE: The subscription signature shown is for events, not for function
2466 injection. See <a href="../classes/Do.html#methods_after">`Y.Do.after`</a>
2472 @param {String} type The custom event name
2473 @param {Function} fn The callback to execute in response to the event
2474 @param {Object} [context] Override `this` object in callback
2475 @param {Any} [args*] 0..n additional arguments to supply to the subscriber
2476 @return {EventHandle} A subscription handle capable of detaching the
2482 }, '3.13.0', {"requires": ["oop"]});