/** * Base class used to define new behavior classes. * @class GenericBehavior */var GenericBehavior = new Object();Object.extend(GenericBehavior, {/** * Creates a new behavior class * @param name The name of the new class * @param body Object containing the definition of the new class * @returns A class that inherits from GenericBehavior * @member: GenericBehavior */    create: function(name, body) {        var theclass = Class.create();                    Object.extend(theclass.prototype, GenericBehavior.BaseClass);        Object.extend(theclass.prototype, body);        theclass.prototype._behaviorClassName = name;        theclass.prototype.SUPER = GenericBehavior.BaseClass;        theclass.prototype.tellSuper = function() {            var args = $A(arguments);            var func = args.shift();            this.SUPER[func].apply(this, args);        }        theclass.prototype.sets = new Object();        //TODO: reference behaviors by name                return theclass;    },        // Attaches a behavior object to the given element    addBehavior: function (elem, behavior_class, args) {        elem = el(elem);        if (!elem || typeof elem != 'object') { return false; }        if (!args) { args = { }; }        elem._behaviorized = 1;        // Create and attach the behavior, return if attach fails        var behavior = new behavior_class(elem, args);        var success = behavior.onAttach({}, elem, args);        if (!success) { return false; }        // store behavior data with element        if (!elem.behaviors) {             elem.behaviors = {                behaviors: new GenericEventResponders(),                realEventListeners: new Array()            };        };        var b = elem.behaviors;        b.behaviors.register(behavior);                // Make the element respond to the synthetic events in the behavior        for (var handler_name in behavior) {            if (typeof elem[handler_name] == 'function') { continue; }                        if (handler_name.match(/^on[A-Z]/) == null) { continue; }            elem[handler_name] = this.callEventFunction(elem, handler_name);        }                // Make the behavior an observer of real events on the element        for (var handler_name in behavior) {            var func = behavior[handler_name];            if (typeof func != 'function') { continue; }            var bits = handler_name.match(/^on([a-z].*)/);            if (bits == null) { continue; }            var revent = bits[1];            var listener = behavior[handler_name].bindAsEventListener(behavior);            b.realEventListeners.push(listener);            Event.observe(elem, revent, listener, false);        }           return behavior;    },    callEventFunction: function(elem, eventname) {        return function(event) {            GenericBehavior.tellElementBehaviors(                elem, eventname, event);        }    },    getElementBehaviors: function(elem) {        return elem.behaviors.behaviors;     },    getElementBehaviorsByName: function(elem, name) {        var behaviors = this.getElementBehaviors(elem);        return behaviors.findAll( function(b) {            return b._behaviorClassName == name;        });    },    tellElementBehaviors: function(elem, method, args) {        var behaviors = this.getElementBehaviors(elem);        if (!behaviors) { return false; }        behaviors.tell(method, args);        return true;    }});GenericBehavior.BaseClass = {    initialize: function(elem, args) {        this.onNew({}, args);    },        snapshot: function() {        this.origHTML = this.e.innerHTML;    },    addToPage: function(name) {        GenericPage.addToPage(this, name);        //this.onDraw({});        return this;    },        addToSet: function(setname) {        this.set = setname || 'default';        this.sets[this.set] =            this.sets[this.set] ||             new GenericEventResponders();        this.sets[this.set].register(this);        return this;    },    tellSet: function(setname, action, args) {        setname = this.set || setname;        this.sets[setname].tell(action, args);    },    tellMySet: function(action, args) {        this.tellSet(this.set, action, args);    },        setargs: function(args) {        this.args = args;    },    // Event handlers    onNew: function(event, args) {        this.setargs(args);    },        onAttach: function(event, elem, args) {        this.e = elem;        //this.snapshot();        return true;    },    onWillClear: function(event) {    },        onDraw: function(event) {        },        onRedraw: function(event) {        this.onWillClear(event);        //Element.unelDeep(this.e);        if (this.origHTML != null) this.e.innerHTML = this.origHTML;        this.onDraw(event);    }};