about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-05-05 20:30:47 +0200
committerbptato <nincsnevem662@gmail.com>2025-05-05 20:36:40 +0200
commit0a8d03f46f4be3dfc6c8febfcd47dea94c972ffd (patch)
treebd254b717f6593687d66a94773c00ac70ce323e4
parentee6033b9024ca836019e7212ff18b24c915e2d6f (diff)
downloadchawan-0a8d03f46f4be3dfc6c8febfcd47dea94c972ffd.tar.gz
event: fix stopPropagation in capturing phase
-rw-r--r--src/html/event.nim20
-rw-r--r--test/js/event.html25
2 files changed, 36 insertions, 9 deletions
diff --git a/src/html/event.nim b/src/html/event.nim
index 7a4d030d..3c415c67 100644
--- a/src/html/event.nim
+++ b/src/html/event.nim
@@ -553,15 +553,17 @@ proc dispatch*(ctx: JSContext; target: EventTarget; event: Event): bool =
       break
     let it = targets[i]
     ctx.dispatchEvent0(event, it, stop, canceled, capture = true)
-  event.eventPhase = 2
-  ctx.dispatchEvent0(event, target, stop, canceled, capture = true)
-  ctx.dispatchEvent0(event, target, stop, canceled, capture = false)
-  if event.bubbles:
-    event.eventPhase = 3
-    for target in targets:
-      if stop:
-        break
-      ctx.dispatchEvent0(event, target, stop, canceled, capture = false)
+  if not stop:
+    event.eventPhase = 2
+    ctx.dispatchEvent0(event, target, stop, canceled, capture = true)
+    ctx.dispatchEvent0(event, target, stop, canceled, capture = false)
+    if event.bubbles:
+      event.eventPhase = 3
+      for i in 1 ..< targets.len:
+        if stop:
+          break
+        let target = targets[i]
+        ctx.dispatchEvent0(event, target, stop, canceled, capture = false)
   event.eventPhase = 0
   event.flags.excl(efDispatch)
   return canceled
diff --git a/test/js/event.html b/test/js/event.html
new file mode 100644
index 00000000..7649e33a
--- /dev/null
+++ b/test/js/event.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<div id=y>
+<div id=x>Fail</div>
+</div>
+<script src=asserts.js></script>
+<script>
+window.onload = function() {
+	const x = document.getElementById("x")
+	const y = document.getElementById("y")
+	let n = 0;
+	x.addEventListener("test", e => n++);
+	x.dispatchEvent(new Event("test", {bubbles: true}));
+	assertEquals(n, 1);
+	document.documentElement.addEventListener("click", e => e.stopPropagation(), true);
+	let ok1 = true, ok2 = true, ok3 = true;
+	y.addEventListener("click", e => ok1 = false, true);
+	y.addEventListener("click", e => ok2 = false);
+	x.addEventListener("click", e => ok3 = false);
+	x.click();
+	assert(ok1);
+	assert(ok2);
+	assert(ok3);
+	x.textContent = "Success";
+}
+</script>