Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/diff/props.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { IS_NON_DIMENSIONAL, NULL, SVG_NAMESPACE } from '../constants';
import options from '../options';

// Per-instance unique key for event clock stamps. Each Preact copy on the page
// gets its own random suffix so that `_dispatched` / `_attached` properties on
// shared event objects and handler functions cannot collide across instances.
// ~1 in 60M collision odds - if you have that many praect versions on the page,
// you deserve some weird bugs.
Comment thread
JoviDeCroock marked this conversation as resolved.
let _id = Math.random().toString(8),
EVENT_DISPATCHED = '__d' + _id,
EVENT_ATTACHED = '__a' + _id;

function setStyle(style, key, value) {
if (key[0] == '-') {
style.setProperty(key, value == NULL ? '' : value);
Expand Down Expand Up @@ -79,14 +88,14 @@ export function setProperty(dom, name, value, oldValue, namespace) {

if (value) {
if (!oldValue) {
value._attached = eventClock;
value[EVENT_ATTACHED] = eventClock;
dom.addEventListener(
name,
useCapture ? eventProxyCapture : eventProxy,
useCapture
);
} else {
value._attached = oldValue._attached;
value[EVENT_ATTACHED] = oldValue[EVENT_ATTACHED];
}
} else {
dom.removeEventListener(
Expand Down Expand Up @@ -155,13 +164,13 @@ function createEventProxy(useCapture) {
return function (e) {
if (this._listeners) {
const eventHandler = this._listeners[e.type + useCapture];
if (e._dispatched == NULL) {
e._dispatched = eventClock++;
if (e[EVENT_DISPATCHED] == NULL) {
e[EVENT_DISPATCHED] = eventClock++;

// When `e._dispatched` is smaller than the time when the targeted event
// When `e[EVENT_DISPATCHED]` is smaller than the time when the targeted event
// handler was attached we know we have bubbled up to an element that was added
// during patching the DOM.
} else if (e._dispatched < eventHandler._attached) {
} else if (e[EVENT_DISPATCHED] < eventHandler[EVENT_ATTACHED]) {
return;
}
return eventHandler(options.event ? options.event(e) : e);
Expand Down
4 changes: 3 additions & 1 deletion src/internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ export interface PreactElement extends preact.ContainerNode {
}

export interface PreactEvent extends Event {
_dispatched?: number;
// Keyed by a per-instance unique string (e.g. `__dXXXXX`) so that
// multiple Preact copies on the same page don't share event clock stamps.
[key: string]: any;
}

// We use the `current` property to differentiate between the two kinds of Refs so
Expand Down
Loading