Fix the handling of replaced polls
authorAlexander Ebert <ebert@woltlab.com>
Mon, 2 Oct 2023 14:08:21 +0000 (16:08 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 2 Oct 2023 14:08:21 +0000 (16:08 +0200)
Editing a message with a poll could replace the poll, requiring a new initialization.

The previous map was replaced with a `WeakSet` because it is never read from and the map leaked memory when the poll was discarded.

See https://www.woltlab.com/community/thread/301810-unable-to-click-on-polls-after-editing-post/

ts/WoltLabSuite/Core/Ui/Poll/Poll.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Poll/Poll.js

index 9696534135e4244fd4626d7e5f65ea84637229cd..140aaa35672117faf448b1c3858bef4ee69a7e06 100644 (file)
@@ -183,18 +183,21 @@ export class Poll {
   }
 }
 
-const polls: Map<number, Poll> = new Map();
+const polls = new WeakSet<HTMLElement>();
 function setup(): void {
   document.querySelectorAll(".pollContainer").forEach((pollElement: HTMLElement) => {
     if (!pollElement.dataset.pollId) {
       throw new Error("Invalid poll element given. Missing pollID.");
     }
 
+    if (polls.has(pollElement)) {
+      return;
+    }
+
     const pollID = parseInt(pollElement.dataset.pollId, 10);
+    new Poll(pollID);
 
-    if (!polls.has(pollID)) {
-      polls.set(pollID, new Poll(pollID));
-    }
+    polls.add(pollElement);
   });
 }
 
index efa81406106623e801143cd643f8eb1d640a9af6..757a9478abc588ca1b467813ebaaf3347812711e 100644 (file)
@@ -145,16 +145,17 @@ define(["require", "exports", "tslib", "../../Dom/Change/Listener", "../../Dom/U
         }
     }
     exports.Poll = Poll;
-    const polls = new Map();
+    const polls = new WeakMap();
     function setup() {
         document.querySelectorAll(".pollContainer").forEach((pollElement) => {
             if (!pollElement.dataset.pollId) {
                 throw new Error("Invalid poll element given. Missing pollID.");
             }
-            const pollID = parseInt(pollElement.dataset.pollId, 10);
-            if (!polls.has(pollID)) {
-                polls.set(pollID, new Poll(pollID));
+            if (polls.has(pollElement)) {
+                return;
             }
+            const pollID = parseInt(pollElement.dataset.pollId, 10);
+            polls.set(pollElement, new Poll(pollID));
         });
     }
     function setupAll() {