diff --git a/.changeset/sharp-frogs-bathe.md b/.changeset/sharp-frogs-bathe.md new file mode 100644 index 00000000..55eccbf8 --- /dev/null +++ b/.changeset/sharp-frogs-bathe.md @@ -0,0 +1,5 @@ +--- +'@remote-dom/react': patch +--- + +Apply React polyfill directly to `globalThis` diff --git a/packages/react/source/polyfill.ts b/packages/react/source/polyfill.ts index c575bf54..74951f65 100644 --- a/packages/react/source/polyfill.ts +++ b/packages/react/source/polyfill.ts @@ -1,7 +1,25 @@ -import {window} from '@remote-dom/core/polyfill'; - class HTMLIFrameElement extends HTMLElement {} +// React checks whether elements are Iframes on initialization. +defineGlobalProperty('HTMLIFrameElement', { + value: HTMLIFrameElement, + configurable: true, +}); + +// React ues the `location` and `navigator` properties when printing help text in +// development, and the `Window` polyfill from Remote DOM doesn’t define these properties. +// We copy their implementation from the existing global scope when it exists, and +// provide a minimal working implementation otherwise. +defineGlobalProperty('location', { + value: globalThis.location ?? {protocol: 'https:'}, + configurable: true, +}); + +defineGlobalProperty('navigator', { + value: globalThis.navigator ?? {userAgent: ''}, + configurable: true, +}); + class CSSStyleDeclaration { getPropertyValue(_key: string): string | null | undefined { return undefined; @@ -24,27 +42,6 @@ class CSSStyleDeclaration { } } -// React ues the `location` property when printing help text in development. -if (!window.location) { - Object.defineProperty(window, 'location', { - value: globalThis.location ?? {protocol: 'https:'}, - configurable: true, - }); -} - -if (!window.navigator) { - Object.defineProperty(window, 'navigator', { - value: globalThis.navigator ?? {userAgent: ''}, - configurable: true, - }); -} - -// React checks whether elements are Iframes on initialization. -Object.defineProperty(window, 'HTMLIFrameElement', { - value: HTMLIFrameElement, - configurable: true, -}); - // React checks for a few properties in `document.createElement('div').style` const STYLE = Symbol('style'); Object.defineProperty(Element.prototype, 'style', { @@ -61,3 +58,10 @@ Object.defineProperty(Element.prototype, 'style', { this.style.cssText = String(cssText); }, }); + +function defineGlobalProperty(name: string, descriptor: PropertyDescriptor) { + Object.defineProperty(window, name, descriptor); + Object.defineProperty(globalThis, name, descriptor); +} + +export {};