diff --git a/src/model/Node.ts b/src/model/Node.ts index 157076ed..c3c9ee69 100755 --- a/src/model/Node.ts +++ b/src/model/Node.ts @@ -23,7 +23,7 @@ export abstract class Node { /** @internal */ protected _visible: boolean; /** @internal */ - protected _listeners: Record void>; + protected _listeners: Record void)[]>; /** @internal */ protected _dirty: boolean = false; /** @internal */ @@ -83,14 +83,38 @@ export abstract class Node { return Orientation.flip(this._parent.getOrientation()); } } - - // event can be: resize, visibility, maximize (on tabset), close - setEventListener(event: string, callback: (params: any) => void) { - this._listeners[event] = callback; + + /** + * Adds the given event listener. Can optionally replace existing listeners. + * @param event valid events: resize, visibility, save, close + * @param callback + * @param replace if set to true, existing listeners will be cleared + */ + setEventListener(event: string, callback: (params: any) => void, replace:boolean=true) { + if (replace || this._listeners[event] === undefined) { + this._listeners[event] = [callback]; + } else { + this._listeners[event].push(callback); + } } - removeEventListener(event: string) { - delete this._listeners[event]; + /** + * If a callback is provided, it will be removed from the event. + * If no callback is provided, all callbacks will be removed from the event. + * @param event valid events: resize, visibility, save, close + * @param callback the specific callback to remove + */ + removeEventListener(event: string, callback?: (params: any) => void) { + if (this._listeners[event] !== undefined) { + if (callback) { + const index = this._listeners[event].indexOf(callback); + if (index !== -1) { + this._listeners[event].splice(index, 1); + } + } else { + this._listeners[event] = []; + } + } } abstract toJson(): IJsonRowNode | IJsonBorderNode | IJsonTabSetNode | IJsonTabNode | undefined; @@ -104,7 +128,9 @@ export abstract class Node { _fireEvent(event: string, params: any) { // console.log(this._type, " fireEvent " + event + " " + JSON.stringify(params)); if (this._listeners[event] !== undefined) { - this._listeners[event](params); + for(const callback of this._listeners[event]) { + callback(params); + } } } diff --git a/test/Model.test.ts b/test/Model.test.ts index 1bf64eaa..2eb28fd9 100755 --- a/test/Model.test.ts +++ b/test/Model.test.ts @@ -504,17 +504,32 @@ describe("Tree", function () { }); it("close tab", () => { - let closed = false; - tab("/ts0/t0").setEventListener("close", () => { closed = true; }) + let closed1 = false; + let closed2 = false; + let closed3 = false; + let closed4 = false; + tab("/ts0/t0").setEventListener("close", () => { closed1 = true; }, false); + tab("/ts0/t0").setEventListener("close", () => { closed2 = true; }); + tab("/ts0/t0").setEventListener("close", () => { closed3 = true; }, false); + const close4Callback = () => { closed4 = true; } + tab("/ts0/t0").setEventListener("close", close4Callback, false); + tab("/ts0/t0").removeEventListener("close", close4Callback); doAction(Actions.deleteTab(tab("/ts0/t0").getId())); - expect(closed).equals(true); + expect(closed1).equals(false); + expect(closed2).equals(true); + expect(closed3).equals(true); + expect(closed4).equals(false); }); it("save tab", () => { - let saved = false; - tab("/ts0/t0").setEventListener("save", () => { saved = true; }) + let saved1 = false; + let saved2 = false; + tab("/ts0/t0").setEventListener("save", () => { saved1 = true; }); + tab("/ts0/t0").removeEventListener("save"); + tab("/ts0/t0").setEventListener("save", () => { saved2 = true; }, false); model.toJson(); - expect(saved).equals(true); + expect(saved1).equals(false); + expect(saved2).equals(true); }); it("visibility tab", () => {