//////////////////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////////////////// var __CFEVENT_ERROR_HANDLER_SET_ARGUMENT = "invalid argument"; var __CFEVENT_ERROR_HANDLER_SET_KEY = "invalid handler set key"; var __CFEVENT_ERROR_HANDLER_SET_REMOVE = "handler not found"; var __CFEVENT_WARNING_LAST_ERROR = "function in event handler raised exception"; var __CFEVENT_WARNING_NOT_LOADED = "event can't process until document is loaded"; var __CFEVENT_HANDLER_BODY = "return __cfEventHandlerExecute(this, " + "arguments.callee.__f, arguments);"; //////////////////////////////////////////////////////////////////////////////// // Classes //////////////////////////////////////////////////////////////////////////////// // CFEventHandlerSet function CFEventHandlerSet(debug) { this.__debug = debug; this.__errorResult = new Object(); this.__handlers = new Array(); } CFEventHandlerSet.prototype.add = function() { var func = arguments[0]; if (typeof(func) != "function") { return cfErrorTrigger("CFEventHandlerSet::add: " + __CFEVENT_ERROR_HANDLER_SET_ARGUMENT); } var handlerArgs = new Array(); for (var i = 1; i < arguments.length; i++) { handlerArgs.push(arguments[i]); } var handler = {func: func, arguments: handlerArgs}; this.__handlers.push(handler); return handler; } CFEventHandlerSet.prototype.execute = function() { var debug = this.__debug; var handlers = this.__handlers; var result = this.__errorResult; var returnValues = new Array(); var value; for (var i = 0; i < handlers.length; i++) { var handler = handlers[i]; var handlerArgs = new Array(); handlerArgs.extend(handler.arguments); for (var j = 0; j < arguments.length; j++) { handlerArgs.push(arguments[j]); } var func = handler.func; if (debug) { value = __cfErrorWatch(undefined, func, handlerArgs, false, result); if (value === result) { alert("CFEventHandlerSet::execute: '" + func.name + "': " + __CFEVENT_WARNING_LAST_ERROR); continue; } } else { value = func.apply(undefined, handlerArgs); } returnValues.push(value); } return returnValues; } CFEventHandlerSet.prototype.getLength = function() { return this.__handlers.length; } CFEventHandlerSet.prototype.remove = function(handler) { if (! this.__handlers.remove(handler)) { return cfErrorTrigger("CFEventHandlerSet::remove: " + __CFEVENT_ERROR_HANDLER_SET_REMOVE); } } // CFEventHandlerExpandedSet function CFEventHandlerExpandedSet(debug) { this.__debug = debug; this.__handlerSets = new Array(); } CFEventHandlerExpandedSet.prototype.add = function() { var key = arguments[0]; var handlerSets = this.__handlerSets; var handlerSet = handlerSets[key]; if (typeof(handlerSet) == "undefined") { handlerSets[key] = handlerSet = new CFEventHandlerSet(this.__debug); } var handlerArgs = new Array(); for (var i = 1; i < arguments.length; i++) { handlerArgs.push(arguments[i]); } return handlerSet.add.apply(handlerSet, handlerArgs); } CFEventHandlerExpandedSet.prototype.execute = function() { var handlerSet = this.__handlerSets[arguments[0]]; if (typeof(handlerSet) == "undefined") { return new Array(); } var handlerArgs = new Array(); for (var i = 1; i < arguments.length; i++) { handlerArgs.push(arguments[i]); } return handlerSet.execute.apply(handlerSet, handlerArgs); } CFEventHandlerExpandedSet.prototype.remove = function(key, handler) { var handlerSet = this.__handlerSets[key]; if (typeof(handlerSet) == "undefined") { return cfErrorTrigger("CFEventHandlerExpandedSet::remove: '" + key + "': " + __CFEVENT_ERROR_HANDLER_SET_KEY); } return handlerSet.remove(handler); } //////////////////////////////////////////////////////////////////////////////// // Private functions //////////////////////////////////////////////////////////////////////////////// function __cfEventHandleDocumentLoadedEvent() { __cfEventHandlerExecute = cfErrorWatch; } function __cfEventHandlerExecute() { return cfWarningTrigger("__cfEventHandlerExecute: " + __CFEVENT_WARNING_NOT_LOADED); } //////////////////////////////////////////////////////////////////////////////// // Public API //////////////////////////////////////////////////////////////////////////////// function cfEventHandlerCreate(f, ignoreError, errorResult) { return function() { // Hack: The global scope isn't immediately initialized for inner // functions in certain versions of Firefox. return window.__cfEventHandlerExecute(this, f, arguments, ignoreError, errorResult); }; } //////////////////////////////////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////////////////////////////////// cfDocumentAddOnLoadedCallback(__cfEventHandleDocumentLoadedEvent);