diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui_3.0.0b1/api/event-custom.js.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.0.0b1/api/event-custom.js.html Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,1115 @@ + + +
+ +/**
+ * Custom event engine, DOM event listener abstraction layer, synthetic DOM
+ * events.
+ * @module event-custom
+ */
+
+/**
+ * Return value from all subscribe operations
+ * @class EventHandle
+ * @constructor
+ * @param evt {CustomEvent} the custom event
+ * @param sub {Subscriber} the subscriber
+ */
+
+// var onsubscribeType = "_event:onsub",
+var AFTER = 'after',
+ CONFIGS = [
+ 'broadcast',
+ 'bubbles',
+ 'context',
+ 'contextFn',
+ 'configured',
+ 'currentTarget',
+ 'defaultFn',
+ 'details',
+ 'emitFacade',
+ 'fireOnce',
+ 'host',
+ 'preventable',
+ 'preventedFn',
+ 'queuable',
+ 'silent',
+ 'stoppedFn',
+ 'target',
+ 'type'
+ ],
+
+ FACADE = new Y.EventFacade(),
+
+ FACADE_KEYS = Y.Object.keys(FACADE),
+
+ YUI3_SIGNATURE = 9,
+ YUI_LOG = 'yui:log';
+
+Y.EventHandle = function(evt, sub) {
+
+ /**
+ * The custom event
+ * @type CustomEvent
+ */
+ this.evt = evt;
+
+ /**
+ * The subscriber object
+ * @type Subscriber
+ */
+ this.sub = sub;
+};
+
+Y.EventHandle.prototype = {
+
+ /**
+ * Detaches this subscriber
+ * @method detach
+ */
+ detach: function() {
+ if (this.evt) {
+ // Y.log('EventHandle.detach: ' + this.sub, 'info', 'Event');
+ this.evt._delete(this.sub);
+ }
+ }
+};
+
+/**
+ * The CustomEvent class lets you define events for your application
+ * that can be subscribed to by one or more independent component.
+ *
+ * @param {String} type The type of event, which is passed to the callback
+ * when the event fires
+ * @param o configuration object
+ * @class CustomEvent
+ * @constructor
+ */
+Y.CustomEvent = function(type, o) {
+
+ // if (arguments.length > 2) {
+// this.log('CustomEvent context and silent are now in the config', 'warn', 'Event');
+ // }
+
+ o = o || {};
+
+ this.id = Y.stamp(this);
+
+ /**
+ * The type of event, returned to subscribers when the event fires
+ * @property type
+ * @type string
+ */
+ this.type = type;
+
+ /**
+ * The context the the event will fire from by default. Defaults to the YUI
+ * instance.
+ * @property context
+ * @type object
+ */
+ this.context = Y;
+
+ this.logSystem = (type == YUI_LOG);
+
+ /**
+ * If 0, this event does not broadcast. If 1, the YUI instance is notified
+ * every time this event fires. If 2, the YUI instance and the YUI global
+ * (if event is enabled on the global) are notified every time this event
+ * fires.
+ * @property broadcast
+ * @type int
+ */
+ // this.broadcast = 0;
+
+ /**
+ * By default all custom events are logged in the debug build, set silent
+ * to true to disable debug outpu for this event.
+ * @property silent
+ * @type boolean
+ */
+ this.silent = this.logSystem;
+
+ // this.queuable = false;
+
+ /**
+ * The subscribers to this event
+ * @property subscribers
+ * @type Subscriber{}
+ */
+ this.subscribers = {};
+
+ /*
+ * The publisher has configured this event
+ * @property configured
+ * @type boolean
+ * @default true
+ */
+ // this.configured = true;
+
+ /**
+ * 'After' subscribers
+ * @property afters
+ * @type Subscriber{}
+ */
+ this.afters = {};
+
+ /**
+ * This event has fired if true
+ *
+ * @property fired
+ * @type boolean
+ * @default false;
+ */
+ // this.fired = false;
+
+ /**
+ * This event should only fire one time if true, and if
+ * it has fired, any new subscribers should be notified
+ * immediately.
+ *
+ * @property fireOnce
+ * @type boolean
+ * @default false;
+ */
+ // this.fireOnce = false;
+
+ /**
+ * Flag for stopPropagation that is modified during fire()
+ * 1 means to stop propagation to bubble targets. 2 means
+ * to also stop additional subscribers on this target.
+ * @property stopped
+ * @type int
+ */
+ // this.stopped = 0;
+
+ /**
+ * Flag for preventDefault that is modified during fire().
+ * if it is not 0, the default behavior for this event
+ * @property prevented
+ * @type int
+ */
+ // this.prevented = 0;
+
+ /**
+ * Specifies the host for this custom event. This is used
+ * to enable event bubbling
+ * @property host
+ * @type EventTarget
+ */
+ // this.host = null;
+
+ /**
+ * The default function to execute after event listeners
+ * have fire, but only if the default action was not
+ * prevented.
+ * @property defaultFn
+ * @type Function
+ */
+ // this.defaultFn = null;
+
+ /**
+ * The function to execute if a subscriber calls
+ * stopPropagation or stopImmediatePropagation
+ * @property stoppedFn
+ * @type Function
+ */
+ // this.stoppedFn = null;
+
+ /**
+ * The function to execute if a subscriber calls
+ * preventDefault
+ * @property preventedFn
+ * @type Function
+ */
+ // this.preventedFn = null;
+
+ /**
+ * Specifies whether or not this event's default function
+ * can be cancelled by a subscriber by executing preventDefault()
+ * on the event facade
+ * @property preventable
+ * @type boolean
+ * @default true
+ */
+ this.preventable = true;
+
+ /**
+ * Specifies whether or not a subscriber can stop the event propagation
+ * via stopPropagation(), stopImmediatePropagation(), or halt()
+ * @property bubbles
+ * @type boolean
+ * @default true
+ */
+ this.bubbles = true;
+
+ /**
+ * Supports multiple options for listener signatures in order to
+ * port YUI 2 apps.
+ * @property signature
+ * @type int
+ * @default 9
+ */
+ this.signature = YUI3_SIGNATURE;
+
+ // this.hasSubscribers = false;
+
+ // this.hasAfters = false;
+
+ /**
+ * If set to true, the custom event will deliver an EventFacade object
+ * that is similar to a DOM event object.
+ * @property emitFacade
+ * @type boolean
+ * @default false
+ */
+ // this.emitFacade = false;
+
+ this.applyConfig(o, true);
+
+ // this.log("Creating " + this.type);
+
+};
+
+Y.CustomEvent.prototype = {
+
+ _YUI_EVENT: true,
+
+ /**
+ * Apply configuration properties. Only applies the CONFIG whitelist
+ * @method applyConfig
+ * @param o hash of properties to apply
+ * @param force {boolean} if true, properties that exist on the event
+ * will be overwritten.
+ */
+ applyConfig: function(o, force) {
+ if (o) {
+ Y.mix(this, o, force, CONFIGS);
+ }
+ },
+
+ _on: function(fn, context, args, when) {
+
+ if (!fn) {
+ Y.error("Invalid callback for CE: " + this.type);
+ }
+
+ var s = new Y.Subscriber(fn, context, args, when);
+
+ if (this.fireOnce && this.fired) {
+ Y.later(0, this, this._notify, s);
+ }
+
+ if (when == AFTER) {
+ this.afters[s.id] = s;
+ this.hasAfters = true;
+ } else {
+ this.subscribers[s.id] = s;
+ this.hasSubscribers = true;
+ }
+
+ return new Y.EventHandle(this, s);
+
+ },
+
+ /**
+ * Listen for this event
+ * @method subscribe
+ * @param {Function} fn The function to execute
+ * @return {EventHandle|EventTarget} unsubscribe handle or a
+ * chainable event target depending on the 'chain' config.
+ * @deprecated use on
+ */
+ subscribe: function(fn, context) {
+ var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
+ return this._on(fn, context, a, true);
+ },
+
+ /**
+ * Listen for this event
+ * @method on
+ * @param {Function} fn The function to execute
+ * @return {EventHandle|EventTarget} unsubscribe handle or a
+ * chainable event target depending on the 'chain' config.
+ */
+ on: function(fn, context) {
+ var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
+ return this._on(fn, context, a, true);
+ },
+
+ /**
+ * Listen for this event after the normal subscribers have been notified and
+ * the default behavior has been applied. If a normal subscriber prevents the
+ * default behavior, it also prevents after listeners from firing.
+ * @method after
+ * @param {Function} fn The function to execute
+ * @return {EventHandle|EventTarget} unsubscribe handle or a
+ * chainable event target depending on the 'chain' config.
+ */
+ after: function(fn, context) {
+ var a = (arguments.length > 2) ? Y.Array(arguments, 2, true): null;
+ return this._on(fn, context, a, AFTER);
+ },
+
+ /**
+ * Detach listeners.
+ * @method detach
+ * @param {Function} fn The subscribed function to remove, if not supplied
+ * all will be removed
+ * @param {Object} context The context object passed to subscribe.
+ * @return {boolean|EventTarget} returns a chainable event target
+ * or a boolean for legacy detach support.
+ */
+ detach: function(fn, context) {
+
+ // if arg[0] typeof unsubscribe handle
+ if (fn && fn.detach) {
+ return fn.detach();
+ }
+
+ if (!fn) {
+ return this.unsubscribeAll();
+ }
+
+ var found = false, subs = this.subscribers, i, s;
+
+ for (i in subs) {
+ if (subs.hasOwnProperty(i)) {
+ s = subs[i];
+ if (s && s.contains(fn, context)) {
+ this._delete(s);
+ found = true;
+ }
+ }
+ }
+
+ return found;
+ },
+
+ /**
+ * Detach listeners.
+ * @method unsubscribe
+ * @param {Function} fn The subscribed function to remove, if not supplied
+ * all will be removed
+ * @param {Object} context The context object passed to subscribe.
+ * @return {boolean|EventTarget} returns a chainable event target
+ * or a boolean for legacy detach support.
+ * @deprecated use detach
+ */
+ unsubscribe: function() {
+ return this.detach.apply(this, arguments);
+ },
+
+ _getFacade: function() {
+
+ var ef = this._facade, o, args = this.details, o2;
+
+ if (!ef) {
+ ef = new Y.EventFacade(this, this.currentTarget);
+ }
+
+ // if the first argument is an object literal, apply the
+ // properties to the event facade
+ o = args && args[0];
+
+ if (Y.Lang.isObject(o, true)) {
+
+ o2 = {};
+
+ // protect the event facade properties
+ Y.mix(o2, ef, true, FACADE_KEYS);
+
+ // mix the data
+ Y.mix(ef, o, true);
+
+ // restore ef
+ Y.mix(ef, o2, true, FACADE_KEYS);
+ }
+
+ // update the details field with the arguments
+ // ef.type = this.type;
+ ef.details = this.details;
+ ef.target = this.target;
+ ef.currentTarget = this.currentTarget;
+ ef.stopped = 0;
+ ef.prevented = 0;
+
+ this._facade = ef;
+
+ return this._facade;
+ },
+
+ /**
+ * Notify a single subscriber
+ * @method _notify
+ * @param s {Subscriber} the subscriber
+ * @param args {Array} the arguments array to apply to the listener
+ * @private
+ */
+ _notify: function(s, args, ef) {
+
+ this.log(this.type + "->" + ": " + s);
+
+ var ret;
+
+ // emit an EventFacade if this is that sort of event
+ if (this.emitFacade) {
+
+ // @TODO object literal support to fire makes it possible for
+ // config info to be passed if we wish.
+
+ if (!ef) {
+ ef = this._getFacade(args);
+
+ if (Y.Lang.isObject(args[0])) {
+ args[0] = ef;
+ } else {
+ args.unshift(ef);
+ }
+ }
+ }
+
+ ret = s.notify(args, this);
+
+ if (false === ret || this.stopped > 1) {
+ this.log(this.type + " cancelled by subscriber");
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * Logger abstraction to centralize the application of the silent flag
+ * @method log
+ * @param msg {string} message to log
+ * @param cat {string} log category
+ */
+ log: function(msg, cat) {
+ if (!this.silent) {
+ Y.log(this.id + ': ' + msg, cat || "info", "event");
+ }
+ },
+
+ /**
+ * Notifies the subscribers. The callback functions will be executed
+ * from the context specified when the event was created, and with the
+ * following parameters:
+ * <ul>
+ * <li>The type of event</li>
+ * <li>All of the arguments fire() was executed with as an array</li>
+ * <li>The custom object (if any) that was passed into the subscribe()
+ * method</li>
+ * </ul>
+ * @method fire
+ * @param {Object*} arguments an arbitrary set of parameters to pass to
+ * the handler.
+ * @return {boolean} false if one of the subscribers returned false,
+ * true otherwise
+ */
+ fire: function() {
+
+ var es = Y.Env._eventstack,
+ subs, s, args, i, ef, q, queue, ce, hasSub,
+ ret = true, events;
+
+ // @TODO find a better way to short circuit this.
+ // if (!this.broadcast && !this.defaultFn && !this.hasSubscribers && !this.hasAfters) {
+ // return true;
+ // }
+
+ if (es) {
+
+ // queue this event if the current item in the queue bubbles
+ // if (b && this.queuable && this.type != es.next.type) {
+ if (this.queuable && this.type != es.next.type) {
+
+ this.log('queue ' + this.type);
+
+ es.queue.push([this, arguments]);
+ return true;
+ }
+
+ } else {
+
+ Y.Env._eventstack = {
+ // id of the first event in the stack
+ id: this.id,
+ next: this,
+ silent: this.silent,
+ logging: (this.type === YUI_LOG),
+ stopped: 0,
+ prevented: 0,
+ queue: []
+ };
+
+ es = Y.Env._eventstack;
+ }
+
+ if (this.fireOnce && this.fired) {
+
+ this.log('fireOnce event: ' + this.type + ' already fired');
+
+ } else {
+
+ args = Y.Array(arguments, 0, true);
+
+ this.stopped = 0;
+ this.prevented = 0;
+ this.target = this.target || this.host;
+
+ events = new Y.EventTarget({
+ fireOnce: true,
+ context: this.host
+ });
+
+ this.events = events;
+
+ if (this.preventedFn) {
+ events.on('prevented', this.preventedFn);
+ }
+
+ if (this.stoppedFn) {
+ events.on('stopped', this.stoppedFn);
+ }
+
+ this.currentTarget = this.host || this.currentTarget;
+
+ this.fired = true;
+ this.details = args.slice(); // original arguments in the details
+
+ // this.log("Firing " + this + ", " + "args: " + args);
+ this.log("Firing " + this.type);
+
+ hasSub = false;
+ es.lastLogState = es.logging;
+ ef = null;
+
+ if (this.emitFacade) {
+
+ // this.fire({
+ // foo: 1
+ // bar: 2
+ // }
+ // this.fire({
+ // bar: 2
+ // } // foo is still 1 unless we create a new facade
+ this._facade = null;
+
+ ef = this._getFacade(args);
+
+ if (Y.Lang.isObject(args[0])) {
+ args[0] = ef;
+ } else {
+ args.unshift(ef);
+ }
+ }
+
+ if (this.hasSubscribers) {
+ subs = Y.merge(this.subscribers);
+
+ for (i in subs) {
+ if (subs.hasOwnProperty(i)) {
+
+ if (!hasSub) {
+ es.logging = (es.logging || (this.type === YUI_LOG));
+ hasSub = true;
+ }
+
+ // stopImmediatePropagation
+ if (this.stopped == 2) {
+ break;
+ }
+
+ s = subs[i];
+ if (s && s.fn) {
+ ret = this._notify(s, args, ef);
+ if (false === ret) {
+ this.stopped = 2;
+ }
+ }
+ }
+ }
+ }
+
+ es.logging = (es.lastLogState);
+
+ // bubble if this is hosted in an event target and propagation has not been stopped
+ if (this.bubbles && this.host && !this.stopped) {
+ es.stopped = 0;
+ es.prevented = 0;
+ ret = this.host.bubble(this);
+
+ this.stopped = Math.max(this.stopped, es.stopped);
+ this.prevented = Math.max(this.prevented, es.prevented);
+
+ }
+
+ // execute the default behavior if not prevented
+ if (this.defaultFn && !this.prevented) {
+ this.defaultFn.apply(this.host || this, args);
+ }
+
+ // broadcast listeners are fired as discreet events on the
+ // YUI instance and potentially the YUI global.
+ if (!this.stopped && this.broadcast) {
+
+ if (this.host !== Y) {
+ Y.fire.apply(Y, args);
+ }
+
+ if (this.broadcast == 2) {
+ Y.Global.fire.apply(Y.Global, args);
+ }
+ }
+
+ // process after listeners. If the default behavior was
+ // prevented, the after events don't fire.
+ if (this.hasAfters && !this.prevented && this.stopped < 2) {
+ subs = Y.merge(this.afters);
+ for (i in subs) {
+ if (subs.hasOwnProperty(i)) {
+
+ if (!hasSub) {
+ es.logging = (es.logging || (this.type === YUI_LOG));
+ hasSub = true;
+ }
+
+ // stopImmediatePropagation
+ if (this.stopped == 2) {
+ break;
+ }
+
+ s = subs[i];
+ if (s && s.fn) {
+ ret = this._notify(s, args, ef);
+ if (false === ret) {
+ this.stopped = 2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (es.id === this.id) {
+// console.log('clearing stack: ' + es.id + ', ' + this);
+
+// reset propragation properties while processing the rest of the queue
+
+// process queued events
+ queue = es.queue;
+
+ while (queue.length) {
+ // q[0] = the event, q[1] = arguments to fire
+ q = queue.pop();
+ ce = q[0];
+
+// Y.log('firing queued event ' + ce.type + ', from ' + this);
+ es.stopped = 0;
+ es.prevented = 0;
+
+// set up stack to allow the next item to be processed
+ es.next = ce;
+
+ ret = ce.fire.apply(ce, q[1]);
+ }
+
+ Y.Env._eventstack = null;
+ }
+
+ return (ret !== false);
+ },
+
+ /**
+ * Removes all listeners
+ * @method unsubscribeAll
+ * @return {int} The number of listeners unsubscribed
+ * @deprecated use detachAll
+ */
+ unsubscribeAll: function() {
+ return this.detachAll.apply(this, arguments);
+ },
+
+ /**
+ * Removes all listeners
+ * @method detachAll
+ * @return {int} The number of listeners unsubscribed
+ */
+ detachAll: function() {
+ var subs = this.subscribers, i, l=0;
+ for (i in subs) {
+ if (subs.hasOwnProperty(i)) {
+ this._delete(subs[i]);
+ l++;
+ }
+ }
+
+ this.subscribers={};
+
+ return l;
+ },
+
+ /**
+ * @method _delete
+ * @param subscriber object
+ * @private
+ */
+ _delete: function(s) {
+
+ if (s) {
+ delete s.fn;
+ delete s.context;
+ delete this.subscribers[s.id];
+ delete this.afters[s.id];
+ }
+
+ },
+
+ /**
+ * @method toString
+ */
+ toString: function() {
+ return this.type;
+ },
+
+ /**
+ * Stop propagation to bubble targets
+ * @method stopPropagation
+ */
+ stopPropagation: function() {
+ this.stopped = 1;
+ Y.Env._eventstack.stopped = 1;
+ this.events.fire('stopped', this);
+ },
+
+ /**
+ * Stops propagation to bubble targets, and prevents any remaining
+ * subscribers on the current target from executing.
+ * @method stopImmediatePropagation
+ */
+ stopImmediatePropagation: function() {
+ this.stopped = 2;
+ Y.Env._eventstack.stopped = 2;
+ this.events.fire('stopped', this);
+ },
+
+ /**
+ * Prevents the execution of this event's defaultFn
+ * @method preventDefault
+ */
+ preventDefault: function() {
+ if (this.preventable) {
+ this.prevented = 1;
+ Y.Env._eventstack.prevented = 1;
+
+ this.events.fire('prevented', this);
+ }
+ },
+
+ /**
+ * Stops the event propagation and prevents the default
+ * event behavior.
+ * @method halt
+ * @param immediate {boolean} if true additional listeners
+ * on the current target will not be executed
+ */
+ halt: function(immediate) {
+ if (immediate) {
+ this.stopImmediatePropagation();
+ } else {
+ this.stopPropagation();
+ }
+ this.preventDefault();
+ }
+
+};
+
+/////////////////////////////////////////////////////////////////////
+
+/**
+ * Stores the subscriber information to be used when the event fires.
+ * @param {Function} fn The wrapped function to execute
+ * @param {Object} context The value of the keyword 'this' in the listener
+ * @param {Array} args* 0..n additional arguments to supply the listener
+ *
+ * @class Subscriber
+ * @constructor
+ */
+Y.Subscriber = function(fn, context, args) {
+
+ /**
+ * The callback that will be execute when the event fires
+ * This is wrapped by Y.rbind if obj was supplied.
+ * @property fn
+ * @type Function
+ */
+ this.fn = fn;
+
+ /**
+ * Optional 'this' keyword for the listener
+ * @property context
+ * @type Object
+ */
+ this.context = context;
+
+ /**
+ * Unique subscriber id
+ * @property id
+ * @type String
+ */
+ this.id = Y.stamp(this);
+
+ /*
+ * }
+ * fn bound to obj with additional arguments applied via Y.rbind
+ * @property wrappedFn
+ * @type Function
+ */
+ // this.wrappedFn = fn;
+
+ /**
+ * Additional arguments to propagate to the subscriber
+ * @property args
+ * @type Array
+ */
+ this.args = args;
+
+ /**
+ * Custom events for a given fire transaction.
+ * @property events
+ * @type {EventTarget}
+ */
+ this.events = null;
+
+ // if (context) {
+ // this.wrappedFn = Y.rbind.apply(Y, args);
+ // }
+
+
+};
+
+Y.Subscriber.prototype = {
+
+ _notify: function(c, args, ce) {
+ var a = this.args, ret;
+ switch (ce.signature) {
+ case 0:
+ ret = this.fn.call(c, ce.type, args, c);
+ break;
+ case 1:
+ ret = this.fn.call(c, args[0] || null, c);
+ break;
+ default:
+ if (a || args) {
+ args = args || [];
+ a = (a) ? args.concat(a) : args;
+ ret = this.fn.apply(c, a);
+ } else {
+ ret = this.fn.call(c);
+ }
+ }
+
+ return ret;
+ },
+
+ /**
+ * Executes the subscriber.
+ * @method notify
+ * @param args {Array} Arguments array for the subscriber
+ * @param ce {CustomEvent} The custom event that sent the notification
+ */
+ notify: function(args, ce) {
+ var c = this.context,
+ ret = true;
+
+ if (!c) {
+ c = (ce.contextFn) ? ce.contextFn() : ce.context;
+ }
+
+ // Ease debugging by only catching errors if we will not re-throw
+ // them.
+ if (Y.config.throwFail) {
+ ret = this._notify(c, args, ce);
+ } else {
+ try {
+ ret = this._notify(c, args, ce);
+ } catch(e) {
+ Y.error(this + ' failed: ' + e.message, e);
+ }
+ }
+
+ return ret;
+ },
+
+ /**
+ * Returns true if the fn and obj match this objects properties.
+ * Used by the unsubscribe method to match the right subscriber.
+ *
+ * @method contains
+ * @param {Function} fn the function to execute
+ * @param {Object} context optional 'this' keyword for the listener
+ * @return {boolean} true if the supplied arguments match this
+ * subscriber's signature.
+ */
+ contains: function(fn, context) {
+ if (context) {
+ return ((this.fn == fn) && this.context == context);
+ } else {
+ return (this.fn == fn);
+ }
+ },
+
+ /**
+ * @method toString
+ */
+ toString: function() {
+ return "Subscriber " + this.id;
+ }
+};
+
+// FACADE = new Y.EventFacade(new Y.CustomEvent('x'));
+