Skip to content

Commit

Permalink
Implement basic structure for dialog light dismiss [1/N]
Browse files Browse the repository at this point in the history
This CL puts the feature flag in place, adds (flag guarded) closedBy
and requestClose() methods to <dialog>, connects the pointer
events handling to a new dialog light dismiss method, and adds a
basic set of tests. None of the actual functionality is here yet,
this is just a shell. Subsequent CLs will flesh out the behavior.

See spec PR for details:
  whatwg/html#10737

Here's the chromestatus:
  https://chromestatus.com/feature/5097714453577728

Bug: 376516550
Change-Id: I3727ca21476a2a3340fd18597970395d64ef7176
  • Loading branch information
mfreed7 authored and chromium-wpt-export-bot committed Nov 5, 2024
1 parent b0c05ab commit 0afd0d8
Showing 1 changed file with 86 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<!doctype html>
<meta charset="utf-8">
<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#dialog-light-dismiss">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="../../popovers/resources/popover-utils.js"></script>

<button id="outside">Outside</button>

<!-- test cases: -->
<dialog closedby="any" data-behavior="any"></dialog>
<dialog closedby="closerequest" data-behavior="closerequest"></dialog>
<dialog closedby="none" data-behavior="none"></dialog>

<dialog closedby data-behavior="closerequest"></dialog>
<dialog closedby="invalid" data-behavior="closerequest"></dialog>
<dialog data-behavior="closerequest"></dialog>

<dialog closedby="AnY" data-behavior="any"></dialog>
<dialog closedby="ClOsErEqUeSt" data-behavior="closerequest"></dialog>
<dialog closedby="NoNe" data-behavior="none"></dialog>

<script>
function openDialog(dialog,modal) {
assert_false(dialog.open);
if (modal) {
dialog.showModal();
} else {
dialog.show();
}
assert_true(dialog.open);
assert_equals(dialog.matches(':modal'),modal);
}
function runTest(dialog) {
for(modal of [false,true]) {
promise_test(async (t) => {
assert_false(dialog.open);
t.add_cleanup(() => dialog.close());
// Try hitting ESC
openDialog(dialog,modal);
const ESC = '\uE00C';
await new test_driver.send_keys(document.documentElement,ESC);
const respondsToEsc = !dialog.open;
dialog.close();
// Try clicking outside
openDialog(dialog,modal);
await clickOn(outside);
const respondsToLightDismiss = !dialog.open;
dialog.close();
// See if expectations match
switch (dialog.dataset.behavior) {
case 'any':
assert_true(respondsToEsc,'Dialog should respond to ESC');
assert_true(respondsToLightDismiss,'Dialog should respond to light dismiss');
break;
case 'closerequest':
assert_true(respondsToEsc,'Dialog should respond to ESC');
assert_false(respondsToLightDismiss,'Dialog should NOT respond to light dismiss');
break;
case 'none':
assert_false(respondsToEsc,'Dialog should NOT respond to ESC');
assert_false(respondsToLightDismiss,'Dialog should NOT respond to light dismiss');
break;
default:
assert_notreached('Invalid expectation');
}
// Check reflection
assert_equals(dialog.closedBy,dialog.dataset.behavior,'Reflection should be limited to known values');
}, `closedby=${dialog.getAttribute('closedby')}, ${modal ? 'Modal' : 'Non-modal'}`);
}
}

// Add close button, in case of manual testing
const testDialogs = document.querySelectorAll('dialog');
testDialogs.forEach(dialog => {
const button = dialog.appendChild(document.createElement('button'));
button.innerText = 'Close';
button.addEventListener('click',() => dialog.close());
});

// Run tests
testDialogs.forEach(runTest);
</script>

0 comments on commit 0afd0d8

Please sign in to comment.