Skip to content

Commit 9cfa970

Browse files
authored
Merge branch 'main' into chore/internal-types
2 parents 88fa65c + b9ff1b7 commit 9cfa970

File tree

6 files changed

+34
-72
lines changed

6 files changed

+34
-72
lines changed

src/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export const MATCHED = 1 << 17;
1010
/** Reset all mode flags */
1111
export const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);
1212

13+
export const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
14+
export const XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
15+
export const MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
16+
1317
export const UNDEFINED = undefined;
1418
export const EMPTY_OBJ = /** @type {any} */ ({});
1519
export const EMPTY_ARR = [];

src/diff/index.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import {
22
EMPTY_OBJ,
3+
MATH_NAMESPACE,
34
MODE_HYDRATE,
45
MODE_SUSPENDED,
56
RESET_MODE,
6-
UNDEFINED
7+
SVG_NAMESPACE,
8+
UNDEFINED,
9+
XHTML_NAMESPACE
710
} from '../constants';
811
import { BaseComponent, getDomSibling } from '../component';
912
import { Fragment } from '../create-element';
@@ -402,10 +405,9 @@ function diffElementNodes(
402405
let checked;
403406

404407
// Tracks entering and exiting namespaces when descending through the tree.
405-
if (nodeType === 'svg') namespace = 'http://www.w3.org/2000/svg';
406-
else if (nodeType === 'math')
407-
namespace = 'http://www.w3.org/1998/Math/MathML';
408-
else if (!namespace) namespace = 'http://www.w3.org/1999/xhtml';
408+
if (nodeType === 'svg') namespace = SVG_NAMESPACE;
409+
else if (nodeType === 'math') namespace = MATH_NAMESPACE;
410+
else if (!namespace) namespace = XHTML_NAMESPACE;
409411

410412
if (excessDomChildren != null) {
411413
for (i = 0; i < excessDomChildren.length; i++) {
@@ -528,9 +530,7 @@ function diffElementNodes(
528530
newVNode,
529531
oldVNode,
530532
globalContext,
531-
nodeType === 'foreignObject'
532-
? 'http://www.w3.org/1999/xhtml'
533-
: namespace,
533+
nodeType === 'foreignObject' ? XHTML_NAMESPACE : namespace,
534534
excessDomChildren,
535535
commitQueue,
536536
excessDomChildren

src/diff/props.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IS_NON_DIMENSIONAL } from '../constants';
1+
import { IS_NON_DIMENSIONAL, SVG_NAMESPACE } from '../constants';
22
import options from '../options';
33

44
function setStyle(style, key, value) {
@@ -13,6 +13,8 @@ function setStyle(style, key, value) {
1313
}
1414
}
1515

16+
const CAPTURE_REGEX = /(PointerCapture)$|Capture$/i;
17+
1618
// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.
1719
// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that
1820
// an event can trigger on a newly reated DOM-node while the event bubbles up.
@@ -64,8 +66,7 @@ export function setProperty(dom, name, value, oldValue, namespace) {
6466
}
6567
// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6
6668
else if (name[0] === 'o' && name[1] === 'n') {
67-
useCapture =
68-
name !== (name = name.replace(/(PointerCapture)$|Capture$/i, '$1'));
69+
useCapture = name !== (name = name.replace(CAPTURE_REGEX, '$1'));
6970

7071
// Infer correct casing for DOM built-in events:
7172
if (
@@ -98,7 +99,7 @@ export function setProperty(dom, name, value, oldValue, namespace) {
9899
);
99100
}
100101
} else {
101-
if (namespace == 'http://www.w3.org/2000/svg') {
102+
if (namespace == SVG_NAMESPACE) {
102103
// Normalize incorrect prop usage for SVG:
103104
// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)
104105
// - className --> class
@@ -166,8 +167,7 @@ function createEventProxy(useCapture) {
166167
} else if (e._dispatched < eventHandler._attached) {
167168
return;
168169
}
169-
if (options.event) e = options.event(e);
170-
return "handleEvent" in eventHandler ? eventHandler.handleEvent(e) : eventHandler(e);
170+
return eventHandler(options.event ? options.event(e) : e);
171171
}
172172
};
173173
}

src/jsx.d.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -521,15 +521,9 @@ export namespace JSXInternal {
521521
export type TargetedPictureInPictureEvent<Target extends EventTarget> =
522522
TargetedEvent<Target, PictureInPictureEvent>;
523523

524-
export type EventHandlerObject<E extends TargetedEvent> = {
525-
handleEvent(e: E): unknown;
526-
};
527-
528-
export type EventHandler<E extends TargetedEvent> =
529-
| {
530-
bivarianceHack(event: E): void;
531-
}['bivarianceHack']
532-
| EventHandlerObject<E>;
524+
export type EventHandler<E extends TargetedEvent> = {
525+
bivarianceHack(event: E): void;
526+
}['bivarianceHack'];
533527

534528
export type AnimationEventHandler<Target extends EventTarget> = EventHandler<
535529
TargetedAnimationEvent<Target>

test/browser/events.test.js

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -235,52 +235,4 @@ describe('event handling', () => {
235235
.to.have.been.calledTwice.and.to.have.been.calledWith('focusin')
236236
.and.calledWith('focusout');
237237
});
238-
239-
it('should register EventListenerObject as handler', () => {
240-
let handler = { handleEvent() {} }
241-
242-
render(<div onClick={handler} />, scratch);
243-
244-
expect(scratch.childNodes[0].attributes.length).to.equal(0);
245-
246-
expect(proto.addEventListener).to.have.been.calledOnce;
247-
});
248-
249-
it('should call registered EventListenerObject through the .handleEvent() method', () => {
250-
let onclick = sinon.spy();
251-
252-
let handler = {
253-
onclick,
254-
handleEvent() {
255-
this.onclick()
256-
}
257-
}
258-
259-
render(<div onClick={handler} />, scratch);
260-
261-
fireEvent(scratch.childNodes[0], 'click');
262-
263-
expect(onclick).to.have.been.calledOnce;
264-
});
265-
266-
it('should keep the registered EventListenerObject referentially identical when calling', () => {
267-
let onclick = sinon.spy();
268-
269-
// if the handler object was destructured or otherwise copied, this will fail
270-
let handler = new class {
271-
onclick = onclick
272-
#onClick() {
273-
this.onclick()
274-
}
275-
handleEvent() {
276-
this.#onClick()
277-
}
278-
}
279-
280-
render(<div onClick={handler} />, scratch);
281-
282-
fireEvent(scratch.childNodes[0], 'click');
283-
284-
expect(onclick).to.have.been.calledOnce;
285-
});
286238
});

test/ts/preact.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
FunctionalComponent,
77
AnyComponent,
88
h,
9-
createRef
9+
createRef,
10+
JSX
1011
} from '../../';
1112

1213
interface DummyProps {
@@ -381,3 +382,14 @@ h('form', { onSubmit: onSubmit });
381382

382383
h('option', { value: 'foo' });
383384
createElement('option', { value: 'foo' });
385+
386+
function Checkbox({ onChange }: JSX.HTMLAttributes<HTMLInputElement>) {
387+
function handleChange(
388+
this: void,
389+
event: JSX.TargetedEvent<HTMLInputElement>
390+
) {
391+
onChange?.call(this, event);
392+
}
393+
394+
return <input onChange={handleChange} />;
395+
}

0 commit comments

Comments
 (0)