LibWeb: Implement the ToggleEvent.source attribute

See: https://github.com/whatwg/html/pull/11186
This commit is contained in:
Gingeh 2025-06-04 15:35:43 +10:00 committed by Tim Ledbetter
parent 82f9b51da6
commit fc35229dab
Notes: github-actions[bot] 2025-06-07 03:07:15 +00:00
13 changed files with 297 additions and 88 deletions

View file

@ -0,0 +1,13 @@
Harness status: OK
Found 7 tests
4 Pass
3 Fail
Pass ToggleEvent.source on popover elements: showPopover() without source.
Fail ToggleEvent.source on popover elements: showPopover() with source.
Pass ToggleEvent.source on popover elements: Calling click() on a popovertarget button.
Fail ToggleEvent.source on popover elements: Calling click() on a command button.
Pass ToggleEvent.source on popover elements: showPopover() then popovertarget button.
Fail ToggleEvent.source on popover elements: showPopover(invoker) then popovertarget button.
Pass ToggleEvent.source on popover elements: popovertarget button then hidePopover().

View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=help href="https://github.com/whatwg/html/issues/9111">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="resources/toggle-event-source-test.js"></script>
<button id=popoversource popovertarget=popover>popovertarget source</button>
<button id=commandsource commandfor=popover command=show-popover>command source</button>
<div id=popover popover=auto>
popover
<button id=popoversourcehide popovertarget=popover>popovertarget source</button>
<button id=commandsourcehide commandfor=popover command=hide-popover>command source</button>
</div>
<script>
const popoversource = document.getElementById('popoversource');
const popoversourcehide = document.getElementById('popoversourcehide');
const commandsource = document.getElementById('commandsource');
const commandsourcehide = document.getElementById('commandsourcehide');
const popover = document.getElementById('popover');
let beforetoggleEvent = null;
let toggleEvent = null;
popover.addEventListener('beforetoggle', event => beforetoggleEvent = event);
popover.addEventListener('toggle', event => toggleEvent = event);
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: showPopover() without source.',
target: popover,
openFunc: async () => popover.showPopover(),
closeFunc: async () => popover.hidePopover(),
openSource: null,
closeSource: null
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: showPopover() with source.',
target: popover,
openFunc: async () => popover.showPopover({source: popoversource}),
closeFunc: async () => popover.hidePopover(),
openSource: popoversource,
closeSource: null
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: Calling click() on a popovertarget button.',
target: popover,
openFunc: async () => popoversource.click(),
closeFunc: async () => popoversourcehide.click(),
openSource: popoversource,
closeSource: popoversourcehide
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: Calling click() on a command button.',
target: popover,
openFunc: async () => commandsource.click(),
closeFunc: async () => commandsourcehide.click(),
openSource: commandsource,
closeSource: commandsourcehide
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: showPopover() then popovertarget button.',
target: popover,
openFunc: async () => popover.showPopover(),
closeFunc: async () => popoversourcehide.click(),
openSource: null,
closeSource: popoversourcehide
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: showPopover(invoker) then popovertarget button.',
target: popover,
openFunc: async () => popover.showPopover({source: popoversource}),
closeFunc: async () => popoversourcehide.click(),
openSource: popoversource,
closeSource: popoversourcehide
});
createToggleEventSourceTest({
description: 'ToggleEvent.source on popover elements: popovertarget button then hidePopover().',
target: popover,
openFunc: async () => popoversource.click(),
closeFunc: async () => popover.hidePopover(),
openSource: popoversource,
closeSource: null
});
</script>

View file

@ -0,0 +1,76 @@
function createToggleEventSourceTest({
description,
target,
openFunc,
closeFunc,
openSource,
closeSource,
skipBeforetoggle}) {
promise_test(async () => {
let beforetoggleEvent = null;
let beforetoggleDuplicate = false;
let toggleEvent = null;
let toggleDuplicate = false;
target.addEventListener('beforetoggle', event => {
if (beforetoggleEvent) {
beforetoggleDuplicate = true;
}
beforetoggleEvent = event;
});
target.addEventListener('toggle', event => {
if (toggleEvent) {
toggleDuplicate = true;
}
toggleEvent = event;
});
await openFunc();
await new Promise(requestAnimationFrame);
await new Promise(requestAnimationFrame);
if (!skipBeforetoggle) {
assert_true(!!beforetoggleEvent,
'An opening beforetoggle event should have been fired.');
assert_false(beforetoggleDuplicate,
'Only one opening beforetoggle event should have been fired.');
assert_equals(beforetoggleEvent.newState, 'open',
'beforetoggle newState should be open.');
assert_equals(beforetoggleEvent.source, openSource,
'Opening beforetoggle.source.');
}
assert_true(!!toggleEvent,
'An opening toggle event should have been fired.');
assert_false(toggleDuplicate,
'Only one opening toggle event should have been fired.');
assert_equals(toggleEvent.newState, 'open',
'toggle newstate should be open.');
assert_equals(toggleEvent.source, openSource,
'Opening toggle.source.');
beforetoggleEvent = null;
beforetoggleDuplicate = false;
toggleEvent = null;
toggleDuplicate = false;
await closeFunc();
await new Promise(requestAnimationFrame);
await new Promise(requestAnimationFrame);
if (!skipBeforetoggle) {
assert_true(!!beforetoggleEvent,
'A closing beforetoggle event should have been fired.');
assert_false(beforetoggleDuplicate,
'Only one closing beforetoggle event should have been fired.');
assert_equals(beforetoggleEvent.newState, 'closed',
'beforetoggle newState should be closed.');
assert_equals(beforetoggleEvent.source, closeSource,
'Closing beforetoggle.source.');
}
assert_true(!!toggleEvent,
'A closing toggle event should have been fired.');
assert_false(toggleDuplicate,
'Only one closing toggle event should have been fired.');
assert_equals(toggleEvent.newState, 'closed',
'toggle newstate should be closed.');
assert_equals(toggleEvent.source, closeSource,
'Closing toggle.source.');
}, description);
}