1'use strict';
2
3require('../common');
4
5const {
6  strictEqual,
7} = require('assert');
8
9// Manually ported from: wpt@dom/events/AddEventListenerOptions-signal.any.js
10
11{
12  // Passing an AbortSignal to addEventListener does not prevent
13  // removeEventListener
14  let count = 0;
15  function handler() {
16    count++;
17  }
18  const et = new EventTarget();
19  const controller = new AbortController();
20  et.addEventListener('test', handler, { signal: controller.signal });
21  et.dispatchEvent(new Event('test'));
22  strictEqual(count, 1, 'Adding a signal still adds a listener');
23  et.dispatchEvent(new Event('test'));
24  strictEqual(count, 2, 'The listener was not added with the once flag');
25  controller.abort();
26  et.dispatchEvent(new Event('test'));
27  strictEqual(count, 2, 'Aborting on the controller removes the listener');
28  // See: https://github.com/nodejs/node/pull/37696 , adding an event listener
29  // should always return undefined.
30  strictEqual(
31    et.addEventListener('test', handler, { signal: controller.signal }),
32    undefined);
33  et.dispatchEvent(new Event('test'));
34  strictEqual(count, 2, 'Passing an aborted signal never adds the handler');
35}
36
37{
38  // Passing an AbortSignal to addEventListener works with the once flag
39  let count = 0;
40  function handler() {
41    count++;
42  }
43  const et = new EventTarget();
44  const controller = new AbortController();
45  et.addEventListener('test', handler, { signal: controller.signal });
46  et.removeEventListener('test', handler);
47  et.dispatchEvent(new Event('test'));
48  strictEqual(count, 0, 'The listener was still removed');
49}
50
51{
52  // Removing a once listener works with a passed signal
53  let count = 0;
54  function handler() {
55    count++;
56  }
57  const et = new EventTarget();
58  const controller = new AbortController();
59  const options = { signal: controller.signal, once: true };
60  et.addEventListener('test', handler, options);
61  controller.abort();
62  et.dispatchEvent(new Event('test'));
63  strictEqual(count, 0, 'The listener was still removed');
64}
65
66{
67  let count = 0;
68  function handler() {
69    count++;
70  }
71  const et = new EventTarget();
72  const controller = new AbortController();
73  const options = { signal: controller.signal, once: true };
74  et.addEventListener('test', handler, options);
75  et.removeEventListener('test', handler);
76  et.dispatchEvent(new Event('test'));
77  strictEqual(count, 0, 'The listener was still removed');
78}
79
80{
81  // Passing an AbortSignal to multiple listeners
82  let count = 0;
83  function handler() {
84    count++;
85  }
86  const et = new EventTarget();
87  const controller = new AbortController();
88  const options = { signal: controller.signal, once: true };
89  et.addEventListener('first', handler, options);
90  et.addEventListener('second', handler, options);
91  controller.abort();
92  et.dispatchEvent(new Event('first'));
93  et.dispatchEvent(new Event('second'));
94  strictEqual(count, 0, 'The listener was still removed');
95}
96
97{
98  // Passing an AbortSignal to addEventListener works with the capture flag
99  let count = 0;
100  function handler() {
101    count++;
102  }
103  const et = new EventTarget();
104  const controller = new AbortController();
105  const options = { signal: controller.signal, capture: true };
106  et.addEventListener('test', handler, options);
107  controller.abort();
108  et.dispatchEvent(new Event('test'));
109  strictEqual(count, 0, 'The listener was still removed');
110}
111
112{
113  // Aborting from a listener does not call future listeners
114  let count = 0;
115  function handler() {
116    count++;
117  }
118  const et = new EventTarget();
119  const controller = new AbortController();
120  const options = { signal: controller.signal };
121  et.addEventListener('test', () => {
122    controller.abort();
123  }, options);
124  et.addEventListener('test', handler, options);
125  et.dispatchEvent(new Event('test'));
126  strictEqual(count, 0, 'The listener was still removed');
127}
128
129{
130  // Adding then aborting a listener in another listener does not call it
131  let count = 0;
132  function handler() {
133    count++;
134  }
135  const et = new EventTarget();
136  const controller = new AbortController();
137  et.addEventListener('test', () => {
138    et.addEventListener('test', handler, { signal: controller.signal });
139    controller.abort();
140  }, { signal: controller.signal });
141  et.dispatchEvent(new Event('test'));
142  strictEqual(count, 0, 'The listener was still removed');
143}
144
145{
146  // Aborting from a nested listener should remove it
147  const et = new EventTarget();
148  const ac = new AbortController();
149  let count = 0;
150  et.addEventListener('foo', () => {
151    et.addEventListener('foo', () => {
152      count++;
153      if (count > 5) ac.abort();
154      et.dispatchEvent(new Event('foo'));
155    }, { signal: ac.signal });
156    et.dispatchEvent(new Event('foo'));
157  }, { once: true });
158  et.dispatchEvent(new Event('foo'));
159}
160