GeezerVison is showing github.com — events: make abort_controller event trusted · nodejs/node@bf728b5
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/events.md +3-2Lines changed: 3 additions & 2 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1272,9 +1272,10 @@ This is not used in Node.js and is provided purely for completeness. | 1272 | 1272 | added: v14.5.0 | 1273 | 1273 | --> | 1274 | 1274 |
| 1275 | | -* Type: {boolean} Always returns `false`. | | 1275 | +* Type: {boolean} True for Node.js internal events, false otherwise. | 1276 | 1276 |
| 1277 | | -This is not used in Node.js and is provided purely for completeness. | | 1277 | +Currently only `AbortSignal`s' `"abort"` event is fired with `isTrusted` | | 1278 | +set to `true`. | 1278 | 1279 |
| 1279 | 1280 | #### `event.preventDefault()` | 1280 | 1281 | <!-- YAML | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/abort_controller.js +5-2Lines changed: 5 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -10,7 +10,8 @@ const { | 10 | 10 |
| 11 | 11 | const { | 12 | 12 | EventTarget, | 13 | | - Event | | 13 | + Event, | | 14 | + kTrustEvent | 14 | 15 | } = require('internal/event_target'); | 15 | 16 | const { | 16 | 17 | customInspectSymbol, | @@ -48,7 +49,9 @@ Object.defineProperties(AbortSignal.prototype, { | 48 | 49 | function abortSignal(signal) { | 49 | 50 | if (signal[kAborted]) return; | 50 | 51 | signal[kAborted] = true; | 51 | | - const event = new Event('abort'); | | 52 | + const event = new Event('abort', { | | 53 | + [kTrustEvent]: true | | 54 | + }); | 52 | 55 | if (typeof signal.onabort === 'function') { | 53 | 56 | signal.onabort(event); | 54 | 57 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/event_target.js +14-1Lines changed: 14 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -8,10 +8,12 @@ const { | 8 | 8 | NumberIsInteger, | 9 | 9 | Object, | 10 | 10 | ObjectDefineProperty, | | 11 | + ObjectGetOwnPropertyDescriptor, | 11 | 12 | String, | 12 | 13 | Symbol, | 13 | 14 | SymbolFor, | 14 | 15 | SymbolToStringTag, | | 16 | + SafeWeakSet, | 15 | 17 | } = primordials; | 16 | 18 |
| 17 | 19 | const { | @@ -40,6 +42,7 @@ const kRemoveListener = Symbol('kRemoveListener'); | 40 | 42 | const kIsNodeStyleListener = Symbol('kIsNodeStyleListener'); | 41 | 43 | const kMaxListeners = Symbol('kMaxListeners'); | 42 | 44 | const kMaxListenersWarned = Symbol('kMaxListenersWarned'); | | 45 | +const kTrustEvent = Symbol('kTrustEvent'); | 43 | 46 |
| 44 | 47 | // Lazy load perf_hooks to avoid the additional overhead on startup | 45 | 48 | let perf_hooks; | @@ -60,7 +63,12 @@ const kBubbles = Symbol('bubbles'); | 60 | 63 | const kComposed = Symbol('composed'); | 61 | 64 | const kPropagationStopped = Symbol('propagationStopped'); | 62 | 65 |
| 63 | | -const isTrusted = () => false; | | 66 | +const isTrustedSet = new SafeWeakSet(); | | 67 | +const isTrusted = ObjectGetOwnPropertyDescriptor({ | | 68 | + get isTrusted() { | | 69 | + return isTrustedSet.has(this); | | 70 | + } | | 71 | +}, 'isTrusted').get; | 64 | 72 |
| 65 | 73 | class Event { | 66 | 74 | constructor(type, options) { | @@ -76,6 +84,10 @@ class Event { | 76 | 84 | this[kDefaultPrevented] = false; | 77 | 85 | this[kTimestamp] = lazyNow(); | 78 | 86 | this[kPropagationStopped] = false; | | 87 | + if (options != null && options[kTrustEvent]) { | | 88 | + isTrustedSet.add(this); | | 89 | + } | | 90 | + | 79 | 91 | // isTrusted is special (LegacyUnforgeable) | 80 | 92 | ObjectDefineProperty(this, 'isTrusted', { | 81 | 93 | get: isTrusted, | @@ -572,5 +584,6 @@ module.exports = { | 572 | 584 | initNodeEventTarget, | 573 | 585 | kCreateEvent, | 574 | 586 | kNewListener, | | 587 | + kTrustEvent, | 575 | 588 | kRemoveListener, | 576 | 589 | }; |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/per_context/primordials.js +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -101,6 +101,10 @@ primordials.SafeSet = makeSafe( | 101 | 101 | Set, | 102 | 102 | class SafeSet extends Set {} | 103 | 103 | ); | | 104 | +primordials.SafeWeakSet = makeSafe( | | 105 | + WeakSet, | | 106 | + class SafeWeakSet extends WeakSet {} | | 107 | +); | 104 | 108 | primordials.SafePromise = makeSafe( | 105 | 109 | Promise, | 106 | 110 | class SafePromise extends Promise {} | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-abortcontroller.js +33-1Lines changed: 33 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -// Flags: --no-warnings --experimental-abortcontroller | | 1 | +// Flags: --no-warnings --expose-internals --experimental-abortcontroller | 2 | 2 | 'use strict'; | 3 | 3 |
| 4 | 4 | const common = require('../common'); | 5 | 5 |
| 6 | 6 | const { ok, strictEqual } = require('assert'); | | 7 | +const { Event } = require('internal/event_target'); | 7 | 8 |
| 8 | 9 | { | | 10 | + // Tests that abort is fired with the correct event type on AbortControllers | 9 | 11 | const ac = new AbortController(); | 10 | 12 | ok(ac.signal); | 11 | 13 | ac.signal.onabort = common.mustCall((event) => { | @@ -20,3 +22,33 @@ const { ok, strictEqual } = require('assert'); | 20 | 22 | ac.abort(); | 21 | 23 | ok(ac.signal.aborted); | 22 | 24 | } | | 25 | + | | 26 | +{ | | 27 | + // Tests that abort events are trusted | | 28 | + const ac = new AbortController(); | | 29 | + ac.signal.addEventListener('abort', common.mustCall((event) => { | | 30 | + ok(event.isTrusted); | | 31 | + })); | | 32 | + ac.abort(); | | 33 | +} | | 34 | + | | 35 | +{ | | 36 | + // Tests that abort events have the same `isTrusted` reference | | 37 | + const first = new AbortController(); | | 38 | + const second = new AbortController(); | | 39 | + let ev1, ev2; | | 40 | + const ev3 = new Event('abort'); | | 41 | + first.signal.addEventListener('abort', common.mustCall((event) => { | | 42 | + ev1 = event; | | 43 | + })); | | 44 | + second.signal.addEventListener('abort', common.mustCall((event) => { | | 45 | + ev2 = event; | | 46 | + })); | | 47 | + first.abort(); | | 48 | + second.abort(); | | 49 | + const firstTrusted = Reflect.getOwnPropertyDescriptor(ev1, 'isTrusted').get; | | 50 | + const secondTrusted = Reflect.getOwnPropertyDescriptor(ev2, 'isTrusted').get; | | 51 | + const untrusted = Reflect.getOwnPropertyDescriptor(ev3, 'isTrusted').get; | | 52 | + strictEqual(firstTrusted, secondTrusted); | | 53 | + strictEqual(untrusted, firstTrusted); | | 54 | +} |
|