Skip to content

Commit

Permalink
#1049@patch: Allows global properties to be overwritten when using Gl…
Browse files Browse the repository at this point in the history
…obalRegistrator from @happy-dom/global-registrator, as some global properties may behave different from the Happy DOM implementation. The properties will be restored when unregistering.
  • Loading branch information
capricorn86 committed Sep 20, 2023
1 parent a81baba commit 497db1d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/global-registrator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"lint": "eslint --ignore-path .gitignore --max-warnings 0 .",
"lint:fix": "eslint --ignore-path .gitignore --max-warnings 0 --fix .",
"test": "tsc --project ./test && node ../happy-dom/bin/change-file-extension.cjs --dir=./tmp --fromExt=.js --toExt=.cjs && node ./tmp/react/React.test.cjs",
"test:debug": "tsc --project ./test && node --inspect-brk ./tmp/react/React.test.js"
"test:debug": "tsc --project ./test && node ../happy-dom/bin/change-file-extension.cjs --dir=./tmp --fromExt=.js --toExt=.cjs && node --inspect-brk ./tmp/react/React.test.cjs"
},
"dependencies": {
"happy-dom": "0.0.0"
Expand Down
34 changes: 26 additions & 8 deletions packages/global-registrator/src/GlobalRegistrator.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,57 @@
import { GlobalWindow } from 'happy-dom';

const IGNORE_LIST = ['undefined', 'NaN', 'global', 'globalThis', 'window', 'globalThis'];
const SELF_REFERING = ['self', 'top', 'parent', 'window'];

/**
*
*/
export default class GlobalRegistrator {
private static registered = [];
private static registered: { [key: string]: string } | null = null;

/**
* Registers Happy DOM globally.
*/
public static register(): void {
if (this.registered.length) {
if (this.registered !== null) {
throw new Error('Failed to register. Happy DOM has already been globally registered.');
}

const window = new GlobalWindow();

this.registered = {};

for (const key of Object.keys(window)) {
if (global[key] === undefined && key !== 'undefined') {
if (global[key] !== window[key] && !IGNORE_LIST.includes(key)) {
this.registered[key] = global[key] !== window[key] ? global[key] : undefined;
global[key] = window[key];
this.registered.push(key);
}
}

for (const key of SELF_REFERING) {
this.registered[key] = undefined;
global[key] = global;
}
}

/**
* Registers Happy DOM globally.
*/
public static unregister(): void {
if (!this.registered.length) {
if (this.registered === null) {
throw new Error(
'Failed to unregister. Happy DOM has not previously been globally registered.'
);
}
while (this.registered.length) {
const key = this.registered.pop();
delete global[key];

for (const key of Object.keys(this.registered)) {
if (this.registered[key] !== undefined) {
global[key] = this.registered[key];
} else {
delete global[key];
}
}

this.registered = null;
}
}
19 changes: 19 additions & 0 deletions packages/global-registrator/test/react/React.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import React from 'react';
import ReactDOM from 'react-dom';
import ReactComponent from './ReactComponent.js';

const selfReferingProperties = ['self', 'top', 'parent', 'window'];

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const originalSetTimeout = global.setTimeout;

GlobalRegistrator.register();

const appElement = document.createElement('app');
Expand All @@ -24,7 +29,21 @@ function unmountReactComponent(): void {
}
}

if (global.setTimeout !== window.setTimeout) {
throw Error('Happy DOM function not registered.');
}

for (const property of selfReferingProperties) {
if (global[property] !== global) {
throw Error('Self refering property property was not registered.');
}
}

mountReactComponent();
unmountReactComponent();

GlobalRegistrator.unregister();

if (global.setTimeout !== originalSetTimeout) {
throw Error('Global property was not restored.');
}

0 comments on commit 497db1d

Please sign in to comment.