[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

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


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