[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/event-custom-base/ -> event-custom-base-debug.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1