[KSS-checkins] r41968 - kukit/kukit.js/trunk/kukit
reebalazs at codespeak.net
reebalazs at codespeak.net
Sun Apr 8 21:04:31 CEST 2007
Author: reebalazs
Date: Sun Apr 8 21:04:30 2007
New Revision: 41968
Modified:
kukit/kukit.js/trunk/kukit/eventreg.js
Log:
First a little refactoring for event binding reg, to introduce some iterators that we will use
Modified: kukit/kukit.js/trunk/kukit/eventreg.js
==============================================================================
--- kukit/kukit.js/trunk/kukit/eventreg.js (original)
+++ kukit/kukit.js/trunk/kukit/eventreg.js Sun Apr 8 21:04:30 2007
@@ -1,9 +1,6 @@
/*
-* Copyright (c) 2005-2006
-* Authors:
-* Godefroid Chapelle <gotcha at bubblenet.be>
-* Florian Schulze <florian.schulze at gmx.net>
-* Balázs Reé <ree at greenfinity.hu>
+* Copyright (c) 2005-2007
+* Authors: KSS Project Contributors (see docs/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
@@ -81,7 +78,7 @@
/* events (methods) registration helpers (not to be called directly) */
kukit.er.EventRegistry.prototype._register = function(namespace, eventname, klass,
- bindmethodname, defaultactionmethodname, bindmethodapi) {
+ bindmethodname, defaultactionmethodname, itername) {
if (typeof(defaultactionmethodname) == 'undefined') {
throw 'some arguments are not passed when calling EventRegistry.register';
}
@@ -105,42 +102,50 @@
}
throw 'In EventRegistry.register double registration of key "' + key + '"';
}
+ // check the iterator.
+ if (! kukit.er.getBindIterator(itername)) {
+ throw 'In EventRegistry.register unknown bind iterator "' + itername + '"';
+ }
// register it
this.content[key] = {
'classname': classname,
'bindmethodname': bindmethodname,
'defaultactionmethodname': defaultactionmethodname,
- 'bindmethodapi': bindmethodapi
+ 'itername': itername
};
};
/* events (methods) binding "ForAll" registration */
-kukit.er.EventRegistry.prototype._registerEventSet = function(namespace, names) {
- // At this name the class and event should be checked already. so this should
+kukit.er.EventRegistry.prototype._registerEventSet = function(namespace, names, itername, bindmethodname) {
+ // At this name the values should be checked already. so this should
// be called _after_ _register.
- this.eventsets.push({'namespace': namespace, 'names': names});
+ this.eventsets.push({
+ 'namespace': namespace,
+ 'names': names,
+ 'itername': itername,
+ 'bindmethodname': bindmethodname
+ });
};
-
/* there are the actual registration methods, to be called from plugins */
kukit.er.EventRegistry.prototype.register = function(namespace, eventname, klass,
bindmethodname, defaultactionmethodname) {
- this._register(namespace, eventname, klass, bindmethodname, defaultactionmethodname, 'old');
- this._registerEventSet(namespace, [eventname]);
+ this._register(namespace, eventname, klass, bindmethodname, defaultactionmethodname, 'each');
+ this._registerEventSet(namespace, [eventname], 'each', bindmethodname);
};
kukit.er.EventRegistry.prototype.registerForAllEvents = function(namespace, eventnames, klass,
- bindmethodname, defaultactionmethodname) {
+ bindmethodname, defaultactionmethodname, itername) {
if (typeof(eventnames) == 'string') {
eventnames = [eventnames];
}
for (var i=0; i<eventnames.length; i++) {
var eventname = eventnames[i];
- this._register(namespace, eventname, klass, bindmethodname, defaultactionmethodname, 'new');
+ this._register(namespace, eventname, klass, bindmethodname, defaultactionmethodname, itername);
}
- this._registerEventSet(namespace, eventnames);
+ this._registerEventSet(namespace, eventnames, itername, bindmethodname);
};
kukit.er.EventRegistry.prototype._getKey = function(namespace, eventname) {
@@ -502,7 +507,7 @@
// We mark a given oper. This means a binding on the binderinstance
// for given event, node and eventrule (containing event namespace,
// name, and evt- parms.)
-
+ //
// first see if it can go to already bound ones
this.bound.checkOperBindable(oper);
// then register it properly to the binding events
@@ -512,70 +517,13 @@
kukit.er.BinderInfo.prototype.processBindingEvents = function () {
// We came to the end of the binding phase. Now we process all our binding
// events, This will do the actual binding on the browser side.
- var eventRegistry = kukit.eventsGlobalRegistry;
- for (var i=0; i < eventRegistry.eventsets.length; i++) {
- var eventset = eventRegistry.eventsets[i];
- if (this.binderinstance.__event_namespace__ == eventset.namespace) {
- this._processBindingEventSet(eventset.names);
- }
- }
+ this.binding.processBindingEvents(this.binderinstance)
// Now we to add these to the new ones.
this.binding.propagateTo(this.bound);
// Delete them from the registry, to protect against accidents.
this.binding = null;
};
-kukit.er.BinderInfo.prototype._processBindingEventSet = function (names) {
- // Bind finally for all the opers collected
- var opers = this.binding.getBoundOpersForEventSet(names);
- if (opers.length == 0) {
- return;
- }
- // find the bind method
- // (We use the name and namespace from the first oper, as the bindmethod
- // should be identical anyway.
- var kss_selector = opers[0].eventrule.kss_selector;
- var namespace = kss_selector.namespace;
- var name = kss_selector.name;
- var reg = kukit.eventsGlobalRegistry.get(namespace, name);
- var methodname = reg.bindmethodname;
- // XXX this is now disabled. We want to allow these events to "bind" on different nodes,
- // however there is no actual event bound.
- if (! methodname) {
- return;
- //throw new kukit.err.rd.EventBindError('Method is not defined as bindable', name, namespace);
- }
- var method = this.binderinstance[methodname];
- if (typeof(method) == 'undefined' ) {
- throw new kukit.err.rd.EventBindError('Method "' + methodname + '" does not exist', name, namespace);
- }
- // Ok. Now decide if we go with the new or the old api.
- if (reg.bindmethodapi == 'new') {
- // Protect the binding for better logging
- try {
- method.call(binderinstance, opers);
- } catch(e) {
- throw new kukit.err.rd.EventBindError('Error during binding, reason: [' + e + ']', name, namespace);
- }
- } else { // old
- for (var i=0; i<opers.length; i++) {
- var oper = opers[i];
- var func_to_bind = oper.makeExecuteActionsHook();
- if (this.binderinstance != oper.binderinstance) {
- throw new kukit.err.rd.EventBindError('fatal: wrong binder instance');
- }
- var binderinstance = oper.binderinstance;
- var eventname = oper.getEventName();
- // Protect the binding for better logging
- try {
- method.call(binderinstance, eventname, func_to_bind, oper);
- } catch(e) {
- throw new kukit.err.rd.EventBindError('Error during binding, reason: [' + e + ']', eventname, oper.getEventNamespace());
- }
- }
- }
-};
-
/*
* class OperRegistry
@@ -588,12 +536,14 @@
*/
kukit.er.OperRegistry = function () {
- this.info = {};
+ this.infopername = {};
+ this.infopernode = {};
};
+// XXX XXX XXX we can do this without full cloning, more efficiently.
kukit.er.OperRegistry.prototype.propagateTo = function (newreg) {
- for (var key in this.info) {
- var rules_per_name = this.info[key];
+ for (var key in this.infopername) {
+ var rules_per_name = this.infopername[key];
for (var name in rules_per_name) {
var oper = rules_per_name[name];
newreg.bindOper(oper);
@@ -601,12 +551,18 @@
}
};
-kukit.er.OperRegistry.prototype.checkOperBindable = function (oper) {
+kukit.er.OperRegistry.prototype.checkOperBindable = function (oper, name, nodehash) {
// Check if the binding with this oper could be done.
// Throw exception otherwise.
- var info = this.info;
- var name = oper.eventrule.kss_selector.name;
- var nodehash = kukit.rd.hashnode(oper.node);
+ //
+ // Remark. We need different check and bind method, because we need to bind to the currently
+ // processed nodes, but we need to check duplication in all the previously bound nodes.
+ var info = this.infopername;
+ // name and nodehash are for speedup.
+ if (typeof(nodehash) == 'undefined') {
+ name = oper.eventrule.kss_selector.name;
+ nodehash = kukit.rd.hashnode(oper.node);
+ }
var rules_per_name = info[name];
if (typeof(rules_per_name) == 'undefined') {
// Create an empty list.
@@ -619,15 +575,40 @@
kukit.er.OperRegistry.prototype.bindOper = function (oper) {
// Marks binding between binderinstance, eventname, node.
+ var name = oper.eventrule.kss_selector.name;
var nodehash = kukit.rd.hashnode(oper.node);
- var rules_per_name = this.checkOperBindable(oper);
+ var rules_per_name = this.checkOperBindable(oper, name, nodehash);
rules_per_name[nodehash] = oper;
+ // also store per node info
+ var rules_per_node = this.infopernode[nodehash];
+ if (typeof(rules_per_node) == 'undefined') {
+ // Create an empty list.
+ rules_per_node = this.infopernode[nodehash] = {};
+ }
+ rules_per_node[name] = oper;
+};
+
+// XXX This will need refactoring.
+/// We would only want to lookup from our registry and not the other way around.
+kukit.er.OperRegistry.prototype.processBindingEvents = function (binderinstance) {
+ var eventRegistry = kukit.eventsGlobalRegistry;
+ for (var i=0; i < eventRegistry.eventsets.length; i++) {
+ var eventset = eventRegistry.eventsets[i];
+ if (binderinstance.__event_namespace__ == eventset.namespace) {
+ // Process the binding event set. This will call the actual bindmethods
+ // according to the specified iterator.
+ var iterator = kukit.er.getBindIterator(eventset.itername);
+ iterator.call(this, eventset, binderinstance);
+ }
+ }
};
+// XXX The following methods will probably disappear as iterators replace their functionality.
+
kukit.er.OperRegistry.prototype.getBoundOperForNode = function (name, node) {
// Get the oper that is bound to a given eventname to a node in this binderinstance
// returns null, if there is no such oper.
- var rules_per_name = this.info[name];
+ var rules_per_name = this.infopername[name];
if (typeof(rules_per_name) == 'undefined') {
return null;
}
@@ -643,7 +624,7 @@
kukit.er.OperRegistry.prototype.getBoundOpers = function (name) {
// Get the opers bound to a given eventname (to any node) in this binderinstance
var opers = [];
- var rules_per_name = this.info[name];
+ var rules_per_name = this.infopername[name];
if (typeof(rules_per_name) != 'undefined') {
// take the values as a list
for (var nodehash in rules_per_name) {
@@ -654,12 +635,78 @@
return opers;
};
-kukit.er.OperRegistry.prototype.getBoundOpersForEventSet = function (names) {
- // Returns all opers for a given eventset.
+// Iterators
+// The getBindIterator returns a function that gets executed on
+// the oper registry.
+//
+// Iterators receive the eventset as a parameter
+// plus a binderinstance and a method. They need to iterate by calling this
+// as method.call(binderinstance, ...); where ... can be any parameters this
+// given iteration specifies.
+//
+
+kukit.er.getBindIterator = function(itername) {
+ return kukit.er.OperRegistry.prototype['iter_' + itername];
+};
+
+kukit.er.OperRegistry.prototype.call_bind_method = function (eventset, binderinstance, p1, p2, p3, p4, p5, p6) {
+ var method = binderinstance[eventset.bindmethodname];
+ // Protect the binding for better logging
+ try {
+ method.call(binderinstance, p1, p2, p3, p4, p5, p6);
+ } catch(e) {
+ throw new kukit.err.rd.EventBindError('Error during binding, reason: [' + e + ']', oper.getEventName(), oper.getEventNamespace());
+ }
+};
+
+// This calls the bind method by each bound oper one by one. Eventname and func_to_bind are passed too.
+// this is the legacy ("each") way
+kukit.er.OperRegistry.prototype.iter_each = function (eventset, binderinstance) {
+ for (var i=0; i<eventset.names.length; i++) {
+ var rules_per_name = this.infopername[eventset.names[i]];
+ if (typeof(rules_per_name) != 'undefined') {
+ for (var nodehash in rules_per_name) {
+ var oper = rules_per_name[nodehash];
+ var eventname = oper.getEventName();
+ var func_to_bind = oper.makeExecuteActionsHook();
+ this.call_bind_method(eventset, binderinstance, eventname, func_to_bind, oper);
+ }
+ }
+ }
+};
+
+// This calls the bind method by the list of bound opers
+kukit.er.OperRegistry.prototype.iter_opers = function (eventset, binderinstance) {
var opers = [];
- for (var i=0; i<names.length; i++) {
- var name = names[i];
- opers = opers.concat(this.getBoundOpers(name));
+ for (var i=0; i<eventset.names.length; i++) {
+ var rules_per_name = this.infopername[eventset.names[i]];
+ if (typeof(rules_per_name) != 'undefined') {
+ for (var nodehash in rules_per_name) {
+ opers.push(rules_per_name[nodehash]);
+ }
+ }
}
- return opers;
+ this.call_bind_method(eventset, binderinstance, opers);
};
+
+// This calls the bind method by a mapping eventname:oper per each bound node individually
+kukit.er.OperRegistry.prototype.iter_node = function (eventset, binderinstance) {
+ for (var nodehash in this.infopernode) {
+ var rules_per_node = this.infopernode[nodehash];
+ // filter only the nodes we are interested in
+ var filtered_rules = {};
+ var found = false;
+ for (var name in eventset.names) {
+ var oper = rules_per_node[name];
+ if (typeof(oper) != 'undefined') {
+ filtered_rules[name] = oper;
+ found = true;
+ }
+ }
+ // call it
+ if (found) {
+ this.call_bind_method(eventset, binderinstance, filtered_rules);
+ }
+ }
+};
+
More information about the Kukit-checkins
mailing list