Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Created November 7, 2011 18:08
Show Gist options
  • Save WebReflection/1345695 to your computer and use it in GitHub Desktop.
Save WebReflection/1345695 to your computer and use it in GitHub Desktop.
A Function.prototype method handy to monitor "functions lifecycle"
Function.prototype.notifier = (function () {"use strict";
// (C) WebReflection - Mit Style License
function create(callback) {
function notifier() {
var args = [].slice.call(arguments), output;
if (fire(notifier, "before", callback, this, args, null)) {
try {
output = callback.apply(this, args);
} catch(e) {
fire(notifier, "error", callback, this, args, e);
}
fire(notifier, "after", callback, this, args, output);
return output;
}
}
notifier._callback = callback;
notifier._handlers = {};
notifier.addListener = addListener;
notifier.fireListener = fireListener;
notifier.removeListener = removeListener;
return notifier;
}
function addListener(type, handler) {
if (hasOwnProperty.call(this._handlers, type)) {
i = indexOf.call(this._handlers[type], handler);
if (i < 0) {
this._handlers[type].push(handler);
}
} else {
this._handlers[type] = [handler];
}
}
function fireListener(type, context, args) {
fire(this, type, this._callback, context, args, null);
}
function removeListener(type, handler) {
if (hasOwnProperty.call(this._handlers, type)) {
i = indexOf.call(this._handlers[type], handler);
if (~i) {
this._handlers[type].splice(i, 1);
if (!this._handlers[type].length) {
delete this._handlers[type];
}
}
}
}
function fire(notifier, type, callback, context, args, error) {
if (hasOwnProperty.call(notifier._handlers, type)) {
for (var
_handlers = notifier._handlers[type].slice(),
i = 0, length = _handlers.length,
extra = type == "after" ? "output" : "error",
e, result;
i < length; i++
) {
e = {
notifier: notifier,
handler: _handlers[i],
callback: callback,
type: type,
arguments: args,
context: context,
preventDefault: preventDefault
};
e[extra] = error;
try {
if (typeof _handlers[i] == "function") {
_handlers[i].call(callback, e);
} else {
_handlers[i].handleEvent(e);
}
result = result || e.dont;
} catch(e) {
fire(
notifier,
"handlererror",
callback,
context,
args,
e
);
}
}
return !result;
}
return true;
}
function preventDefault() {
this.dont = true;
}
var
indexOf = [].indexOf || function indexOf(that) {
for(i = this.length; i-- && this[i]!== that; );
return i;
},
hasOwnProperty = {}.hasOwnProperty,
NOTIFIER = "_notifier",
i
;
return function notifier(object) {
var
self = this,
notifier = hasOwnProperty.call(self, NOTIFIER) ?
self[NOTIFIER] :
self[NOTIFIER] = create(self)
,
key
;
for (key in object) {
if (hasOwnProperty.call(object, key)) {
addListener.call(notifier, key, object[key]);
}
}
return notifier;
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment