Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!doctype html>
<meta charset="utf-8" />
<meta name="author" title="Luke Warlow" href="mailto:luke@warlow.dev" />
<meta name="timeout" content="long" />
<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="resources/invoker-utils.js"></script>
<details id="invokee">Details Contents</details>
<button id="invokerbutton" invoketarget="invokee"></button>
<script>
function resetState() {
invokerbutton.removeAttribute("invokeaction");
invokee.removeAttribute("open");
}
// Open actions
[
null,
"",
"toggle",
"open",
/* test case sensitivity */
"tOgGlE",
"oPeN",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed details opens`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
assert_false(invokee.matches("[open]"));
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
await clickOn(invokerbutton);
t.add_cleanup(() => invokee.removeAttribute("open"));
assert_false(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) closed details with preventDefault does not open`,
);
});
// Close actions
[
null,
"",
"toggle",
"close",
/* test case sensitivity */
"tOgGlE",
"cLoSe",
].forEach((action) => {
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
invokee.setAttribute("open", "");
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open details closes`,
);
promise_test(
async function (t) {
t.add_cleanup(resetState);
if (action !== null) invokerbutton.invokeAction = action;
invokee.setAttribute("open", "");
invokerbutton.setAttribute("invokeaction", "toggle");
invokee.addEventListener("invoke", (e) => e.preventDefault(), {
once: true,
});
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
},
`invoking (as ${
action === null ? "auto" : action || "explicit empty"
}) open details with prevent default closes`,
);
});
// toggle specific
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = "toggle";
invokee.addEventListener(
"invoke",
(e) => {
invokee.setAttribute("open", "");
},
{
once: true,
},
);
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking (as toggle) closed details where event listener opens leads to a closed details");
// open specific
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = "open";
invokee.setAttribute("open", "");
assert_true(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_true(invokee.matches("[open]"));
}, "invoking open details with open action is noop");
// close
promise_test(async function (t) {
t.add_cleanup(resetState);
invokerbutton.invokeAction = "close";
assert_false(invokee.matches("[open]"));
await clickOn(invokerbutton);
assert_false(invokee.matches("[open]"));
}, "invoking closed details with close action is noop");
</script>