]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test(vapor): test case for dom event handling
authorEvan You <evan@vuejs.org>
Wed, 12 Feb 2025 08:41:35 +0000 (16:41 +0800)
committerEvan You <evan@vuejs.org>
Wed, 12 Feb 2025 08:41:35 +0000 (16:41 +0800)
packages/runtime-vapor/__tests__/dom/event.spec.ts [new file with mode: 0644]
packages/runtime-vapor/src/dom/event.ts

diff --git a/packages/runtime-vapor/__tests__/dom/event.spec.ts b/packages/runtime-vapor/__tests__/dom/event.spec.ts
new file mode 100644 (file)
index 0000000..4b59882
--- /dev/null
@@ -0,0 +1,106 @@
+import { effectScope } from '@vue/reactivity'
+import {
+  delegate,
+  delegateEvents,
+  on,
+  renderEffect,
+  setDynamicEvents,
+} from '../../src'
+
+describe('dom event', () => {
+  delegateEvents('click')
+
+  test('on', () => {
+    const el = document.createElement('div')
+    const handler = vi.fn()
+    on(el, 'click', handler)
+    el.click()
+    expect(handler).toHaveBeenCalled()
+  })
+
+  test('delegate with direct attachment', () => {
+    const el = document.createElement('div')
+    document.body.appendChild(el)
+    const handler = vi.fn()
+    ;(el as any).$evtclick = handler
+    el.click()
+    expect(handler).toHaveBeenCalled()
+  })
+
+  test('delegate', () => {
+    const el = document.createElement('div')
+    document.body.appendChild(el)
+    const handler = vi.fn()
+    delegate(el, 'click', handler)
+    el.click()
+    expect(handler).toHaveBeenCalled()
+  })
+
+  test('delegate with stopPropagation', () => {
+    const parent = document.createElement('div')
+    const child = document.createElement('div')
+    parent.appendChild(child)
+    document.body.appendChild(parent)
+    const parentHandler = vi.fn()
+    delegate(parent, 'click', parentHandler)
+    const childHandler = vi.fn(e => e.stopPropagation())
+    delegate(child, 'click', childHandler)
+    child.click()
+    expect(parentHandler).not.toHaveBeenCalled()
+    expect(childHandler).toHaveBeenCalled()
+  })
+
+  test('delegate with stopImmediatePropagation', () => {
+    const parent = document.createElement('div')
+    const child = document.createElement('div')
+    parent.appendChild(child)
+    document.body.appendChild(parent)
+    const parentHandler = vi.fn()
+    delegate(parent, 'click', parentHandler)
+    const childHandler = vi.fn(e => e.stopImmediatePropagation())
+    delegate(child, 'click', childHandler)
+    child.click()
+    expect(parentHandler).not.toHaveBeenCalled()
+    expect(childHandler).toHaveBeenCalled()
+  })
+
+  test('delegate with multiple handlers', () => {
+    const el = document.createElement('div')
+    document.body.appendChild(el)
+    const handler1 = vi.fn()
+    const handler2 = vi.fn()
+    delegate(el, 'click', handler1)
+    delegate(el, 'click', handler2)
+    el.click()
+    expect(handler1).toHaveBeenCalled()
+    expect(handler2).toHaveBeenCalled()
+  })
+
+  test('delegate with multiple handlers + stopImmediatePropagation', () => {
+    const el = document.createElement('div')
+    document.body.appendChild(el)
+    const handler1 = vi.fn(e => e.stopImmediatePropagation())
+    const handler2 = vi.fn()
+    delegate(el, 'click', handler1)
+    delegate(el, 'click', handler2)
+    el.click()
+    expect(handler1).toHaveBeenCalled()
+    expect(handler2).not.toHaveBeenCalled()
+  })
+
+  test('setDynamicEvents', () => {
+    const el = document.createElement('div')
+    const handler = vi.fn()
+    const scope = effectScope()
+    scope.run(() => {
+      renderEffect(() => {
+        setDynamicEvents(el, {
+          click: handler,
+        })
+      })
+    })
+    el.click()
+    expect(handler).toHaveBeenCalled()
+    scope.stop()
+  })
+})
index c9c72a288ef54a7b3edda5465e73a191d345304d..4987ecfc0d80fd19009bba533742aeae55d51861 100644 (file)
@@ -89,6 +89,7 @@ const delegatedEventHandler = (e: Event) => {
         }
       } else {
         handlers(e)
+        if (e.cancelBubble) return
       }
     }
     node =
@@ -103,6 +104,6 @@ export function setDynamicEvents(
   events: Record<string, (...args: any[]) => any>,
 ): void {
   for (const name in events) {
-    on(el, name, () => events[name], { effect: true })
+    on(el, name, events[name], { effect: true })
   }
 }