mirror of https://github.com/nodejs/node.git
events: make abort_controller event trusted
The AbortController abort event is trusted, currently we fire all events with isTrusted: false. Allow dispatching events internally with `isTrusted: true` and add a test for it. Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Fixes: https://github.com/nodejs/node/issues/35748 PR-URL: https://github.com/nodejs/node/pull/35811 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
81ba3ae699
commit
f20a783a31
|
@ -1282,9 +1282,10 @@ This is not used in Node.js and is provided purely for completeness.
|
|||
added: v14.5.0
|
||||
-->
|
||||
|
||||
* Type: {boolean} Always returns `false`.
|
||||
* Type: {boolean} True for Node.js internal events, false otherwise.
|
||||
|
||||
This is not used in Node.js and is provided purely for completeness.
|
||||
Currently only `AbortSignal`s' `"abort"` event is fired with `isTrusted`
|
||||
set to `true`.
|
||||
|
||||
#### `event.preventDefault()`
|
||||
<!-- YAML
|
||||
|
|
|
@ -11,7 +11,8 @@ const {
|
|||
|
||||
const {
|
||||
EventTarget,
|
||||
Event
|
||||
Event,
|
||||
kTrustEvent
|
||||
} = require('internal/event_target');
|
||||
const {
|
||||
customInspectSymbol,
|
||||
|
@ -49,7 +50,9 @@ ObjectDefineProperties(AbortSignal.prototype, {
|
|||
function abortSignal(signal) {
|
||||
if (signal[kAborted]) return;
|
||||
signal[kAborted] = true;
|
||||
const event = new Event('abort');
|
||||
const event = new Event('abort', {
|
||||
[kTrustEvent]: true
|
||||
});
|
||||
if (typeof signal.onabort === 'function') {
|
||||
signal.onabort(event);
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ const {
|
|||
ObjectAssign,
|
||||
ObjectDefineProperties,
|
||||
ObjectDefineProperty,
|
||||
ObjectGetOwnPropertyDescriptor,
|
||||
String,
|
||||
Symbol,
|
||||
SymbolFor,
|
||||
SymbolToStringTag,
|
||||
SafeWeakSet,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
|
@ -41,6 +43,7 @@ const kRemoveListener = Symbol('kRemoveListener');
|
|||
const kIsNodeStyleListener = Symbol('kIsNodeStyleListener');
|
||||
const kMaxListeners = Symbol('kMaxListeners');
|
||||
const kMaxListenersWarned = Symbol('kMaxListenersWarned');
|
||||
const kTrustEvent = Symbol('kTrustEvent');
|
||||
|
||||
// Lazy load perf_hooks to avoid the additional overhead on startup
|
||||
let perf_hooks;
|
||||
|
@ -61,7 +64,12 @@ const kBubbles = Symbol('bubbles');
|
|||
const kComposed = Symbol('composed');
|
||||
const kPropagationStopped = Symbol('propagationStopped');
|
||||
|
||||
const isTrusted = () => false;
|
||||
const isTrustedSet = new SafeWeakSet();
|
||||
const isTrusted = ObjectGetOwnPropertyDescriptor({
|
||||
get isTrusted() {
|
||||
return isTrustedSet.has(this);
|
||||
}
|
||||
}, 'isTrusted').get;
|
||||
|
||||
class Event {
|
||||
constructor(type, options) {
|
||||
|
@ -77,6 +85,10 @@ class Event {
|
|||
this[kDefaultPrevented] = false;
|
||||
this[kTimestamp] = lazyNow();
|
||||
this[kPropagationStopped] = false;
|
||||
if (options != null && options[kTrustEvent]) {
|
||||
isTrustedSet.add(this);
|
||||
}
|
||||
|
||||
// isTrusted is special (LegacyUnforgeable)
|
||||
ObjectDefineProperty(this, 'isTrusted', {
|
||||
get: isTrusted,
|
||||
|
@ -573,5 +585,6 @@ module.exports = {
|
|||
initNodeEventTarget,
|
||||
kCreateEvent,
|
||||
kNewListener,
|
||||
kTrustEvent,
|
||||
kRemoveListener,
|
||||
};
|
||||
|
|
|
@ -101,6 +101,10 @@ primordials.SafeSet = makeSafe(
|
|||
Set,
|
||||
class SafeSet extends Set {}
|
||||
);
|
||||
primordials.SafeWeakSet = makeSafe(
|
||||
WeakSet,
|
||||
class SafeWeakSet extends WeakSet {}
|
||||
);
|
||||
primordials.SafePromise = makeSafe(
|
||||
Promise,
|
||||
class SafePromise extends Promise {}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// Flags: --no-warnings
|
||||
// Flags: --no-warnings --expose-internals
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
|
||||
const { ok, strictEqual } = require('assert');
|
||||
const { Event } = require('internal/event_target');
|
||||
|
||||
{
|
||||
// Tests that abort is fired with the correct event type on AbortControllers
|
||||
const ac = new AbortController();
|
||||
ok(ac.signal);
|
||||
ac.signal.onabort = common.mustCall((event) => {
|
||||
|
@ -20,3 +22,33 @@ const { ok, strictEqual } = require('assert');
|
|||
ac.abort();
|
||||
ok(ac.signal.aborted);
|
||||
}
|
||||
|
||||
{
|
||||
// Tests that abort events are trusted
|
||||
const ac = new AbortController();
|
||||
ac.signal.addEventListener('abort', common.mustCall((event) => {
|
||||
ok(event.isTrusted);
|
||||
}));
|
||||
ac.abort();
|
||||
}
|
||||
|
||||
{
|
||||
// Tests that abort events have the same `isTrusted` reference
|
||||
const first = new AbortController();
|
||||
const second = new AbortController();
|
||||
let ev1, ev2;
|
||||
const ev3 = new Event('abort');
|
||||
first.signal.addEventListener('abort', common.mustCall((event) => {
|
||||
ev1 = event;
|
||||
}));
|
||||
second.signal.addEventListener('abort', common.mustCall((event) => {
|
||||
ev2 = event;
|
||||
}));
|
||||
first.abort();
|
||||
second.abort();
|
||||
const firstTrusted = Reflect.getOwnPropertyDescriptor(ev1, 'isTrusted').get;
|
||||
const secondTrusted = Reflect.getOwnPropertyDescriptor(ev2, 'isTrusted').get;
|
||||
const untrusted = Reflect.getOwnPropertyDescriptor(ev3, 'isTrusted').get;
|
||||
strictEqual(firstTrusted, secondTrusted);
|
||||
strictEqual(untrusted, firstTrusted);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue