~smagoun/whoopsie/whoopsie-lp1017637

« back to all changes in this revision

Viewing changes to backend/stats/static/js/yui/build/event-custom-base/event-custom-base-debug.js

  • Committer: Evan Dandrea
  • Date: 2012-05-09 05:53:45 UTC
  • Revision ID: evan.dandrea@canonical.com-20120509055345-z2j41tmcbf4as5uf
The backend now lives in lp:daisy and the website (errors.ubuntu.com) now lives in lp:errors.

Show diffs side-by-side

added added

removed removed

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