From 78520507d892dcca6b352f4197259a22da9cfc41 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 30 Sep 2011 16:41:21 +0700 Subject: [PATCH] [lib] callback precendence --- lib/Porter.js | 68 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/lib/Porter.js b/lib/Porter.js index 1c2ca7c..bf56e09 100644 --- a/lib/Porter.js +++ b/lib/Porter.js @@ -42,17 +42,34 @@ this.headers = this.options.headers; - this._listeners = { - 'loading': noop, - 'loaded': noop, - 'interactive': noop, - 'default': noop + function addListener(self, action, listener) { + var listeners = self._listeners[action]; + listeners ? + listeners.push(listener) + : + (self._listeners[action] = [listener]); + }; + + function executeListener(self, action) { + var args = Array.prototype.slice.call(arguments, 2), + listeners = self._listeners[action]; + + if (listeners) { + for (var i = 0, l = listeners.length; i < l; i++) { + // Returning false will stop propagation + if (listeners[i].apply(null, args) === false) break; + } + return true; + } else { + return false; + } + }; this.on = function(listeners) { for (var listener in listeners) { if (listeners.hasOwnProperty(listener)) { - self._listeners[listener] = listeners[listener]; + addListener(self, listener, listeners[listener]); } } return self; @@ -105,23 +122,23 @@ } } - // merge the global _listeners into this xhr. - for(l in self._listeners) { - if(self._listeners.hasOwnProperty(l)) { - ajax._listeners[l] = self._listeners[l]; - } - } - // is callbacks actually plural? if so, merge. if(!(typeof callbacks === 'function')) { for(c in callbacks) { if(callbacks.hasOwnProperty(c)) { - ajax._listeners[c] = callbacks[c]; + addListener(ajax, c, callbacks[c]); } } } else { - ajax._listeners['default'] = callbacks; + addListener(ajax, 'default', callbacks); + } + + // merge the global _listeners into this xhr. + for(l in self._listeners) { + if(self._listeners.hasOwnProperty(l)) { + addListener(ajax, l, self._listeners[l]); + } } ajax.xhr.open(conf.type, conf.url, true); @@ -156,7 +173,7 @@ ajax.xhr.send(JSON.stringify(conf.data)); } - catch(ex) { ajax._listeners['default'](ex, null, null, null); } + catch(ex) { executeListener(ajax, 'default', ex, null, null, null); } } else { ajax.xhr.send(); @@ -166,13 +183,13 @@ switch (ajax.xhr.readyState) { case 1: - ajax._listeners.loading(); + executeListener(ajax, 'loading'); break; case 2: - ajax._listeners.loaded(); + executeListener(ajax, 'loaded'); break; case 3: - ajax._listeners.interactive(); + executeListener(ajax, 'interactive'); break; case 4: @@ -213,7 +230,7 @@ response = isJSON(response) ? JSON.parse(response) : response; } catch(ex) { - ajax._listeners['default'](ex, null, null, null); + executeListener(ajax, 'default', ex, null, null, null); } // if there is validation, and it returns anything other @@ -225,11 +242,12 @@ validation = validator['inbound'](response); } - if(ajax._listeners[status]) { - ajax._listeners[status](validation ? null : validation, response, statusText, self.xhr); - } - else if(ajax._listeners['default']) { - ajax._listeners['default'](validation ? null : validation, response, statusText, self.xhr); + var codeAction = executeListener(ajax, status, + validation ? null : validation, + response, statusText, self.xhr); + if (!codeAction) { + executeListener(ajax, 'default', validation ? null : validation, + response, statusText, self.xhr); } cache[conf.url] = response;