123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- (function(global){
-
-
-
- function SignalBinding(signal, listener, isOnce, listenerContext, priority) {
-
- this._listener = listener;
-
- this._isOnce = isOnce;
-
- this.context = listenerContext;
-
- this._signal = signal;
-
- this._priority = priority || 0;
- }
- SignalBinding.prototype = {
-
- active : true,
-
- params : null,
-
- execute : function (paramsArr) {
- var handlerReturn, params;
- if (this.active && !!this._listener) {
- params = this.params? this.params.concat(paramsArr) : paramsArr;
- handlerReturn = this._listener.apply(this.context, params);
- if (this._isOnce) {
- this.detach();
- }
- }
- return handlerReturn;
- },
-
- detach : function () {
- return this.isBound()? this._signal.remove(this._listener, this.context) : null;
- },
-
- isBound : function () {
- return (!!this._signal && !!this._listener);
- },
-
- isOnce : function () {
- return this._isOnce;
- },
-
- getListener : function () {
- return this._listener;
- },
-
- getSignal : function () {
- return this._signal;
- },
-
- _destroy : function () {
- delete this._signal;
- delete this._listener;
- delete this.context;
- },
-
- toString : function () {
- return '[SignalBinding isOnce:' + this._isOnce +', isBound:'+ this.isBound() +', active:' + this.active + ']';
- }
- };
-
-
- function validateListener(listener, fnName) {
- if (typeof listener !== 'function') {
- throw new Error( 'listener is a required param of {fn}() and should be a Function.'.replace('{fn}', fnName) );
- }
- }
-
- function Signal() {
-
- this._bindings = [];
- this._prevParams = null;
-
- var self = this;
- this.dispatch = function(){
- Signal.prototype.dispatch.apply(self, arguments);
- };
- }
- Signal.prototype = {
-
- VERSION : '1.0.0',
-
- memorize : false,
-
- _shouldPropagate : true,
-
- active : true,
-
- _registerListener : function (listener, isOnce, listenerContext, priority) {
- var prevIndex = this._indexOfListener(listener, listenerContext),
- binding;
- if (prevIndex !== -1) {
- binding = this._bindings[prevIndex];
- if (binding.isOnce() !== isOnce) {
- throw new Error('You cannot add'+ (isOnce? '' : 'Once') +'() then add'+ (!isOnce? '' : 'Once') +'() the same listener without removing the relationship first.');
- }
- } else {
- binding = new SignalBinding(this, listener, isOnce, listenerContext, priority);
- this._addBinding(binding);
- }
- if(this.memorize && this._prevParams){
- binding.execute(this._prevParams);
- }
- return binding;
- },
-
- _addBinding : function (binding) {
-
- var n = this._bindings.length;
- do { --n; } while (this._bindings[n] && binding._priority <= this._bindings[n]._priority);
- this._bindings.splice(n + 1, 0, binding);
- },
-
- _indexOfListener : function (listener, context) {
- var n = this._bindings.length,
- cur;
- while (n--) {
- cur = this._bindings[n];
- if (cur._listener === listener && cur.context === context) {
- return n;
- }
- }
- return -1;
- },
-
- has : function (listener, context) {
- return this._indexOfListener(listener, context) !== -1;
- },
-
- add : function (listener, listenerContext, priority) {
- validateListener(listener, 'add');
- return this._registerListener(listener, false, listenerContext, priority);
- },
-
- addOnce : function (listener, listenerContext, priority) {
- validateListener(listener, 'addOnce');
- return this._registerListener(listener, true, listenerContext, priority);
- },
-
- remove : function (listener, context) {
- validateListener(listener, 'remove');
- var i = this._indexOfListener(listener, context);
- if (i !== -1) {
- this._bindings[i]._destroy();
- this._bindings.splice(i, 1);
- }
- return listener;
- },
-
- removeAll : function () {
- var n = this._bindings.length;
- while (n--) {
- this._bindings[n]._destroy();
- }
- this._bindings.length = 0;
- },
-
- getNumListeners : function () {
- return this._bindings.length;
- },
-
- halt : function () {
- this._shouldPropagate = false;
- },
-
- dispatch : function (params) {
- if (! this.active) {
- return;
- }
- var paramsArr = Array.prototype.slice.call(arguments),
- n = this._bindings.length,
- bindings;
- if (this.memorize) {
- this._prevParams = paramsArr;
- }
- if (! n) {
-
- return;
- }
- bindings = this._bindings.slice();
- this._shouldPropagate = true;
-
-
- do { n--; } while (bindings[n] && this._shouldPropagate && bindings[n].execute(paramsArr) !== false);
- },
-
- forget : function(){
- this._prevParams = null;
- },
-
- dispose : function () {
- this.removeAll();
- delete this._bindings;
- delete this._prevParams;
- },
-
- toString : function () {
- return '[Signal active:'+ this.active +' numListeners:'+ this.getNumListeners() +']';
- }
- };
-
-
-
- var signals = Signal;
-
-
- signals.Signal = Signal;
-
- if(typeof define === 'function' && define.amd){
- define(function () { return signals; });
- } else if (typeof module !== 'undefined' && module.exports){
- module.exports = signals;
- } else {
-
-
- global['signals'] = signals;
- }
- }(this));
|