1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<link rel="author" href="mailto:masonf@chromium.org">
<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>
<div id=unrelated>Unrelated</div>
<dialog id=dialog_outer>Dialog outer
<div id=popover_inner popover>Popover inner</div>
</dialog>
<div id=popover_outer popover>Popover outer
<dialog id=dialog_inner>Dialog inner</dialog>
</div>
<style>
dialog { top: 50px; bottom: auto; padding:0; }
[popover] { top: 100px; bottom: auto; padding:0; }
</style>
<script>
function resetDialogOuterTest(dialog,popover) {
popover.hidePopover();
dialog.close();
dialog.showModal();
popover.showPopover();
assert_true(dialog.open && popover.matches(':popover-open'),'setup');
}
async function runDialogOuterTest(t,dialog,popover) {
t.add_cleanup(() => {
dialog.removeAttribute('closedby');
popover.hidePopover();
dialog.close();
});
resetDialogOuterTest(dialog,popover);
await clickOn(popover);
assert_true(popover.matches(':popover-open'),
'clicking on popover should always leave everything open');
assert_true(dialog.open,'dialog should stay open');
resetDialogOuterTest(dialog,popover);
await clickOn(dialog);
assert_false(popover.matches(':popover-open'),'popover should close');
assert_true(dialog.open,'dialog should stay open');
resetDialogOuterTest(dialog,popover);
await clickOn(unrelated);
assert_false(popover.matches(':popover-open'),'popover should always close');
assert_equals(dialog.open,dialog.closedBy !== 'any',
'dialog should close if closedby=any');
resetDialogOuterTest(dialog,popover);
const ESC = '\uE00C';
await test_driver.send_keys(document.documentElement,ESC);
assert_false(popover.matches(':popover-open'),
'popover should close after first ESC');
assert_true(dialog.open,'dialog should stay open for first ESC');
await test_driver.send_keys(document.documentElement,ESC);
assert_equals(dialog.open,dialog.closedBy === 'none',
'dialog should close on second ESC, if closedby is not none');
}
promise_test(async (t) => {
dialog_outer.setAttribute('closedby','any');
await runDialogOuterTest(t,dialog_outer,popover_inner);
},'Dialog closedby=any parent, popover child');
promise_test(async (t) => {
dialog_outer.setAttribute('closedby','closerequest');
await runDialogOuterTest(t,dialog_outer,popover_inner);
},'Dialog closedby=closerequest parent, popover child');
promise_test(async (t) => {
dialog_outer.setAttribute('closedby','none');
await runDialogOuterTest(t,dialog_outer,popover_inner);
},'Dialog closedby=none parent, popover child');
function resetPopoverOuterTest(dialog,popover) {
dialog.close();
popover.hidePopover();
popover.showPopover();
dialog.showModal();
assert_true(dialog.open && popover.matches(':popover-open'),'setup');
}
async function runPopoverOuterTest(t,dialog,popover) {
t.add_cleanup(() => {
dialog.removeAttribute('closedby');
dialog.close();
popover.hidePopover();
});
resetPopoverOuterTest(dialog,popover);
await clickOn(dialog);
assert_true(dialog.open,'clicking on dialog should always leave everything open');
assert_true(popover.matches(':popover-open'),'popover should stay open');
resetPopoverOuterTest(dialog,popover);
await clickOn(popover);
assert_equals(dialog.open,dialog.closedBy !== 'any',
'dialog should close if closedby=any');
// Note that "clicking on" popover really means clicking on dialog's
// ::backdrop, and the dialog is a child of the popover. So by popover's light
// dismiss logic, it will *not* close. That's semi-expected here, but not in
// the next case.
assert_true(popover.matches(':popover-open'),'popover should stay open');
resetPopoverOuterTest(dialog,popover);
await clickOn(unrelated);
assert_equals(dialog.open,dialog.closedBy !== 'any',
'dialog should close if closedby=any');
// See note above.
assert_true(popover.matches(':popover-open'),'popover should stay open');
if (!dialog.open) {
// If we light dismissed the dialog, check that the popover responds to a
// second click.
await clickOn(unrelated);
assert_false(popover.matches(':popover-open'),'popover should stay open');
}
resetPopoverOuterTest(dialog,popover);
const ESC = '\uE00C';
await test_driver.send_keys(document.documentElement,ESC);
assert_equals(dialog.open,dialog.closedBy === 'none',
'dialog should close after first ESC, if closedby!=none');
assert_true(popover.matches(':popover-open'),
'popover should stay open for first ESC');
await test_driver.send_keys(document.documentElement,ESC);
assert_equals(popover.matches(':popover-open'),dialog.closedBy === 'none',
'popover should close on second ESC, unless inner dialog prevents with closedby==none');
}
promise_test(async (t) => {
dialog_inner.setAttribute('closedby','any');
await runPopoverOuterTest(t,dialog_inner,popover_outer);
},'Popover parent, dialog closedby=any child');
promise_test(async (t) => {
dialog_inner.setAttribute('closedby','closerequest');
await runPopoverOuterTest(t,dialog_inner,popover_outer);
},'Popover parent, dialog closedby=closerequest child');
promise_test(async (t) => {
dialog_inner.setAttribute('closedby','none');
await runPopoverOuterTest(t,dialog_inner,popover_outer);
},'Popover parent, dialog closedby=none child');
</script>
|