Skip to content

Commit

Permalink
capricorn86#1215@trivial: Adds support for a new package called happy…
Browse files Browse the repository at this point in the history
…-dom-without-nodejs.
  • Loading branch information
capricorn86 committed Jan 18, 2024
1 parent 1379a54 commit 0b2467f
Show file tree
Hide file tree
Showing 28 changed files with 232 additions and 148 deletions.
69 changes: 0 additions & 69 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 4 additions & 29 deletions packages/happy-dom-without-nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The goal of [Happy DOM](https://github.com/capricorn86/happy-dom) is to emulate

[Happy DOM](https://github.com/capricorn86/happy-dom) focuses heavily on performance and can be used as an alternative to [JSDOM](https://github.com/jsdom/jsdom).

This package makes it possible to use Happy DOM in an environment without Node.js. Some functionality such as HTTP requests is not supported by this package yet.

As VM is part of Node.js, this package does not support running JavaScript in a sandbox. Javascript will be executed in the global scope.

### DOM Features

- Custom Elements (Web Components)
Expand Down Expand Up @@ -39,7 +43,6 @@ And much more..
### Module Systems

- [ESM](https://nodejs.org/api/esm.html#introduction)
- [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules)

# Installation

Expand All @@ -49,10 +52,6 @@ npm install happy-dom

# Usage

Happy DOM can be used as a simulated [Browser](https://github.com/capricorn86/happy-dom/wiki/Browser) or by using the [Window](https://github.com/capricorn86/happy-dom/wiki/Window) class directly to quickly setup up a DOM.

## Window

```javascript
import { Window } from 'happy-dom';

Expand All @@ -70,30 +69,6 @@ container.appendChild(button);
console.log(document.body.innerHTML);
```

## Browser

```javascript
import { Browser, BrowserErrorCaptureEnum } from 'happy-dom';

const browser = new Browser({ settings: { errorCapture: BrowserErrorCaptureEnum.processLevel } });
const page = browser.newPage();

// Navigates page
await page.goto('https://github.com/capricorn86');

// Clicks on link
page.mainFrame.document.querySelector('a[href*="capricorn86/happy-dom"]').click();

// Waits for all operations on the page to complete (fetch, timers etc.)
await page.waitUntilComplete();

// Outputs "GitHub - capricorn86/happy-dom: Happy DOM..."
console.log(page.mainFrame.document.title);

// Closes the browser
await browser.close();
```

# Documentation

Read more about how to use Happy DOM in our [Wiki](https://github.com/capricorn86/happy-dom/wiki).
Expand Down
18 changes: 11 additions & 7 deletions packages/happy-dom-without-nodejs/bin/polyfill-source.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ process.on('unhandledRejection', (reason) => {

main();

const POLYFILL_MODULES = ['net', 'crypto', 'url', 'stream', 'vm'];
const POLYFILL_MODULES = ['net', 'crypto', 'url', 'stream', 'vm', 'buffer', 'console'];

const POLYFILLS = [
function polyfillProcess(_directory, file, content) {
Expand All @@ -27,13 +27,16 @@ const POLYFILLS = [
},
function polyfillFetch(_directory, file, content) {
if (file.endsWith('/Fetch.d.ts') || file.endsWith('/SyncFetch.d.ts')) {
return `export default class Fetch { send(): Promise<void>; }`;
return `export default class NotSupported { send(): Promise<void>; }`;
}
if (file.endsWith('/Fetch.js') || file.endsWith('/SyncFetch.js')) {
return `export default class Fetch { send() { throw Error('Fetch is not supported without Node.js.'); } }`;
return `export default class NotSupported { send() { throw Error('Fetch is not supported without Node.js.'); } }`;
}
if (file.endsWith('/Fetch.cjs') || file.endsWith('/SyncFetch.cjs')) {
return `class Fetch { send() { throw Error('Fetch is not supported without Node.js.'); } }\n\nmodule.exports = Fetch;\nmodule.exports.default = Fetch;`;
if (file.includes('/fetch/') || file.includes('/xml-http-request/')) {
if (file.endsWith('.d.ts')) {
return `export default class NotSupported { }`;
}
return 'export default class NotSupported { }';
}
return content;
},
Expand All @@ -53,11 +56,12 @@ const POLYFILLS = [
const regexp = new RegExp(`import.+from\\s*(["']${module}["'])`);
moduleMatch = content.match(regexp);
if (moduleMatch) {
const modulePath = Path.relative(Path.dirname(file), polyfillDirectory) + `/${module}.js`;
content = content.replace(
moduleMatch[0],
moduleMatch[0].replace(
moduleMatch[1] || moduleMatch[2],
`'${Path.relative(Path.dirname(file), Path.join(polyfillDirectory, `${module}.js`))}'`
moduleMatch[1],
`'${modulePath.startsWith('.') ? modulePath : `./${modulePath}`}'`
)
);
}
Expand Down
12 changes: 6 additions & 6 deletions packages/happy-dom-without-nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@
"access": "public"
},
"scripts": {
"compile": "rm -rf ./lib ./src && cp -r ../happy-dom/lib ./lib && cp -r ../happy-dom/src ./src && cp -r ./polyfills ./lib && npm run polyfill",
"polyfill": "node ./bin/polyfill-source.cjs --dir=./lib",
"test": "tsc --noEmit"
"compile": "npm run copy-src-and-lib && npm run compile-polyfill-modules && npm run polyfill-source-in-lib",
"copy-src-and-lib": "rm -rf ./lib ./src && cp -r ../happy-dom/lib ./lib && cp -r ../happy-dom/src ./src",
"compile-polyfill-modules": "tsc --project ./tsconfig.polyfills.json",
"polyfill-source-in-lib": "node ./bin/polyfill-source.cjs --dir=./lib",
"test": "tsc --noEmit --project ./tsconfig.typecheck.json"
},
"dependencies": {
"css.escape": "^1.5.1",
"entities": "^4.5.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
"whatwg-mimetype": "^3.0.0",
"whatwg-url": "^14.0.0",
"buffer": "^6.0.3"
"whatwg-url": "^14.0.0"
},
"devDependencies": {
"@types/css.escape": "^1.5.0",
Expand Down
16 changes: 16 additions & 0 deletions packages/happy-dom-without-nodejs/polyfills/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable import/no-extraneous-dependencies */

import { Blob } from 'happy-dom-without-nodejs';
/**
*
*/
class Buffer {
/**
*
*/
public static from(): Buffer {
return new Buffer();
}
}

export { Buffer, Blob };
10 changes: 10 additions & 0 deletions packages/happy-dom-without-nodejs/polyfills/console.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
*
*/
class ConsoleConstructor {}
/**
*
*/
class Console {}

export { Console, ConsoleConstructor };
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function isIP(ip) {
function isIP(ip: string): number {
const ipv4 =
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const ipv6 =
Expand Down
3 changes: 0 additions & 3 deletions packages/happy-dom-without-nodejs/polyfills/url.js

This file was deleted.

4 changes: 4 additions & 0 deletions packages/happy-dom-without-nodejs/polyfills/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { URL, URLSearchParams } from 'whatwg-url';
type UrlObject = {};

export { URL, URLSearchParams, UrlObject };
12 changes: 0 additions & 12 deletions packages/happy-dom-without-nodejs/polyfills/vm.js

This file was deleted.

35 changes: 35 additions & 0 deletions packages/happy-dom-without-nodejs/polyfills/vm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
type Context = object;

/**
*
*/
class Script {
private code: string;

/**
*
* @param code
*/
constructor(code: string) {
this.code = code;
}
/**
*
* @param context
*/
public runInContext(context: Context): void {
const evaluate = (code: string): void => {
eval(code);
};
evaluate.call(context, this.code);
}
}
const contextSymbol = Symbol('context');
const isContext = (context: Context): boolean => {
return context[contextSymbol] === true;
};
const createContext = (context: Context): Context => {
context[contextSymbol] = true;
return context;
};
export { Script, isContext, createContext };
33 changes: 33 additions & 0 deletions packages/happy-dom-without-nodejs/tsconfig.polyfills.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"compilerOptions": {
"rootDir": "polyfills",
"outDir": "lib/polyfills",
"target": "ES2020",
"declaration": true,
"declarationMap": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"esModuleInterop": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"baseUrl": ".",
"composite": false,
"incremental": false,
"allowJs": true,
"lib": [
"es2020",
"dom"
],
"types": []
},
"include": [
"polyfills"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"skipLibCheck": false,
"baseUrl": ".",
"composite": false,
"incremental": false,
Expand All @@ -28,8 +28,5 @@
},
"include": [
"lib"
],
"exclude": [
"@types/dom"
]
]
}
1 change: 0 additions & 1 deletion packages/happy-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"test:debug": "vitest run --inspect-brk --threads=false"
},
"dependencies": {
"css.escape": "^1.5.1",
"entities": "^4.5.0",
"webidl-conversions": "^7.0.0",
"whatwg-encoding": "^2.0.0",
Expand Down
Loading

0 comments on commit 0b2467f

Please sign in to comment.