76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Adds event facades, preventable default behavior, and bubbling.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @module event-custom
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @submodule event-custom-complex
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Wraps and protects a custom event for use when emitFacade is set to true.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Requires the event-custom-complex module
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @class EventFacade
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param e {Event} the custom event
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param currentTarget {HTMLElement} the element the listener was attached to
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The arguments passed to fire
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property details
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Array
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The event type, this can be overridden by the fire() payload
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property type
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type string
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The real event type
dcde9f9fdb7cdb40d391c49e82df809afef42c01Luke Smith * @property _type
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type string
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass //////////////////////////////////////////////////////
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Node reference for the targeted eventtarget
78d3c37c02e77731a25f370f9fac264ef51f01a9Luke Smith * @property target
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Node
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Node reference for the element that the listener was attached to.
78d3c37c02e77731a25f370f9fac264ef51f01a9Luke Smith * @property currentTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Node
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Node reference to the relatedTarget
78d3c37c02e77731a25f370f9fac264ef51f01a9Luke Smith * @property relatedTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Node
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stops the propagation to the next bubble target
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method stopPropagation
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stops the propagation to the next bubble target and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * prevents any additional listeners from being exectued
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * on the current target.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method stopImmediatePropagation
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Prevents the event's default behavior
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method preventDefault
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stops the event propagation and prevents the default
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * event behavior.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method halt
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param immediate {boolean} if true additional listeners
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * on the current target will not be executed
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var es, ef, q, queue, ce, ret, events, subs, postponed,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self = this, host = self.host || self, next, oldbubble;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // queue this event if the current item in the queue bubbles
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (self.queuable && self.type != self.stack.next.type) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return true;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // id of the first event in the stack
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // defaultFnQueue: new Y.Queue(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.stopped = (self.type !== es.type) ? 0 : es.stopped;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.prevented = (self.type !== es.type) ? 0 : es.prevented;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.details = args.slice(); // original arguments in the details
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // self.log("Firing " + self + ", " + "args: " + args);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self._facade = null; // kill facade to eliminate stale properties
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // if (subCount) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // self._procSubs(Y.merge(self.subscribers), args, ef);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // bubble if this is hosted in an event target and propagation has not been stopped
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (self.bubbles && host.bubble && !self.stopped) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // self.bubbling = true;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // if (host !== ef.target || es.type != self.type) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.stopped = Math.max(self.stopped, es.stopped);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.prevented = Math.max(self.prevented, es.prevented);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // self.bubbling = false;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ((!self.defaultTargetOnly && !es.defaultTargetOnly) ||
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // broadcast listeners are fired as discreet events on the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // YUI instance and potentially the YUI global.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Queue the after
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (subs[1] && !self.prevented && self.stopped < 2) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (es.id === self.id || self.type != host._yuievt.bubbling) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // set up stack to allow the next item to be processed
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // if the first argument is an object literal, apply the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // properties to the event facade
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // protect the event facade properties
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // mix the data
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // restore ef
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Allow the event type to be faked
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // http://yuilibrary.com/projects/yui3/ticket/2528376
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // update the details field with the arguments
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // ef.type = this.type;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // use the original target when the event bubbled to this target
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._facade;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stop propagation to bubble targets
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @for CustomEvent
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method stopPropagation
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stops propagation to bubble targets, and prevents any remaining
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * subscribers on the current target from executing.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method stopImmediatePropagation
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Prevents the execution of this event's defaultFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method preventDefault
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Stops the event propagation and prevents the default
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * event behavior.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method halt
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param immediate {boolean} if true additional listeners
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * on the current target will not be executed
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Registers another EventTarget as a bubble target. Bubble order
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * is determined by the order registered. Multiple targets can
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * be specified.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Events can only bubble if emitFacade is true.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Included in the event-custom-complex submodule.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method addTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param o {EventTarget} the target to add
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @for EventTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Returns an array of bubble targets for this object.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method getTargets
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return EventTarget[]
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Removes a bubble target
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method removeTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param o {EventTarget} the target to remove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @for EventTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Propagate an event. Requires the event-custom-complex module.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method bubble
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param evt {CustomEvent} the custom event to propagate
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return {boolean} the aggregated return value from Event.Custom.fire
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @for EventTarget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass originalTarget = target || (evt && evt.target) || this,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Y.log('Bubbling ' + evt.type);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (i in targs) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // if this event was not published on the bubble target,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // continue propagating the event.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // set the original target to that the target payload on the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // facade is correct.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // default publish may not have emitFacade true -- that
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // shouldn't be what the implementer meant to do
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ret = ret && ce.fire.apply(ce, args || evt.details || []);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // stopPropagation() was called