|
10 | 10 | <div popover>Popover</div> |
11 | 11 |
|
12 | 12 | <script> |
13 | | -function getPopoverAndSignal(t) { |
14 | | - const popover = document.querySelector('[popover]'); |
15 | | - const controller = new AbortController(); |
16 | | - const signal = controller.signal; |
17 | | - t.add_cleanup(() => controller.abort()); |
18 | | - return {popover, signal}; |
19 | | -} |
20 | 13 | window.onload = () => { |
21 | 14 | for(const method of ["listener","attribute"]) { |
22 | 15 | promise_test(async t => { |
|
29 | 22 | function listener(e) { |
30 | 23 | if (e.type === "beforetoggle") { |
31 | 24 | if (e.newState === "open") { |
32 | | - ++showCount; |
33 | | - assert_equals(e.oldState,"closed",'The "beforetoggle" event should be fired before the popover is open'); |
| 25 | + assert_equals(e.currentState,"closed",'The "beforetoggle" event should be fired before the popover is open'); |
34 | 26 | assert_true(e.target.matches(':closed'),'The popover should be in the :closed state when the opening event fires.'); |
35 | 27 | assert_false(e.target.matches(':open'),'The popover should *not* be in the :open state when the opening event fires.'); |
| 28 | + ++showCount; |
36 | 29 | } else { |
37 | | - ++hideCount; |
38 | 30 | assert_equals(e.newState,"closed",'Popover toggleevent states should be "open" and "closed"'); |
39 | | - assert_equals(e.oldState,"open",'The "beforetoggle" event should be fired before the popover is closed') |
| 31 | + assert_equals(e.currentState,"open",'The "beforetoggle" event should be fired before the popover is closed') |
40 | 32 | assert_true(e.target.matches(':open'),'The popover should be in the :open state when the hiding event fires.'); |
41 | 33 | assert_false(e.target.matches(':closed'),'The popover should *not* be in the :closed state when the hiding event fires.'); |
| 34 | + ++hideCount; |
42 | 35 | } |
43 | 36 | } else { |
44 | | - assert_equals(e.type,"toggle",'Popover events should be "beforetoggle" and "toggle"') |
| 37 | + assert_equals(e.type,"aftertoggle",'Popover events should be "beforetoggle" and "aftertoggle"') |
45 | 38 | if (e.newState === "open") { |
46 | | - ++afterShowCount; |
| 39 | + assert_equals(e.currentState,"open",'Aftertoggle should be fired after the popover is open'); |
47 | 40 | if (document.body.contains(e.target)) { |
48 | 41 | assert_true(e.target.matches(':open'),'The popover should be in the :open state when the after opening event fires.'); |
49 | 42 | assert_false(e.target.matches(':closed'),'The popover should *not* be in the :closed state when the after opening event fires.'); |
50 | 43 | } |
| 44 | + ++afterShowCount; |
51 | 45 | } else { |
52 | | - ++afterHideCount; |
53 | 46 | assert_equals(e.newState,"closed",'Popover toggleevent states should be "open" and "closed"'); |
| 47 | + assert_equals(e.currentState,"closed",'Aftertoggle should be fired after the popover is closed'); |
54 | 48 | assert_true(e.target.matches(':closed'),'The popover should be in the :closed state when the after hiding event fires.'); |
55 | 49 | assert_false(e.target.matches(':open'),'The popover should *not* be in the :open state when the after hiding event fires.'); |
| 50 | + ++afterHideCount; |
56 | 51 | } |
57 | | - e.preventDefault(); // "toggle" should not be cancelable. |
| 52 | + e.preventDefault(); // "aftertoggle" should not be cancelable. |
58 | 53 | } |
59 | 54 | }; |
60 | 55 | switch (method) { |
61 | 56 | case "listener": |
62 | | - const {signal} = getPopoverAndSignal(t); |
| 57 | + const controller = new AbortController(); |
| 58 | + const signal = controller.signal; |
| 59 | + t.add_cleanup(() => controller.abort()); |
63 | 60 | // These events bubble. |
64 | 61 | document.addEventListener('beforetoggle', listener, {signal}); |
65 | | - document.addEventListener('toggle', listener, {signal}); |
| 62 | + document.addEventListener('aftertoggle', listener, {signal}); |
66 | 63 | break; |
67 | 64 | case "attribute": |
68 | 65 | assert_false(popover.hasAttribute('onbeforetoggle')); |
69 | 66 | t.add_cleanup(() => popover.removeAttribute('onbeforetoggle')); |
70 | 67 | popover.onbeforetoggle = listener; |
71 | | - assert_false(popover.hasAttribute('ontoggle')); |
72 | | - t.add_cleanup(() => popover.removeAttribute('ontoggle')); |
73 | | - popover.ontoggle = listener; |
| 68 | + assert_false(popover.hasAttribute('onaftertoggle')); |
| 69 | + t.add_cleanup(() => popover.removeAttribute('onaftertoggle')); |
| 70 | + popover.onaftertoggle = listener; |
74 | 71 | break; |
75 | 72 | default: assert_unreached(); |
76 | 73 | } |
|
85 | 82 | assert_equals(0,afterShowCount); |
86 | 83 | assert_equals(0,afterHideCount); |
87 | 84 | await waitForRender(); |
88 | | - assert_equals(1,afterShowCount,'toggle show is fired asynchronously'); |
| 85 | + assert_equals(1,afterShowCount,'aftertoggle show is fired asynchronously'); |
89 | 86 | assert_equals(0,afterHideCount); |
90 | 87 | assert_true(popover.matches(':open')); |
91 | 88 | popover.hidePopover(); |
|
96 | 93 | assert_equals(0,afterHideCount); |
97 | 94 | await waitForRender(); |
98 | 95 | assert_equals(1,afterShowCount); |
99 | | - assert_equals(1,afterHideCount,'toggle hide is fired asynchronously'); |
| 96 | + assert_equals(1,afterHideCount,'aftertoggle hide is fired asynchronously'); |
100 | 97 | // No additional events |
101 | 98 | await waitForRender(); |
102 | 99 | await waitForRender(); |
|
109 | 106 | } |
110 | 107 |
|
111 | 108 | promise_test(async t => { |
112 | | - const {popover,signal} = getPopoverAndSignal(t); |
| 109 | + const popover = document.querySelector('[popover]'); |
| 110 | + const controller = new AbortController(); |
| 111 | + const signal = controller.signal; |
| 112 | + t.add_cleanup(() => controller.abort()); |
113 | 113 | let cancel = true; |
114 | 114 | popover.addEventListener('beforetoggle',(e) => { |
115 | 115 | if (e.newState !== "open") |
|
128 | 128 | }, 'The "beforetoggle" event is cancelable for the "opening" transition'); |
129 | 129 |
|
130 | 130 | promise_test(async t => { |
131 | | - const {popover,signal} = getPopoverAndSignal(t); |
| 131 | + const popover = document.querySelector('[popover]'); |
| 132 | + const controller = new AbortController(); |
| 133 | + const signal = controller.signal; |
| 134 | + t.add_cleanup(() => {controller.abort();}); |
132 | 135 | popover.addEventListener('beforetoggle',(e) => { |
133 | 136 | assert_not_equals(e.newState,"closed",'The "beforetoggle" event was fired for the closing transition'); |
134 | 137 | }, {signal}); |
|
141 | 144 | await waitForRender(); // Check for async events also |
142 | 145 | assert_false(popover.matches(':open')); |
143 | 146 | }, 'The "beforetoggle" event is not fired for element removal'); |
144 | | - |
145 | | - promise_test(async t => { |
146 | | - const {popover,signal} = getPopoverAndSignal(t); |
147 | | - let events; |
148 | | - function resetEvents() { |
149 | | - events = { |
150 | | - singleShow: false, |
151 | | - singleHide: false, |
152 | | - coalescedShow: false, |
153 | | - coalescedHide: false, |
154 | | - }; |
155 | | - } |
156 | | - function setEvent(type) { |
157 | | - assert_equals(events[type],false,'event repeated'); |
158 | | - events[type] = true; |
159 | | - } |
160 | | - function assertOnly(type,msg) { |
161 | | - Object.keys(events).forEach(val => { |
162 | | - assert_equals(events[val],val===type,`${msg} (${val})`); |
163 | | - }); |
164 | | - } |
165 | | - popover.addEventListener('toggle',(e) => { |
166 | | - switch (e.newState) { |
167 | | - case "open": |
168 | | - switch (e.oldState) { |
169 | | - case "open": setEvent('coalescedShow'); break; |
170 | | - case "closed": setEvent('singleShow'); break; |
171 | | - default: assert_unreached(); |
172 | | - } |
173 | | - break; |
174 | | - case "closed": |
175 | | - switch (e.oldState) { |
176 | | - case "closed": setEvent('coalescedHide'); break; |
177 | | - case "open": setEvent('singleHide'); break; |
178 | | - default: assert_unreached(); |
179 | | - } |
180 | | - break; |
181 | | - default: assert_unreached(); |
182 | | - } |
183 | | - }, {signal}); |
184 | | - |
185 | | - resetEvents(); |
186 | | - assertOnly('none'); |
187 | | - assert_false(popover.matches(':open')); |
188 | | - popover.showPopover(); |
189 | | - await waitForRender(); |
190 | | - assert_true(popover.matches(':open')); |
191 | | - assertOnly('singleShow','Single event should have been fired, which is a "show"'); |
192 | | - |
193 | | - resetEvents(); |
194 | | - popover.hidePopover(); |
195 | | - popover.showPopover(); // Immediate re-show |
196 | | - await waitForRender(); |
197 | | - assert_true(popover.matches(':open')); |
198 | | - assertOnly('coalescedShow','Single coalesced event should have been fired, which is a "show"'); |
199 | | - |
200 | | - resetEvents(); |
201 | | - popover.hidePopover(); |
202 | | - await waitForRender(); |
203 | | - assertOnly('singleHide','Single event should have been fired, which is a "hide"'); |
204 | | - assert_false(popover.matches(':open')); |
205 | | - |
206 | | - resetEvents(); |
207 | | - popover.showPopover(); |
208 | | - popover.hidePopover(); // Immediate re-hide |
209 | | - await waitForRender(); |
210 | | - assertOnly('coalescedHide','Single coalesced event should have been fired, which is a "hide"'); |
211 | | - assert_false(popover.matches(':open')); |
212 | | - }, 'The "toggle" event is coalesced'); |
213 | 147 | }; |
214 | 148 | </script> |
0 commit comments