From e30d62bdabb287c3d40de30fec7e918284fdd348 Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Sun, 3 Sep 2017 22:34:00 +0200 Subject: [PATCH 1/8] add test for creation of SlotList with null arguments --- test/org/osflash/signals/SlotListTest.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/org/osflash/signals/SlotListTest.test.ts b/test/org/osflash/signals/SlotListTest.test.ts index fd32fda..147c521 100644 --- a/test/org/osflash/signals/SlotListTest.test.ts +++ b/test/org/osflash/signals/SlotListTest.test.ts @@ -55,6 +55,10 @@ describe("SlotListTest", () => { assert.throws(() => new SlotList(null, listOfA), Error); }); + it("constructing_with_null_head_and_null_tail_throws_error", () => { + assert.throws(() => new SlotList(null, null), Error); + }); + it("list_with_one_listener_contains_it", () => { assert.isTrue(listOfA.contains(listenerA)); }); From d074f15eb9e16ae8fe265897855c6009af372c3a Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Sun, 3 Sep 2017 22:48:42 +0200 Subject: [PATCH 2/8] improve code coverage of SlotList class --- test/org/osflash/signals/SlotListTest.test.ts | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/test/org/osflash/signals/SlotListTest.test.ts b/test/org/osflash/signals/SlotListTest.test.ts index 147c521..e7f7c38 100644 --- a/test/org/osflash/signals/SlotListTest.test.ts +++ b/test/org/osflash/signals/SlotListTest.test.ts @@ -14,6 +14,7 @@ describe("SlotListTest", () => { let listenerA: Function; let listenerB: Function; let listenerC: Function; + let listenerD: Function; let slotA: ISlot; let slotB: ISlot; let slotC: ISlot; @@ -29,6 +30,8 @@ describe("SlotListTest", () => { }; listenerC = function(e: any = null): void { }; + listenerD = function(e: any = null): void { + }; slotA = new Slot(listenerA, signal); slotB = new Slot(listenerB, signal); slotC = new Slot(listenerC, signal); @@ -59,6 +62,10 @@ describe("SlotListTest", () => { assert.throws(() => new SlotList(null, null), Error); }); + it("contains_should_return_false_when_listener_is_not_part_of_list", () => { + assert.isFalse(listOfABC.contains(listenerD)); + }); + it("list_with_one_listener_contains_it", () => { assert.isTrue(listOfA.contains(listenerA)); }); @@ -75,128 +82,106 @@ describe("SlotListTest", () => { assert.equal(listenerA, listOfA.head.listener); }); - it("NIL_does_not_contain_anonymous_listener", () => { assert.isFalse(SlotList.NIL.contains(new Function())); }); - it("find_in_empty_list_yields_null", () => { assert.isNull(SlotList.NIL.find(listenerA)); }); - it("NIL_does_not_contain_null_listener", () => { assert.isFalse(SlotList.NIL.contains(null)); }); - it("find_the_1st_of_2_listeners_yields_its_slot", () => { assert.equal(slotA, listOfAB.find(listenerA)); }); - it("find_the_2nd_of_2_listeners_yields_its_slot", () => { assert.equal(slotB, listOfAB.find(listenerB)); }); - it("find_the_1st_of_3_listeners_yields_its_slot", () => { assert.equal(slotA, listOfABC.find(listenerA)); }); - it("find_the_2nd_of_3_listeners_yields_its_slot", () => { assert.equal(slotB, listOfABC.find(listenerB)); }); - it("find_the_3rd_of_3_listeners_yields_its_slot", () => { assert.equal(slotC, listOfABC.find(listenerC)); }); - it("prepend_a_slot_makes_it_head_of_new_list", () => { let newList: SlotList = listOfA.prepend(slotB); assert.equal(slotB, newList.head); }); - it("prepend_a_slot_makes_the_old_list_the_tail", () => { let newList: SlotList = listOfA.prepend(slotB); assert.equal(listOfA, newList.tail); }); - it("after_prepend_slot_new_list_contains_its_listener", () => { let newList: SlotList = listOfA.prepend(slotB); assert.isTrue(newList.contains(slotB.listener)); }); - it("append_a_slot_yields_new_list_with_same_head", () => { let oldHead: ISlot = listOfA.head; let newList: SlotList = listOfA.append(slotB); assert.equal(oldHead, newList.head); }); - it("append_to_list_of_one_yields_list_of_length_two", () => { let newList: SlotList = listOfA.append(slotB); assert.equal(2, newList.length); }); - it("after_append_slot_new_list_contains_its_listener", () => { let newList: SlotList = listOfA.append(slotB); assert.isTrue(newList.contains(slotB.listener)); }); - it("append_slot_yields_a_different_list", () => { let newList: SlotList = listOfA.append(slotB); assert.notEqual(listOfA, newList); }); - it("append_null_yields_same_list", () => { let newList: SlotList = listOfA.append(null); assert.equal(listOfA, newList); }); - it("filterNot_on_empty_list_yields_same_list", () => { let newList: SlotList = SlotList.NIL.filterNot(listenerA); assert.equal(SlotList.NIL, newList); }); - it("filterNot_null_yields_same_list", () => { let newList: SlotList = listOfA.filterNot(null); assert.equal(listOfA, newList); }); - it("filterNot_head_from_list_of_1_yields_empty_list", () => { let newList: SlotList = listOfA.filterNot(listOfA.head.listener); assert.equal(SlotList.NIL, newList); }); - it("filterNot_1st_listener_from_list_of_2_yields_list_of_2nd_listener", () => { let newList: SlotList = listOfAB.filterNot(listenerA); assert.equal(listenerB, newList.head.listener); assert.equal(1, newList.length); }); - it("filterNot_2nd_listener_from_list_of_2_yields_list_of_head", () => { let newList: SlotList = listOfAB.filterNot(listenerB); assert.equal(listenerA, newList.head.listener); assert.equal(1, newList.length); }); - it("filterNot_2nd_listener_from_list_of_3_yields_list_of_1st_and_3rd", () => { let newList: SlotList = listOfABC.filterNot(listenerB); assert.equal(listenerA, newList.head.listener); @@ -204,6 +189,14 @@ describe("SlotListTest", () => { assert.equal(2, newList.length); }); + it("filterNot_with_unknow_listener_should_not_change_list", () => { + let newList: SlotList = listOfABC.filterNot(listenerD); + assert.equal(listenerA, newList.head.listener); + assert.equal(listenerB, newList.tail.head.listener); + assert.equal(listenerC, newList.tail.tail.head.listener); + assert.equal(3, newList.length); + assert.equal(listOfABC, newList); + }); // Issue #56 it("insertWithPriority_adds_4_slots_without_losing_any", () => { @@ -227,11 +220,10 @@ describe("SlotListTest", () => { assert.equal(slot4, list.tail.tail.head); assert.equal(slot2, list.tail.tail.tail.head); }); -}); - - - - - - + it("toString_should_return_string", () => { + assert.isString(listOfA.toString()); + assert.isString(listOfAB.toString()); + assert.isString(listOfABC.toString()); + }); +}); From e87ae1b48fcc4caaf43975d9f5eeefe02e51fc44 Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 00:19:08 +0200 Subject: [PATCH 3/8] correct bug in DeluxeSignal when propagating event to parent --- src/org/osflash/signals/DeluxeSignal.ts | 58 +++++++++++++++---------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/org/osflash/signals/DeluxeSignal.ts b/src/org/osflash/signals/DeluxeSignal.ts index 7ba5805..4229f5a 100644 --- a/src/org/osflash/signals/DeluxeSignal.ts +++ b/src/org/osflash/signals/DeluxeSignal.ts @@ -35,12 +35,12 @@ export class DeluxeSignal extends PrioritySignal { */ constructor(target: Object = null, ...valueClasses) { // Cannot use super.apply(null, valueClasses), so allow the subclass to call super(valueClasses). - valueClasses = (valueClasses.length == 1 && valueClasses[0] instanceof Array) ? valueClasses[0] : valueClasses; + valueClasses = (valueClasses.length === 1 && valueClasses[0] instanceof Array) ? valueClasses[0] : valueClasses; super(valueClasses); - //@CHANGED - this was the first call in the constructor - //Typescript does not allow "this" to be called before super + // @CHANGED - this was the first call in the constructor + // Typescript does not allow "this" to be called before super this._target = target; } @@ -50,7 +50,9 @@ export class DeluxeSignal extends PrioritySignal { } public set target(value: Object) { - if (value == this._target) return; + if (value === this._target) { + return; + } this.removeAll(); this._target = value; } @@ -63,27 +65,32 @@ export class DeluxeSignal extends PrioritySignal { /*override*/ public dispatch(...valueObjects): void { // Validate value objects against pre-defined value classes. - var numValueClasses: number = this._valueClasses.length; - var numValueObjects: number = valueObjects.length; + let numValueClasses: number = this._valueClasses.length; + let numValueObjects: number = valueObjects.length; if (numValueObjects < numValueClasses) { - throw new Error('Incorrect number of arguments. ' + - 'Expected at least ' + numValueClasses + ' but received ' + - numValueObjects + '.'); + throw new Error( + "Incorrect number of arguments. " + + "Expected at least " + numValueClasses + " but received " + + numValueObjects + "." + ); } // Cannot dispatch differently typed objects than declared classes. - for (var i: number = 0; i < numValueClasses; i++) { + for (let i: number = 0; i < numValueClasses; i++) { // Optimized for the optimistic case that values are correct. - if (valueObjects[i] === null || valueObjects[i].constructor === this._valueClasses[i]) + if (valueObjects[i] === null || valueObjects[i].constructor === this._valueClasses[i]) { continue; + } - throw new Error('Value object <' + valueObjects[i] - + '> is not an instance of <' + this._valueClasses[i] + '>.'); + throw new Error( + "Value object <" + valueObjects[i] + + "> is not an instance of <" + this._valueClasses[i] + ">." + ); } // Extract and clone event object if necessary. - var event: IEvent = (valueObjects[0]); + let event: IEvent = (valueObjects[0]); if (event) { if (event.target) { event = event.clone(); @@ -96,29 +103,34 @@ export class DeluxeSignal extends PrioritySignal { } // Broadcast to listeners. - var slotsToProcess: SlotList = this.slots; + let slotsToProcess: SlotList = this.slots; while (slotsToProcess.nonEmpty) { slotsToProcess.head.execute(valueObjects); slotsToProcess = slotsToProcess.tail; } // Bubble the event as far as possible. - if (!event || !event.bubbles) return; + if (!event || !event.bubbles) { + return; + } - var currentTarget: Object = this.target; + let currentTarget: Object = this.target; while (currentTarget && currentTarget.hasOwnProperty("parent")) { - currentTarget = currentTarget["parent"]; - if (!currentTarget) break; + currentTarget = (currentTarget).parent; + + if (!currentTarget) { + break; + } - if ((currentTarget).onEventBubbled !== undefined) { + if ((currentTarget).onEventBubbled !== null) { event.currentTarget = currentTarget; + // onEventBubbled() can stop the bubbling by returning false. - if ((currentTarget).onEventBubbled(event)) + if (!(currentTarget).onEventBubbled(event)) { break; + } } } } - } - From 325a412e3248a6e6798ee2ed5964322fad5b7572 Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 00:19:48 +0200 Subject: [PATCH 4/8] enable bubling test for DeluxeSignal class --- .../DeluxeSignalWithBubblingEventTest.test.ts | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts index f3c9b7e..a1b6899 100644 --- a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts +++ b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts @@ -11,14 +11,23 @@ import { IEvent } from "../../../../src/org/osflash/signals/events/IEvent"; describe("DeluxeSignalWithBubblingEventTest", () => { let async: AsyncUtil = new AsyncUtil(); - let theParent: IBubbleEventHandler; + let theParent: Child; let theChild: Child; let theGrandChild: Child; let cancelTimeout: Function; + let doneFunc: Function; + + function onEventBubbled(e: IEvent): boolean { + cancelTimeout(); + assert.equal(theGrandChild, e.target, "e.target should be the object that originally dispatched event"); + assert.equal(this, e.currentTarget, "e.currentTarget should be the object receiving the bubbled event"); + doneFunc(); + return false; + } beforeEach(() => { - theParent = this; - theChild = new Child(this, "theChild"); + theParent = new Child(null, "theParent", onEventBubbled); + theChild = new Child(theParent, "theChild"); theGrandChild = new Child(theChild, "theGrandChild"); }); @@ -26,30 +35,28 @@ describe("DeluxeSignalWithBubblingEventTest", () => { theChild = null; theGrandChild = null; cancelTimeout = null; + doneFunc = null; }); it("parent_child_relationships()", () => { - assert.equal(this, theChild.parent, "theChild's parent is this"); - // TODO: find a way to typecheck for interfaces - // assert.isTrue(this instanceof IBubbleEventHandler, "this can handle bubbling events"); + assert.equal(theParent, theChild.parent, "theChild's parent is this"); }); - it.skip("dispatch_bubbling_event_from_theGrandChild_should_bubble_to_parent_IBubbleHandler()", (done) => { + it("dispatch_bubbling_event_from_theGrandChild_should_bubble_to_parent_IBubbleHandler()", (done) => { // If cancelTimeout() isn"t called, this test will fail. - cancelTimeout = async.add(null, 10); + cancelTimeout = async.add(null, 1000); + + // keep reference for done function + doneFunc = done; + + // prepare event let event: IEvent = new GenericEvent(); event.bubbles = true; + // dispatch event from grand child, expecting that it will arrive on parent theGrandChild.completed.dispatch(event); }); - function onEventBubbled(e: IEvent): boolean { - cancelTimeout(); - assert.equal(theGrandChild, e.target, "e.target should be the object that originally dispatched event"); - assert.equal(this, e.currentTarget, "e.currentTarget should be the object receiving the bubbled event"); - return false; - } - // TODO: returning after throwing an error is not possible in TS it.skip("returning_false_from_onEventBubbled_should_stop_bubbling()", () => { let bubbleHater: BubbleHater = new BubbleHater(); @@ -82,11 +89,13 @@ class Child implements IBubbleEventHandler { public parent: Object; public completed: DeluxeSignal; public name: string; + public listener: Function = null; public popsBubbles: boolean = false; - constructor(parent: Object = null, name = "") { + constructor(parent: Object = null, name = "", listener = null) { this.parent = parent; this.name = name; + this.listener = listener; this.completed = new DeluxeSignal(this); } @@ -95,7 +104,11 @@ class Child implements IBubbleEventHandler { } public onEventBubbled(event: IEvent): boolean { - return !this.popsBubbles; + if (this.listener !== null) { + return this.listener(event); + } else { + return !this.popsBubbles; + } } } From 1b220dc0c4b60f6a60e3144e8923aa36559888fb Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 00:29:56 +0200 Subject: [PATCH 5/8] correct unit tests for DeluxeSignal class --- .../osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts index a1b6899..495f0a1 100644 --- a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts +++ b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts @@ -20,7 +20,7 @@ describe("DeluxeSignalWithBubblingEventTest", () => { function onEventBubbled(e: IEvent): boolean { cancelTimeout(); assert.equal(theGrandChild, e.target, "e.target should be the object that originally dispatched event"); - assert.equal(this, e.currentTarget, "e.currentTarget should be the object receiving the bubbled event"); + assert.equal(theParent, e.currentTarget, "e.currentTarget should be the object receiving the bubbled event"); doneFunc(); return false; } @@ -44,7 +44,7 @@ describe("DeluxeSignalWithBubblingEventTest", () => { it("dispatch_bubbling_event_from_theGrandChild_should_bubble_to_parent_IBubbleHandler()", (done) => { // If cancelTimeout() isn"t called, this test will fail. - cancelTimeout = async.add(null, 1000); + cancelTimeout = async.add(null, 1500); // keep reference for done function doneFunc = done; From 0181e3c8c8ce25eccbcdd6ad7293da8727e9b028 Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 00:49:32 +0200 Subject: [PATCH 6/8] enable unit test for DeluxeSignal class --- .../signals/DeluxeSignalWithBubblingEventTest.test.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts index 495f0a1..923fe76 100644 --- a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts +++ b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts @@ -32,6 +32,7 @@ describe("DeluxeSignalWithBubblingEventTest", () => { }); afterEach(() => { + theParent = null; theChild = null; theGrandChild = null; cancelTimeout = null; @@ -57,13 +58,11 @@ describe("DeluxeSignalWithBubblingEventTest", () => { theGrandChild.completed.dispatch(event); }); - // TODO: returning after throwing an error is not possible in TS - it.skip("returning_false_from_onEventBubbled_should_stop_bubbling()", () => { + it("returning_false_from_onEventBubbled_should_stop_bubbling()", () => { let bubbleHater: BubbleHater = new BubbleHater(); theChild = new Child(bubbleHater, "bubblePopper"); theChild.popsBubbles = true; theGrandChild = new Child(theChild, "bubbleBlower"); - let bubblingEvent: IEvent = new GenericEvent(true); // Will only complete without error if theChild pops the bubble. theGrandChild.completed.dispatch(bubblingEvent); @@ -77,7 +76,6 @@ describe("DeluxeSignalWithBubblingEventTest", () => { // Changing popsBubbles to false will fail the test nicely. theChild.popsBubbles = false; theGrandChild = new Child(this.theChild, "bubbleBlower"); - let bubblingEvent: IEvent = new GenericEvent(true); // Because theChild didn"t pop the bubble, this causes bubbleHater to throw an error. theGrandChild.completed.dispatch(bubblingEvent); From c3c3f05ac7b62f18162e92e2232ec0a8a0f9e7df Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 00:56:01 +0200 Subject: [PATCH 7/8] enable unit test for DeluxeSignal class --- .../signals/DeluxeSignalWithBubblingEventTest.test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts index 923fe76..4346089 100644 --- a/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts +++ b/test/org/osflash/signals/DeluxeSignalWithBubblingEventTest.test.ts @@ -68,14 +68,13 @@ describe("DeluxeSignalWithBubblingEventTest", () => { theGrandChild.completed.dispatch(bubblingEvent); }); - // TODO: Check why the error is not thrown - it.skip("returning_true_from_onEventBubbled_should_continue_bubbling()", () => { + it("returning_true_from_onEventBubbled_should_continue_bubbling()", () => { assert.throws(() => { let bubbleHater: BubbleHater = new BubbleHater(); theChild = new Child(bubbleHater, "bubblePopper"); // Changing popsBubbles to false will fail the test nicely. theChild.popsBubbles = false; - theGrandChild = new Child(this.theChild, "bubbleBlower"); + theGrandChild = new Child(theChild, "bubbleBlower"); let bubblingEvent: IEvent = new GenericEvent(true); // Because theChild didn"t pop the bubble, this causes bubbleHater to throw an error. theGrandChild.completed.dispatch(bubblingEvent); From 2eec5e52d41604416c96bd3c7979179233ef33c2 Mon Sep 17 00:00:00 2001 From: Tiago Schenkel Date: Mon, 4 Sep 2017 01:01:15 +0200 Subject: [PATCH 8/8] update static lib --- dist/signals.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/signals.min.js b/dist/signals.min.js index 3e1b62c..004438e 100644 --- a/dist/signals.min.js +++ b/dist/signals.min.js @@ -1 +1 @@ -var SignalsJS=function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var r={};return e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=5)}([function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e,r,n){void 0===r&&(r=!1),void 0===n&&(n=0),this._enabled=!0,this._once=!1,this._priority=0,this._listener=t,this._once=r,this._signal=e,this._priority=n,this.verifyListener(t)}return t.prototype.execute0=function(){if(this._enabled){if(this._once&&this.remove(),this._params&&this._params.length)return void this._listener.apply(null,this._params);this._listener()}},t.prototype.execute1=function(t){if(this._enabled){if(this._once&&this.remove(),this._params&&this._params.length)return void this._listener.apply(null,[t].concat(this._params));this._listener(t)}},t.prototype.execute=function(t){if(this._enabled){this._once&&this.remove(),this._params&&this._params.length&&(t=t.concat(this._params));var e=t.length;0==e?this._listener():1==e?this._listener(t[0]):2==e?this._listener(t[0],t[1]):3==e?this._listener(t[0],t[1],t[2]):this._listener.apply(null,t)}},Object.defineProperty(t.prototype,"listener",{get:function(){return this._listener},set:function(t){if(null==t)throw new Error("Given listener is null.\nDid you want to set enabled to false instead?");this.verifyListener(t),this._listener=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"once",{get:function(){return this._once},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"priority",{get:function(){return this._priority},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return"[Slot listener: "+this._listener+", once: "+this._once+", priority: "+this._priority+", enabled: "+this._enabled+"]"},Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this._enabled=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"params",{get:function(){return this._params},set:function(t){this._params=t},enumerable:!0,configurable:!0}),t.prototype.remove=function(){this._signal.remove(this._listener)},t.prototype.verifyListener=function(t){if(null==t)throw new Error("Given listener is null.");if(null==this._signal)throw new Error("Internal signal reference has not been set yet.")},t}();e.Slot=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(4),i=r(0),o=function(){function t(){for(var t=[],e=0;e."+this._valueClasses[e])},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"numListeners",{get:function(){return this.slots.length},enumerable:!0,configurable:!0}),t.prototype.addOnce=function(t){return this.registerListener(t,!0)},t.prototype.remove=function(t){var e=this.slots.find(t);return e?(this.slots=this.slots.filterNot(t),e):null},t.prototype.removeAll=function(){this.slots=n.SlotList.NIL},t.prototype.dispatch=function(){for(var t=[],e=0;e is not an instance of <"+this._valueClasses[i]+">.");var o=this.slots;if(o.nonEmpty)for(;o.nonEmpty;)o.head.execute(t),o=o.tail},t.prototype.registerListener=function(t,e){if(void 0===e&&(e=!1),this.registrationPossible(t,e)){var r=new i.Slot(t,this,e);return this.slots=this.slots.prepend(r),r}return this.slots.find(t)},t.prototype.registrationPossible=function(t,e){if(!this.slots.nonEmpty)return!0;var r=this.slots.find(t);if(!r)return!0;if(r.once!=e)throw new Error("You cannot addOnce() then add() the same listener without removing the relationship first.");return!1},t}();e.OnceSignal=o},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(3),o=r(0),s=function(t){function e(){for(var e=[],r=0;rthis.head.priority)return this.prepend(e);for(var n=new t(this.head),i=n,o=this.tail;o.nonEmpty;){if(r>o.head.priority)return i.tail=o.prepend(e),n;i=i.tail=new t(o.head),o=o.tail}return i.tail=new t(e),n},t.prototype.filterNot=function(e){if(!this.nonEmpty||null==e)return this;if(e==this.head.listener)return this.tail;for(var r=new t(this.head),n=r,i=this.tail;i.nonEmpty;){if(i.head.listener==e)return n.tail=i.tail,r;n=n.tail=new t(i.head),i=i.tail}return this},t.prototype.contains=function(t){if(!this.nonEmpty)return!1;for(var e=this;e.nonEmpty;){if(e.head.listener==t)return!0;e=e.tail}return!1},t.prototype.find=function(t){if(!this.nonEmpty)return null;for(var e=this;e.nonEmpty;){if(e.head.listener==t)return e.head;e=e.tail}return null},t.prototype.toString=function(){for(var t="",e=this;e.nonEmpty;)t+=e.head+" -> ",e=e.tail;return"[List "+(t+="NIL")+"]"},t.NIL=new t(null,null),t}();e.SlotList=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(6);e.DeluxeSignal=n.DeluxeSignal;var i=r(7);e.GenericEvent=i.GenericEvent;var o=r(8);e.IOnceSignal=o.IOnceSignal;var s=r(9);e.IPrioritySignal=s.IPrioritySignal;var a=r(10);e.ISignal=a.ISignal;var l=r(11);e.ISlot=l.ISlot;var u=r(12);e.MonoSignal=u.MonoSignal;var c=r(1);e.OnceSignal=c.OnceSignal;var h=r(2);e.PrioritySignal=h.PrioritySignal;var f=r(13);e.Promise=f.Promise;var p=r(3);e.Signal=p.Signal;var y=r(0);e.Slot=y.Slot;var v=r(4);e.SlotList=v.SlotList},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(2),o=function(t){function e(e){void 0===e&&(e=null);for(var r=[],n=1;n is not an instance of <"+this._valueClasses[i]+">.");var o=t[0];o&&(o.target&&(o=o.clone(),t[0]=o),o.target=this.target,o.currentTarget=this.target,o.signal=this);for(var s=this.slots;s.nonEmpty;)s.head.execute(t),s=s.tail;if(o&&o.bubbles)for(var a=this.target;a&&a.hasOwnProperty("parent")&&(a=a.parent)&&(void 0===a.onEventBubbled||(o.currentTarget=a,!a.onEventBubbled(o))););},e}(i.PrioritySignal);e.DeluxeSignal=o},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t){void 0===t&&(t=!1),this._bubbles=t}return Object.defineProperty(t.prototype,"signal",{get:function(){return this._signal},set:function(t){this._signal=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"target",{get:function(){return this._target},set:function(t){this._target=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"currentTarget",{get:function(){return this._currentTarget},set:function(t){this._currentTarget=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bubbles",{get:function(){return this._bubbles},set:function(t){this._bubbles=t},enumerable:!0,configurable:!0}),t.prototype.clone=function(){return new t(this._bubbles)},t}();e.GenericEvent=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.IOnceSignal=Symbol("IOnceSignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.IPrioritySignal=Symbol("IPrioritySignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ISignal=Symbol("ISignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ISlot=Symbol("ISlot")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(0),i=function(){function t(){for(var t=[],e=0;e."+this._valueClasses[e])},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"numListeners",{get:function(){return this.slot?1:0},enumerable:!0,configurable:!0}),t.prototype.add=function(t){return this.registerListener(t)},t.prototype.addOnce=function(t){return this.registerListener(t,!0)},t.prototype.remove=function(t){if(this.slot&&this.slot.listener==t){var e=this.slot;return this.slot=null,e}return null},t.prototype.removeAll=function(){this.slot&&this.slot.remove()},t.prototype.dispatch=function(){for(var t=[],e=0;e is not an instance of <"+this._valueClasses[i]+">.");this.slot&&this.slot.execute(t)},t.prototype.registerListener=function(t,e){if(void 0===e&&(e=!1),this.slot)throw new Error("You cannot add or addOnce with a listener already added, remove the current listener first.");return this.slot=new n.Slot(t,this,e)},t}();e.MonoSignal=i},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(1),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.addOnce=function(e){var r=t.prototype.addOnce.call(this,e);return this.isDispatched&&(r.execute(this.valueObjects),r.remove()),r},e.prototype.dispatch=function(){for(var e=[],r=0;r."+this._valueClasses[e])},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"numListeners",{get:function(){return this.slots.length},enumerable:!0,configurable:!0}),t.prototype.addOnce=function(t){return this.registerListener(t,!0)},t.prototype.remove=function(t){var e=this.slots.find(t);return e?(this.slots=this.slots.filterNot(t),e):null},t.prototype.removeAll=function(){this.slots=n.SlotList.NIL},t.prototype.dispatch=function(){for(var t=[],e=0;e is not an instance of <"+this._valueClasses[i]+">.");var o=this.slots;if(o.nonEmpty)for(;o.nonEmpty;)o.head.execute(t),o=o.tail},t.prototype.registerListener=function(t,e){if(void 0===e&&(e=!1),this.registrationPossible(t,e)){var r=new i.Slot(t,this,e);return this.slots=this.slots.prepend(r),r}return this.slots.find(t)},t.prototype.registrationPossible=function(t,e){if(!this.slots.nonEmpty)return!0;var r=this.slots.find(t);if(!r)return!0;if(r.once!=e)throw new Error("You cannot addOnce() then add() the same listener without removing the relationship first.");return!1},t}();e.OnceSignal=o},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(3),o=r(0),s=function(t){function e(){for(var e=[],r=0;rthis.head.priority)return this.prepend(e);for(var n=new t(this.head),i=n,o=this.tail;o.nonEmpty;){if(r>o.head.priority)return i.tail=o.prepend(e),n;i=i.tail=new t(o.head),o=o.tail}return i.tail=new t(e),n},t.prototype.filterNot=function(e){if(!this.nonEmpty||null==e)return this;if(e==this.head.listener)return this.tail;for(var r=new t(this.head),n=r,i=this.tail;i.nonEmpty;){if(i.head.listener==e)return n.tail=i.tail,r;n=n.tail=new t(i.head),i=i.tail}return this},t.prototype.contains=function(t){if(!this.nonEmpty)return!1;for(var e=this;e.nonEmpty;){if(e.head.listener==t)return!0;e=e.tail}return!1},t.prototype.find=function(t){if(!this.nonEmpty)return null;for(var e=this;e.nonEmpty;){if(e.head.listener==t)return e.head;e=e.tail}return null},t.prototype.toString=function(){for(var t="",e=this;e.nonEmpty;)t+=e.head+" -> ",e=e.tail;return"[List "+(t+="NIL")+"]"},t.NIL=new t(null,null),t}();e.SlotList=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(6);e.DeluxeSignal=n.DeluxeSignal;var i=r(7);e.GenericEvent=i.GenericEvent;var o=r(8);e.IOnceSignal=o.IOnceSignal;var s=r(9);e.IPrioritySignal=s.IPrioritySignal;var a=r(10);e.ISignal=a.ISignal;var l=r(11);e.ISlot=l.ISlot;var u=r(12);e.MonoSignal=u.MonoSignal;var c=r(1);e.OnceSignal=c.OnceSignal;var h=r(2);e.PrioritySignal=h.PrioritySignal;var f=r(13);e.Promise=f.Promise;var p=r(3);e.Signal=p.Signal;var y=r(0);e.Slot=y.Slot;var v=r(4);e.SlotList=v.SlotList},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(2),o=function(t){function e(e){void 0===e&&(e=null);for(var r=[],n=1;n is not an instance of <"+this._valueClasses[i]+">.");var o=t[0];o&&(o.target&&(o=o.clone(),t[0]=o),o.target=this.target,o.currentTarget=this.target,o.signal=this);for(var s=this.slots;s.nonEmpty;)s.head.execute(t),s=s.tail;if(o&&o.bubbles)for(var a=this.target;a&&a.hasOwnProperty("parent")&&(a=a.parent)&&(null===a.onEventBubbled||(o.currentTarget=a,a.onEventBubbled(o))););},e}(i.PrioritySignal);e.DeluxeSignal=o},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t){void 0===t&&(t=!1),this._bubbles=t}return Object.defineProperty(t.prototype,"signal",{get:function(){return this._signal},set:function(t){this._signal=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"target",{get:function(){return this._target},set:function(t){this._target=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"currentTarget",{get:function(){return this._currentTarget},set:function(t){this._currentTarget=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bubbles",{get:function(){return this._bubbles},set:function(t){this._bubbles=t},enumerable:!0,configurable:!0}),t.prototype.clone=function(){return new t(this._bubbles)},t}();e.GenericEvent=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.IOnceSignal=Symbol("IOnceSignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.IPrioritySignal=Symbol("IPrioritySignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ISignal=Symbol("ISignal")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ISlot=Symbol("ISlot")},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(0),i=function(){function t(){for(var t=[],e=0;e."+this._valueClasses[e])},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"numListeners",{get:function(){return this.slot?1:0},enumerable:!0,configurable:!0}),t.prototype.add=function(t){return this.registerListener(t)},t.prototype.addOnce=function(t){return this.registerListener(t,!0)},t.prototype.remove=function(t){if(this.slot&&this.slot.listener==t){var e=this.slot;return this.slot=null,e}return null},t.prototype.removeAll=function(){this.slot&&this.slot.remove()},t.prototype.dispatch=function(){for(var t=[],e=0;e is not an instance of <"+this._valueClasses[i]+">.");this.slot&&this.slot.execute(t)},t.prototype.registerListener=function(t,e){if(void 0===e&&(e=!1),this.slot)throw new Error("You cannot add or addOnce with a listener already added, remove the current listener first.");return this.slot=new n.Slot(t,this,e)},t}();e.MonoSignal=i},function(t,e,r){"use strict";var n=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(e,r){function n(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}();Object.defineProperty(e,"__esModule",{value:!0});var i=r(1),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.addOnce=function(e){var r=t.prototype.addOnce.call(this,e);return this.isDispatched&&(r.execute(this.valueObjects),r.remove()),r},e.prototype.dispatch=function(){for(var e=[],r=0;r