Skip to content

Commit

Permalink
[inert] Add WPTs for interaction of inert attribute with modal dialog
Browse files Browse the repository at this point in the history
https://html.spec.whatwg.org/multipage/interaction.html#inert is clear:

> While document is so blocked [by a modal dialog], every node that is
> connected to document, with the exception of the subject element and
> its shadow-including descendants, must be marked inert. (The elements
> excepted by this paragraph can additionally be marked inert through
> other means; being part of a modal dialog does not "protect" a node
> from being marked inert.)

However, both Firefox and WebKit ignore this, and let modal dialogs
escape the inertness set by an ancestor with the 'inert' attribute.

There is also an interesting case: when the modal dialog is the root
element. Firefox handles this fine, but Chromium used to fail the test,
and WebKit directly crashes.

Bug: 692360
Change-Id: Ie52201a1f31790392180c96a9e08be1b5eee86d8
  • Loading branch information
Loirooriol authored and chromium-wpt-export-bot committed Nov 18, 2021
1 parent 08fb0f8 commit 64f0950
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
55 changes: 55 additions & 0 deletions inert/inert-with-modal-dialog-001.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Interaction of 'inert' attribute with modal dialog</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert">
<meta name="assert" content="Checks that being part of a modal dialog does not protect a node from being marked inert by an 'inert' attribute.">
<div id="log"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const child = document.createElement("span");
const dialog = document.createElement("dialog");
const wrapper = document.createElement("div");

setup(() => {
child.append("(child)");
dialog.append("[dialog]", child);
wrapper.append("{wrapper}", dialog);
document.body.append(wrapper);
dialog.showModal();
add_completion_callback(() => {
wrapper.remove();
getSelection().removeAllRanges();
});
});

function checkSelection(expectedText) {
const commandDidWork = document.execCommand("selectAll");
assert_true(commandDidWork);
const actualText = getSelection().toString().trim();
assert_equals(actualText, expectedText);
}

test(function() {
checkSelection("[dialog](child)");
}, "Modal dialog only marks outside nodes as inert");

test(function() {
child.inert = true;
this.add_cleanup(() => { child.inert = false; });
checkSelection("[dialog]");
}, "Inner nodes with 'inert' attribute become inert anyways");

test(function() {
dialog.inert = true;
this.add_cleanup(() => { dialog.inert = false; });
checkSelection("");
}, "If the modal dialog has the 'inert' attribute, everything becomes inert");

test(function() {
wrapper.inert = true;
this.add_cleanup(() => { wrapper.inert = false; });
checkSelection("");
}, "Ditto if it's an ancestor who has the 'inert' attribute");
</script>
63 changes: 63 additions & 0 deletions inert/inert-with-modal-dialog-002.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<title>Interaction of 'inert' attribute with modal dialog, when the dialog is the root element</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert">
<meta name="assert" content="Checks that being part of a modal dialog does not protect a node from being marked inert by an 'inert' attribute.">
<div id="log"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const child = document.createElement("span");
const dialog = document.createElement("dialog");
const root = document.documentElement;

setup(() => {
child.append("(child)");
dialog.append("[dialog]", child);
root.remove();
document.append(dialog);
dialog.showModal();
add_completion_callback(() => {
getSelection().removeAllRanges();
});
});

function checkSelection(expectedText) {
let commandDidWork = document.execCommand("selectAll");
if (!commandDidWork) {
// Firefox seems to require editability in order to be able to run
// execCommand("selectAll") when document.body is null.
// Note Chromium doesn't need it, and it would actually try to tidy
// the document structure, so the dialog would no longer be the root.
document.designMode = "on";
commandDidWork = document.execCommand("selectAll");
document.designMode = "off";
assert_true(commandDidWork);
}
assert_equals(document.documentElement, dialog);
const actualText = getSelection().toString().trim();
assert_equals(actualText, expectedText);
}

test(function() {
checkSelection("[dialog](child)");
}, "Modal dialog only marks outside nodes as inert");

test(function() {
child.inert = true;
this.add_cleanup(() => { child.inert = false; });
checkSelection("[dialog]");
}, "Inner nodes with 'inert' attribute become inert anyways");

test(function() {
dialog.inert = true;
this.add_cleanup(() => { dialog.inert = false; });
checkSelection("");
}, "If the modal dialog has the 'inert' attribute, everything becomes inert");

// Ideally this would happen in a completion callback, but then it would
// be too late: the results would have been show inside the dialog.
dialog.remove();
document.append(root);
</script>

0 comments on commit 64f0950

Please sign in to comment.