/* Copyright (c) 2008, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.net/yui/license.txt version: 2.6.0 */ /** * 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 {Object} oScope The context the event will fire from. "this" will * refer to this object in the callback. Default value: * the window object. The listener can override this. * @param {boolean} silent pass true to prevent the event from writing to * the debugsystem * @param {int} signature the signature that the custom event subscriber * will receive. YAHOO.util.CustomEvent.LIST or * YAHOO.util.CustomEvent.FLAT. The default is * YAHOO.util.CustomEvent.LIST. * @namespace YAHOO.util * @class CustomEvent * @constructor */ YAHOO.util.CustomEvent = function(type, oScope, silent, signature) { /** * The type of event, returned to subscribers when the event fires * @property type * @type string */ this.type = type; /** * The scope the the event will fire from by default. Defaults to the window * obj * @property scope * @type object */ this.scope = oScope || window; /** * 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 = silent; /** * Custom events support two styles of arguments provided to the event * subscribers. * * @property signature * @type int */ this.signature = signature || YAHOO.util.CustomEvent.LIST; /** * The subscribers to this event * @property subscribers * @type Subscriber[] */ this.subscribers = []; if (!this.silent) { } var onsubscribeType = "_YUICEOnSubscribe"; // Only add subscribe events for events that are not generated by // CustomEvent if (type !== onsubscribeType) { /** * Custom events provide a custom event that fires whenever there is * a new subscriber to the event. This provides an opportunity to * handle the case where there is a non-repeating event that has * already fired has a new subscriber. * * @event subscribeEvent * @type YAHOO.util.CustomEvent * @param {Function} fn The function to execute * @param {Object} obj An object to be passed along when the event * fires * @param {boolean|Object} override If true, the obj passed in becomes * the execution scope of the listener. * if an object, that object becomes the * the execution scope. */ this.subscribeEvent = new YAHOO.util.CustomEvent(onsubscribeType, this, true); } /** * In order to make it possible to execute the rest of the subscriber * stack when one thows an exception, the subscribers exceptions are * caught. The most recent exception is stored in this property * @property lastError * @type Error */ this.lastError = null; }; /** * Subscriber listener sigature constant. The LIST type returns three * parameters: the event type, the array of args passed to fire, and * the optional custom object * @property YAHOO.util.CustomEvent.LIST * @static * @type int */ YAHOO.util.CustomEvent.LIST = 0; /** * Subscriber listener sigature constant. The FLAT type returns two * parameters: the first argument passed to fire and the optional * custom object * @property YAHOO.util.CustomEvent.FLAT * @static * @type int */ YAHOO.util.CustomEvent.FLAT = 1; YAHOO.util.CustomEvent.prototype = { /** * Subscribes the caller to this event * @method subscribe * @param {Function} fn The function to execute * @param {Object} obj An object to be passed along when the event * fires * @param {boolean|Object} override If true, the obj passed in becomes * the execution scope of the listener. * if an object, that object becomes the * the execution scope. */ subscribe: function(fn, obj, override) { if (!fn) { throw new Error("Invalid callback for subscriber to '" + this.type + "'"); } if (this.subscribeEvent) { this.subscribeEvent.fire(fn, obj, override); } this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, override) ); }, /** * Unsubscribes subscribers. * @method unsubscribe * @param {Function} fn The subscribed function to remove, if not supplied * all will be removed * @param {Object} obj The custom object passed to subscribe. This is * optional, but if supplied will be used to * disambiguate multiple listeners that are the same * (e.g., you subscribe many object using a function * that lives on the prototype) * @return {boolean} True if the subscriber was found and detached. */ unsubscribe: function(fn, obj) { if (!fn) { return this.unsubscribeAll(); } var found = false; for (var i=0, len=this.subscribers.length; i *
  • The type of event
  • *
  • All of the arguments fire() was executed with as an array
  • *
  • The custom object (if any) that was passed into the subscribe() * method
  • * * @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() { this.lastError = null; var errors = [], len=this.subscribers.length; if (!len && this.silent) { return true; } var args=[].slice.call(arguments, 0), ret=true, i, rebuild=false; if (!this.silent) { } // make a copy of the subscribers so that there are // no index problems if one subscriber removes another. var subs = this.subscribers.slice(), throwErrors = YAHOO.util.Event.throwErrors; for (i=0; i 0) { param = args[0]; } try { ret = s.fn.call(scope, param, s.obj); } catch(e) { this.lastError = e; // errors.push(e); if (throwErrors) { throw e; } } } else { try { ret = s.fn.call(scope, this.type, args, s.obj); } catch(ex) { this.lastError = ex; if (throwErrors) { throw ex; } } } if (false === ret) { if (!this.silent) { } break; // return false; } } } return (ret !== false); }, /** * Removes all listeners * @method unsubscribeAll * @return {int} The number of listeners unsubscribed */ unsubscribeAll: function() { for (var i=this.subscribers.length-1; i>-1; i--) { this._delete(i); } this.subscribers=[]; return i; }, /** * @method _delete * @private */ _delete: function(index) { var s = this.subscribers[index]; if (s) { delete s.fn; delete s.obj; } // this.subscribers[index]=null; this.subscribers.splice(index, 1); }, /** * @method toString */ toString: function() { return "CustomEvent: " + "'" + this.type + "', " + "scope: " + this.scope; } }; ///////////////////////////////////////////////////////////////////// /** * Stores the subscriber information to be used when the event fires. * @param {Function} fn The function to execute * @param {Object} obj An object to be passed along when the event fires * @param {boolean} override If true, the obj passed in becomes the execution * scope of the listener * @class Subscriber * @constructor */ YAHOO.util.Subscriber = function(fn, obj, override) { /** * The callback that will be execute when the event fires * @property fn * @type function */ this.fn = fn; /** * An optional custom object that will passed to the callback when * the event fires * @property obj * @type object */ this.obj = YAHOO.lang.isUndefined(obj) ? null : obj; /** * The default execution scope for the event listener is defined when the * event is created (usually the object which contains the event). * By setting override to true, the execution scope becomes the custom * object passed in by the subscriber. If override is an object, that * object becomes the scope. * @property override * @type boolean|object */ this.override = override; }; /** * Returns the execution scope for this listener. If override was set to true * the custom obj will be the scope. If override is an object, that is the * scope, otherwise the default scope will be used. * @method getScope * @param {Object} defaultScope the scope to use if this listener does not * override it. */ YAHOO.util.Subscriber.prototype.getScope = function(defaultScope) { if (this.override) { if (this.override === true) { return this.obj; } else { return this.override; } } return defaultScope; }; /** * 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} obj an object to be passed along when the event fires * @return {boolean} true if the supplied arguments match this * subscriber's signature. */ YAHOO.util.Subscriber.prototype.contains = function(fn, obj) { if (obj) { return (this.fn == fn && this.obj == obj); } else { return (this.fn == fn); } }; /** * @method toString */ YAHOO.util.Subscriber.prototype.toString = function() { return "Subscriber { obj: " + this.obj + ", override: " + (this.override || "no") + " }"; }; /** * The Event Utility provides utilities for managing DOM Events and tools * for building event systems * * @module event * @title Event Utility * @namespace YAHOO.util * @requires yahoo */ // The first instance of Event will win if it is loaded more than once. // @TODO this needs to be changed so that only the state data that needs to // be preserved is kept, while methods are overwritten/added as needed. // This means that the module pattern can't be used. if (!YAHOO.util.Event) { /** * The event utility provides functions to add and remove event listeners, * event cleansing. It also tries to automatically remove listeners it * registers during the unload event. * * @class Event * @static */ YAHOO.util.Event = function() { /** * True after the onload event has fired * @property loadComplete * @type boolean * @static * @private */ var loadComplete = false; /** * Cache of wrapped listeners * @property listeners * @type array * @static * @private */ var listeners = []; /** * User-defined unload function that will be fired before all events * are detached * @property unloadListeners * @type array * @static * @private */ var unloadListeners = []; /** * Cache of DOM0 event handlers to work around issues with DOM2 events * in Safari * @property legacyEvents * @static * @private */ var legacyEvents = []; /** * Listener stack for DOM0 events * @property legacyHandlers * @static * @private */ var legacyHandlers = []; /** * The number of times to poll after window.onload. This number is * increased if additional late-bound handlers are requested after * the page load. * @property retryCount * @static * @private */ var retryCount = 0; /** * onAvailable listeners * @property onAvailStack * @static * @private */ var onAvailStack = []; /** * Lookup table for legacy events * @property legacyMap * @static * @private */ var legacyMap = []; /** * Counter for auto id generation * @property counter * @static * @private */ var counter = 0; /** * Normalized keycodes for webkit/safari * @property webkitKeymap * @type {int: int} * @private * @static * @final */ var webkitKeymap = { 63232: 38, // up 63233: 40, // down 63234: 37, // left 63235: 39, // right 63276: 33, // page up 63277: 34, // page down 25: 9 // SHIFT-TAB (Safari provides a different key code in // this case, even though the shiftKey modifier is set) }; // String constants used by the addFocusListener and removeFocusListener methods var _FOCUS = YAHOO.env.ua.ie ? "focusin" : "focus"; var _BLUR = YAHOO.env.ua.ie ? "focusout" : "blur"; return { /** * The number of times we should look for elements that are not * in the DOM at the time the event is requested after the document * has been loaded. The default is 2000@amp;20 ms, so it will poll * for 40 seconds or until all outstanding handlers are bound * (whichever comes first). * @property POLL_RETRYS * @type int * @static * @final */ POLL_RETRYS: 2000, /** * The poll interval in milliseconds * @property POLL_INTERVAL * @type int * @static * @final */ POLL_INTERVAL: 20, /** * Element to bind, int constant * @property EL * @type int * @static * @final */ EL: 0, /** * Type of event, int constant * @property TYPE * @type int * @static * @final */ TYPE: 1, /** * Function to execute, int constant * @property FN * @type int * @static * @final */ FN: 2, /** * Function wrapped for scope correction and cleanup, int constant * @property WFN * @type int * @static * @final */ WFN: 3, /** * Object passed in by the user that will be returned as a * parameter to the callback, int constant. Specific to * unload listeners * @property OBJ * @type int * @static * @final */ UNLOAD_OBJ: 3, /** * Adjusted scope, either the element we are registering the event * on or the custom object passed in by the listener, int constant * @property ADJ_SCOPE * @type int * @static * @final */ ADJ_SCOPE: 4, /** * The original obj passed into addListener * @property OBJ * @type int * @static * @final */ OBJ: 5, /** * The original scope parameter passed into addListener * @property OVERRIDE * @type int * @static * @final */ OVERRIDE: 6, /** * The original capture parameter passed into _addListener * @property CAPTURE * @type int * @static * @final */ CAPTURE: 7, /** * addListener/removeListener can throw errors in unexpected scenarios. * These errors are suppressed, the method returns false, and this property * is set * @property lastError * @static * @type Error */ lastError: null, /** * Safari detection * @property isSafari * @private * @static * @deprecated use YAHOO.env.ua.webkit */ isSafari: YAHOO.env.ua.webkit, /** * webkit version * @property webkit * @type string * @private * @static * @deprecated use YAHOO.env.ua.webkit */ webkit: YAHOO.env.ua.webkit, /** * IE detection * @property isIE * @private * @static * @deprecated use YAHOO.env.ua.ie */ isIE: YAHOO.env.ua.ie, /** * poll handle * @property _interval * @static * @private */ _interval: null, /** * document readystate poll handle * @property _dri * @static * @private */ _dri: null, /** * True when the document is initially usable * @property DOMReady * @type boolean * @static */ DOMReady: false, /** * Errors thrown by subscribers of custom events are caught * and the error message is written to the debug console. If * this property is set to true, it will also re-throw the * error. * @property throwErrors * @type boolean * @default false */ throwErrors: false, /** * @method startInterval * @static * @private */ startInterval: function() { if (!this._interval) { var self = this; var callback = function() { self._tryPreloadAttach(); }; this._interval = setInterval(callback, this.POLL_INTERVAL); } }, /** * Executes the supplied callback when the item with the supplied * id is found. This is meant to be used to execute behavior as * soon as possible as the page loads. If you use this after the * initial page load it will poll for a fixed time for the element. * The number of times it will poll and the frequency are * configurable. By default it will poll for 10 seconds. * *

    The callback is executed with a single parameter: * the custom object parameter, if provided.

    * * @method onAvailable * * @param {string||string[]} p_id the id of the element, or an array * of ids to look for. * @param {function} p_fn what to execute when the element is found. * @param {object} p_obj an optional object to be passed back as * a parameter to p_fn. * @param {boolean|object} p_override If set to true, p_fn will execute * in the scope of p_obj, if set to an object it * will execute in the scope of that object * @param checkContent {boolean} check child node readiness (onContentReady) * @static */ onAvailable: function(p_id, p_fn, p_obj, p_override, checkContent) { var a = (YAHOO.lang.isString(p_id)) ? [p_id] : p_id; for (var i=0; iThe callback is executed with a single parameter: * the custom object parameter, if provided.

    * * @method onContentReady * * @param {string} p_id the id of the element to look for. * @param {function} p_fn what to execute when the element is ready. * @param {object} p_obj an optional object to be passed back as * a parameter to p_fn. * @param {boolean|object} p_override If set to true, p_fn will execute * in the scope of p_obj. If an object, p_fn will * exectute in the scope of that object * * @static */ onContentReady: function(p_id, p_fn, p_obj, p_override) { this.onAvailable(p_id, p_fn, p_obj, p_override, true); }, /** * Executes the supplied callback when the DOM is first usable. This * will execute immediately if called after the DOMReady event has * fired. @todo the DOMContentReady event does not fire when the * script is dynamically injected into the page. This means the * DOMReady custom event will never fire in FireFox or Opera when the * library is injected. It _will_ fire in Safari, and the IE * implementation would allow for us to fire it if the defered script * is not available. We want this to behave the same in all browsers. * Is there a way to identify when the script has been injected * instead of included inline? Is there a way to know whether the * window onload event has fired without having had a listener attached * to it when it did so? * *

    The callback is a CustomEvent, so the signature is:

    *

    type <string>, args <array>, customobject <object>

    *

    For DOMReady events, there are no fire argments, so the * signature is:

    *

    "DOMReady", [], obj

    * * * @method onDOMReady * * @param {function} p_fn what to execute when the element is found. * @param {object} p_obj an optional object to be passed back as * a parameter to p_fn. * @param {boolean|object} p_scope If set to true, p_fn will execute * in the scope of p_obj, if set to an object it * will execute in the scope of that object * * @static */ onDOMReady: function(p_fn, p_obj, p_override) { if (this.DOMReady) { setTimeout(function() { var s = window; if (p_override) { if (p_override === true) { s = p_obj; } else { s = p_override; } } p_fn.call(s, "DOMReady", [], p_obj); }, 0); } else { this.DOMReadyEvent.subscribe(p_fn, p_obj, p_override); } }, /** * Appends an event handler * * @method _addListener * * @param {String|HTMLElement|Array|NodeList} el An id, an element * reference, or a collection of ids and/or elements to assign the * listener to. * @param {String} sType The type of event to append * @param {Function} fn The method the event invokes * @param {Object} obj An arbitrary object that will be * passed as a parameter to the handler * @param {Boolean|object} override If true, the obj passed in becomes * the execution scope of the listener. If an * object, this object becomes the execution * scope. * @param {boolen} capture capture or bubble phase * @return {Boolean} True if the action was successful or defered, * false if one or more of the elements * could not have the listener attached, * or if the operation throws an exception. * @private * @static */ _addListener: function(el, sType, fn, obj, override, capture) { if (!fn || !fn.call) { return false; } // The el argument can be an array of elements or element ids. if ( this._isValidCollection(el)) { var ok = true; for (var i=0,len=el.length; i-1; i--) { ok = ( this._removeListener(el[i], sType, fn, capture) && ok ); } return ok; } if (!fn || !fn.call) { //return false; return this.purgeElement(el, false, sType); } if ("unload" == sType) { for (i=unloadListeners.length-1; i>-1; i--) { li = unloadListeners[i]; if (li && li[0] == el && li[1] == sType && li[2] == fn) { unloadListeners.splice(i, 1); // unloadListeners[i]=null; return true; } } return false; } var cacheItem = null; // The index is a hidden parameter; needed to remove it from // the method signature because it was tempting users to // try and take advantage of it, which is not possible. var index = arguments[4]; if ("undefined" === typeof index) { index = this._getCacheIndex(el, sType, fn); } if (index >= 0) { cacheItem = listeners[index]; } if (!el || !cacheItem) { return false; } if (this.useLegacyEvent(el, sType)) { var legacyIndex = this.getLegacyIndex(el, sType); var llist = legacyHandlers[legacyIndex]; if (llist) { for (i=0, len=llist.length; i 0 && onAvailStack.length > 0); } // onAvailable var notAvail = []; var executeItem = function (el, item) { var scope = el; if (item.override) { if (item.override === true) { scope = item.obj; } else { scope = item.override; } } item.fn.call(scope, item.obj); }; var i, len, item, el, ready=[]; // onAvailable onContentReady for (i=0, len=onAvailStack.length; i-1; i--) { item = onAvailStack[i]; if (!item || !item.id) { onAvailStack.splice(i, 1); } } this.startInterval(); } else { clearInterval(this._interval); this._interval = null; } this.locked = false; }, /** * Removes all listeners attached to the given element via addListener. * Optionally, the node's children can also be purged. * Optionally, you can specify a specific type of event to remove. * @method purgeElement * @param {HTMLElement} el the element to purge * @param {boolean} recurse recursively purge this element's children * as well. Use with caution. * @param {string} sType optional type of listener to purge. If * left out, all listeners will be removed * @static */ purgeElement: function(el, recurse, sType) { var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el; var elListeners = this.getListeners(oEl, sType), i, len; if (elListeners) { for (i=elListeners.length-1; i>-1; i--) { var l = elListeners[i]; this._removeListener(oEl, l.type, l.fn, l.capture); } } if (recurse && oEl && oEl.childNodes) { for (i=0,len=oEl.childNodes.length; i 0) { // 2.5.0 listeners are removed for all browsers again. FireFox preserves // at least some listeners between page refreshes, potentially causing // errors during page load (mouseover listeners firing before they // should if the user moves the mouse at the correct moment). if (listeners) { for (j=listeners.length-1; j>-1; j--) { l = listeners[j]; if (l) { EU._removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], l[EU.CAPTURE], j); } } l=null; } legacyEvents = null; EU._simpleRemove(window, "unload", EU._unload); }, /** * Returns scrollLeft * @method _getScrollLeft * @static * @private */ _getScrollLeft: function() { return this._getScroll()[1]; }, /** * Returns scrollTop * @method _getScrollTop * @static * @private */ _getScrollTop: function() { return this._getScroll()[0]; }, /** * Returns the scrollTop and scrollLeft. Used to calculate the * pageX and pageY in Internet Explorer * @method _getScroll * @static * @private */ _getScroll: function() { var dd = document.documentElement, db = document.body; if (dd && (dd.scrollTop || dd.scrollLeft)) { return [dd.scrollTop, dd.scrollLeft]; } else if (db) { return [db.scrollTop, db.scrollLeft]; } else { return [0, 0]; } }, /** * Used by old versions of CustomEvent, restored for backwards * compatibility * @method regCE * @private * @static * @deprecated still here for backwards compatibility */ regCE: function() { // does nothing }, /** * Adds a DOM event directly without the caching, cleanup, scope adj, etc * * @method _simpleAdd * @param {HTMLElement} el the element to bind the handler to * @param {string} sType the type of event handler * @param {function} fn the callback to invoke * @param {boolen} capture capture or bubble phase * @static * @private */ _simpleAdd: function () { if (window.addEventListener) { return function(el, sType, fn, capture) { el.addEventListener(sType, fn, (capture)); }; } else if (window.attachEvent) { return function(el, sType, fn, capture) { el.attachEvent("on" + sType, fn); }; } else { return function(){}; } }(), /** * Basic remove listener * * @method _simpleRemove * @param {HTMLElement} el the element to bind the handler to * @param {string} sType the type of event handler * @param {function} fn the callback to invoke * @param {boolen} capture capture or bubble phase * @static * @private */ _simpleRemove: function() { if (window.removeEventListener) { return function (el, sType, fn, capture) { el.removeEventListener(sType, fn, (capture)); }; } else if (window.detachEvent) { return function (el, sType, fn) { el.detachEvent("on" + sType, fn); }; } else { return function(){}; } }() }; }(); (function() { var EU = YAHOO.util.Event; /** * YAHOO.util.Event.on is an alias for addListener * @method on * @see addListener * @static */ EU.on = EU.addListener; /** * YAHOO.util.Event.onFocus is an alias for addFocusListener * @method on * @see addFocusListener * @static */ EU.onFocus = EU.addFocusListener; /** * YAHOO.util.Event.onBlur is an alias for addBlurListener * @method onBlur * @see addBlurListener * @static */ EU.onBlur = EU.addBlurListener; /*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */ // Internet Explorer: use the readyState of a defered script. // This isolates what appears to be a safe moment to manipulate // the DOM prior to when the document's readyState suggests // it is safe to do so. if (EU.isIE) { // Process onAvailable/onContentReady items when the // DOM is ready. YAHOO.util.Event.onDOMReady( YAHOO.util.Event._tryPreloadAttach, YAHOO.util.Event, true); var n = document.createElement('p'); EU._dri = setInterval(function() { try { // throws an error if doc is not ready n.doScroll('left'); clearInterval(EU._dri); EU._dri = null; EU._ready(); n = null; } catch (ex) { } }, EU.POLL_INTERVAL); // The document's readyState in Safari currently will // change to loaded/complete before images are loaded. } else if (EU.webkit && EU.webkit < 525) { EU._dri = setInterval(function() { var rs=document.readyState; if ("loaded" == rs || "complete" == rs) { clearInterval(EU._dri); EU._dri = null; EU._ready(); } }, EU.POLL_INTERVAL); // FireFox and Opera: These browsers provide a event for this // moment. The latest WebKit releases now support this event. } else { EU._simpleAdd(document, "DOMContentLoaded", EU._ready); } ///////////////////////////////////////////////////////////// EU._simpleAdd(window, "load", EU._load); EU._simpleAdd(window, "unload", EU._unload); EU._tryPreloadAttach(); })(); } /** * EventProvider is designed to be used with YAHOO.augment to wrap * CustomEvents in an interface that allows events to be subscribed to * and fired by name. This makes it possible for implementing code to * subscribe to an event that either has not been created yet, or will * not be created at all. * * @Class EventProvider */ YAHOO.util.EventProvider = function() { }; YAHOO.util.EventProvider.prototype = { /** * Private storage of custom events * @property __yui_events * @type Object[] * @private */ __yui_events: null, /** * Private storage of custom event subscribers * @property __yui_subscribers * @type Object[] * @private */ __yui_subscribers: null, /** * Subscribe to a CustomEvent by event type * * @method subscribe * @param p_type {string} the type, or name of the event * @param p_fn {function} the function to exectute when the event fires * @param p_obj {Object} An object to be passed along when the event * fires * @param p_override {boolean} If true, the obj passed in becomes the * execution scope of the listener */ subscribe: function(p_type, p_fn, p_obj, p_override) { this.__yui_events = this.__yui_events || {}; var ce = this.__yui_events[p_type]; if (ce) { ce.subscribe(p_fn, p_obj, p_override); } else { this.__yui_subscribers = this.__yui_subscribers || {}; var subs = this.__yui_subscribers; if (!subs[p_type]) { subs[p_type] = []; } subs[p_type].push( { fn: p_fn, obj: p_obj, override: p_override } ); } }, /** * Unsubscribes one or more listeners the from the specified event * @method unsubscribe * @param p_type {string} The type, or name of the event. If the type * is not specified, it will attempt to remove * the listener from all hosted events. * @param p_fn {Function} The subscribed function to unsubscribe, if not * supplied, all subscribers will be removed. * @param p_obj {Object} The custom object passed to subscribe. This is * optional, but if supplied will be used to * disambiguate multiple listeners that are the same * (e.g., you subscribe many object using a function * that lives on the prototype) * @return {boolean} true if the subscriber was found and detached. */ unsubscribe: function(p_type, p_fn, p_obj) { this.__yui_events = this.__yui_events || {}; var evts = this.__yui_events; if (p_type) { var ce = evts[p_type]; if (ce) { return ce.unsubscribe(p_fn, p_obj); } } else { var ret = true; for (var i in evts) { if (YAHOO.lang.hasOwnProperty(evts, i)) { ret = ret && evts[i].unsubscribe(p_fn, p_obj); } } return ret; } return false; }, /** * Removes all listeners from the specified event. If the event type * is not specified, all listeners from all hosted custom events will * be removed. * @method unsubscribeAll * @param p_type {string} The type, or name of the event */ unsubscribeAll: function(p_type) { return this.unsubscribe(p_type); }, /** * Creates a new custom event of the specified type. If a custom event * by that name already exists, it will not be re-created. In either * case the custom event is returned. * * @method createEvent * * @param p_type {string} the type, or name of the event * @param p_config {object} optional config params. Valid properties are: * *
      *
    • * scope: defines the default execution scope. If not defined * the default scope will be this instance. *
    • *
    • * silent: if true, the custom event will not generate log messages. * This is false by default. *
    • *
    • * onSubscribeCallback: specifies a callback to execute when the * event has a new subscriber. This will fire immediately for * each queued subscriber if any exist prior to the creation of * the event. *
    • *
    * * @return {CustomEvent} the custom event * */ createEvent: function(p_type, p_config) { this.__yui_events = this.__yui_events || {}; var opts = p_config || {}; var events = this.__yui_events; if (events[p_type]) { } else { var scope = opts.scope || this; var silent = (opts.silent); var ce = new YAHOO.util.CustomEvent(p_type, scope, silent, YAHOO.util.CustomEvent.FLAT); events[p_type] = ce; if (opts.onSubscribeCallback) { ce.subscribeEvent.subscribe(opts.onSubscribeCallback); } this.__yui_subscribers = this.__yui_subscribers || {}; var qs = this.__yui_subscribers[p_type]; if (qs) { for (var i=0; i *
  • The first argument fire() was executed with
  • *
  • The custom object (if any) that was passed into the subscribe() * method
  • * * @method fireEvent * @param p_type {string} the type, or name of the event * @param arguments {Object*} an arbitrary set of parameters to pass to * the handler. * @return {boolean} the return value from CustomEvent.fire * */ fireEvent: function(p_type, arg1, arg2, etc) { this.__yui_events = this.__yui_events || {}; var ce = this.__yui_events[p_type]; if (!ce) { return null; } var args = []; for (var i=1; i