2021-02-04 12:17:44 +02:00
|
|
|
// Flags: --expose-internals --no-warnings --expose-gc
|
2020-05-23 15:43:58 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
const common = require('../common');
|
2021-02-04 12:17:44 +02:00
|
|
|
const {
|
|
|
|
|
defineEventHandler,
|
|
|
|
|
kWeakHandler,
|
|
|
|
|
} = require('internal/event_target');
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
const assert = require('assert');
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2025-11-26 11:09:07 +00:00
|
|
|
const { listenerCount, once } = require('events');
|
2020-06-22 07:15:54 -07:00
|
|
|
|
2023-08-12 21:20:54 +03:00
|
|
|
const { inspect } = require('util');
|
|
|
|
|
const { setTimeout: delay } = require('timers/promises');
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
// The globals are defined.
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(Event);
|
|
|
|
|
assert.ok(EventTarget);
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2020-06-22 07:15:54 -07:00
|
|
|
// The warning event has special behavior regarding attaching listeners
|
|
|
|
|
let lastWarning;
|
|
|
|
|
process.on('warning', (e) => {
|
|
|
|
|
lastWarning = e;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Utility promise for parts of the test that need to wait for eachother -
|
|
|
|
|
// Namely tests for warning events
|
|
|
|
|
/* eslint-disable no-unused-vars */
|
|
|
|
|
let asyncTest = Promise.resolve();
|
|
|
|
|
|
2020-05-23 15:43:58 -07:00
|
|
|
// First, test Event
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.type, 'foo');
|
|
|
|
|
assert.strictEqual(ev.cancelable, false);
|
|
|
|
|
assert.strictEqual(ev.defaultPrevented, false);
|
|
|
|
|
assert.strictEqual(typeof ev.timeStamp, 'number');
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2020-05-28 16:52:52 +03:00
|
|
|
// Compatibility properties with the DOM
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.deepStrictEqual(ev.composedPath(), []);
|
|
|
|
|
assert.strictEqual(ev.returnValue, true);
|
|
|
|
|
assert.strictEqual(ev.bubbles, false);
|
|
|
|
|
assert.strictEqual(ev.composed, false);
|
|
|
|
|
assert.strictEqual(ev.isTrusted, false);
|
|
|
|
|
assert.strictEqual(ev.eventPhase, 0);
|
|
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
// Not cancelable
|
|
|
|
|
ev.preventDefault();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.defaultPrevented, false);
|
2020-05-23 15:43:58 -07:00
|
|
|
}
|
2020-06-04 21:49:06 -05:00
|
|
|
{
|
|
|
|
|
[
|
|
|
|
|
'foo',
|
|
|
|
|
1,
|
|
|
|
|
false,
|
|
|
|
|
].forEach((i) => (
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => new Event('foo', i), {
|
2020-06-04 21:49:06 -05:00
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
message: 'The "options" argument must be of type object.' +
|
2022-11-22 15:03:33 -08:00
|
|
|
common.invalidArgTypeHelper(i),
|
2020-06-04 21:49:06 -05:00
|
|
|
})
|
|
|
|
|
));
|
|
|
|
|
}
|
2020-05-28 17:33:21 +03:00
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.cancelBubble = true;
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.stopPropagation();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.cancelBubble = 'some-truthy-value';
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
2020-05-28 16:52:52 +03:00
|
|
|
{
|
|
|
|
|
// No argument behavior - throw TypeError
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => {
|
2020-05-28 16:52:52 +03:00
|
|
|
new Event();
|
|
|
|
|
}, TypeError);
|
|
|
|
|
// Too many arguments passed behavior - ignore additional arguments
|
|
|
|
|
const ev = new Event('foo', {}, {});
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.type, 'foo');
|
2020-05-28 16:52:52 +03:00
|
|
|
}
|
2020-05-28 17:33:21 +03:00
|
|
|
{
|
2020-06-22 06:42:33 -07:00
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.cancelBubble = true;
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.stopPropagation();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, false);
|
2020-05-28 17:33:21 +03:00
|
|
|
ev.cancelBubble = 'some-truthy-value';
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.cancelBubble, true);
|
2020-05-28 17:33:21 +03:00
|
|
|
}
|
2020-05-23 15:43:58 -07:00
|
|
|
{
|
|
|
|
|
const ev = new Event('foo', { cancelable: true });
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.type, 'foo');
|
|
|
|
|
assert.strictEqual(ev.cancelable, true);
|
|
|
|
|
assert.strictEqual(ev.defaultPrevented, false);
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
ev.preventDefault();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.defaultPrevented, true);
|
|
|
|
|
assert.throws(() => new Event(Symbol()), TypeError);
|
2020-05-23 15:43:58 -07:00
|
|
|
}
|
2020-05-28 18:08:31 +03:00
|
|
|
{
|
|
|
|
|
const ev = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.isTrusted, false);
|
2020-05-28 18:08:31 +03:00
|
|
|
}
|
2020-05-23 15:43:58 -07:00
|
|
|
{
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
|
|
|
|
|
const ev1 = common.mustCall(function(event) {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.type, 'foo');
|
|
|
|
|
assert.strictEqual(this, eventTarget);
|
|
|
|
|
assert.strictEqual(event.eventPhase, 2);
|
2020-05-23 15:43:58 -07:00
|
|
|
}, 2);
|
|
|
|
|
|
|
|
|
|
const ev2 = {
|
|
|
|
|
handleEvent: common.mustCall(function(event) {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.type, 'foo');
|
|
|
|
|
assert.strictEqual(this, ev2);
|
2022-11-22 15:03:33 -08:00
|
|
|
}),
|
2020-05-23 15:43:58 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
eventTarget.addEventListener('foo', ev1);
|
|
|
|
|
eventTarget.addEventListener('foo', ev2, { once: true });
|
2025-11-26 11:09:07 +00:00
|
|
|
assert.strictEqual(listenerCount(eventTarget, 'foo'), 2);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(eventTarget.dispatchEvent(new Event('foo')));
|
2025-11-26 11:09:07 +00:00
|
|
|
assert.strictEqual(listenerCount(eventTarget, 'foo'), 1);
|
2020-05-23 15:43:58 -07:00
|
|
|
eventTarget.dispatchEvent(new Event('foo'));
|
|
|
|
|
|
|
|
|
|
eventTarget.removeEventListener('foo', ev1);
|
2025-11-26 11:09:07 +00:00
|
|
|
assert.strictEqual(listenerCount(eventTarget, 'foo'), 0);
|
2020-05-23 15:43:58 -07:00
|
|
|
eventTarget.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2020-05-28 21:19:13 +03:00
|
|
|
{
|
|
|
|
|
// event subclassing
|
|
|
|
|
const SubEvent = class extends Event {};
|
|
|
|
|
const ev = new SubEvent('foo');
|
|
|
|
|
const eventTarget = new EventTarget();
|
2025-11-15 16:04:50 +01:00
|
|
|
const fn = common.mustCall((event) => assert.strictEqual(event, ev));
|
2020-05-28 21:19:13 +03:00
|
|
|
eventTarget.addEventListener('foo', fn, { once: true });
|
|
|
|
|
eventTarget.dispatchEvent(ev);
|
|
|
|
|
}
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2021-07-15 09:33:06 +02:00
|
|
|
{
|
|
|
|
|
// Same event dispatched multiple times.
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
const eventTarget1 = new EventTarget();
|
|
|
|
|
const eventTarget2 = new EventTarget();
|
|
|
|
|
|
|
|
|
|
eventTarget1.addEventListener('foo', common.mustCall((event) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.AT_TARGET);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget1);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), [eventTarget1]);
|
2021-07-15 09:33:06 +02:00
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
eventTarget2.addEventListener('foo', common.mustCall((event) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.AT_TARGET);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget2);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), [eventTarget2]);
|
2021-07-15 09:33:06 +02:00
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
eventTarget1.dispatchEvent(event);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.NONE);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget1);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), []);
|
2021-07-15 09:33:06 +02:00
|
|
|
|
|
|
|
|
|
2021-08-15 15:58:01 +01:00
|
|
|
eventTarget2.dispatchEvent(event);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.NONE);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget2);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), []);
|
2021-08-15 15:58:01 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// Same event dispatched multiple times, without listeners added.
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
const eventTarget1 = new EventTarget();
|
|
|
|
|
const eventTarget2 = new EventTarget();
|
|
|
|
|
|
|
|
|
|
eventTarget1.dispatchEvent(event);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.NONE);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget1);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), []);
|
2021-08-15 15:58:01 +01:00
|
|
|
|
2021-07-15 09:33:06 +02:00
|
|
|
eventTarget2.dispatchEvent(event);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.eventPhase, Event.NONE);
|
|
|
|
|
assert.strictEqual(event.target, eventTarget2);
|
|
|
|
|
assert.deepStrictEqual(event.composedPath(), []);
|
2021-07-15 09:33:06 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-23 15:43:58 -07:00
|
|
|
{
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
const event = new Event('foo', { cancelable: true });
|
|
|
|
|
eventTarget.addEventListener('foo', (event) => event.preventDefault());
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(!eventTarget.dispatchEvent(event));
|
2020-05-23 15:43:58 -07:00
|
|
|
}
|
2020-05-28 19:08:43 +03:00
|
|
|
{
|
|
|
|
|
// Adding event listeners with a boolean useCapture
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
const fn = common.mustCall((event) => assert.strictEqual(event.type, 'foo'));
|
2020-05-28 19:08:43 +03:00
|
|
|
eventTarget.addEventListener('foo', fn, false);
|
|
|
|
|
eventTarget.dispatchEvent(event);
|
|
|
|
|
}
|
2020-05-23 15:43:58 -07:00
|
|
|
|
2021-07-22 15:50:47 +02:00
|
|
|
{
|
|
|
|
|
// The `options` argument can be `null`.
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
const fn = common.mustCall((event) => assert.strictEqual(event.type, 'foo'));
|
2021-07-22 15:50:47 +02:00
|
|
|
eventTarget.addEventListener('foo', fn, null);
|
|
|
|
|
eventTarget.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 20:26:18 +09:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const listener = {};
|
|
|
|
|
// AddEventListener should not require handleEvent to be
|
|
|
|
|
// defined on an EventListener.
|
|
|
|
|
target.addEventListener('foo', listener);
|
|
|
|
|
listener.handleEvent = common.mustCall(function(event) {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.type, 'foo');
|
|
|
|
|
assert.strictEqual(this, listener);
|
2022-06-29 20:26:18 +09:00
|
|
|
});
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const listener = {};
|
|
|
|
|
// do not throw
|
|
|
|
|
target.removeEventListener('foo', listener);
|
|
|
|
|
target.addEventListener('foo', listener);
|
|
|
|
|
target.removeEventListener('foo', listener);
|
|
|
|
|
listener.handleEvent = common.mustNotCall();
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 15:43:58 -07:00
|
|
|
{
|
2021-02-04 15:31:47 +02:00
|
|
|
const uncaughtException = common.mustCall((err, origin) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(err.message, 'boom');
|
|
|
|
|
assert.strictEqual(origin, 'uncaughtException');
|
2020-05-23 15:43:58 -07:00
|
|
|
}, 4);
|
|
|
|
|
|
2021-02-04 15:31:47 +02:00
|
|
|
// Make sure that we no longer call 'error' on error.
|
|
|
|
|
process.on('error', common.mustNotCall());
|
|
|
|
|
// Don't call rejection even for async handlers.
|
|
|
|
|
process.on('unhandledRejection', common.mustNotCall());
|
|
|
|
|
process.on('uncaughtException', uncaughtException);
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
|
|
|
|
|
const ev1 = async () => { throw new Error('boom'); };
|
|
|
|
|
const ev2 = () => { throw new Error('boom'); };
|
|
|
|
|
const ev3 = { handleEvent() { throw new Error('boom'); } };
|
|
|
|
|
const ev4 = { async handleEvent() { throw new Error('boom'); } };
|
|
|
|
|
|
|
|
|
|
// Errors in a handler won't stop calling the others.
|
|
|
|
|
eventTarget.addEventListener('foo', ev1, { once: true });
|
|
|
|
|
eventTarget.addEventListener('foo', ev2, { once: true });
|
|
|
|
|
eventTarget.addEventListener('foo', ev3, { once: true });
|
|
|
|
|
eventTarget.addEventListener('foo', ev4, { once: true });
|
|
|
|
|
|
|
|
|
|
eventTarget.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
|
|
|
|
|
// Once handler only invoked once
|
|
|
|
|
const ev = common.mustCall((event) => {
|
2020-06-22 06:51:53 -07:00
|
|
|
// Can invoke the same event name recursively
|
|
|
|
|
eventTarget.dispatchEvent(new Event('foo'));
|
2020-05-23 15:43:58 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Errors in a handler won't stop calling the others.
|
2020-06-22 06:51:53 -07:00
|
|
|
eventTarget.addEventListener('foo', ev, { once: true });
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
eventTarget.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Coercion to string works
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual((new Event(1)).type, '1');
|
|
|
|
|
assert.strictEqual((new Event(false)).type, 'false');
|
|
|
|
|
assert.strictEqual((new Event({})).type, String({}));
|
2020-05-23 15:43:58 -07:00
|
|
|
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
|
'foo',
|
|
|
|
|
{}, // No type event
|
|
|
|
|
undefined,
|
|
|
|
|
1,
|
2021-03-26 08:51:08 -07:00
|
|
|
false,
|
2020-05-23 15:43:58 -07:00
|
|
|
].forEach((i) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => target.dispatchEvent(i), {
|
2020-06-04 21:49:06 -05:00
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
message: 'The "event" argument must be an instance of Event.' +
|
2022-11-22 15:03:33 -08:00
|
|
|
common.invalidArgTypeHelper(i),
|
2020-05-23 15:43:58 -07:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2020-06-04 21:49:06 -05:00
|
|
|
const err = (arg) => ({
|
|
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
message: 'The "listener" argument must be an instance of EventListener.' +
|
2022-11-22 15:03:33 -08:00
|
|
|
common.invalidArgTypeHelper(arg),
|
2020-06-04 21:49:06 -05:00
|
|
|
});
|
|
|
|
|
|
2020-05-23 15:43:58 -07:00
|
|
|
[
|
|
|
|
|
'foo',
|
|
|
|
|
1,
|
2021-03-26 08:51:08 -07:00
|
|
|
false,
|
2025-11-15 16:04:50 +01:00
|
|
|
].forEach((i) => assert.throws(() => target.addEventListener('foo', i), err(i)));
|
2020-05-23 15:43:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
once(target, 'foo').then(common.mustCall());
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.cancelBubble, false);
|
2020-05-23 15:43:58 -07:00
|
|
|
event.stopImmediatePropagation();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.cancelBubble, true);
|
2020-05-23 15:43:58 -07:00
|
|
|
target.addEventListener('foo', common.mustNotCall());
|
|
|
|
|
target.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
target.addEventListener('foo', common.mustCall((event) => {
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
}));
|
|
|
|
|
target.addEventListener('foo', common.mustNotCall());
|
|
|
|
|
target.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
target.addEventListener('foo', common.mustCall((event) => {
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
}));
|
|
|
|
|
target.addEventListener('foo', common.mustNotCall());
|
|
|
|
|
target.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.target, null);
|
2020-05-23 15:43:58 -07:00
|
|
|
target.addEventListener('foo', common.mustCall((event) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.target, target);
|
|
|
|
|
assert.strictEqual(event.currentTarget, target);
|
|
|
|
|
assert.strictEqual(event.srcElement, target);
|
2020-05-23 15:43:58 -07:00
|
|
|
}));
|
|
|
|
|
target.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target1 = new EventTarget();
|
|
|
|
|
const target2 = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
target1.addEventListener('foo', common.mustCall((event) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => target2.dispatchEvent(event), {
|
2022-11-22 15:03:33 -08:00
|
|
|
code: 'ERR_EVENT_RECURSION',
|
2020-05-23 15:43:58 -07:00
|
|
|
});
|
|
|
|
|
}));
|
|
|
|
|
target1.dispatchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const a = common.mustCall(() => target.removeEventListener('foo', a));
|
|
|
|
|
const b = common.mustCall(2);
|
|
|
|
|
|
|
|
|
|
target.addEventListener('foo', a);
|
|
|
|
|
target.addEventListener('foo', b);
|
|
|
|
|
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const a = common.mustCall(3);
|
|
|
|
|
|
|
|
|
|
target.addEventListener('foo', a, { capture: true });
|
|
|
|
|
target.addEventListener('foo', a, { capture: false });
|
|
|
|
|
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
target.removeEventListener('foo', a, { capture: true });
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
target.removeEventListener('foo', a, { capture: false });
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2020-05-28 21:19:13 +03:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(target.toString(), '[object EventTarget]');
|
2020-05-28 16:52:52 +03:00
|
|
|
const event = new Event('');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.toString(), '[object Event]');
|
2020-05-28 21:19:13 +03:00
|
|
|
}
|
2020-05-30 00:51:02 +03:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
target.onfoo = common.mustCall();
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2022-02-16 21:36:20 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(target.onfoo, null);
|
2022-02-16 21:36:20 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-30 00:51:02 +03:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
let count = 0;
|
|
|
|
|
target.onfoo = () => count++;
|
|
|
|
|
target.onfoo = common.mustCall(() => count++);
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(count, 1);
|
2020-05-30 00:51:02 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
let count = 0;
|
|
|
|
|
target.addEventListener('foo', () => count++);
|
|
|
|
|
target.onfoo = common.mustCall(() => count++);
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(count, 2);
|
2020-05-30 00:51:02 +03:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
const fn = common.mustNotCall();
|
|
|
|
|
target.onfoo = fn;
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(target.onfoo, fn);
|
2020-05-30 00:51:02 +03:00
|
|
|
target.onfoo = null;
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2020-05-30 15:48:46 +00:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// `this` value of dispatchEvent
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const target2 = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(target.dispatchEvent.call(target2, event));
|
2020-05-30 15:48:46 +00:00
|
|
|
|
|
|
|
|
[
|
|
|
|
|
'foo',
|
|
|
|
|
{},
|
|
|
|
|
[],
|
|
|
|
|
1,
|
|
|
|
|
null,
|
|
|
|
|
undefined,
|
|
|
|
|
false,
|
|
|
|
|
Symbol(),
|
2021-03-26 08:51:08 -07:00
|
|
|
/a/,
|
2020-05-30 15:48:46 +00:00
|
|
|
].forEach((i) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => target.dispatchEvent.call(i, event), {
|
2022-11-22 15:03:33 -08:00
|
|
|
code: 'ERR_INVALID_THIS',
|
2020-05-30 15:48:46 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-05-30 02:56:01 +03:00
|
|
|
|
|
|
|
|
{
|
2020-10-26 11:11:13 +02:00
|
|
|
// Event Statics
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(Event.NONE, 0);
|
|
|
|
|
assert.strictEqual(Event.CAPTURING_PHASE, 1);
|
|
|
|
|
assert.strictEqual(Event.AT_TARGET, 2);
|
|
|
|
|
assert.strictEqual(Event.BUBBLING_PHASE, 3);
|
|
|
|
|
assert.strictEqual(new Event('foo').eventPhase, Event.NONE);
|
2020-05-30 02:56:01 +03:00
|
|
|
const target = new EventTarget();
|
|
|
|
|
target.addEventListener('foo', common.mustCall((e) => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(e.eventPhase, Event.AT_TARGET);
|
2020-05-30 02:56:01 +03:00
|
|
|
}), { once: true });
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
2020-10-26 11:11:13 +02:00
|
|
|
// Event is a function
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(Event.length, 1);
|
2020-05-30 02:56:01 +03:00
|
|
|
}
|
2020-06-22 06:42:33 -07:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const ev = new Event('toString');
|
2025-11-15 16:04:50 +01:00
|
|
|
const fn = common.mustCall((event) => assert.strictEqual(event.type, 'toString'));
|
2020-06-22 06:42:33 -07:00
|
|
|
target.addEventListener('toString', fn);
|
|
|
|
|
target.dispatchEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
const ev = new Event('__proto__');
|
2025-11-15 16:04:50 +01:00
|
|
|
const fn = common.mustCall((event) => assert.strictEqual(event.type, '__proto__'));
|
2020-06-22 06:42:33 -07:00
|
|
|
target.addEventListener('__proto__', fn);
|
|
|
|
|
target.dispatchEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-22 07:15:54 -07:00
|
|
|
{
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
// Single argument throws
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => eventTarget.addEventListener('foo'), TypeError);
|
2020-06-22 07:15:54 -07:00
|
|
|
// Null events - does not throw
|
|
|
|
|
eventTarget.addEventListener('foo', null);
|
|
|
|
|
eventTarget.removeEventListener('foo', null);
|
|
|
|
|
eventTarget.addEventListener('foo', undefined);
|
|
|
|
|
eventTarget.removeEventListener('foo', undefined);
|
|
|
|
|
// Strings, booleans
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', 'hello'), TypeError);
|
|
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', false), TypeError);
|
|
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', Symbol()), TypeError);
|
2020-06-22 07:15:54 -07:00
|
|
|
asyncTest = asyncTest.then(async () => {
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
// Single argument throws
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => eventTarget.addEventListener('foo'), TypeError);
|
2020-06-22 07:15:54 -07:00
|
|
|
// Null events - does not throw
|
|
|
|
|
|
|
|
|
|
eventTarget.addEventListener('foo', null);
|
|
|
|
|
eventTarget.removeEventListener('foo', null);
|
|
|
|
|
|
|
|
|
|
// Warnings always happen after nextTick, so wait for a timer of 0
|
|
|
|
|
await delay(0);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(lastWarning.name, 'AddEventListenerArgumentTypeWarning');
|
|
|
|
|
assert.strictEqual(lastWarning.target, eventTarget);
|
2020-06-22 07:15:54 -07:00
|
|
|
lastWarning = null;
|
|
|
|
|
eventTarget.addEventListener('foo', undefined);
|
|
|
|
|
await delay(0);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(lastWarning.name, 'AddEventListenerArgumentTypeWarning');
|
|
|
|
|
assert.strictEqual(lastWarning.target, eventTarget);
|
2020-06-22 07:15:54 -07:00
|
|
|
eventTarget.removeEventListener('foo', undefined);
|
|
|
|
|
// Strings, booleans
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', 'hello'), TypeError);
|
|
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', false), TypeError);
|
|
|
|
|
assert.throws(() => eventTarget.addEventListener('foo', Symbol()), TypeError);
|
2020-06-22 07:15:54 -07:00
|
|
|
});
|
|
|
|
|
}
|
2020-10-31 07:38:52 +09:00
|
|
|
{
|
|
|
|
|
const eventTarget = new EventTarget();
|
|
|
|
|
const event = new Event('foo');
|
|
|
|
|
eventTarget.dispatchEvent(event);
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.target, eventTarget);
|
2020-10-31 07:38:52 +09:00
|
|
|
}
|
2020-10-26 11:11:13 +02:00
|
|
|
{
|
|
|
|
|
// Event target exported keys
|
|
|
|
|
const eventTarget = new EventTarget();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.deepStrictEqual(Object.keys(eventTarget), []);
|
|
|
|
|
assert.deepStrictEqual(Object.getOwnPropertyNames(eventTarget), []);
|
2020-10-26 11:11:13 +02:00
|
|
|
const parentKeys = Object.keys(Object.getPrototypeOf(eventTarget)).sort();
|
|
|
|
|
const keys = ['addEventListener', 'dispatchEvent', 'removeEventListener'];
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.deepStrictEqual(parentKeys, keys);
|
2020-10-26 11:11:13 +02:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// Subclassing
|
|
|
|
|
class SubTarget extends EventTarget {}
|
|
|
|
|
const target = new SubTarget();
|
|
|
|
|
target.addEventListener('foo', common.mustCall());
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// Test event order
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
let state = 0;
|
|
|
|
|
target.addEventListener('foo', common.mustCall(() => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(state, 0);
|
2020-10-26 11:11:13 +02:00
|
|
|
state++;
|
|
|
|
|
}));
|
|
|
|
|
target.addEventListener('foo', common.mustCall(() => {
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(state, 1);
|
2020-10-26 11:11:13 +02:00
|
|
|
}));
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2020-11-02 22:40:00 +02:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
const descriptor = Object.getOwnPropertyDescriptor(target, 'onfoo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(descriptor.configurable, true);
|
|
|
|
|
assert.strictEqual(descriptor.enumerable, true);
|
2020-11-02 22:40:00 +02:00
|
|
|
}
|
2020-11-06 11:01:59 +02:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo');
|
|
|
|
|
const output = [];
|
|
|
|
|
target.addEventListener('foo', () => output.push(1));
|
|
|
|
|
target.onfoo = common.mustNotCall();
|
|
|
|
|
target.addEventListener('foo', () => output.push(3));
|
|
|
|
|
target.onfoo = () => output.push(2);
|
|
|
|
|
target.addEventListener('foo', () => output.push(4));
|
|
|
|
|
target.dispatchEvent(new Event('foo'));
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.deepStrictEqual(output, [1, 2, 3, 4]);
|
2020-11-06 11:01:59 +02:00
|
|
|
}
|
2022-10-18 17:43:11 -07:00
|
|
|
{
|
|
|
|
|
const target = new EventTarget();
|
|
|
|
|
defineEventHandler(target, 'foo', 'bar');
|
|
|
|
|
const output = [];
|
|
|
|
|
target.addEventListener('bar', () => output.push(1));
|
|
|
|
|
target.onfoo = () => output.push(2);
|
|
|
|
|
target.dispatchEvent(new Event('bar'));
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.deepStrictEqual(output, [1, 2]);
|
2022-10-18 17:43:11 -07:00
|
|
|
}
|
2020-11-25 14:58:58 +02:00
|
|
|
{
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
const listener = common.mustNotCall();
|
|
|
|
|
et.addEventListener('foo', common.mustCall((e) => {
|
|
|
|
|
et.removeEventListener('foo', listener);
|
|
|
|
|
}));
|
|
|
|
|
et.addEventListener('foo', listener);
|
|
|
|
|
et.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2020-12-29 01:06:34 +08:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('test');
|
|
|
|
|
const evConstructorName = inspect(ev, {
|
2022-11-22 15:03:33 -08:00
|
|
|
depth: -1,
|
2020-12-29 01:06:34 +08:00
|
|
|
});
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(evConstructorName, 'Event');
|
2020-12-29 01:06:34 +08:00
|
|
|
|
|
|
|
|
const inspectResult = inspect(ev, {
|
2022-11-22 15:03:33 -08:00
|
|
|
depth: 1,
|
2020-12-29 01:06:34 +08:00
|
|
|
});
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(inspectResult.includes('Event'));
|
2020-12-29 01:06:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
const inspectResult = inspect(et, {
|
2022-11-22 15:03:33 -08:00
|
|
|
depth: 1,
|
2020-12-29 01:06:34 +08:00
|
|
|
});
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.ok(inspectResult.includes('EventTarget'));
|
2020-12-29 01:06:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const ev = new Event('test');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(ev.constructor.name, 'Event');
|
2020-12-29 01:06:34 +08:00
|
|
|
|
|
|
|
|
const et = new EventTarget();
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(et.constructor.name, 'EventTarget');
|
2020-12-29 01:06:34 +08:00
|
|
|
}
|
2021-02-04 12:17:44 +02:00
|
|
|
{
|
2022-02-16 21:36:20 +02:00
|
|
|
// Weak event listeners work
|
2021-02-04 12:17:44 +02:00
|
|
|
const et = new EventTarget();
|
|
|
|
|
const listener = common.mustCall();
|
|
|
|
|
et.addEventListener('foo', listener, { [kWeakHandler]: et });
|
|
|
|
|
et.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
{
|
2022-02-16 21:36:20 +02:00
|
|
|
// Weak event listeners can be removed and weakness is not part of the key
|
2021-02-04 12:17:44 +02:00
|
|
|
const et = new EventTarget();
|
|
|
|
|
const listener = common.mustNotCall();
|
|
|
|
|
et.addEventListener('foo', listener, { [kWeakHandler]: et });
|
|
|
|
|
et.removeEventListener('foo', listener);
|
|
|
|
|
et.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// Test listeners are held weakly
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
et.addEventListener('foo', common.mustNotCall(), { [kWeakHandler]: {} });
|
|
|
|
|
setImmediate(() => {
|
2025-01-22 15:30:30 -08:00
|
|
|
globalThis.gc();
|
2021-02-04 12:17:44 +02:00
|
|
|
et.dispatchEvent(new Event('foo'));
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-12-09 15:07:20 +09:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => et.addEventListener(), {
|
2022-12-09 15:07:20 +09:00
|
|
|
code: 'ERR_MISSING_ARGS',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => et.addEventListener('foo'), {
|
2022-12-09 15:07:20 +09:00
|
|
|
code: 'ERR_MISSING_ARGS',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => et.removeEventListener(), {
|
2022-12-09 15:07:20 +09:00
|
|
|
code: 'ERR_MISSING_ARGS',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => et.removeEventListener('foo'), {
|
2022-12-09 15:07:20 +09:00
|
|
|
code: 'ERR_MISSING_ARGS',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => et.dispatchEvent(), {
|
2022-12-09 15:07:20 +09:00
|
|
|
code: 'ERR_MISSING_ARGS',
|
|
|
|
|
name: 'TypeError',
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-04-14 06:12:28 -04:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => {
|
2023-04-14 06:12:28 -04:00
|
|
|
et.addEventListener(Symbol('symbol'), () => {});
|
|
|
|
|
}, TypeError);
|
|
|
|
|
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.throws(() => {
|
2023-04-14 06:12:28 -04:00
|
|
|
et.removeEventListener(Symbol('symbol'), () => {});
|
|
|
|
|
}, TypeError);
|
|
|
|
|
}
|
2023-06-22 16:38:02 +03:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Test that event listeners are removed by signal even when
|
|
|
|
|
// signal's abort event propagation stopped
|
|
|
|
|
const controller = new AbortController();
|
|
|
|
|
const { signal } = controller;
|
|
|
|
|
signal.addEventListener('abort', (e) => e.stopImmediatePropagation(), { once: true });
|
|
|
|
|
const et = new EventTarget();
|
|
|
|
|
et.addEventListener('foo', common.mustNotCall(), { signal });
|
|
|
|
|
controller.abort();
|
|
|
|
|
et.dispatchEvent(new Event('foo'));
|
|
|
|
|
}
|
2023-10-26 10:05:59 +03:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const event = new Event('foo');
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.cancelBubble, false);
|
2023-10-26 10:05:59 +03:00
|
|
|
event.cancelBubble = true;
|
2025-11-15 16:04:50 +01:00
|
|
|
assert.strictEqual(event.cancelBubble, true);
|
2023-10-26 10:05:59 +03:00
|
|
|
}
|
2024-08-29 13:56:54 -04:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// A null eventInitDict should not throw an error.
|
|
|
|
|
new Event('', null);
|
|
|
|
|
new Event('', undefined);
|
|
|
|
|
}
|