From c4c7c62816bc0d0a2308acf97d0e37494889eed0 Mon Sep 17 00:00:00 2001 From: lin onetwo Date: Tue, 18 Mar 2025 00:50:03 +0800 Subject: [PATCH] feat: prevent adding the same event listener multiple times --- core/modules/widgets/widget.js | 4 ++- .../test/tiddlers/tests/test-widget-event.js | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 36ddd0a37..e2bfb79ca 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -634,7 +634,9 @@ Listener could return a boolean indicating whether to further propagation or not */ Widget.prototype.addEventListener = function(type,handler) { this.eventListeners[type] = this.eventListeners[type] || []; - this.eventListeners[type].push(handler); + if(this.eventListeners[type].indexOf(handler) === -1) { + this.eventListeners[type].push(handler); + } }; /* diff --git a/editions/test/tiddlers/tests/test-widget-event.js b/editions/test/tiddlers/tests/test-widget-event.js index 123679757..b70f5424c 100644 --- a/editions/test/tiddlers/tests/test-widget-event.js +++ b/editions/test/tiddlers/tests/test-widget-event.js @@ -193,6 +193,32 @@ describe("Widget Event Listeners", function() { expect(calls).not.toContain("listener1"); }); + it("should prevent adding the same event listener multiple times", function() { + var calls = 0; + var wiki = new $tw.Wiki(); + var widget = createWidgetNode({type:"widget", text:"text"}, wiki); + + function listener(e) { + calls++; + return true; + } + + // Add the same listener multiple times + widget.addEventListener("testEvent", listener); + widget.addEventListener("testEvent", listener); + widget.addEventListener("testEvent", listener); + + // Dispatch the event + var event = {type:"testEvent"}; + widget.dispatchEvent(event); + + // The listener should only be called once + expect(calls).toBe(1); + + // Check the internal structure of eventListeners array + expect(widget.eventListeners["testEvent"].length).toBe(1); + }); + }); })();