Skip to content

Commit

Permalink
lib: expose DOMException as global
Browse files Browse the repository at this point in the history
Refs: #39098

PR-URL: #39176
Fixes: #39098
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Zijian Liu <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
XadillaX authored and jasnell committed Aug 6, 2021
1 parent 0a7f850 commit e4b1fb5
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 17 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ module.exports = {
BigInt: 'readable',
BigInt64Array: 'readable',
BigUint64Array: 'readable',
DOMException: 'readable',
Event: 'readable',
EventTarget: 'readable',
MessageChannel: 'readable',
Expand Down
10 changes: 10 additions & 0 deletions doc/api/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,15 @@ added: v0.0.1

[`setTimeout`][] is described in the [timers][] section.

## `DOMException`
<!-- YAML
added: REPLACEME
-->

<!-- type=global -->

The WHATWG `DOMException` class. See [`DOMException`][] for more details.

## `TextDecoder`
<!-- YAML
added: v11.0.0
Expand Down Expand Up @@ -430,6 +439,7 @@ The object that acts as the namespace for all W3C
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.

[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
[`DOMException`]: https://developer.mozilla.org/en-US/docs/Web/API/DOMException
[`EventTarget` and `Event` API]: events.md#event-target-and-event-api
[`MessageChannel`]: worker_threads.md#worker_threads_class_messagechannel
[`MessageEvent`]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
Expand Down
2 changes: 2 additions & 0 deletions lib/.eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ rules:
message: "Use `const { Atomics } = globalThis;` instead of the global."
- name: Buffer
message: "Use `const { Buffer } = require('buffer');` instead of the global."
- name: DOMException
message: "Use lazy function `const { lazyDOMException } = require('internal/util');` instead of the global."
- name: Event
message: "Use `const { Event } = require('internal/event_target');` instead of the global."
- name: EventTarget
Expand Down
17 changes: 16 additions & 1 deletion lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const {
globalThis,
} = primordials;
const config = internalBinding('config');
const { deprecate } = require('internal/util');
const { deprecate, lazyDOMExceptionClass } = require('internal/util');

setupProcessObject();

Expand Down Expand Up @@ -201,6 +201,12 @@ if (!config.noBrowserGlobals) {
exposeInterface(globalThis, 'URL', URL);
// https://url.spec.whatwg.org/#urlsearchparams
exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
exposeGetterAndSetter(globalThis,
'DOMException',
lazyDOMExceptionClass,
(value) => {
exposeInterface(globalThis, 'DOMException', value);
});

const {
TextEncoder, TextDecoder
Expand Down Expand Up @@ -483,6 +489,15 @@ function exposeInterface(target, name, interfaceObject) {
});
}

function exposeGetterAndSetter(target, name, getter, setter = undefined) {
ObjectDefineProperty(target, name, {
enumerable: false,
configurable: true,
get: getter,
set: setter,
});
}

// https://heycam.github.io/webidl/#define-the-operations
function defineOperation(target, name, method) {
ObjectDefineProperty(target, name, {
Expand Down
13 changes: 9 additions & 4 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,15 @@ function createDeferredPromise() {
return { promise, resolve, reject };
}

let DOMException;
let _DOMException;
const lazyDOMExceptionClass = () => {
_DOMException ??= internalBinding('messaging').DOMException;
return _DOMException;
};

const lazyDOMException = hideStackFrames((message, name) => {
if (DOMException === undefined)
DOMException = internalBinding('messaging').DOMException;
return new DOMException(message, name);
_DOMException ??= internalBinding('messaging').DOMException;
return new _DOMException(message, name);
});

function structuredClone(value) {
Expand Down Expand Up @@ -481,6 +485,7 @@ module.exports = {
isInsideNodeModules,
join,
lazyDOMException,
lazyDOMExceptionClass,
normalizeEncoding,
once,
promisify,
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-global-domexception.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict';

require('../common');

const assert = require('assert');

assert.strictEqual(typeof DOMException, 'function');

assert.throws(() => {
atob('我要抛错!');
}, DOMException);
2 changes: 0 additions & 2 deletions test/wpt/test-atob.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ runner.setFlags(['--expose-internals']);
runner.setInitScript(`
const { internalBinding } = require('internal/test/binding');
const { atob, btoa } = require('buffer');
const { DOMException } = internalBinding('messaging');
global.DOMException = DOMException;
`);

runner.runJsTests();
10 changes: 0 additions & 10 deletions test/wpt/test-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,4 @@ const { WPTRunner } = require('../common/wpt');

const runner = new WPTRunner('url');

// Needed to access to DOMException.
runner.setFlags(['--expose-internals']);

// DOMException is needed by urlsearchparams-constructor.any.js
runner.setInitScript(`
const { internalBinding } = require('internal/test/binding');
const { DOMException } = internalBinding('messaging');
global.DOMException = DOMException;
`);

runner.runJsTests();

0 comments on commit e4b1fb5

Please sign in to comment.