Skip to content

Commit

Permalink
lib: add EventTarget-related browser globals
Browse files Browse the repository at this point in the history
Add

- Event
- EventTarget
- MessagePort
- MessageChannel
- MessageEvent

to the set of global objects, since they are available now and behave
like they do in the browser.

Fixes: #35495

PR-URL: #35496
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Khaidi Chu <i@2333.moe>
  • Loading branch information
addaleax authored and nodejs-github-bot committed Oct 11, 2020
1 parent 705d888 commit eee522a
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ module.exports = {
BigInt: 'readable',
BigInt64Array: 'readable',
BigUint64Array: 'readable',
Event: 'readable',
EventTarget: 'readable',
MessageChannel: 'readable',
MessageEvent: 'readable',
MessagePort: 'readable',
TextEncoder: 'readable',
TextDecoder: 'readable',
queueMicrotask: 'readable',
Expand Down
21 changes: 18 additions & 3 deletions doc/api/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -1069,9 +1069,15 @@ const ac = new AbortController();
process.nextTick(() => ac.abort());
```

<a id="event-target-and-event-api"></a>
## `EventTarget` and `Event` API
<!-- YAML
added: v14.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/35496
description:
The `EventTarget` and `Event` classes are now available as globals.
-->

> Stability: 1 - Experimental
Expand All @@ -1082,7 +1088,7 @@ Neither the `EventTarget` nor `Event` classes are available for end
user code to create.

```js
const target = getEventTargetSomehow();
const target = new EventTarget();

target.addEventListener('foo', (event) => {
console.log('foo event happened!');
Expand Down Expand Up @@ -1168,7 +1174,7 @@ const handler4 = {
}
};

const target = getEventTargetSomehow();
const target = new EventTarget();

target.addEventListener('foo', handler1);
target.addEventListener('foo', handler2);
Expand All @@ -1189,6 +1195,10 @@ The `EventTarget` does not implement any special default handling for
### Class: `Event`
<!-- YAML
added: v14.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/35496
description: The `Event` class is now available through the global object.
-->

The `Event` object is an adaptation of the [`Event` Web API][]. Instances
Expand Down Expand Up @@ -1341,6 +1351,11 @@ The event type identifier.
### Class: `EventTarget`
<!-- YAML
added: v14.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/35496
description:
The `EventTarget` class is now available through the global object.
-->

#### `eventTarget.addEventListener(type, listener[, options])`
Expand Down Expand Up @@ -1374,7 +1389,7 @@ a `listener`. Any individual `listener` may be added once with
```js
function handler(event) {}

const target = getEventTargetSomehow();
const target = new EventTarget();
target.addEventListener('foo', handler, { capture: true }); // first
target.addEventListener('foo', handler, { capture: false }); // second

Expand Down
55 changes: 55 additions & 0 deletions doc/api/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ added: v0.1.100

Used to print to stdout and stderr. See the [`console`][] section.

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

<!-- type=global -->

> Stability: 1 - Experimental
A browser-compatible implementation of the `Event` class. See
[`EventTarget` and `Event` API][] for more details.

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

<!-- type=global -->

> Stability: 1 - Experimental
A browser-compatible implementation of the `EventTarget` class. See
[`EventTarget` and `Event` API][] for more details.

## `exports`

This variable may appear to be global but is not. See [`exports`][].
Expand All @@ -187,6 +211,33 @@ within the browser `var something` will define a new global variable. In
Node.js this is different. The top-level scope is not the global scope;
`var something` inside a Node.js module will be local to that module.

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

<!-- type=global -->

The `MessageChannel` class. See [`MessageChannel`][] for more details.

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

<!-- type=global -->

The `MessageEvent` class. See [`MessageEvent`][] for more details.

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

<!-- type=global -->

The `MessagePort` class. See [`MessagePort`][] for more details.

## `module`

This variable may appear to be global but is not. See [`module`][].
Expand Down Expand Up @@ -322,6 +373,10 @@ 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
[`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
[`MessagePort`]: worker_threads.md#worker_threads_class_messageport
[`TextDecoder`]: util.md#util_class_util_textdecoder
[`TextEncoder`]: util.md#util_class_util_textencoder
[`URLSearchParams`]: url.md#url_class_urlsearchparams
Expand Down
15 changes: 15 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,21 @@ if (!config.noBrowserGlobals) {
exposeInterface(global, 'AbortController', AbortController);
exposeInterface(global, 'AbortSignal', AbortSignal);

const {
EventTarget,
Event,
} = require('internal/event_target');
exposeInterface(global, 'EventTarget', EventTarget);
exposeInterface(global, 'Event', Event);
const {
MessageChannel,
MessagePort,
MessageEvent,
} = require('internal/worker/io');
exposeInterface(global, 'MessageChannel', MessageChannel);
exposeInterface(global, 'MessagePort', MessagePort);
exposeInterface(global, 'MessageEvent', MessageEvent);

// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
const timers = require('timers');
defineOperation(global, 'clearInterval', timers.clearInterval);
Expand Down
3 changes: 2 additions & 1 deletion src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class ExternalReferenceRegistry {
V(string_decoder) \
V(trace_events) \
V(timers) \
V(types)
V(types) \
V(worker)

#if NODE_HAVE_I18N_SUPPORT
#define EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) V(icu)
Expand Down
14 changes: 13 additions & 1 deletion src/node_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "debug_utils-inl.h"
#include "memory_tracker-inl.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_buffer.h"
#include "node_options-inl.h"
#include "node_perf.h"
Expand Down Expand Up @@ -860,9 +861,20 @@ void InitWorker(Local<Object> target,
NODE_DEFINE_CONSTANT(target, kTotalResourceLimitCount);
}

} // anonymous namespace
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetEnvMessagePort);
registry->Register(Worker::New);
registry->Register(Worker::StartThread);
registry->Register(Worker::StopThread);
registry->Register(Worker::Ref);
registry->Register(Worker::Unref);
registry->Register(Worker::GetResourceLimits);
registry->Register(Worker::TakeHeapSnapshot);
}

} // anonymous namespace
} // namespace worker
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(worker, node::worker::InitWorker)
NODE_MODULE_EXTERNAL_REFERENCE(worker, node::worker::RegisterExternalReferences)
14 changes: 14 additions & 0 deletions test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const expectedModules = new Set([
'Internal Binding types',
'Internal Binding url',
'Internal Binding util',
'Internal Binding worker',
'NativeModule buffer',
'NativeModule events',
'NativeModule fs',
Expand Down Expand Up @@ -76,6 +77,17 @@ const expectedModules = new Set([
'NativeModule internal/process/warning',
'NativeModule internal/querystring',
'NativeModule internal/source_map/source_map_cache',
'NativeModule internal/streams/buffer_list',
'NativeModule internal/streams/destroy',
'NativeModule internal/streams/duplex',
'NativeModule internal/streams/end-of-stream',
'NativeModule internal/streams/legacy',
'NativeModule internal/streams/passthrough',
'NativeModule internal/streams/pipeline',
'NativeModule internal/streams/readable',
'NativeModule internal/streams/state',
'NativeModule internal/streams/transform',
'NativeModule internal/streams/writable',
'NativeModule internal/timers',
'NativeModule internal/url',
'NativeModule internal/util',
Expand All @@ -84,8 +96,10 @@ const expectedModules = new Set([
'NativeModule internal/util/types',
'NativeModule internal/validators',
'NativeModule internal/vm/module',
'NativeModule internal/worker/io',
'NativeModule internal/worker/js_transferable',
'NativeModule path',
'NativeModule stream',
'NativeModule timers',
'NativeModule url',
'NativeModule util',
Expand Down
4 changes: 1 addition & 3 deletions test/parallel/test-event-on-async-iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ const common = require('../common');
const assert = require('assert');
const { on, EventEmitter } = require('events');
const {
EventTarget,
NodeEventTarget,
Event
NodeEventTarget
} = require('internal/event_target');

async function basic() {
Expand Down
3 changes: 1 addition & 2 deletions test/parallel/test-events-once.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
// Flags: --expose-internals --no-warnings
// Flags: --no-warnings

const common = require('../common');
const { once, EventEmitter } = require('events');
Expand All @@ -9,7 +9,6 @@ const {
fail,
rejects,
} = require('assert');
const { EventTarget, Event } = require('internal/event_target');

async function onceAnEvent() {
const ee = new EventEmitter();
Expand Down
6 changes: 0 additions & 6 deletions test/parallel/test-eventtarget-whatwg-passive.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
// Flags: --expose-internals
'use strict';

const common = require('../common');

const {
Event,
EventTarget,
} = require('internal/event_target');

const {
fail,
ok,
Expand Down
6 changes: 4 additions & 2 deletions test/parallel/test-worker-message-event.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Flags: --expose-internals
'use strict';
require('../common');
const assert = require('assert');
const { MessageEvent, MessageChannel } = require('internal/worker/io');

const dummyPort = new MessageChannel().port1;

Expand Down Expand Up @@ -90,3 +88,7 @@ const dummyPort = new MessageChannel().port1;
message: /The "init\.ports\[0\]" property must be an instance of MessagePort/,
});
}

{
assert(new MessageEvent('message') instanceof Event);
}

0 comments on commit eee522a

Please sign in to comment.