Skip to content

Commit

Permalink
add timer to event handler so we can check whether it was attached du…
Browse files Browse the repository at this point in the history
…ring the current propagation
  • Loading branch information
JoviDeCroock committed Sep 3, 2023
1 parent 7a3706a commit 30fa4b4
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/diff/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
}
// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6
else if (name[0] === 'o' && name[1] === 'n') {
useCapture = name !== (name = name.replace(/(PointerCapture)$|Capture$/, '$1'));
useCapture =
name !== (name = name.replace(/(PointerCapture)$|Capture$/, '$1'));

// Infer correct casing for DOM built-in events:
if (name.toLowerCase() in dom) name = name.toLowerCase().slice(2);
Expand All @@ -94,8 +95,11 @@ export function setProperty(dom, name, value, oldValue, isSvg) {

if (value) {
if (!oldValue) {
value._attached = Date.now();
const handler = useCapture ? eventProxyCapture : eventProxy;
dom.addEventListener(name, handler, useCapture);
} else {
value._attached = oldValue._attached;
}
} else {
const handler = useCapture ? eventProxyCapture : eventProxy;
Expand Down Expand Up @@ -151,7 +155,18 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
* @private
*/
function eventProxy(e) {
return this._listeners[e.type + false](options.event ? options.event(e) : e);
const eventHandler = this._listeners[e.type + false];
/**
* This trick is inspired by Vue https://github.com/vuejs/core/blob/main/packages/runtime-dom/src/modules/events.ts#L90-L101
* when the dom performs an event it leaves micro-ticks in between bubbling up which means that an event can trigger on a newly
* created DOM-node while the event bubbles up, this can cause quirky behavior as seen in https://github.com/preactjs/preact/issues/3927
*/
if (!e._dispatched) {
e._dispatched = Date.now();
} else if (e._dispatched <= eventHandler._attached) {
return;
}
return eventHandler(options.event ? options.event(e) : e);
}

function eventProxyCapture(e) {
Expand Down

0 comments on commit 30fa4b4

Please sign in to comment.