Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce node specific dependencies #1158

Closed
wants to merge 7 commits into from
7 changes: 3 additions & 4 deletions packages/happy-dom/src/console/VirtualConsole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import IVirtualConsolePrinter from './types/IVirtualConsolePrinter.js';
import VirtualConsoleLogLevelEnum from './enums/VirtualConsoleLogLevelEnum.js';
import VirtualConsoleLogTypeEnum from './enums/VirtualConsoleLogTypeEnum.js';
import IVirtualConsoleLogGroup from './types/IVirtualConsoleLogGroup.js';
import * as PerfHooks from 'perf_hooks';
import { ConsoleConstructor } from 'console';

/**
Expand Down Expand Up @@ -276,7 +275,7 @@ export default class VirtualConsole implements Console {
* @param [label=default] Label.
*/
public time(label = 'default'): void {
this._time[label] = PerfHooks.performance.now();
this._time[label] = performance.now();
}

/**
Expand All @@ -288,7 +287,7 @@ export default class VirtualConsole implements Console {
public timeEnd(label = 'default'): void {
const time = this._time[label];
if (time) {
const duration = PerfHooks.performance.now() - time;
const duration = performance.now() - time;
this._printer.print({
type: VirtualConsoleLogTypeEnum.timeEnd,
level: VirtualConsoleLogLevelEnum.info,
Expand All @@ -308,7 +307,7 @@ export default class VirtualConsole implements Console {
public timeLog(label = 'default', ...args: Array<object | string>): void {
const time = this._time[label];
if (time) {
const duration = PerfHooks.performance.now() - time;
const duration = performance.now() - time;
this._printer.print({
type: VirtualConsoleLogTypeEnum.timeLog,
level: VirtualConsoleLogLevelEnum.info,
Expand Down
1 change: 0 additions & 1 deletion packages/happy-dom/src/event/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import IWindow from '../window/IWindow.js';
import IShadowRoot from '../nodes/shadow-root/IShadowRoot.js';
import IEventTarget from './IEventTarget.js';
import NodeTypeEnum from '../nodes/node/NodeTypeEnum.js';
import { performance } from 'perf_hooks';
import EventPhaseEnum from './EventPhaseEnum.js';
import IDocument from '../nodes/document/IDocument.js';

Expand Down
1 change: 0 additions & 1 deletion packages/happy-dom/src/fetch/Request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import FetchBodyUtility from './utilities/FetchBodyUtility.js';
import AbortSignal from './AbortSignal.js';
import Stream from 'stream';
import Blob from '../file/Blob.js';
import { TextDecoder } from 'util';
import FetchRequestValidationUtility from './utilities/FetchRequestValidationUtility.js';
import IRequestReferrerPolicy from './types/IRequestReferrerPolicy.js';
import IRequestRedirect from './types/IRequestRedirect.js';
Expand Down
1 change: 0 additions & 1 deletion packages/happy-dom/src/fetch/Response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import FormData from '../form-data/FormData.js';
import FetchBodyUtility from './utilities/FetchBodyUtility.js';
import DOMException from '../exception/DOMException.js';
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum.js';
import { TextDecoder } from 'util';
import MultipartFormDataParser from './multipart/MultipartFormDataParser.js';

const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import URL from '../../url/URL.js';
import IRequest from '../types/IRequest.js';
import IDocument from '../../nodes/document/IDocument.js';
import { isIP } from 'net';
import Headers from '../Headers.js';
import IRequestReferrerPolicy from '../types/IRequestReferrerPolicy.js';

Expand Down Expand Up @@ -207,13 +206,32 @@ export default class FetchRequestReferrerUtility {

// 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
const hostIp = url.host.replace(/(^\[)|(]$)/g, '');
const hostIPVersion = isIP(hostIp);

if (hostIPVersion === 4 && /^127\./.test(hostIp)) {
// IPv4 addr test pattern
const v4Seg = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])';
const v4Str = `(?:${v4Seg}\\.){3}${v4Seg}`;
const IPv4Reg = new RegExp(`^${v4Str}$`);

// IPv6 addr test pattern
const v6Seg = '(?:[0-9a-fA-F]{1,4})';
const IPv6Reg = new RegExp(
'^(?:' +
`(?:${v6Seg}:){7}(?:${v6Seg}|:)|` +
`(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|` +
`(?:${v6Seg}:){5}(?::${v4Str}|(?::${v6Seg}){1,2}|:)|` +
`(?:${v6Seg}:){4}(?:(?::${v6Seg}){0,1}:${v4Str}|(?::${v6Seg}){1,3}|:)|` +
`(?:${v6Seg}:){3}(?:(?::${v6Seg}){0,2}:${v4Str}|(?::${v6Seg}){1,4}|:)|` +
`(?:${v6Seg}:){2}(?:(?::${v6Seg}){0,3}:${v4Str}|(?::${v6Seg}){1,5}|:)|` +
`(?:${v6Seg}:){1}(?:(?::${v6Seg}){0,4}:${v4Str}|(?::${v6Seg}){1,6}|:)|` +
`(?::(?:(?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` +
')(?:%[0-9a-zA-Z-.:]{1,})?$'
);

if (IPv4Reg.test(hostIp) && /^127\./.test(hostIp)) {
return true;
}

if (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) {
if (IPv6Reg.test(hostIp) && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) {
return true;
}

Expand Down
14 changes: 12 additions & 2 deletions packages/happy-dom/src/window/IWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ import IHappyDOMSettings from './IHappyDOMSettings.js';
import RequestInfo from '../fetch/types/IRequestInfo.js';
import FileList from '../nodes/html-input-element/FileList.js';
import Stream from 'stream';
import { webcrypto } from 'crypto';
import FormData from '../form-data/FormData.js';
import AbortController from '../fetch/AbortController.js';
import AbortSignal from '../fetch/AbortSignal.js';
Expand All @@ -133,6 +132,17 @@ import Clipboard from '../clipboard/Clipboard.js';
import ClipboardItem from '../clipboard/ClipboardItem.js';
import ClipboardEvent from '../event/events/ClipboardEvent.js';

async function webcryptoImportFallback(): Promise<void> {
if (
!('crypto' in globalThis) ||
Object.getPrototypeOf(globalThis.crypto) === Object.getPrototypeOf({})
) {
// Import required only on node < 19
globalThis['crypto'] = (await import('crypto')).webcrypto;
}
}
webcryptoImportFallback();

/**
* Browser window.
*/
Expand Down Expand Up @@ -414,7 +424,7 @@ export default interface IWindow extends IEventTarget, INodeJSGlobal {
readonly pageYOffset: number;
readonly scrollX: number;
readonly scrollY: number;
readonly crypto: typeof webcrypto;
readonly crypto: typeof globalThis.crypto;

/**
* Returns an object containing the values of all CSS properties of an element.
Expand Down
24 changes: 19 additions & 5 deletions packages/happy-dom/src/window/Window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,8 @@ import Fetch from '../fetch/Fetch.js';
import RangeImplementation from '../range/Range.js';
import DOMRect from '../nodes/element/DOMRect.js';
import VMGlobalPropertyScript from './VMGlobalPropertyScript.js';
import * as PerfHooks from 'perf_hooks';
import VM from 'vm';
import { Buffer } from 'buffer';
import { webcrypto } from 'crypto';
import XMLHttpRequestImplementation from '../xml-http-request/XMLHttpRequest.js';
import XMLHttpRequestUpload from '../xml-http-request/XMLHttpRequestUpload.js';
import XMLHttpRequestEventTarget from '../xml-http-request/XMLHttpRequestEventTarget.js';
Expand Down Expand Up @@ -147,6 +145,17 @@ import Clipboard from '../clipboard/Clipboard.js';
import ClipboardItem from '../clipboard/ClipboardItem.js';
import ClipboardEvent from '../event/events/ClipboardEvent.js';

async function webcryptoImportFallback(): Promise<void> {
if (
!('crypto' in globalThis) ||
Object.getPrototypeOf(globalThis.crypto) === Object.getPrototypeOf({})
) {
// Import required only on node < 19
globalThis['crypto'] = (await import('crypto')).webcrypto;
}
}
webcryptoImportFallback();

const ORIGINAL_SET_TIMEOUT = setTimeout;
const ORIGINAL_CLEAR_TIMEOUT = clearTimeout;
const ORIGINAL_SET_INTERVAL = setInterval;
Expand Down Expand Up @@ -219,7 +228,12 @@ export default class Window extends EventTarget implements IWindow {
enableFileSystemHttpRequests: false,
navigator: {
userAgent: `Mozilla/5.0 (X11; ${
process.platform.charAt(0).toUpperCase() + process.platform.slice(1) + ' ' + process.arch
process?.platform
? process.platform.charAt(0).toUpperCase() +
process.platform.slice(1) +
' ' +
process.arch
: 'Unknown'
}) AppleWebKit/537.36 (KHTML, like Gecko) HappyDOM/${PackageVersion.version}`
},
device: {
Expand Down Expand Up @@ -478,12 +492,12 @@ export default class Window extends EventTarget implements IWindow {
public readonly devicePixelRatio = 1;
public readonly sessionStorage: Storage;
public readonly localStorage: Storage;
public readonly performance = PerfHooks.performance;
public readonly performance = performance;
public readonly innerWidth: number = 1024;
public readonly innerHeight: number = 768;
public readonly outerWidth: number = 1024;
public readonly outerHeight: number = 768;
public readonly crypto = webcrypto;
public readonly crypto = globalThis.crypto;

// Node.js Globals
public Array: typeof Array;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import XMLHttpRequestSyncRequestScriptBuilder from '../../src/xml-http-request/u
import XMLHttpRequestCertificate from '../../src/xml-http-request/XMLHttpRequestCertificate.js';
import ProgressEvent from '../../src/event/events/ProgressEvent.js';
import HTTP from 'http';
import { TextDecoder } from 'util';
import Blob from '../../src/file/Blob.js';
import IDocument from '../../src/nodes/document/IDocument.js';
import { beforeEach, afterEach, describe, it, expect, vi } from 'vitest';
Expand Down