servo/tests/wpt/web-platform-tests/css/css-toggle/toggle-activation.tentative.html

489 lines
21 KiB
HTML

<!DOCTYPE HTML>
<meta charset="UTF-8">
<title>CSS Toggles: activation of toggles</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://tabatkins.github.io/css-toggle/#toggle-trigger-property">
<link rel="help" href="https://tabatkins.github.io/css-toggle/#fire-a-toggle-activation">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/toggle-helpers.js"></script>
<style>
:toggle(finding-test 0) { --finding-test:0; }
:toggle(finding-test 1) { --finding-test:1; }
:toggle(test-states 0) { --test-states:0; }
:toggle(test-states 1) { --test-states:1; }
:toggle(test-states 2) { --test-states:2; }
:toggle(test-group 0) { --test-group:0; }
:toggle(test-group 1) { --test-group:1; }
:toggle(test-overflow 0) { --test-overflow:0; }
:toggle(test-overflow 1) { --test-overflow:1; }
:toggle(set-num 0) { --set-num:0; }
:toggle(set-num 1) { --set-num:1; }
:toggle(set-num 2) { --set-num:2; }
:toggle(set-names zero) { --set-names:0; }
:toggle(set-names one) { --set-names:1; }
:toggle(set-names two) { --set-names:2; }
:toggle(set-names three) { --set-names:3; }
</style>
<body>
<div id="container"></div>
<script>
let container = document.getElementById("container");
let toggle_finding_tests = [
{
description: "wide toggle on previous sibling",
markup: `<div>
<div id="toggle"></div>
<div id="target"></div>
</div>`,
found: true
},
{
description: "narrow toggle on previous sibling",
markup: `<div>
<div id="toggle"></div>
<div id="target"></div>
</div>`,
found: false,
self: true
},
{
description: "wide toggle on previous sibling with intervening narrow toggle",
markup: `<div>
<div id="toggle"></div>
<div style="toggle: finding-test self"></div>
<div id="target"></div>
</div>`,
found: true
},
{
description: "wide toggle on parent with intervening narrow toggle",
markup: `<div id="toggle">
<div style="toggle: finding-test self"></div>
<div id="target"></div>
</div>`,
found: true
},
{
description: "wide toggle on parent's prior sibling with intervening narrow toggle",
markup: `<div id="toggle"></div>
<div>
<div style="toggle: finding-test self"></div>
<div id="target"></div>
</div>`,
found: true
},
{
description: "wide toggle on later sibling",
markup: `<div id="target"></div>
<div id="toggle"></div>`,
found: false
},
{
description: "wide toggle on child",
markup: `<div id="target">
<div id="toggle"></div>
</div>`,
found: false
}
];
for (let toggle_finding_test of toggle_finding_tests) {
promise_test(async function() {
container.innerHTML = toggle_finding_test.markup;
let toggle = document.getElementById("toggle");
let toggle_cs = getComputedStyle(toggle);
let target = document.getElementById("target");
let toggle_root_style = "finding-test";
if (toggle_finding_test.self) {
toggle_root_style += " self";
}
toggle.style.toggleRoot = toggle_root_style;
target.style.toggleTrigger = "finding-test";
await wait_for_toggle_creation(toggle);
assert_true(toggle.matches(':toggle(finding-test 0)'),
"matches before click");
assert_equals(toggle_cs.getPropertyValue("--finding-test"), "0",
"computed style before click");
target.click();
if (toggle_finding_test.found) {
assert_true(toggle.matches(':toggle(finding-test 1)'),
"matches after click");
assert_equals(toggle_cs.getPropertyValue("--finding-test"), "1",
"computed style after click");
} else {
assert_true(toggle.matches(':toggle(finding-test 0)'),
"matches after click");
assert_equals(toggle_cs.getPropertyValue("--finding-test"), "0",
"computed style after click");
}
}, `finding toggle: ${toggle_finding_test.description}`);
}
promise_test(async function() {
let e = await set_up_single_toggle_in(container, "test-states 1 at 0");
let cs = getComputedStyle(e);
assert_true(e.matches(":toggle(test-states 0)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
assert_true(e.matches(":toggle(test-states 1)"));
assert_equals(cs.getPropertyValue("--test-states"), "1");
e.click();
assert_true(e.matches(":toggle(test-states 0)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.style.toggleRoot = "test-states 2 at 2";
await wait_for_toggle_creation(e);
assert_true(e.matches(":toggle(test-states 0)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
e.click();
assert_true(e.matches(":toggle(test-states 2)"));
assert_equals(cs.getPropertyValue("--test-states"), "2");
e.style.toggleRoot = "";
await wait_for_toggle_creation(e);
assert_true(e.matches(":toggle(test-states 2)"));
assert_equals(cs.getPropertyValue("--test-states"), "2");
e.click();
assert_true(e.matches(":toggle(test-states 0)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
assert_true(e.matches(":toggle(test-states 1)"));
assert_equals(cs.getPropertyValue("--test-states"), "1");
e.click();
assert_true(e.matches(":toggle(test-states 0)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
}, "states used from toggle or toggle specifier as appropriate (integer)");
promise_test(async function() {
let e = await set_up_single_toggle_in(container, "test-states [one two] at 0");
let cs = getComputedStyle(e);
let t = e.toggles.get("test-states");
assert_equals(t.value, 0);
assert_true(e.matches(":toggle(test-states 0)"));
assert_true(e.matches(":toggle(test-states one)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
assert_equals(t.value, "two");
assert_true(e.matches(":toggle(test-states 1)"));
assert_true(e.matches(":toggle(test-states two)"));
assert_equals(cs.getPropertyValue("--test-states"), "1");
e.click();
assert_equals(t.value, "one");
assert_true(e.matches(":toggle(test-states 0)"));
assert_true(e.matches(":toggle(test-states one)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.style.toggleRoot = "test-states [zero one two] at 2";
await wait_for_toggle_creation(e);
assert_equals(t.value, "one");
assert_true(e.matches(":toggle(test-states 0)"));
assert_true(e.matches(":toggle(test-states one)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
assert_equals(t.value, "two");
assert_true(e.matches(":toggle(test-states 1)"));
assert_true(e.matches(":toggle(test-states two)"));
assert_equals(cs.getPropertyValue("--test-states"), "1");
e.click();
assert_equals(t.value, "zero");
assert_true(e.matches(":toggle(test-states zero)"));
assert_equals(cs.getPropertyValue("--test-states"), "");
e.style.toggleRoot = "";
await wait_for_toggle_creation(e);
assert_equals(t.value, "zero");
assert_true(e.matches(":toggle(test-states zero)"));
assert_equals(cs.getPropertyValue("--test-states"), "");
e.click();
assert_equals(t.value, "one");
assert_true(e.matches(":toggle(test-states 0)"));
assert_true(e.matches(":toggle(test-states one)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
e.click();
assert_equals(t.value, "two");
assert_true(e.matches(":toggle(test-states 1)"));
assert_true(e.matches(":toggle(test-states two)"));
assert_equals(cs.getPropertyValue("--test-states"), "1");
e.click();
assert_equals(t.value, "one");
assert_true(e.matches(":toggle(test-states 0)"));
assert_true(e.matches(":toggle(test-states one)"));
assert_equals(cs.getPropertyValue("--test-states"), "0");
}, "states used from toggle or toggle specifier as appropriate (names)");
promise_test(async function() {
container.innerHTML = `
<div style="toggle-group: test-group">
<div id="t" style="toggle: test-group 1 at 0 group"></div>
<div id="other" style="toggle: test-group 1 at 0 group"></div>
</div>
`;
let t = document.getElementById("t");
let other = document.getElementById("other");
let t_cs = getComputedStyle(t);
let other_cs = getComputedStyle(other);
await wait_for_toggle_creation(t);
await wait_for_toggle_creation(other);
other.click();
assert_true(t.matches(":toggle(test-group 0)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "0");
assert_true(other.matches(":toggle(test-group 1)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "1");
t.click();
assert_true(t.matches(":toggle(test-group 1)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "1");
assert_true(other.matches(":toggle(test-group 0)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "0");
other.click();
assert_true(t.matches(":toggle(test-group 0)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "0");
assert_true(other.matches(":toggle(test-group 1)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "1");
// Test that we use the group value from the toggle specifier when it's
// different from the toggle, but only when that's the toggle we're
// changing.
t.style.toggleRoot = "test-group 1 at 0";
t.click();
assert_true(t.matches(":toggle(test-group 1)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "1");
assert_true(other.matches(":toggle(test-group 1)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "1");
other.click();
assert_true(t.matches(":toggle(test-group 1)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "1");
assert_true(other.matches(":toggle(test-group 0)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "0");
other.click();
assert_true(t.matches(":toggle(test-group 0)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "0");
assert_true(other.matches(":toggle(test-group 1)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "1");
// Test that we use the group value from the toggle when there is no toggle
// specifier.
t.style.toggleRoot = "";
t.click();
assert_true(t.matches(":toggle(test-group 1)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "1");
assert_true(other.matches(":toggle(test-group 0)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "0");
other.click();
assert_true(t.matches(":toggle(test-group 0)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "0");
assert_true(other.matches(":toggle(test-group 1)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "1");
other.click();
assert_true(t.matches(":toggle(test-group 0)"));
assert_equals(t_cs.getPropertyValue("--test-group"), "0");
assert_true(other.matches(":toggle(test-group 0)"));
assert_equals(other_cs.getPropertyValue("--test-group"), "0");
}, "group used from toggle or toggle specifier as appropriate");
promise_test(async function() {
let e = await set_up_single_toggle_in(container, "test-overflow sticky");
let cs = getComputedStyle(e);
assert_true(e.matches(":toggle(test-overflow 0)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "0");
e.click();
assert_true(e.matches(":toggle(test-overflow 1)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "1");
e.click();
assert_true(e.matches(":toggle(test-overflow 1)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "1");
e.style.toggleRoot = "test-overflow";
await wait_for_toggle_creation(e);
assert_true(e.matches(":toggle(test-overflow 1)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "1");
e.click();
assert_true(e.matches(":toggle(test-overflow 0)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "0");
e.style.toggleRoot = "";
await wait_for_toggle_creation(e);
assert_true(e.matches(":toggle(test-overflow 0)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "0");
e.click();
assert_true(e.matches(":toggle(test-overflow 1)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "1");
e.click();
assert_true(e.matches(":toggle(test-overflow 1)"));
assert_equals(cs.getPropertyValue("--test-overflow"), "1");
}, "overflow used from toggle or toggle specifier as appropriate");
promise_test(async function() {
container.innerHTML = `<div id="t" style="toggle-root: set-num 5 at 1"></div>
<div id="a" style="toggle-trigger: set-num set 2"></div>
<div id="b" style="toggle-trigger: set-num set 0"></div>
<div id="c" style="toggle-trigger: set-num set named-state"></div>
<div id="m"></div>
`;
let t = document.getElementById("t");
let a = document.getElementById("a");
let b = document.getElementById("b");
let c = document.getElementById("c");
let m = document.getElementById("m");
let cs = getComputedStyle(m);
await wait_for_toggle_creation(t);
assert_true(m.matches(':toggle(set-num 1)'), "initial state");
assert_equals(cs.getPropertyValue("--set-num"), "1");
a.click();
assert_true(m.matches(':toggle(set-num 2)'), "state after clicking a");
assert_equals(cs.getPropertyValue("--set-num"), "2");
b.click();
assert_true(m.matches(':toggle(set-num 0)'), "state after clicking b");
assert_equals(cs.getPropertyValue("--set-num"), "0");
c.click();
assert_true(m.matches(':toggle(set-num named-state)'), "state after clicking c");
assert_equals(cs.getPropertyValue("--set-num"), "");
}, "changing with toggle-trigger: set (numbers)");
promise_test(async function() {
container.innerHTML = `<div id="t" style="toggle-root: set-names [zero one two three four five] at two"></div>
<div id="a" style="toggle-trigger: set-names set one"></div>
<div id="b" style="toggle-trigger: set-names set 3"></div>
<div id="c" style="toggle-trigger: set-names set zero"></div>
<div id="d" style="toggle-trigger: set-names set named-state"></div>
<div id="m"></div>
`;
let t = document.getElementById("t");
let a = document.getElementById("a");
let b = document.getElementById("b");
let c = document.getElementById("c");
let d = document.getElementById("d");
let m = document.getElementById("m");
let cs = getComputedStyle(m);
await wait_for_toggle_creation(t);
assert_true(m.matches(':toggle(set-names two)'));
assert_true(m.matches(':toggle(set-names 2)'));
assert_equals(cs.getPropertyValue("--set-names"), "2");
a.click();
assert_true(m.matches(':toggle(set-names one)'));
assert_true(m.matches(':toggle(set-names 1)'));
assert_equals(cs.getPropertyValue("--set-names"), "1");
b.click();
assert_true(m.matches(':toggle(set-names three)'));
assert_true(m.matches(':toggle(set-names 3)'));
assert_equals(cs.getPropertyValue("--set-names"), "3");
c.click();
assert_true(m.matches(':toggle(set-names zero)'));
assert_true(m.matches(':toggle(set-names 0)'));
assert_equals(cs.getPropertyValue("--set-names"), "0");
d.click();
assert_true(m.matches(':toggle(set-names named-state)'));
assert_false(m.matches(':toggle(set-names 0)'));
assert_equals(cs.getPropertyValue("--set-names"), "");
b.click();
assert_true(m.matches(':toggle(set-names 3)'));
assert_equals(cs.getPropertyValue("--set-names"), "3");
d.click();
assert_false(m.matches(':toggle(set-names 3)'));
assert_equals(cs.getPropertyValue("--set-names"), "");
}, "changing with toggle-trigger: set (named states)");
function test_action_and_cycle(states_and_cycle, start, action, result) {
promise_test(async function() {
container.innerHTML = `
<div id="toggle" style="toggle-root: test ${states_and_cycle}"></div>
<div id="start" style="toggle-trigger: test set ${start}"></div>
<div id="action" style="toggle-trigger: test ${action}"></div>
`;
let toggle = document.getElementById("toggle");
await wait_for_toggle_creation(toggle);
document.getElementById("start").click();
assert_true(toggle.matches(`:toggle(test ${start})`), "value after set");
document.getElementById("action").click();
assert_true(toggle.matches(`:toggle(test ${result})`), "value after action");
}, `toggle with "${states_and_cycle}" changing from "${start}" with action "${action}"`);
}
function test_action_and_all_cycles(states, start, action, result_cycle, result_cycle_on, result_sticky) {
test_action_and_cycle(states, start, action, result_cycle);
test_action_and_cycle(`${states} cycle`, start, action, result_cycle);
test_action_and_cycle(`${states} cycle-on`, start, action, result_cycle_on);
test_action_and_cycle(`${states} sticky`, start, action, result_sticky);
}
test_action_and_all_cycles("2", "0", "next", "1", "1", "1");
test_action_and_all_cycles("2", "1", "next", "2", "2", "2");
test_action_and_all_cycles("2", "2", "next", "0", "1", "2");
test_action_and_all_cycles("3", "5", "next", "0", "1", "3");
test_action_and_all_cycles("4", "3", "next", "4", "4", "4");
test_action_and_all_cycles("4", "3", "next 3", "0", "1", "4");
test_action_and_all_cycles("3", "named-value", "next", "0", "1", "3");
test_action_and_all_cycles("[a b c d]", "a", "next", "b", "b", "b");
test_action_and_all_cycles("[a b c d]", "a", "next 5", "a", "b", "d");
test_action_and_all_cycles("[a b c d]", "c", "next", "d", "d", "d");
test_action_and_all_cycles("[a b c d]", "d", "next", "a", "b", "d");
test_action_and_all_cycles("[a b c d]", "extra-state", "next", "a", "b", "d");
test_action_and_all_cycles("2", "0", "prev", "2", "2", "0");
test_action_and_all_cycles("2", "1", "prev", "0", "2", "0");
test_action_and_all_cycles("2", "2", "prev", "1", "1", "1");
test_action_and_all_cycles("2", "5", "prev", "2", "2", "2");
test_action_and_all_cycles("3", "5", "prev 3", "2", "2", "2");
test_action_and_all_cycles("3", "2", "prev 3", "3", "3", "0");
test_action_and_all_cycles("3", "named-value", "prev", "3", "3", "3");
test_action_and_all_cycles("[a b c d]", "a", "prev", "d", "d", "a");
test_action_and_all_cycles("[a b c d]", "b", "prev", "a", "d", "a");
test_action_and_all_cycles("[a b c d]", "d", "prev", "c", "c", "c");
test_action_and_all_cycles("[a b c d]", "c", "prev 5", "d", "d", "a");
test_action_and_all_cycles("[a b c d]", "extra-state", "prev", "d", "d", "d");
// TODO(https://github.com/tabatkins/css-toggle/issues/39): This set of
// tests is testing proposed behavior; the spec currently says something
// that we agree is wrong.
promise_test(async function() {
container.innerHTML = `
<button id="toggle" style="toggle: test"></button>
`;
let toggle = document.getElementById("toggle");
await wait_for_toggle_creation(toggle);
assert_true(!toggle.matches(`:toggle(test)`), "value before click");
toggle.click();
assert_true(toggle.matches(`:toggle(test)`), "value after click");
}, "toggle activation on button with toggle-trigger (1)");
promise_test(async function() {
container.innerHTML = `
<div id="toggle" style="toggle-root: test">
<button id="trigger" style="toggle-trigger: test"></button>
</div>
`;
let toggle = document.getElementById("toggle");
await wait_for_toggle_creation(toggle);
assert_true(!toggle.matches(`:toggle(test)`), "value before click");
document.getElementById("trigger").click();
assert_true(toggle.matches(`:toggle(test)`), "value after click");
}, "toggle activation on button with toggle-trigger (2)");
promise_test(async function() {
container.innerHTML = `
<div id="toggle" style="toggle: test">
<button id="button"></button>
</div>
`;
let toggle = document.getElementById("toggle");
await wait_for_toggle_creation(toggle);
assert_true(!toggle.matches(`:toggle(test)`), "value before click");
document.getElementById("button").click();
assert_true(!toggle.matches(`:toggle(test)`), "value after button click");
toggle.click();
assert_true(toggle.matches(`:toggle(test)`), "value after div click");
}, "toggle activation on button inside element with toggle-trigger");
promise_test(async function() {
container.innerHTML = `
<div id="toggle" style="toggle: test">
<div id="div"></div>
</div>
`;
let toggle = document.getElementById("toggle");
await wait_for_toggle_creation(toggle);
assert_true(!toggle.matches(`:toggle(test)`), "value before click");
document.getElementById("div").click();
assert_true(toggle.matches(`:toggle(test)`), "value after inner div click");
toggle.click();
assert_true(!toggle.matches(`:toggle(test)`), "value after outer div click");
}, "toggle activation on div inside element with toggle-trigger");
</script>