var found = false; for (var i=0, len=this.subscribers.length; i<len; ++i) { var s = this.subscribers[i]; if (s && s.contains(fn, obj)) { this._delete(i);
found = 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<len; ++i) { var s = subs[i]; if (!s) {
rebuild=true;
} else { if (!this.silent) {
}
var scope = s.getScope(this.scope);
if (this.signature == YAHOO.util.CustomEvent.FLAT) { var param = null; if (args.length > 0) {
param = args[0];
}
// 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) {
/** *onAvailablelisteners *@propertyonAvailStack *@static *@private
*/ var onAvailStack = [];
/** *Lookuptableforlegacyevents *@propertylegacyMap *@static *@private
*/ var legacyMap = [];
/** *Counterforautoidgeneration *@propertycounter *@static *@private
*/ var counter = 0;
/** *Normalizedkeycodesforwebkit/safari *@propertywebkitKeymap *@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";
// 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<len; ++i) {
ok = this._addListener(el[i],
sType,
fn,
obj,
override,
capture) && ok;
} return ok;
} elseif (YAHOO.lang.isString(el)) { var oEl = this.getEl(el); // If the el argument is a string, we assume it is // actually the id of the element. If the page is loaded // we convert el to the actual element, otherwise we // defer attaching the event until onload event fires
// check to see if we need to delay hooking up the event // until after the page loads. if (oEl) {
el = oEl;
} else { // defer adding the event until the element is available this.onAvailable(el, function() {
YAHOO.util.Event._addListener(el, sType, fn, obj, override, capture);
});
returntrue;
}
}
// Element should be an html element or an array if we get // here. if (!el) { returnfalse;
}
// we need to make sure we fire registered unload events // prior to automatically unhooking them. So we hang on to // these instead of attaching them to the window and fire the // handles explicitly during our one unload event. if ("unload" == sType && obj !== this) {
unloadListeners[unloadListeners.length] =
[el, sType, fn, obj, override, capture]; returntrue;
}
// if the user chooses to override the scope, we use the custom // object passed in, otherwise the executing scope will be the // HTML element that the event is registered on var scope = el; if (override) { if (override === true) {
scope = obj;
} else {
scope = override;
}
}
// wrap the function so we can return the obj object when // the event fires; var wrappedFn = function(e) { return fn.call(scope, YAHOO.util.Event.getEvent(e, el),
obj);
};
var li = [el, sType, fn, wrappedFn, scope, obj, override, capture]; var index = listeners.length; // cache the listener so we can try to automatically unload
listeners[index] = li;
if (this.useLegacyEvent(el, sType)) { var legacyIndex = this.getLegacyIndex(el, sType);
// Add a new dom0 wrapper if one is not detected for this // element if ( legacyIndex == -1 ||
el != legacyEvents[legacyIndex][0] ) {
// cache the signature for the DOM0 event, and // include the existing handler for the event, if any
legacyEvents[legacyIndex] =
[el, sType, el["on" + sType]];
legacyHandlers[legacyIndex] = [];
// add a reference to the wrapped listener to our custom // stack of events //legacyHandlers[legacyIndex].push(index);
legacyHandlers[legacyIndex].push(li);
} else { try { this._simpleAdd(el, sType, wrappedFn, capture);
} catch(ex) { // handle an error trying to attach an event. If it fails // we need to clean up the cache this.lastError = ex; this._removeListener(el, sType, fn, capture); returnfalse;
}
}
/** *Whenusinglegacyevents,thehandlerisroutedtothisobject *sowecanfireourcustomlistenerstack. *@methodfireLegacyEvent *@static *@private
*/
fireLegacyEvent: function(e, legacyIndex) { var ok=true, le, lh, li, scope, ret;
lh = legacyHandlers[legacyIndex].slice(); for (var i=0, len=lh.length; i<len; ++i) { // for (var i in lh.length) {
li = lh[i]; if ( li && li[this.WFN] ) {
scope = li[this.ADJ_SCOPE];
ret = li[this.WFN].call(scope, e);
ok = (ok && ret);
}
}
// Fire the original handler if we replaced one. We fire this // after the other events to keep stopPropagation/preventDefault // that happened in the DOM0 handler from touching our DOM2 // substitute
le = legacyEvents[legacyIndex]; if (le && le[2]) {
le[2](e);
}
// The el argument can be a string if (typeof el == "string") {
el = this.getEl(el); // The el argument can be an array of elements or element ids.
} elseif ( this._isValidCollection(el)) { var ok = true; for (i=el.length-1; i>-1; i--) {
ok = ( this._removeListener(el[i], sType, fn, capture) && ok );
} return ok;
}
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; returntrue;
}
}
returnfalse;
}
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) { returnfalse;
}
if (this.useLegacyEvent(el, sType)) { var legacyIndex = this.getLegacyIndex(el, sType); var llist = legacyHandlers[legacyIndex]; if (llist) { for (i=0, len=llist.length; i<len; ++i) { // for (i in llist.length) {
li = llist[i]; if (li &&
li[this.EL] == el &&
li[this.TYPE] == sType &&
li[this.FN] == fn) {
llist.splice(i, 1); // llist[i]=null; break;
}
}
}
// webkit key normalization
if (YAHOO.env.ua.webkit && (code in webkitKeymap)) { code = webkitKeymap[code];
}
return code;
},
/**
* Locating the saved event handler data by function ref
*
* @method _getCacheIndex
* @static
* @private
*/
_getCacheIndex: function(el, sType, fn) {
for (vari=0, l=listeners.length; i<l; i=i+1) { varli = listeners[i];
if ( li && li[this.FN] == fn && li[this.EL] == el && li[this.TYPE] == sType ) {
return i;
}
}
return -1;
},
/**
* Generates an unique ID for the element if it does not already
* have one.
* @method generateId
* @param el the element to create the id for
* @return {string} the resulting id of the element
* @static
*/
generateId: function(el) { var id = el.id;
if (!id) {
id = "yuievtautoid-" + counter;
++counter;
el.id = id;
}
return id;
},
/**
* We want to be able to use getElementsByTagName as a collection
* to attach a group of events to. Unfortunately, different
* browsers return different types of collections. This function
* tests to determine if the object is array-like. It will also
* fail if the object is an array, but is empty.
* @method _isValidCollection
* @param o the object to test
* @return {boolean} true if the object is array-like and populated
* @static
* @private
*/
_isValidCollection: function(o) {
try {
return ( o && // o is something
typeof o !== "string" && // o is not a string
o.length && // o is indexed
!o.tagName && // o is not an HTML element
!o.alert && // o is not a window
typeof o[0] !== "undefined" );
} catch(ex) {
return false;
}
},
/**
* @private
* @property elCache
* DOM element cache
* @static
* @deprecated Elements are not cached due to issues that arise when
* elements are removed and re-added
*/
elCache: {},
/**
* We cache elements bound by id because when the unload event
* fires, we can no longer use document.getElementById
* @method getEl
* @static
* @private
* @deprecated Elements are not cached any longer
*/
getEl: function(id) {
return (typeof id === "string") ? document.getElementById(id) : id;
},
/**
* Clears the element cache
* @deprecated Elements are not cached any longer
* @method clearCache
* @static
* @private
*/
clearCache: function() { },
/**
* Custom event the fires when the dom is initially usable
* @event DOMReadyEvent
*/
DOMReadyEvent: new YAHOO.util.CustomEvent("DOMReady", this),
/**
* hook up any deferred listeners
* @method _load
* @static
* @private
*/
_load: function(e) {
if (!loadComplete) {
loadComplete = true; var EU = YAHOO.util.Event;
// Just in case DOMReady did not go off for some reason
EU._ready();
// Available elements may not have been detected before the
// window load event fires. Try to find them now so that the
// the user is more likely to get the onAvailable notifications
// before the window load notification
EU._tryPreloadAttach();
}
},
/**
* Fires the DOMReady event listeners the first time the document is
* usable.
* @method _ready
* @static
* @private
*/
_ready: function(e) { var EU = YAHOO.util.Event;
if (!EU.DOMReady) {
EU.DOMReady=true;
// Fire the content ready custom event
EU.DOMReadyEvent.fire();
// Remove the DOMContentLoaded (FF/Opera)
EU._simpleRemove(document, "DOMContentLoaded", EU._ready);
}
},
/**
* Polling function that runs before the onload event fires,
* attempting to attach to DOM Nodes as soon as they are
* available
* @method _tryPreloadAttach
* @static
* @private
*/
_tryPreloadAttach: function() {
if (this.isIE) {
// Hold off if DOMReady has not fired and check current
// readyState to protect against the IE operation aborted
// issue.
if (!this.DOMReady) {
this.startInterval();
return;
}
}
this.locked = true;
// keep trying until after the page is loaded. We need to
// check the page load state prior to trying to bind the
// elements so that we can be certain all elements have been
// tested appropriately var tryAgain = !loadComplete;
if (!tryAgain) {
tryAgain = (retryCount > 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);
};
vari, len, item, el, ready=[];
// onAvailable onContentReady
for (i=0, len=onAvailStack.length; i<len; i=i+1) {
item = onAvailStack[i];
if (item) {
el = this.getEl(item.id);
if (el) {
if (item.checkReady) {
if (loadComplete || el.nextSibling || !tryAgain) {
ready.push(item);
onAvailStack[i] = null;
}
} else {
executeItem(el, item);
onAvailStack[i] = null;
}
} else {
notAvail.push(item);
}
}
}
// make sure onContentReady fires after onAvailable
for (i=0, len=ready.length; i<len; i=i+1) {
item = ready[i];
executeItem(this.getEl(item.id), item);
}
retryCount--;
if (tryAgain) {
for (i=onAvailStack.length-1; i>-1; i--) {
item = onAvailStack[i];
if (!item || !item.id) {
onAvailStack.splice(i, 1);
}
}
/**
* 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<len ; ++i) {
this.purgeElement(oEl.childNodes[i], recurse, sType);
}
}
},
/**
* Returns all listeners attached to the given element via addListener.
* Optionally, you can specify a specific type of event to return.
* @method getListeners
* @param el {HTMLElement|string} the element or element id to inspect
* @param sType {string} optional type of listener to return. If
* left out, all listeners will be returned
* @return {Object} the listener. Contains the following fields:
* type: (string) the type of event
* fn: (function) the callback supplied to addListener
* obj: (object) the custom object supplied to addListener
* adjust: (boolean|object) whether or not to adjust the default scope
* scope: (boolean) the derived scope based on the adjust parameter
* scope: (capture) the capture parameter supplied to addListener
* index: (int) its position in the Event util listener cache
* @static
*/
getListeners: function(el, sType) { var results=[], searchLists;
if (!sType) {
searchLists = [listeners, unloadListeners];
} else if (sType === "unload") {
searchLists = [unloadListeners];
} else {
searchLists = [listeners];
}
var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el;
for (var j=0;j<searchLists.length; j=j+1) { var searchList = searchLists[j];
if (searchList) {
for (vari=0,len=searchList.length; i<len ; ++i) { var l = searchList[i];
if ( l && l[this.EL] === oEl &&
(!sType || sType === l[this.TYPE]) ) {
results.push({
type: l[this.TYPE],
fn: l[this.FN],
obj: l[this.OBJ],
adjust: l[this.OVERRIDE],
scope: l[this.ADJ_SCOPE],
capture: l[this.CAPTURE],
index: i
});
}
}
}
}
return (results.length) ? results : null;
},
/**
* Removes all listeners registered by pe.event. Called
* automatically during the unload event.
* @method _unload
* @static
* @private
*/
_unload: function(e) {
var EU = YAHOO.util.Event, i, j, l, len, index, ul = unloadListeners.slice();
// execute and clear stored unload listeners
for (i=0,len=unloadListeners.length; i<len; ++i) {
l = ul[i];
if (l) { var scope = window;
if (l[EU.ADJ_SCOPE]) {
if (l[EU.ADJ_SCOPE] === true) {
scope = l[EU.UNLOAD_OBJ];
} else {
scope = l[EU.ADJ_SCOPE];
}
}
l[EU.FN].call(scope, EU.getEvent(e, l[EU.EL]), l[EU.UNLOAD_OBJ] ); ul[i] = null;
l=null;
scope=null;
}
}
// 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;
}
/**
* Returns the scrollTop and scrollLeft. Used to calculate the
* pageX and pageY in Internet Explorer
* @method _getScroll
* @static
* @private
*/
_getScroll: function() { vardd = 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) {
}
/**
* 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() { };
/**
* 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];
/**
* 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 (vari 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:
*
* <ul>
* <li>
* scope: defines the default execution scope. If not defined
* the default scope will be this instance.
* </li>
* <li>
* silent: if true, the custom event will not generate log messages.
* This is false by default.
* </li>
* <li>
* 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.
* </li>
* </ul>
*
* @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 (vari=0; i<qs.length; ++i) {
ce.subscribe(qs[i].fn, qs[i].obj, qs[i].override);
}
}
}
return events[p_type];
},
/**
* Fire a custom event by name. The callback functions will be executed
* from the scope specified when the event was created, and with the
* following parameters:
* <ul>
* <li>The first argument fire() was executed with</li>
* <li>The custom object (if any) that was passed into the subscribe()
* method</li>
* </ul>
* @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 (vari=1; i<arguments.length; ++i) {
args.push(arguments[i]);
}
return ce.fire.apply(ce, args);
},
/**
* Returns true if the custom event of the provided type has been created
* with createEvent.
* @method hasEvent
* @param type {string} the type, or name of the event
*/
hasEvent: function(type) {
if (this.__yui_events) {
if (this.__yui_events[type]) {
return true;
}
}
return false;
}
};
//@TODO optimize
//@TODO use event utility, lang abstractions
//@TODO replace
/**
* KeyListener is a utility that provides an easy interface for listening for
* keydown/keyup events fired against DOM elements.
* @namespace YAHOO.util
* @class KeyListener
* @constructor
* @param {HTMLElement} attachTo The element or element ID to which the key
* event should be attached
* @param {String} attachTo The element or element ID to which the key
* event should be attached
* @param {Object} keyData The object literal representing the key(s)
* to detect. Possible attributes are
* shift(boolean), alt(boolean), ctrl(boolean)
* and keys(either an int or an array of ints
* representing keycodes).
* @param {Function} handler The CustomEvent handler to fire when the
* key event is detected
* @param {Object} handler An object literal representing the handler.
* @param {String} event Optional. The event (keydown or keyup) to
* listen for. Defaults automatically to keydown.
*
* @knownissue the "keypress" event is completely broken in Safari 2.x and below.
* the workaround is use "keydown" for key listening. However, if
* it is desired to prevent the default behavior of the keystroke,
* that can only be done on the keypress event. This makes key
* handling quite ugly.
* @knownissue keydown is also broken in Safari 2.x and below for the ESC key.
* There currently is no workaround other than choosing another
* key to listen for.
*/
YAHOO.util.KeyListener = function(attachTo, keyData, handler, event) {
if (!attachTo) {
} else if (!keyData) {
} else if (!handler) {
}
if (!event) {
event = YAHOO.util.KeyListener.KEYDOWN;
}
/**
* The CustomEvent fired internally when a key is pressed
* @event keyEvent
* @private
* @param {Object} keyData The object literal representing the key(s) to
* detect. Possible attributes are shift(boolean),
* alt(boolean), ctrl(boolean) and keys(either an
* int or an array of ints representing keycodes).
*/ var keyEvent = new YAHOO.util.CustomEvent("keyPressed");
/**
* The CustomEvent fired when the KeyListener is enabled via the enable()
* function
* @event enabledEvent
* @param {Object} keyData The object literal representing the key(s) to
* detect. Possible attributes are shift(boolean),
* alt(boolean), ctrl(boolean) and keys(either an
* int or an array of ints representing keycodes).
*/
this.enabledEvent = new YAHOO.util.CustomEvent("enabled");
/**
* The CustomEvent fired when the KeyListener is disabled via the
* disable() function
* @event disabledEvent
* @param {Object} keyData The object literal representing the key(s) to
* detect. Possible attributes are shift(boolean),
* alt(boolean), ctrl(boolean) and keys(either an
* int or an array of ints representing keycodes).
*/
this.disabledEvent = new YAHOO.util.CustomEvent("disabled");
if (typeof attachTo == 'string') {
attachTo = document.getElementById(attachTo);
}
/**
* Handles the key event when a key is pressed.
* @method handleKeyPress
* @param {DOMEvent} e The keypress DOM event
* @param {Object} obj The DOM event scope object
* @private
*/
function handleKeyPress(e, obj) {
if (! keyData.shift) {
keyData.shift = false;
}
if (! keyData.alt) {
keyData.alt = false;
}
if (! keyData.ctrl) {
keyData.ctrl = false;
}
// check held down modifying keys first
if (e.shiftKey == keyData.shift &&
e.altKey == keyData.alt &&
e.ctrlKey == keyData.ctrl) { // if we pass this, all modifiers match
var dataItem;
if (keyData.keys instanceof Array) {
for (vari=0;i<keyData.keys.length;i++) {
dataItem = keyData.keys[i];
/**
* Enables the KeyListener by attaching the DOM event listeners to the
* target DOM element
* @method enable
*/
this.enable = function() {
if (! this.enabled) {
YAHOO.util.Event.addListener(attachTo, event, handleKeyPress);
this.enabledEvent.fire(keyData);
}
/**
* Boolean indicating the enabled/disabled state of the Tooltip
* @property enabled
* @type Boolean
*/
this.enabled = true;
};
/**
* Disables the KeyListener by removing the DOM event listeners from the
* target DOM element
* @method disable
*/
this.disable = function() {
if (this.enabled) {
YAHOO.util.Event.removeListener(attachTo, event, handleKeyPress);
this.disabledEvent.fire(keyData);
}
this.enabled = false;
};
/**
* Returns a String representation of the object.
* @method toString
* @return {String} The string representation of the KeyListener
*/
this.toString = function() {
return "KeyListener [" + keyData.keys + "] " + attachTo.tagName +
(attachTo.id ? "[" + attachTo.id + "]" : "");
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.