diff --git a/slhx-js/runtime/slhx.js b/slhx-js/runtime/slhx.js index f935f85..ea684bf 100644 --- a/slhx-js/runtime/slhx.js +++ b/slhx-js/runtime/slhx.js @@ -8,6 +8,7 @@ const pending = new WeakMap(); const queues = new WeakMap(); const timers = new WeakMap(); + const everyTimers = new WeakMap(); const pendingClassStates = new WeakMap(); const indicatorStates = new WeakMap(); const disabledStates = new WeakMap(); @@ -621,13 +622,18 @@ function bindPolling(root) { forEachElement(root, (el) => { - if (!el.hasAttribute("data-slhx-every") || timers.has(el)) return; + if (!el.hasAttribute("data-slhx-every") || everyTimers.has(el)) return; const ms = duration(el.getAttribute("data-slhx-every")); if (!ms) return; - timers.set(el, setInterval(() => document.contains(el) ? send(el, "every") : clearInterval(timers.get(el)), ms)); + everyTimers.set(el, setInterval(() => document.contains(el) ? send(el, "every") : stopPolling(el), ms)); }); } + function stopPolling(el) { + clearInterval(everyTimers.get(el)); + everyTimers.delete(el); + } + function bindSse(root) { const url = root.getAttribute("data-slhx-sse"); if (!url || sseSources.has(root) || typeof EventSource === "undefined") return; diff --git a/slhx-js/tests/runtime.rs b/slhx-js/tests/runtime.rs index 7530e1a..d7388cb 100644 --- a/slhx-js/tests/runtime.rs +++ b/slhx-js/tests/runtime.rs @@ -41,11 +41,14 @@ fn runtime_interval_dispatch_avoids_duplicate_timers() { // req: convention/005 let source = slhx_js::RUNTIME_JS; + assert!(source.contains("const everyTimers = new WeakMap()")); assert!(source.contains("forEachElement(root, (el) =>")); - assert!(source.contains("!el.hasAttribute(\"data-slhx-every\") || timers.has(el)")); - assert!(source.contains("if (!el.hasAttribute(\"data-slhx-every\") || timers.has(el)) return")); - assert!(source.contains("setInterval(() => document.contains(el) ? send(el, \"every\")")); - assert!(source.contains("clearInterval(timers.get(el))")); + assert!(source.contains("!el.hasAttribute(\"data-slhx-every\") || everyTimers.has(el)")); + assert!(source.contains("if (!el.hasAttribute(\"data-slhx-every\") || everyTimers.has(el)) return")); + assert!(source.contains("setInterval(() => document.contains(el) ? send(el, \"every\") : stopPolling(el), ms)")); + assert!(source.contains("function stopPolling(el)")); + assert!(source.contains("clearInterval(everyTimers.get(el))")); + assert!(source.contains("everyTimers.delete(el)")); } #[test]