src/cm/media/js/lib/yui/yui_3.10.3/docs/event-custom/index.html
changeset 525 89ef5ed3c48b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cm/media/js/lib/yui/yui_3.10.3/docs/event-custom/index.html	Tue Jul 16 14:29:46 2013 +0200
@@ -0,0 +1,1247 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>EventTarget</title>
+    <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic">
+    <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css">
+    <link rel="stylesheet" href="../assets/css/main.css">
+    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
+    <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
+    <script src="../../build/yui/yui-min.js"></script>
+    
+</head>
+<body>
+<!--
+<a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
+-->
+<div id="doc">
+    <div id="hd">
+        <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1>
+    </div>
+    
+        <a href="#toc" class="jump">Jump to Table of Contents</a>
+    
+
+            <h1>EventTarget</h1>
+    <div class="yui3-g">
+        <div class="yui3-u-3-4">
+            <div id="main">
+                <div class="content"><link type="text/css" rel="stylesheet" href="../../build/cssbutton/cssbutton-min.css">
+<div class="intro">
+    <p>
+        The YUI Custom Event System enables you to define and use events beyond
+        those available in the DOM &mdash; events that are specific to and of
+        interest in your own application. Custom Events are designed to work
+        much like DOM events.  They can bubble, pass event facades, have their
+        propagation and default behaviors suppressed, etc.
+    </p>
+
+    <p>
+        The APIs for working with custom events are provided by the
+        <code>EventTarget</code> class.  All other infrastructure classes extend
+        <code>EventTarget</code>, but if you just need the custom event APIs, you can
+        <code>extend</code> or <code>augment</code> your classes with <code>EventTarget</code> directly.
+    </p>
+
+    <p class="deprecated"><strong>DEPRECATION NOTE:</strong> The <code>subscribers</code> and <code>afters</code> properties which
+       used to sit on <code>CustomEvent</code> object instances have been deprecated and 
+       removed for performance reasons as of the 3.7.0 release.
+    </p>
+
+    <p>If you're referring to the <code>subscribers</code> or <code>afters</code> properties directly just
+       to access the set of subscribers,  consider switching to the public <code>getSubs()</code> 
+       method instead which hides you from the implementation details.</p>
+
+    <p>If you have a use case which requires you to access the above properties 
+       directly you can set <code>Y.CustomEvent.keepDeprecatedSubs</code> to true, to restore 
+       them, but you will incur a performance hit if you enable this flag.
+    </p>
+
+    <!--p>
+        Bundled with <code>EventTarget</code> are <a
+        href="http://en.wikipedia.org/wiki/Aspect_oriented_programming">Aspect
+        Oriented Programming</a> methods that allow you to subscribe to the
+        execution of object methods, and 
+        their own.
+    </p-->
+</div>
+
+<!-- insert Events Evolved video here -->
+
+<h2 id="getting-started">Getting Started</h2>
+
+<p>
+To include the source files for EventTarget and its dependencies, first load
+the YUI seed file if you haven't already loaded it.
+</p>
+
+<pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.10.3&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>
+
+
+<p>
+Next, create a new YUI instance for your application and populate it with the
+modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
+YUI will automatically load any dependencies required by the modules you
+specify.
+</p>
+
+<pre class="code prettyprint">&lt;script&gt;
+&#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
+YUI().use(&#x27;event-custom&#x27;, function (Y) {
+    &#x2F;&#x2F; EventTarget is available and ready for use. Add implementation
+    &#x2F;&#x2F; code here.
+});
+&lt;&#x2F;script&gt;</pre>
+
+
+<p>
+For more information on creating YUI instances and on the
+<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
+documentation for the <a href="../yui/index.html">YUI Global Object</a>.
+</p>
+
+
+<h2 id="video-overview">Video Overview</h2>
+
+<iframe width="640" height="360" src="http://www.youtube.com/embed/s_7VjN3qxe8" frameborder="0" allowfullscreen></iframe>
+
+<p>
+    This video from YUIConf 2009 gives a good overview of the YUI event system
+    API.  The content covers DOM and custom events.  Note: the <a
+    href="../event/index.html#synthetic-events">synthetic event</a> system was
+    updated since this video.
+</p>
+
+<h2 id="the-basics">The Basics</h2>
+
+<p>
+    You can get started using custom events and the <code>EventTarget</code> API without
+    creating your own class.  The YUI instance (typically <code>Y</code>) is an
+    <code>EventTarget</code>, as is pretty much every other class in YUI.  We'll go over
+    the basics using <code>Y</code>, then move into creating your own <code>EventTarget</code>s.
+</p>
+
+<p>
+    If you've looked over the <a href="../event/index.html#the-basics">DOM
+    Event system docs</a>, this should look very familiar. That's because
+    <code>Node</code>s are also <code>EventTarget</code>s.
+</p>
+
+<h3 id="subscribing-to-events">Subscribing to Events</h3>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Custom events can have any name you want
+Y.on(&#x27;anyOldNameYouWant&#x27;, function () {
+    alert(&quot;Looky there!&quot;);
+});
+
+&#x2F;&#x2F; Group subscriptions by passing an object or array to on()
+Y.on({
+    somethingImportant: updateCalendar,
+    birthday          : eatCake,
+    weekendEnd        : backToTheGrindstone
+});
+
+&#x2F;&#x2F; Some events have prefixes
+Y.once(&quot;fuji:available&quot;, climb);
+
+&#x2F;&#x2F; Custom events have distinct &quot;after&quot; moments
+Y.after(&quot;spa-category|pedicure&quot;, gelatoTime);</pre>
+
+
+<p>
+    All <code>EventTarget</code>s host methods
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventTarget.html#method_on"><code>on</code></a>, 
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventTarget.html#method_once"><code>once</code></a>, 
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventTarget.html#method_after"><code>after</code></a>, and
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventTarget.html#method_onceAfter"><code>onceAfter</code></a>. 
+    Both <code>once</code> and <code>onceAfter</code> will automatically detach the subscription
+    after the callback is executed the first time.  All subscription methods
+    return a subscription object called an
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventHandle.html">EventHandle</a>. The
+    distinction between <code>on</code> and <code>after</code> is discussed in the
+    <a href="#after">"after" phase</a> section below.
+</p>
+
+<h3 id="fire">Firing Events</h3>
+
+<pre class="code prettyprint">&#x2F;&#x2F; All subscribers to the myapp:ready event will be executed
+Y.fire(&#x27;myapp:ready&#x27;);
+
+&#x2F;&#x2F; Pass along relevant data to the callbacks as arguments
+Y.fire(&#x27;birthday&#x27;, {
+    name: &#x27;Walt Disney&#x27;,
+    birthdate: new Date(1901, 11, 5)
+});</pre>
+
+
+<p id="event-data-object">
+    Notify event subscribers by calling <code>fire( eventName )</code>, passing any
+    extra data about the event as additional arguments.  Though <code>fire</code>
+    accepts any number of arguments, it is preferable to send all event data
+    in an object passed as the second argument.  Doing so avoids locking your
+    code into a specific <code>fire</code> and callback signature.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Subscription callbacks receive fire() arguments
+Y.on(&#x27;birthday&#x27;, function (name, birthdate) {
+    var age = new Date().getFullYear() - birthdate.getFullYear();
+    alert(&#x27;Happy &#x27; + age + &#x27;, &#x27; + name + &#x27;!&#x27;);
+});
+
+&#x2F;&#x2F; Possible, but not recommended
+Y.fire(&#x27;birthday&#x27;, &#x27;A. A. Milne&#x27;, new Date(1882, 0, 18));
+
+&#x2F;&#x2F; Instead, try to always pass only one object with all data
+Y.on(&#x27;birthday&#x27;, function (e) {
+    var age = new Date().getFullYear() - e.birthdate.getFullYear();
+    alert(&#x27;Happy &#x27; + age + &#x27;, &#x27; + e.name + &#x27;!&#x27;);
+});
+
+Y.fire(&#x27;birthday&#x27;, {
+    name: &#x27;&quot;Uncle&quot; Walt Whitman&#x27;,
+    birthdate: new Date(1819, 4, 31)
+});</pre>
+
+
+<p>
+    In the world of DOM events, the <code>fire</code> step is something the browser is
+    responsible for.  A typical model involves the browser receiving keyboard
+    input from the user and firing <code>keydown</code>, <code>keyup</code>, and <code>keypress</code> events.
+    Custom events put your code in the position of dispatching events in
+    response to criteria that are relavant to your objects or application.
+</p>
+
+<h3 id="callback-arguments-and-event-facades">Callback arguments and event facades</h3>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Simple notification events don&#x27;t send event objects, only fire() data
+Y.on(&#x27;talkie&#x27;, function (data) {
+    alert(&#x27;(&#x27; + data.time + &#x27;) Walkie &#x27; + data.message);
+    &#x2F;&#x2F; data.preventDefault is not defined. data is just a plain object
+});
+
+Y.fire(&#x27;talkie&#x27;, {
+    message: &#x27;roger, over.&#x27;,
+    time: new Date()
+});
+
+&#x2F;&#x2F; Events configured to emitFacade will send an event object, merged with
+&#x2F;&#x2F; fire() data
+Y.publish(&#x27;bill:due&#x27;, {
+    emitFacade: true,
+    defaultFn : payUp
+});
+
+Y.on(&#x27;bill:due&#x27;, function (e) {
+    &#x2F;&#x2F; Event facades have standard properties and methods as well as properties
+    &#x2F;&#x2F; from payload data passed to fire()
+    if (e.payee === &#x27;Rich Uncle Sal&#x27;) {
+        e.preventDefault(); &#x2F;&#x2F; the &#x60;payUp&#x60; method won&#x27;t be called (Sal can wait)
+    }
+});
+
+&#x2F;&#x2F; Objects passed as the second argument to fire() for facade events will have
+&#x2F;&#x2F; their properties merged onto the facade received by the callback.
+Y.fire(&#x27;bill:due&#x27;, {
+    payee: &#x27;Great Aunt Myra&#x27;,
+    amount: 20
+});</pre>
+
+
+<p>
+    Custom event callbacks are <em>usually, but not always</em> passed an
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventFacade.html">EventFacade</a> as their
+    first argument.  Custom events can be configured to send event facades or
+    only the data they were fired with.  <a href="#event-data-object">Always
+    passing event data in an object</a> as the second argument to <code>fire</code> allows
+    you to write all your callbacks to expect event data as a single first
+    argument, whether it's an <code>EventFacade</code> or just a plain object.  The
+    <code>emitFacade</code> and <code>defaultFn</code> configurations are detailed below, in
+    <a href="#publishing-events">Publishing Events</a>.
+</p>
+
+<h3 id="detaching-event-subscriptions">Detaching Event Subscriptions</h3>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Subscription methods return a subscription handle...
+var subscription = Y.on(&#x27;myapp:ready&#x27;, initComponents);
+
+&#x2F;&#x2F; ...with a detach method
+subscription.detach();
+
+&#x2F;&#x2F; Or detach by signature
+Y.detach(&#x27;myapp:ready&#x27;, initComponents);
+
+&#x2F;&#x2F; Or by subscription category
+Y.on(&#x27;spa-category|pedicure&#x27;, gelatoTime);
+
+&#x2F;&#x2F; Detach subscriptions to all events in the spa-category subscription group
+Y.detach(&#x27;spa-category|*&#x27;);</pre>
+
+
+<p>
+    The preferred method of detaching subscriptions is to use the
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventHandle.html">EventHandle</a> that is
+    returned from the subscription methods.  Alternately you can use the
+    <a href="http://yuilibrary.com/yui/docs/api/classes/EventTarget.html#method_detach"><code>detach</code> or
+    <code>detachAll</code> methods</a> which work as described in the
+    <a href="../event/index.html#detach-methods">Event user guide</a>.
+</p>
+
+<h3 id="extend-event-target">Extending EventTarget</h3>
+
+<p>Add the <code>EventTarget</code> APIs onto any class using <code>Y.augment()</code>.</p>
+
+<pre class="code prettyprint">function MyClass() {
+    &#x2F;* insert constructor logic here *&#x2F;
+}
+
+MyClass.prototype = {
+    add: function (item) {
+        &#x2F;&#x2F; You can assume the APIs are available from your class instances
+        this.fire(&quot;addItem&quot;, { item: item });
+    },
+    ...
+};
+
+&#x2F;&#x2F; Make MyClass an EventTarget
+Y.augment(MyClass, Y.EventTarget);
+
+var instance = new MyClass();
+instance.on(&#x27;addItem&#x27;, function (e) {
+    alert(&quot;Yay, I&#x27;m adding &quot; + e.item);
+});
+
+instance.add(&#x27;a new item&#x27;); &#x2F;&#x2F; ==&gt; &quot;Yay, I&#x27;m adding a new item&quot;</pre>
+
+
+<p>
+    <code>Y.augment</code> works like a lazy <code>extend</code> or a mixin.  It adds the APIs to the
+    host class, but on the first call to any of the methods, it calls the
+    <code>EventTarget</code> constructor on the instance to make sure the necessary
+    internal objects are ready for use.  If your class extends another,
+    augmenting it won't interfere with that inheritance hierarchy.
+</p>
+
+<p>
+    <code>EventTarget</code>s can be set up with a number of default configurations for
+    the events they <code>fire</code>.  Pass the defaults as the fourth argument to
+    <code>Y.augment</code>.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Make all events fired from MyClass instances send an event facade
+Y.augment(MyClass, Y.EventTarget, true, null, {
+    emitFacade: true
+});</pre>
+
+
+<h2 id="publishing-events">Publishing Events</h2>
+
+<p>
+    Some custom event <a href="#configs">configurations can be defaulted</a>
+    from class configuration, but others need to be specified on a per-event
+    basis.  Use the <code>publish</code> method to do this.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; publish takes an event name and a configuration object
+Y.publish(&#x27;somethingSpecial&#x27;, {
+    emitFacade: true,
+    broadcast: 2,
+    defaultFn: clapClapHallelujah,
+    fireOnce: true
+});</pre>
+
+
+<h3 id="facade">Event Facades</h3>
+
+<p>
+    The most common configuration for custom events is <code>emitFacade</code>.  This is
+    because with the event facades comes a lot of additional functionality,
+    such as <a href="#defaultFn">preventable default behaviors</a> and <a
+    href="#bubbling">bubbling</a>.
+</p>
+
+<pre class="code prettyprint">function Recipe() {
+    &#x2F;&#x2F; publishing events is typically done at instantiation
+    this.publish(&#x27;add&#x27;, {
+        emitFacade: true,
+        defaultFn: this._defAddFn
+    });
+}</pre>
+
+
+<p>
+    Event facades mirror the event objects
+    <a href="../event/index.html#facade-properties">you're familiar with from
+    the DOM</a>.  They have properties like <code>e.type</code> and <code>e.target</code> and
+    the same methods, allowing you to call <code>e.preventDefault()</code> to disable
+    default behavior you've configured for the event or <code>e.stopPropagation()</code>
+    to stop the event from bubbling.
+</p>
+
+<pre class="code prettyprint">var gruel = new Recipe();
+
+gruel.on(&#x27;add&#x27;, function (e) {
+    if (e.item === &quot;brussel sprouts&quot;) {
+        &#x2F;&#x2F; call e.preventDefault() just as you would for DOM events
+        e.preventDefault(); &#x2F;&#x2F; brussel sprouts? eww!
+    }
+});</pre>
+
+
+<p>
+    <code>emitFacade</code> is typically passed as a default configuration to <code>Y.augment</code>.
+    All other YUI infrastructure classes extend <code>EventTarget</code> and set 
+    <code>emitFacade</code> to <code>true</code> for you.
+</p>
+
+<pre class="code prettyprint">Y.extend(MyClass, Y.Base, {
+    add: function (item) {
+        &#x2F;&#x2F; This will fire with an event facade because Y.Base sets emitFacade to true
+        this.fire(&#x27;addItem&#x27;, { item: item });
+    },
+    ...
+});</pre>
+
+
+<h3 id="once"><code>fireOnce</code> Events</h3>
+
+<p>
+    Important, typically system-level or lifecycle related events can be
+    configured as <code>fireOnce</code>.  These events mimic things like <code>window.onload</code>
+    or the <code>domready</code> event.
+</p>
+
+<pre class="code prettyprint">Widget.prototype.render = function (where) {
+    ...
+
+    &#x2F;&#x2F; Widget rendering only happens once
+    this.publish(&#x27;render&#x27;, {
+        defaultFn: this._defRenderFn,
+        fireOnce: true,
+        ...
+    });
+
+    this.fire(&#x27;render&#x27;, ...);
+};</pre>
+
+
+<p>
+    After <code>fireOnce</code> events have been <code>fire()</code>d, any subsequent (late)
+    subscriptions are immediately executed.  This can introduce race
+    conditions, however, since subscribers might expect to be called at a later
+    time, after the code that follows the subscription has also executed.  In
+    this case, you can configure <code>fireOnce</code> events with the <code>async</code> flag
+    and post-<code>fire</code> subscriptions will be executed in a <code>setTimeout</code>,
+    allowing all subsequent code to run before the late subscriber is notified.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; BEFORE
+Y.publish(&#x27;myapp:ready&#x27;, {
+    fireOnce: true
+});
+
+&#x2F;&#x2F; ... elsewhere in the code
+&#x2F;&#x2F; If myapp:ready has been fired, setStuffUp executes right now, but might
+&#x2F;&#x2F; expect MyApp.Stuff to be created already.  So, boom.
+Y.on(&#x27;myapp:ready&#x27;, setStuffUp);
+
+MyApp.Stuff = {};
+
+&#x2F;&#x2F; AFTER
+Y.publish(&#x27;myapp:ready&#x27;, {
+    fireOnce: true,
+    async   : true
+});
+
+&#x2F;&#x2F; ... elsewhere in the code
+&#x2F;&#x2F; Even if myapp:ready has been fired, setStuffUp will execute later. So, no boom
+Y.on(&#x27;myapp:ready&#x27;, setStuffUp);
+
+MyApp.Stuff = {};</pre>
+
+
+<h3 id="bubbling">Bubbling Events</h3>
+
+<p>
+    Events that are configured with <code>emitFacade</code> support bubbling to other
+    <code>EventTarget</code>s, allowing you to subscribe to them from other objects, much
+    like DOM event bubbling.  Add other <code>EventTarget</code>s to an instance's bubble
+    path with <code>addTarget</code>.
+</p>
+
+<pre class="code prettyprint">function LeafNode() { ... }
+
+LeafNode.prototype.rename = function (newName) {
+    var oldName = this.name;
+    this.name   = newName;
+
+    this.fire(&quot;update&quot;, {
+        prevVal: oldName,
+        newVal : newName
+    });
+};
+
+function TreeNode() { ... }
+
+TreeNode.prototype.add = function (node) {
+    this._items.push(node);
+
+    &#x2F;&#x2F; The new child node&#x27;s events will bubble to this TreeNode
+    node.addTarget(this);
+};
+
+Y.augment(LeafNode, Y.EventTarget, true, null, { emitFacade: true });
+Y.augment(TreeNode, Y.EventTarget, true, null, { emitFacade: true });
+
+var rootNode = new TreeNode(&quot;ROOT&quot;),
+    branchA  = new TreeNode(&quot;branchA&quot;),
+    leaf1    = new LeafNode(&quot;leaf1&quot;);
+
+rootNode.add(branchA);                 &#x2F;&#x2F;            ROOT
+rootNode.add( new LeafNode(&quot;leaf2&quot;) ); &#x2F;&#x2F;           &#x2F;    \
+                                       &#x2F;&#x2F;      branchA   leaf2
+branchA.add(leaf1);                    &#x2F;&#x2F;     &#x2F;       \
+branchA.add( new LeafNode(&quot;leaf3&quot;) );  &#x2F;&#x2F;  leaf1     leaf3
+
+&#x2F;&#x2F; Subscribe to &#x27;update&#x27; events from any leaf or tree node under root
+rootNode.on(&#x27;update&#x27;, function (e) {
+    alert(e.prevVal + &quot; has been renamed &quot; + e.newVal);
+});
+
+leaf1.rename(&quot;Flower!&quot;); &#x2F;&#x2F; ==&gt; &quot;leaf1 has been renamed Flower!&quot;</pre>
+
+
+
+<h3 id="prefix">Event Prefixes</h3>
+
+<p>
+    Individual events or all events fired by an <code>EventTarget</code> can be configured
+    to include a prefix to help filter subscriptions to common event names by
+    their origin. Prefixed event names look like <code>&#x27;prefix:eventName&#x27;</code>.
+</p>
+
+<p>
+    Taking the <a href="#bubbling">code snippet above</a>, configuring a default
+    <code>prefix</code> while augmenting the classes will allow for subscription to
+    only <code>LeafNode</code> updates.
+</p>
+<pre class="code prettyprint">&#x2F;&#x2F; All events fired by LeafNode instances will be prefixed with &quot;leaf:&quot;
+Y.augment(LeafNode, Y.EventTarget, true, null, {
+    emitFacade: true,
+    prefix: &#x27;leaf&#x27;
+});
+&#x2F;&#x2F; ...and for TreeNodes, &quot;tree:&quot;
+Y.augment(TreeNode, Y.EventTarget, true, null, {
+    emitFacade: true,
+    prefix: &#x27;tree&#x27;
+});
+
+...
+
+&#x2F;&#x2F; Listen specifically for changes from LeafNodes
+rootNode.on(&#x27;leaf:update&#x27;, function (e) {
+    alert(e.prevVal + &quot; has been renamed &quot; + e.newVal);
+});
+
+leaf1.rename(&quot;Flower!&quot;); &#x2F;&#x2F; ==&gt; &quot;leaf1 has been renamed Flower!&quot;
+branchA.rename(&quot;Chewbacca!&quot;); &#x2F;&#x2F; (nothing)</pre>
+
+
+<p>
+    Subscribing with prefixes is similar to
+    <a href="../event/delegation.html">using DOM event delegation</a>, though it
+    is done using <code>on()</code> rather than <code>delegate()</code>.
+</p>
+
+<p>
+    Optionally, you can omit the prefix when subscribing on the object that
+    fires the event.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; prefix is optional when subscribing on the firing object...
+leaf1.on(&#x27;leaf:update&#x27;, worksJustLike);
+leaf1.on(&#x27;update&#x27;, function (e) {
+    e.type; &#x2F;&#x2F; &#x27;leaf:update&#x27; -- the event type will remain prefixed
+    ...
+});
+
+&#x2F;&#x2F; ...but prefixes are required from other objects
+rootNode.on(&#x27;update&#x27;, function (e) {
+    &#x2F;&#x2F; will not capture leaf:update events
+});</pre>
+
+
+<p>
+    Subscribe to all events of a specific type, regardless of prefix, using the
+    wildcard prefix <code>*:eventName</code>.
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; Execute the callback if either the group object or one of its items fires an
+&#x2F;&#x2F; &#x60;update&#x60; event
+rootNode.on(&#x27;*:update&#x27;, function (e) {
+    switch (e.type) {
+        case &quot;leaf:update&quot;: ...
+        case &quot;tree:update&quot;: ...
+    }
+});</pre>
+
+
+<h3 id="defaultFn">Adding Default Behavior</h3>
+
+<p>
+    Custom events can be bound to behaviors just like DOM events (e.g. clicking
+    on a link causes navigation to a new page).  This is especially useful when
+    doing
+    <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>
+    operations that you want to expose to other objects in your system to
+    prevent, alter, or enhance.
+</p>
+
+<p>
+    Add a default behavior to an event by configuring the event's <code>defaultFn</code>.
+    By convention, default functions are named <code>_def(the name of the event)Fn</code>.
+</p>
+
+<pre class="code prettyprint">function TreeNode(name) {
+    this.name   = name;
+    this._items = [];
+
+    &#x2F;&#x2F; Event publishing is typically done during instantiation
+    this.publish(&#x27;add&#x27;, {
+        defaultFn: this._defAddFn
+    });
+}
+
+&#x2F;&#x2F; Adding a child node is an interesting mutation operation. Move the mutation
+&#x2F;&#x2F; logic from the method to a mutation event&#x27;s default behavior
+TreeNode.prototype.add = function (node) {
+    this.fire(&#x27;add&#x27;, { newNode: node });
+};
+
+&#x2F;&#x2F; Default functions receive the event facade like other subscribers
+TreeNode.prototype._defAddFn = function (e) {
+    this._items.push(e.newNode);
+
+    e.newNode.addTarget(this);
+};
+
+...
+
+branchA.add(leaf1); &#x2F;&#x2F; without &#x27;add&#x27; subscriptions, the behavior is the same</pre>
+
+
+<p>
+    Unless configured with <code>preventable: false</code>, default behaviors can be
+    disabled with <code>e.preventDefault()</code> just like the DOM.  Unlike their DOM
+    counterparts, though, event subscribers <em>can change facade
+    properties</em> to alter the default behavior by way of effectively changing
+    its input.
+</p>
+
+<pre class="code prettyprint">TreeNode.prototype.add = function (node) {
+    this.fire(&#x27;add&#x27;, {
+        newNode: node,
+        bubbleEvents: true
+    });
+};
+
+&#x2F;&#x2F; Default functions receive the event facade like other subscribers
+TreeNode.prototype._defAddFn = function (e) {
+    this._items.push(e.newNode);
+
+    if (e.bubbleEvents) {
+        e.newNode.addTarget(this);
+    }
+};
+
+...
+
+&#x2F;&#x2F; You can prevent default behavior from anywhere along the bubble path
+rootNode.on(&#x27;tree:add&#x27;, function (e) {
+    if (e.newNode.name === &quot;Leafy&quot;) {
+        e.preventDefault();
+    } else if (e.newNode.name === &quot;James Bond&quot;) {
+        e.bubbleEvents = false; &#x2F;&#x2F; Shhhh
+    }
+});
+
+rootNode.add( new LeafNode(&quot;Leafy&quot;) ); &#x2F;&#x2F; Node NOT added
+rootNode.add( new LeafNode(&quot;James Bond&quot;) ); &#x2F;&#x2F; Node added without event bubbling</pre>
+
+
+<h3 id="broadcast">Broadcasting Events to Y or Between YUI instances</h3>
+
+<p>
+    Event broadcasting is very similar to bubbling, but with some important
+    distinctions:
+</p>
+
+<ol>
+    <li>
+        Broadcasting is specific to the YUI instance and the <code>Y.Global</code> shared
+        <code>EventTarget</code>
+    </li>
+    <li>Events don't need to be configured with <code>emitFacade</code> to broadcast</li>
+    <li>Broadcasting happens after the default behavior, which also means...</li>
+    <li>Event behavior can't be prevented from broadcast subscribers</li>
+    <li>Broadcast can be defaulted for all events for an <code>EventTarget</code></li>
+</ol>
+
+<p>
+    Broadcasting is essentially a "fast track" bubbling configuration allowing
+    you to specify that events can be subscribed to from the YUI instance (with
+    <code>broadcast: 1</code>) or from <code>Y.Global</code> (with <code>broadcast: 2</code>).
+</p>
+
+<pre class="code prettyprint">&#x2F;&#x2F; All events from instances of MyClass can be subscribed from Y.on()
+Y.augment(MyClass, Y.EventTarget, true, null, {
+    emitFacade: true,
+    prefix: &#x27;awesome&#x27;,
+    broadcast: 1
+});
+
+&#x2F;&#x2F; Respond to a &#x27;thing&#x27; event from any instance of MyClass in the YUI sandbox
+Y.on(&#x27;awesome:song&#x27;, partyOn);
+
+var instance = new MyClass()
+
+instance.fire(&quot;song&quot;, { which: &quot;Bohemian Rhapsody&quot;, whom: &quot;Wayne&quot; });</pre>
+
+
+<p>
+    <code>Y.Global</code> is an <code>EventTarget</code> that is shared between all YUI instances,
+    allowing cross-sandbox communication.  To avoid feedback loops, it's best
+    to add an instance identity to outgoing events and only respond to
+    incoming events from other identities.
+</p>
+
+<pre class="code prettyprint">YUI().use(&#x27;node&#x27;, &#x27;event-custom&#x27;, function (Y) {
+    var id = &quot;Alpha Beta Base&quot;; &#x2F;&#x2F; probably Y.guid() would be safer
+
+    Y.Global.on(&#x27;message&#x27;, function (e) {
+        if (e.origin !== id) {
+            alert(&quot;message received from &quot; + e.origin + &quot;: &quot; + e.message);
+
+            murdock.fire(&quot;message&quot;, {
+                message: &quot;We&#x27;ll get you down.  And down safe.&quot;,
+                origin: id
+            });
+        }
+    });
+
+    function Character() {
+        this.publish(&#x27;message&#x27;, { broadcast: 2 });
+        ...
+    }
+
+    Y.augment(Character, Y.EventTarget, true, null, {
+        emitFacade: true
+    });
+    
+    var murdock = new Character();
+
+    Y.one(&#x27;#status&#x27;).on(&#x27;click&#x27;, function () {
+        murdock.fire(&quot;message&quot;, {
+            message: &quot;You&#x27;re coming in too fast!&quot;,
+            origin: id
+        });
+    });
+});
+
+YUI().use(&#x27;node&#x27;, &#x27;event-custom&#x27;, function (OtherY) {
+    var id = &quot;Lunar Shuttle&quot;;
+
+    OtherY.Global.on(&#x27;message&#x27;, function (e) {
+        if (e.origin !== id) {
+            alert(&quot;message received from &quot; + e.origin + &quot;: &quot; + e.message);
+        }
+    });
+
+    function Character() {
+        this.publish(&#x27;message&#x27;, { broadcast: 2 });
+    }
+
+    OtherY.augment(Character, OtherY.EventTarget, true, null, {
+        emitFacade: true
+    });
+    
+    var striker = new Character()
+
+    OtherY.one(&#x27;#report&#x27;).on(&#x27;click&#x27;, function () {
+        striker.fire(&quot;message&quot;, {
+            message: &quot;She&#x27;s beginning to crack up&quot;,
+            origin: id
+        });
+    });
+});</pre>
+
+<button id="status" class="yui3-button">Come in, Lunar Shuttle</button>
+<button id="report" class="yui3-button">Can you read me, Alpha Beta?</button>
+
+<script>
+YUI().use('node', 'event-custom', function (Y) {
+    var id = "Alpha Beta Base"; // probably Y.guid() would be safer
+
+    Y.Global.on('message', function (e) {
+        if (e.origin !== id) {
+            alert("message received from " + e.origin + ": " + e.message);
+
+            murdock.fire("message", {
+                message: "We'll get you down.  And down safe.",
+                origin: id
+            });
+        }
+    });
+
+    function Character() {
+        this.publish('message', { broadcast: 2 });
+    }
+
+    Y.augment(Character, Y.EventTarget, true, null, {
+        emitFacade: true
+    });
+    
+    var murdock = new Character();
+
+    Y.one('#status').on('click', function () {
+        murdock.fire("message", {
+            message: "You're coming in too fast!",
+            origin: id
+        });
+    });
+});
+
+YUI().use('node', 'event-custom', function (OtherY) {
+    var id = "Lunar Shuttle";
+
+    OtherY.Global.on('message', function (e) {
+        if (e.origin !== id) {
+            alert("message received from " + e.origin + ": " + e.message);
+        }
+    });
+
+    function Character() {
+        this.publish('message', { broadcast: 2 });
+    }
+
+    OtherY.augment(Character, OtherY.EventTarget, true, null, {
+        emitFacade: true
+    });
+    
+    var striker = new Character()
+
+    OtherY.one('#report').on('click', function () {
+        striker.fire("message", {
+            message: "She's beginning to crack up",
+            origin: id
+        });
+    });
+});
+</script>
+
+<!--h3>Monitoring Events</h3>
+
+<p>TODO</p-->
+
+
+<h3 id="configs">Available Event Configurations and Defaults</h3>
+
+<p>
+    Events can be configured with the following properties. Properties marked
+    as "Class Configurable" can be passed to the <code>EventTarget</code> constructor
+    configuration to default for all events.
+</p>
+
+<table>
+<thead>
+    <tr>
+        <th>Configuration</th>
+        <th>Description</th>
+        <th>Default</th>
+        <th>Class Configurable?</th>
+    </tr>
+</thead>
+<tbody>
+    <tr>
+        <td><code>prefix</code></td>
+        <td>
+            <code>e.type</code> will always include the configured prefix.
+            <a href="#prefix">Details above</a>.
+        </td>
+        <td>(empty)</td>
+        <td>YES</td>
+    </tr>
+    <tr>
+        <td><code>context</code></td>
+        <td>
+            The default <code>this</code> object to execute callbacks with. Rarely set.
+        </td>
+        <td>The instance</td>
+        <td>YES</td>
+    </tr>
+    <tr>
+        <td><code>emitFacade</code></td>
+        <td>
+            If <code>true</code>, sends event facades to callbacks, allows bubbling and
+            default functions, etc.  This is commonly set to true for a class.
+            <a href="#facade">Details above</a>.
+        </td>
+        <td><code>false</code></td>
+        <td>YES</td>
+    </tr>
+    <tr>
+        <td><code>fireOnce</code></td>
+        <td>
+            If <code>true</code>, events will only fire once. Subscriptions made after
+            firing will be immediately executed.
+            <a href="#once">Details above</a>.
+        </td>
+        <td><code>false</code></td>
+        <td>YES</td>
+    </tr>
+    <!--tr>
+        <td><code>monitored</code></td>
+        <td>
+            Allows you to subscribe to the event lifecycle moments (publish,
+            fire, and subscribe) as separate events.
+            <a href="#monitor">Details above</a>.
+        </td>
+        <td><code>false</code></td>
+        <td>YES</td>
+    </tr-->
+    <tr>
+        <td><code>broadcast</code></td>
+        <td>
+            <a href="#broadcast">Details above</a>. Fire the event from:
+            <ul>
+                <li><code>0</code> - Only the EventTarget instance</li>
+                <li><code>1</code> - The EventTarget and the YUI instance (<code>Y</code>)</li>
+                <li><code>2</code> - The EventTarget, <code>Y</code>, and <code>Y.Global</code></li>
+            </ul>
+        </td>
+        <td>0</td>
+        <td>YES</td>
+    </tr>
+    <tr>
+        <td><code>bubbles</code></td>
+        <td>
+            For events configured to <code>emitFacade</code> allow bubbling events to
+            other <code>EventTarget</code>s.
+        </td>
+        <td><code>true</code></td>
+        <td>YES</td>
+    </tr>
+    <tr>
+        <td><code>defaultFn</code></td>
+        <td>
+            Behavior associated with the event. Usually this is preventable
+            (see <code>preventable</code> below).  <a href="#defaultFn">Details above</a>.
+        </td>
+        <td>(none)</td>
+        <td>&nbsp;</td>
+    </tr>
+    <tr>
+        <td><code>preventable</code></td>
+        <td>
+            If set to <code>false</code>, <code>e.preventDefault()</code> will not disable execution
+            of the event's <code>defaultFn</code>.
+        </td>
+        <td><code>true</code></td>
+        <td>&nbsp;</td>
+    </tr>
+    <tr>
+        <td><code>preventedFn</code></td>
+        <td>
+            <p>
+                Behavior associated with the event when <code>e.preventDefault()</code> is
+                called from a subscriber.  Use this function to reset partially
+                applied transactional state.
+            </p>
+            <p>Incompatible with <code>preventable: false</code>.</p>
+        </td>
+        <td>(none)</td>
+        <td>&nbsp;</td>
+    </tr>
+    <tr>
+        <td><code>stoppedFn</code></td>
+        <td>
+            Behavior associated with the event when <code>e.stopPropagation()</code> is
+            called from a subscriber.  Seldom used.
+        </td>
+        <td>(none)</td>
+        <td>&nbsp;</td>
+    </tr>
+    <tr>
+        <td><code>async</code></td>
+        <td>
+            Only applicable to events also configured with <code>fireOnce: true</code>.
+            If <code>true</code>, new subscriptions to this event after it has already 
+            been fired will be queued to execute in a <code>setTimeout</code> instead of
+            immediately (synchronously).
+        </td>
+        <td>false</td>
+        <td>&nbsp;</td>
+    </tr>
+</tbody>
+</table>
+
+<h3 id="after">The "after" phase</h3>
+
+<p>
+    Unlike DOM events, custom events also expose an "after" phase that
+    corresponds to the time immediately after an event's <a
+    href="#defaultFn">default behavior</a> executes.  Subscribe to an event's
+    "after" phase with the <code>after(...)</code> method. The signature is the same as
+    <code>on(...)</code>.
+</p>
+
+<pre class="code prettyprint">rootNode.after(&#x27;tree:add&#x27;, calc.updateTotals, calc);</pre>
+
+
+<p>
+    The primary benefit of using <code>after()</code> subscriptions over <code>on()</code>
+    subscriptions is that if any <code>on()</code> subscribers call <code>e.preventDefault()</code>,
+    neither the event's configured <code>defaultFn</code> <em>nor the <code>after()</code>
+    subscribers</em> will be executed.  If an <code>after()</code> subscription is
+    executed, you know that the <code>defaultFn</code> did as well.
+</p>
+
+<p>
+    <strong>Use <code>after()</code> to subscribe to events with a default behavior when
+    you want to react to the event with a side effect.</strong>
+</p>
+
+<p>
+    <strong>Use <code>on()</code> to subscribe to events if you need to prevent or alter
+    the default behavior or if they don't have default behavior.</strong>
+</p>
+
+<h2 id="event-lifecycle">Event Lifecycle</h2>
+
+<p>The order of operations when firing an event is as follows:</p>
+
+<h3 id="simple-event-lifecycle">Simple Events (no facade)</h3>
+
+<ol>
+    <li><code>on()</code> subscribers are executed</li>
+    <li><code>after()</code> subscribers are executed</li>
+    <li><code>Y.on()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.after()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.Global.on()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.Global.after()</code> broadcast subscribers are executed.</li>
+</ol>
+
+<p>
+    If an <code>on()</code> or <code>after()</code> subscriber returns <code>false</code>, no more subscribers
+    will be notified.
+</p>
+
+<h3 id="complex-event-lifecycle">Complex Events (with facade)</h3>
+
+<ol>
+    <li><code>on()</code> subscribers are executed</li>
+    <li>
+        <code>on()</code> subscribers for each bubble target and their respective targets
+        are executed until all targets' bubble paths are walked or a subscriber
+        stops the propagation of the event.
+    </li>
+    <li>
+        If the event was prevented, any configured <code>preventedFn</code> will execute.
+    </li>
+    <li>If not prevented, any configured <code>defaultFn</code> will execute.</li>
+    <li>If bubbling was stopped, any configured <code>stoppedFn</code> will execute.</li>
+    <li><code>Y.on()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.after()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.Global.on()</code> broadcast subscribers are executed.</li>
+    <li><code>Y.Global.after()</code> broadcast subscribers are executed.</li>
+    <li><code>after()</code> subscribers are executed.</li>
+    <li>
+        <code>after()</code> subscribers for each bubble target and their respective
+        targets are executed.
+    </li>
+</ol>
+
+<p>
+    The flow can be interrupted by <code>on()</code> subscribers doing any of these
+    things:
+</p>
+
+<dl>
+    <dt><code>e.preventDefault()</code></dt>
+        <dd>
+            <ol>
+                <li>The <code>defaultFn</code> will not be executed</li>
+                <li>The <code>preventedFn</code> will execute</li>
+                <li>No <code>after()</code> subscriptions will be executed</li>
+            </ol>
+        </dd>
+    <dt><code>e.stopPropagation()</code></dt>
+        <dd>
+            <ol>
+                <li>The remainder of subscribers at this <code>EventTarget</code> <strong>WILL</strong> execute</li>
+                <li>No bubble targets of this <code>EventTarget</code> will be notified</li>
+                <li>The <code>stoppedFn</code> will execute</li>
+                <li>The <code>defaultFn</code> and <code>after()</code> subscribers will execute</li>
+            </ol>
+        </dd>
+    <dt><code>e.stopImmediatePropagation()</code></dt>
+        <dd>
+            Same as <code>e.stopPropagation()</code> except no more subscribers at this
+            <code>EventTarget</code> will execute.
+        </dd>
+    <dt><code>e.halt()</code></dt>
+        <dd>
+            Same as <code>e.preventDefault()</code> plus <code>e.stopPropagation()</code>.
+        </dd>
+    <dt><code>e.halt(true)</code></dt>
+        <dd>
+            Same as <code>e.preventDefault()</code> plus <code>e.stopImmediatePropagation()</code>.
+        </dd>
+    <dt><code>return false</code></dt>
+        <dd>Same as <code>e.halt(true)</code>.  Not recommended.  Use the API methods.</dd>
+</dl>
+
+<!--h2 class="no-toc">Subscribing to Object Methods with <code>Y.Do.*</code></h2>
+
+<h3 class="no-toc">Before and After</h3>
+
+<h3 class="no-toc">Altering the Wrapped Method Behavior</h3>
+
+<h3 class="no-toc"><code>EventTarget</code> API methods</h3>
+
+<p>
+    TODO
+</p-->
+</div>
+            </div>
+        </div>
+
+        <div class="yui3-u-1-4">
+            <div class="sidebar">
+                
+                    <div id="toc" class="sidebox">
+                        <div class="hd">
+                            <h2 class="no-toc">Table of Contents</h2>
+                        </div>
+
+                        <div class="bd">
+                            <ul class="toc">
+<li>
+<a href="#getting-started">Getting Started</a>
+</li>
+<li>
+<a href="#video-overview">Video Overview</a>
+</li>
+<li>
+<a href="#the-basics">The Basics</a>
+<ul class="toc">
+<li>
+<a href="#subscribing-to-events">Subscribing to Events</a>
+</li>
+<li>
+<a href="#fire">Firing Events</a>
+</li>
+<li>
+<a href="#callback-arguments-and-event-facades">Callback arguments and event facades</a>
+</li>
+<li>
+<a href="#detaching-event-subscriptions">Detaching Event Subscriptions</a>
+</li>
+<li>
+<a href="#extend-event-target">Extending EventTarget</a>
+</li>
+</ul>
+</li>
+<li>
+<a href="#publishing-events">Publishing Events</a>
+<ul class="toc">
+<li>
+<a href="#facade">Event Facades</a>
+</li>
+<li>
+<a href="#once"><code>fireOnce</code> Events</a>
+</li>
+<li>
+<a href="#bubbling">Bubbling Events</a>
+</li>
+<li>
+<a href="#prefix">Event Prefixes</a>
+</li>
+<li>
+<a href="#defaultFn">Adding Default Behavior</a>
+</li>
+<li>
+<a href="#broadcast">Broadcasting Events to Y or Between YUI instances</a>
+</li>
+<li>
+<a href="#configs">Available Event Configurations and Defaults</a>
+</li>
+<li>
+<a href="#after">The "after" phase</a>
+</li>
+</ul>
+</li>
+<li>
+<a href="#event-lifecycle">Event Lifecycle</a>
+<ul class="toc">
+<li>
+<a href="#simple-event-lifecycle">Simple Events (no facade)</a>
+</li>
+<li>
+<a href="#complex-event-lifecycle">Complex Events (with facade)</a>
+</li>
+</ul>
+</li>
+</ul>
+                        </div>
+                    </div>
+                
+
+                
+                    <div class="sidebox">
+                        <div class="hd">
+                            <h2 class="no-toc">Examples</h2>
+                        </div>
+
+                        <div class="bd">
+                            <ul class="examples">
+                                
+                                    
+                                        <li data-description="Publish an event with a default behavior, as well as behaviors for reacting to preventing the default or stopping bubbling.">
+                                            <a href="flow-example.html">Custom Event Bubbling and Behaviors</a>
+                                        </li>
+                                    
+                                
+                            </ul>
+                        </div>
+                    </div>
+                
+
+                
+            </div>
+        </div>
+    </div>
+</div>
+
+<script src="../assets/vendor/prettify/prettify-min.js"></script>
+<script>prettyPrint();</script>
+
+<script>
+YUI.Env.Tests = {
+    examples: [],
+    project: '../assets',
+    assets: '../assets/event-custom',
+    name: 'event-custom',
+    title: 'EventTarget',
+    newWindow: '',
+    auto:  false 
+};
+YUI.Env.Tests.examples.push('flow-example');
+
+</script>
+<script src="../assets/yui/test-runner.js"></script>
+
+
+
+</body>
+</html>