95 lines
2.6 KiB
JavaScript
Executable File
95 lines
2.6 KiB
JavaScript
Executable File
/**
|
|
* AOP style event handling, for listening for method calls. Very similar to dojo.connect
|
|
|
|
/* Add a listener for the execution of the given function slot on the given object.
|
|
*
|
|
* When object[eventName]() is executed the handler is called.
|
|
* The optional before parameter can be used to indicate if the listener
|
|
* should be fired before or after the default action (default is after)
|
|
*/
|
|
exports.observe = function(object, eventName, listener, before) {
|
|
if(!listener){
|
|
throw new Error("No listener provided");
|
|
}
|
|
if(typeof object.observe === "function"){
|
|
// CommonJS observable object
|
|
return object.observe(eventName, listener);
|
|
}
|
|
var listenerProxy = function(that, args){//make sure we have unique function so we can remove it
|
|
try{
|
|
listener.apply(that, args);
|
|
}catch(e){
|
|
require("./process").print(e);
|
|
}
|
|
};
|
|
if(typeof object.addListener === "function"){
|
|
// NodeJS EventEmitter
|
|
object.addListener(eventName, listener);
|
|
return {
|
|
observe: function(listener){
|
|
return exports.observe(object, eventName, listener);
|
|
},
|
|
emit: function(event){
|
|
object.emit(eventName, event);
|
|
},
|
|
dismiss: function(){
|
|
object.removeListener(eventName, listener);
|
|
}
|
|
};
|
|
}
|
|
var afters, befores,
|
|
main = object[eventName];
|
|
if(typeof main != "function"){
|
|
main = function(){};
|
|
}
|
|
if(main._afters){
|
|
afters = main._afters;
|
|
befores = main._befores;
|
|
}
|
|
else{
|
|
befores = [];
|
|
afters = [];
|
|
var newFunc = object[eventName] = function(){
|
|
for(var i = 0; i < befores.length; i++){
|
|
befores[i](this, arguments);
|
|
}
|
|
try{
|
|
return main.apply(this, arguments);
|
|
}
|
|
finally{
|
|
for(var i = 0; i < afters.length; i++){
|
|
afters[i](this, arguments);
|
|
}
|
|
}
|
|
};
|
|
newFunc._befores = befores;
|
|
newFunc._afters = afters;
|
|
}
|
|
if(before){
|
|
befores.push(listenerProxy);
|
|
}
|
|
else{
|
|
afters.push(listenerProxy);
|
|
}
|
|
return createSignal();
|
|
function createSignal(){
|
|
var observers;
|
|
return {
|
|
observe: function(listener){
|
|
afters.push(listener);
|
|
},
|
|
emit: function(){
|
|
main.apply(object, arguments);
|
|
},
|
|
dismiss: function(){
|
|
if(before){
|
|
befores.splice(befores.indexOf(listenerProxy), 1);
|
|
}
|
|
else{
|
|
afters.splice(afters.indexOf(listenerProxy), 1);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
};
|