Skip to content

Commit caab9c3

Browse files
nachooyaclaudeV3RON
authored
fix(runtime): don't overwrite native Event/EventTarget on web (#122)
## Summary `@react-native-harness/runtime`'s `initialize.ts` unconditionally assigns `event-target-shim`'s classes to `globalThis.Event` and `globalThis.EventTarget`. That polyfill is required on RN's JavaScriptCore runtime (which has no DOM), but on web (RN Web running in a real browser) it clobbers the browser's native ctors. Safari's native `EventTarget.dispatchEvent()` does an internal brand check on its argument and throws > `TypeError: Argument 1 ('event') to EventTarget.dispatchEvent must be an instance of Event` when a polyfill instance is dispatched onto a native `EventTarget` — even though the polyfill behaves mostly like `Event`. That's enough to break any DOM-event-driven flow in the page. ## Fix Only install the polyfill when a native ctor is not already present: ```ts if (typeof globalThis.Event !== 'function') { globalThis.Event = Shim.Event; } if (typeof globalThis.EventTarget !== 'function') { globalThis.EventTarget = Shim.EventTarget; } ``` - On RN/JSC: `typeof globalThis.Event !== 'function'`, polyfill installs — unchanged behaviour. - On RN Web / any browser: `Event` is a native ctor, polyfill is skipped, native dispatch keeps working. ## Test plan - [x] `pnpm nx run-many -t build typecheck lint -p @react-native-harness/runtime` — green. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Szymon Chmal <szymon@chmal.it>
1 parent 64a74d7 commit caab9c3

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
__default__: patch
3+
---
4+
5+
Harness now keeps the browser's native `Event` and `EventTarget` on web, while still applying the shim where React Native needs it, so web users no longer lose native DOM behavior.

packages/runtime/src/initialize.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@ import { getClient } from './client/index.js';
33
import { disableHMRWhenReady } from './disableHMRWhenReady.js';
44
import { setupJestMock } from './jest-mock.js';
55

6-
// Polyfill for EventTarget
6+
// Polyfill for EventTarget on runtimes that don't ship one (RN's JSC).
7+
// Do NOT overwrite when a native ctor already exists (RN Web / browsers):
8+
// Safari's EventTarget.dispatchEvent() does an internal brand check and
9+
// rejects polyfill instances with a TypeError, which breaks any
10+
// DOM-event-driven flow in the page — most visibly DRM (FairPlay) via
11+
// libraries that re-dispatch synthetic `encrypted` events.
712
const Shim = require('event-target-shim');
8-
globalThis.Event = Shim.Event;
9-
globalThis.EventTarget = Shim.EventTarget;
13+
if (typeof globalThis.Event !== 'function') {
14+
globalThis.Event = Shim.Event;
15+
}
16+
if (typeof globalThis.EventTarget !== 'function') {
17+
globalThis.EventTarget = Shim.EventTarget;
18+
}
1019

1120
// Setup jest mock to warn users about using Jest APIs
1221
setupJestMock();

0 commit comments

Comments
 (0)