[KSS-checkins] r42229 - kukit/kukit.js/branch/ree-load-event-cleanup/kukit
reebalazs at codespeak.net
reebalazs at codespeak.net
Sat Apr 21 14:47:43 CEST 2007
Author: reebalazs
Date: Sat Apr 21 14:47:42 2007
New Revision: 42229
Modified:
kukit/kukit.js/branch/ree-load-event-cleanup/kukit/oper.js
kukit/kukit.js/branch/ree-load-event-cleanup/kukit/plugin.js
Log:
Refactored the default event binding. Made a registerBrowserEvent function, that handles the prevent event parms, and is now reused from the native events and from key events too. One goal is that it can also be used better from custom event binders as well.
Modified: kukit/kukit.js/branch/ree-load-event-cleanup/kukit/oper.js
==============================================================================
--- kukit/kukit.js/branch/ree-load-event-cleanup/kukit/oper.js (original)
+++ kukit/kukit.js/branch/ree-load-event-cleanup/kukit/oper.js Sat Apr 21 14:47:42 2007
@@ -199,14 +199,26 @@
return this.eventrule.kss_selector.namespace;
};
-kukit.op.Oper.prototype.makeExecuteActionsHook = function () {
+kukit.op.Oper.prototype.makeExecuteActionsHook = function (filter) {
// Factory that creates the function that executes the actions.
// The function may take a dict that is updated on the oper
+ // If filter is specified, it will we called with a function and
+ // the event will only be triggered if the filter returned true.
+ // THe return value of func_to_bind will show if the event
+ // has executed or not.
var eventname = this.getEventName();
var self = this;
var func_to_bind = function(dict) {
+ // (XXX XXX TODO it should happen here, that we change to a different
+ // oper class. This is for the future when we separate the BindOper
+ // from the ActionOper.)
var newoper = self.clone(dict, true);
+ // call the filter and if it says skip it, we are done
+ if (filter && ! filter(newoper)) return false;
+ // execute the event's actions
newoper.binderinstance._EventBinder_triggerevent(eventname, newoper);
+ // show that the event's actions have been executed
+ return true;
};
return func_to_bind;
};
Modified: kukit/kukit.js/branch/ree-load-event-cleanup/kukit/plugin.js
==============================================================================
--- kukit/kukit.js/branch/ree-load-event-cleanup/kukit/plugin.js (original)
+++ kukit/kukit.js/branch/ree-load-event-cleanup/kukit/plugin.js Sat Apr 21 14:47:42 2007
@@ -56,6 +56,72 @@
};
/*
+* function registerBrowserEvent
+*
+* This can be used to register native events in a way that
+* they handle allowbubbling, preventdefault and preventbubbling as needed.
+* (THe handling of these parms are optional, it is allowed not to have them
+* in the oper.parms.)
+*
+* THe register function can also take a filter function as parameter.
+* This function needs to receive oper as a parameter,
+* where 'browserevent' will be set on oper too as the native browser event.
+* The function must return true if it wants the event to execure, false otherwise.
+* If it returns false, the event will not be prevented and counts as if
+* were not called.
+* This allows for certain event binder like key handlers, to put an extra condition
+* on the triggering of event.
+*/
+
+kukit.pl.registerBrowserEvent = function(oper, filter) {
+ var func_to_bind = oper.makeExecuteActionsHook(filter);
+ var func = function(e) {
+ target = kukit.pl.getTargetForBrowserEvent(e);
+ if (oper.parms.allowbubbling || target == oper.node) {
+ // Execute the action, provide browserevent on oper
+ // ... however, do it protected. We want the preventdefault
+ // in any case!
+ var exc;
+ var success;
+ try {
+ success = func_to_bind({'browserevent': e});
+ } catch(exc1) {
+ exc = exc1;
+ }
+ if (success || exc) {
+ // This should only be skipped, if the filter told
+ // us that we don't need this event to be executed.
+ // If an exception happened during the event execution,
+ // we do yet want to proceed with the prevents.
+ //
+ // Cancel default event ?
+ if (oper.parms.preventdefault) {
+ // W3C style
+ if (e.preventDefault)
+ e.preventDefault();
+ // MS style
+ try { e.returnValue = false; } catch (exc2) {}
+ }
+ // Prevent bubbling to other kss events ?
+ if (oper.parms.preventbubbling) {
+ if (!e) var e = window.event;
+ e.cancelBubble = true;
+ if (e.stopPropagation) e.stopPropagation();
+ }
+ }
+ //
+ if (exc != null) {
+ // throw the original exception
+ throw exc;
+ }
+ } else {
+ kukit.log('Ignored bubbling event for "' + name + '" (target =' + target.tagName + '), EventRule #' + oper.eventrule.getNr() + ' mergeid ' + oper.eventrule.kss_selector.mergeid);
+ }
+ };
+ kukit.ut.registerEventListener(oper.node, oper.getEventName(), func);
+};
+
+/*
* class NativeEventBinder
*/
kukit.pl.NativeEventBinder = function() {
@@ -100,52 +166,17 @@
throw 'In native events only the click event can have preventdefault.';
}
}
- var allowbubbling = oper.parms.allowbubbling;
- var preventdefault = oper.parms.preventdefault;
- var node = oper.node;
- var func = function(e) {
- target = kukit.pl.getTargetForBrowserEvent(e);
- if (allowbubbling || target == node) {
-
- // Execute the action, provide browserevent on oper
- // ... however, do it protected. We want the preventdefault
- // in any case!
- var exc;
- try {
- func_to_bind({'browserevent': e});
- } catch(exc1) {
- exc = exc1;
- }
- // Cancel default event ?
- if (preventdefault) {
- // W3C style
- if (e.preventDefault)
- e.preventDefault();
- // MS style
- try { e.returnValue = false; } catch (exc2) {}
- }
- // Prevent bubbling to other kss events ?
- if (oper.parms.preventbubbling) {
- if (!e) var e = window.event;
- e.cancelBubble = true;
- if (e.stopPropagation) e.stopPropagation();
- }
- //
- if (exc != null) {
- // throw the original exception
- throw exc;
- }
- } else {
- kukit.log('Ignored bubbling event for "' + name + '" (target =' + target.tagName + '), EventRule #' + oper.eventrule.getNr() + ' mergeid ' + oper.eventrule.kss_selector.mergeid);
- }
- };
- kukit.ut.registerEventListener(node, name, func);
+ kukit.pl.registerBrowserEvent(oper);
+ //
// XXX Safari hack
// necessary since Safari does not prevent the <a href...> following
// (in case of allowbubbling we have to apply it to all clicks, as there
// might be a link inside that we cannot detect on the current node)
- if (preventdefault && kukit.HAVE_SAFARI
- && (allowbubbling || name == 'click' && node.tagName.toLowerCase() == 'a')) {
+ //
+ // XXX not needed since we have the legacy name parameter:
+ // var name = oper.getEventName();
+ if (oper.parms.preventdefault && kukit.HAVE_SAFARI
+ && (oper.parms.allowbubbling || name == 'click' && oper.node.tagName.toLowerCase() == 'a')) {
function cancelClickSafari() {
return false;
}
@@ -154,49 +185,32 @@
};
kukit.pl.NativeEventBinder.prototype.__bind_key__ = function(name, func_to_bind, oper) {
- oper.completeParms([], {'preventdefault': 'true', 'allowbubbling': '', 'keycodes': ''}, 'native key event binding');
+ oper.completeParms([], {'preventdefault': 'true', 'allowbubbling': '', 'preventbubbling': '', 'keycodes': ''}, 'native key event binding');
oper.evalList('keycodes', 'native key event binding');
oper.evalBool('preventdefault', 'native key event binding');
oper.evalBool('allowbubbling', 'native key event binding');
- var allowbubbling = oper.parms.allowbubbling;
- var preventdefault = oper.parms.preventdefault;
- var node = oper.node;
- // Convert keyCode to dict
- var keycodes = {};
- for (var i=0; i<oper.parms.keycodes.length; i++) {
- keyCode = oper.parms.keycodes[i];
- keycodes[keyCode] = true;
- }
- var func = function(e) {
- target = kukit.pl.getTargetForBrowserEvent(e);
- if (allowbubbling || target == node) {
- var keyCode = e.keyCode.toString();
- if (oper.parms.keycodes.length == 0 || keycodes[keyCode]) {
- // Execute the action, provide browserevent on oper
- func_to_bind({'browserevent': e});
- // Cancel default event
- if (preventdefault) {
- // W3C style
- if (e.preventDefault)
- e.preventDefault();
- // MS style
- try { e.returnValue = false; } catch (exc) {}
- }
- } else {
- kukit.log('Ignored event for "' + name + '", keycode ' + e.keyCode + ' not in ' + oper.parms.keycodes);
- }
- } else {
- kukit.log('Ignored bubbling event for "' + name + '" (target =' + target.tagName + '), EventRule #' + oper.eventrule.getNr() + ' mergeid ' + oper.eventrule.kss_selector.mergeid);
+ var filter;
+ if (oper.parms.keycodes.length >= 0) {
+ // Convert keyCode to dict
+ var keycodes = {};
+ for (var i=0; i<oper.parms.keycodes.length; i++) {
+ keyCode = oper.parms.keycodes[i];
+ keycodes[keyCode] = true;
}
- };
- kukit.ut.registerEventListener(node, name, func);
+ // Set filter so that only the specified keys should trigger.
+ filter = function(oper) {
+ var keyCode = oper.browserevent.keyCode.toString();
+ return keycodes[keyCode];
+ };
+ }
+ kukit.pl.registerBrowserEvent(oper, filter);
};
/*
* Registration of all the native events that can bound to a node or to document
* (= document or window, depending on the event specs)
* Unsupported are those with absolute no hope to work in a cross browser way
-* Preventdefault is only allowed for click, currently
+* Preventdefault is only allowed for click and key events, currently
*/
kukit.eventsGlobalRegistry.register(null, 'blur', kukit.pl.NativeEventBinder, '__bind__nodeorwindow', null);
kukit.eventsGlobalRegistry.register(null, 'focus', kukit.pl.NativeEventBinder, '__bind__nodeorwindow', null);
More information about the Kukit-checkins
mailing list