Skip to content

Commit

Permalink
Make dialog focus async when removing open attribute
Browse files Browse the repository at this point in the history
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 3419353
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
  • Loading branch information
josepharhar authored and chromium-wpt-export-bot committed Jan 6, 2025
1 parent 00162eb commit e36b66f
Showing 1 changed file with 18 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,34 @@
<script src="/resources/testdriver-vendor.js"></script>

<button>button</button>
<dialog>hello world</dialog>
<dialog>
<button>button in dialog</button>
</dialog>

<script>
const dialog = document.querySelector('dialog');
const button = document.querySelector('button');
const dialogbutton = document.querySelector('dialog > button');

promise_test(async t => {
button.focus();
dialog.showModal();
assert_equals(document.activeElement, dialogbutton,
'<button> in <dialog> should be focused after opening.');

let closeFired = false;
let cancelFired = false;
dialog.addEventListener('close', () => closeFired = true);
dialog.addEventListener('cancel', () => cancelFired = true);

dialog.removeAttribute('open');
assert_equals(document.activeElement, dialogbutton,
'<button> in <dialog> should still be focused immediately after removing open.');
await new Promise(resolve => t.step_timeout(resolve, 0));
await new Promise(requestAnimationFrame);

assert_equals(document.activeElement, button,
'Previously focused element should be focused after waiting for a task.');
assert_false(dialog.matches(':modal'),
'The dialog should not match :modal after closing.');
assert_false(cancelFired,
Expand All @@ -40,17 +50,24 @@
}, 'Removing the open attribute from an open modal dialog should run the closing algorithm.');

promise_test(async t => {
button.focus();
dialog.show();
assert_equals(document.activeElement, dialogbutton,
'<button> in <dialog> should be focused after opening.');

let closeFired = false;
let cancelFired = false;
dialog.addEventListener('close', () => closeFired = true);
dialog.addEventListener('cancel', () => cancelFired = true);

dialog.removeAttribute('open');
assert_equals(document.activeElement, dialogbutton,
'<button> in <dialog> should still be focused immediately after removing open.');
await new Promise(resolve => t.step_timeout(resolve, 0));
await new Promise(requestAnimationFrame);

assert_equals(document.activeElement, button,
'Previously focused element should be focused after waiting for a task.');
assert_false(cancelFired,
'The cancel event should not fire when removing the open attribute.');
assert_true(closeFired,
Expand Down

0 comments on commit e36b66f

Please sign in to comment.