Thomas, I don't know if you finally said something to Sam, or if he's just been laughing in the background while we wait (im)patiently for this update, but it's finally here: http://encytemedia.com/blog/articles/2006/08/30/a-flurry-of-prototype-updates... so thanks for your involvement (you at least had a hand in it I'm sure).

Very cool, and with that said, I want to get my EventPublisher class (attached) submitted into one of the two libs (proto or scripty)... but I guess I'm not sure which is the best fit. I get a lot of requests from people about it so I think it's high time I get it (or try to get it) officially included in _something_ -- so Thomas, where in your opinion do you think I should submit it?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs
-~----------~----~----~----~------~----~------~--~---

/**
 * The EventPublisher class allows objects to fire events (and other objects to
 * subscribe handlers to those events). The events can be fired either 
 * synchronously or asynchonously (depending on how the handlers register 
themselves),
 * and may pass optional arguments to the handlers.
 */ 
EventPublisher = Class.create();
EventPublisher.prototype = 
{       
        /**
         * @constructor
         */
        initialize: function() 
        {
        },
        
        /**
         * Attaches a {handler} function to the publisher's {eventName} event 
for execution upon the event firing
         * @param {String} eventName The name of the event to attach the 
handler function to
         * @param {Function} handler The function which will execute when the 
specified event is fired
         * @param {Boolean} asynchFlag [optional] Defaults to false if omitted. 
Indicates whether to execute {handler} asynchronously (true) or not (false).
         */ 
        attachEventHandler: function(eventName, handler) 
        {
                // using an event cache array to track all handlers for proper 
cleanup
                if (this.allEvents == null)
                        this.allEvents = new Array();
                // loop through the event cache to prevent adding duplicates
                var len = this.allEvents.length;
                var foundEvent = false;
                for (var i = 0; i < len; i++) 
                {
                        if (this.allEvents[i] == eventName) 
                        {
                                foundEvent = true;
                                break;
                        }
                }
                if (!foundEvent)
                        this.allEvents.push(eventName);
                        
                eventName = eventName + "_evt"; // appending _evt to event name 
to avoid collisions
                if (this[eventName] == null)
                        this[eventName] = new Array();
                        
                //create a custom object containing the handler method and the 
asynch flag
                var asynchVar = arguments.length > 2 ? arguments[2] : false;
                var handlerObj = 
                {
                        method: handler,
                        asynch: asynchVar
                };
                
                this[eventName].push(handlerObj);
        },
        
        /**
         * Removes a single handler from a specific event
         * @param {String} eventName The event name to clear the handler from
         * @param {Function} handler A reference to the handler function to 
un-register from the event
         */ 
        removeEventHandler: function(eventName, handler) 
        {
                eventName = eventName + "_evt"; // appending _evt to event name 
to avoid collisions
                if (this[eventName] != null)
                        this[eventName] = this[eventName].reject(function(obj) 
{ return obj.method == handler; });
        },
        
        /**
         * Removes all handlers from a single event
         * @param {String} eventName The event name to clear handlers from
         */ 
        clearEventHandlers: function(eventName) 
        {
                eventName = eventName + "_evt"; // appending _evt to event name 
to avoid collisions
                this[eventName] = null;
        },
        
        /**
         * Removes all handlers from ALL events
         */ 
        clearAllEventHandlers: function() 
        {
                if (this.allEvents) 
                {
                        var len = this.allEvents.length;
                        for (var i = 0; i < len; i++) 
                        {
                                this.clearEventHandlers(this.allEvents[i]);
                        }
                }
        },    
        
        /**
         * Fires the event {eventName}, resulting in all registered handlers to 
be executed.
         * @param {String} eventName The name of the event to fire
         * @params {Object} args [optional] Any object, will be passed into the 
handler function as the only argument
         */
        fireEvent: function(eventName) 
        {
                var evtName = eventName + "_evt"; // appending _evt to event 
name to avoid collisions
                if (this[evtName] != null) 
                {
                        var len = this[evtName].length; //optimization
                                                        
                        for (var i = 0; i < len; i++)
                        {
                                try
                                {
                                        if (arguments.length > 1)
                                        {
                                                if (this[evtName][i].asynch)
                                                {
                                                        var eventArgs = 
arguments[1];
                                                        var method = 
this[evtName][i].method.bind(this);
                                                        setTimeout(function() { 
method(eventArgs) }.bind(this), 10);
                                                }
                                                else
                                                        
this[evtName][i].method(arguments[1]);                        
                                        } else 
                                        {
                                                if (this[evtName][i].asynch)
                                                {
                                                        var eventHandler = 
this[evtName][i].method;
                                                        
setTimeout(eventHandler, 1);
                                                }
                                                else
                                                        if (this && 
this[evtName] && this[evtName][i] && this[evtName][i].method)
                                                                
this[evtName][i].method();
                                        }
                                }
                                catch (e) 
                                {
                                        if (this.id) 
                                        {
                                                alert("error: error in " + 
this.id + ".fireevent():\n\nevent name: " + eventName + "\n\nerror message: " + 
e.message);
                                        } 
                                        else 
                                        {
                                                alert("error: error in [unknown 
object].fireevent():\n\nevent name: " + eventName + "\n\nerror message: " + 
e.message);
                                        }
                                }
                        }
                }
        }
};

Reply via email to