mirror of
https://github.com/servo/servo.git
synced 2025-07-14 10:53:42 +01:00
336 lines
14 KiB
HTML
336 lines
14 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 id="style"></style>
|
|
|
|
<body>
|
|
|
|
<div id="container"></div>
|
|
<script>
|
|
|
|
let container = document.getElementById("container");
|
|
|
|
function test_trigger_on_group(toggle_specifier, other_specifier, action, toggle_expected, group_expected)
|
|
{
|
|
promise_test(async function() {
|
|
let group = document.createElement("div");
|
|
group.style.toggleGroup = "test-group";
|
|
|
|
let toggle = document.createElement("div");
|
|
toggle.style.toggle = `test-group ${toggle_specifier} group`;
|
|
toggle.style.toggleTrigger = `test-group ${action}`;
|
|
group.appendChild(toggle);
|
|
|
|
let other = document.createElement("div");
|
|
other.style.toggle = `test-group ${other_specifier} group`;
|
|
group.appendChild(other);
|
|
|
|
let style = document.getElementById("style");
|
|
style.textContent = `
|
|
:toggle(test-group ${toggle_expected}) { --v:${toggle_expected}; }
|
|
:toggle(test-group ${group_expected}) { --v:${group_expected}; }
|
|
`;
|
|
|
|
container.replaceChildren(group);
|
|
await wait_for_toggle_creation(toggle);
|
|
|
|
toggle.click();
|
|
assert_true(toggle.matches(`:toggle(test-group ${toggle_expected}`), "value of triggered toggle");
|
|
assert_equals(getComputedStyle(toggle).getPropertyValue("--v"), toggle_expected, "style on triggered toggle");
|
|
assert_true(other.matches(`:toggle(test-group ${group_expected}`), "value of other toggle in group");
|
|
assert_equals(getComputedStyle(other).getPropertyValue("--v"), group_expected, "style on other toggle in group");
|
|
}, `group behavior for toggle "${toggle_specifier}" and action "${action}" with other element in group "${other_specifier}"`);
|
|
}
|
|
|
|
test_trigger_on_group("", "", "next", "1", "0");
|
|
test_trigger_on_group("1 at 0", "1 at 0", "next", "1", "0");
|
|
test_trigger_on_group("", "1 at 1", "next", "1", "0");
|
|
test_trigger_on_group("1 at 1", "1 at 1", "next", "0", "1");
|
|
test_trigger_on_group("1 at 1 cycle", "1 at 1", "next", "0", "1");
|
|
test_trigger_on_group("1 at 1 cycle-on", "1 at 1", "next", "1", "0");
|
|
test_trigger_on_group("1 at 1 sticky", "1 at 1", "next", "1", "0");
|
|
test_trigger_on_group("1 at 1", "1 at 1", "set 3", "3", "0");
|
|
test_trigger_on_group("1 at 1", "1 at 1", "set 0", "0", "1");
|
|
test_trigger_on_group("1 at 7", "1 at 5", "set 9", "9", "0");
|
|
test_trigger_on_group("1 at 7", "1 at 5", "set 0", "0", "5");
|
|
test_trigger_on_group("", "1 at 1 cycle", "next", "1", "0");
|
|
test_trigger_on_group("", "1 at 1 cycle-on", "next", "1", "0");
|
|
test_trigger_on_group("", "1 at 1 sticky", "next", "1", "0");
|
|
test_trigger_on_group("1 at 0", "1 at 1", "prev", "1", "0");
|
|
test_trigger_on_group("1 at 0", "1 at 0", "prev", "1", "0");
|
|
test_trigger_on_group("1 at 1", "1 at 1", "prev", "0", "1");
|
|
test_trigger_on_group("1 at 1 cycle", "1 at 1", "prev", "0", "1");
|
|
test_trigger_on_group("1 at 1 cycle-on", "1 at 1", "prev", "1", "0");
|
|
test_trigger_on_group("1 at 1 sticky", "1 at 1", "prev", "0", "1");
|
|
test_trigger_on_group("", "1 at 1", "set 0", "0", "1");
|
|
test_trigger_on_group("", "1 at 1", "set 1", "1", "0");
|
|
test_trigger_on_group("", "1 at 1", "set 7", "7", "0");
|
|
test_trigger_on_group("", "1 at 1", "set named-state", "named-state", "0");
|
|
test_trigger_on_group("[a b c] at a", "1 at 1", "next", "b", "0");
|
|
test_trigger_on_group("[a b c] at c", "1 at 1", "next", "a", "1");
|
|
test_trigger_on_group("[a b c] at a", "1 at 1", "prev", "c", "0");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "prev", "a", "1");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "set 2", "c", "0");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "set c", "c", "0");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "set 0", "0", "1");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "set a", "0", "1");
|
|
test_trigger_on_group("[a b c] at b", "1 at 1", "set new-state", "new-state", "0");
|
|
test_trigger_on_group("", "[a b c] at b", "next", "1", "a");
|
|
test_trigger_on_group("", "[a b c] at b", "prev", "1", "a");
|
|
test_trigger_on_group("", "[a b c] at b", "set 1", "1", "a");
|
|
test_trigger_on_group("", "[a b c] at b", "set 0", "0", "b");
|
|
|
|
let finding_group_tests = [
|
|
// Markup to create the test assertions:
|
|
// class=assert-in: assert that this element's in-scope toggle is in the
|
|
// test-group group and was not the activated toggle
|
|
// class=assert-out: assert that this element's in-scope toggle is not in
|
|
// the test-group group and was not the activated toggle
|
|
// class=assert-activated: assert that this element's in-scope toggle was
|
|
// the activated toggle
|
|
//
|
|
// Helper markup to create more markup:
|
|
// class=establish: establish the group with the toggle-group property
|
|
// class=establish-self: same, but with the self keyword (narrow scope)
|
|
// class=root: create a test-group toggle with the toggle-root property
|
|
// class=root-nogroup: same, but without the 'group' keyword
|
|
// class=activate: toggle-trigger to activate test-group toggle
|
|
//
|
|
// class=activate (above) is *also* a helper to run the test; it will be
|
|
// activated. There must only be one element with class=activate.
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="root-nogroup assert-out"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root assert-out"></div>
|
|
<div class="establish"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="establish"></div>
|
|
<div class="root assert-out"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="establish-self">
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-in"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root assert-out"></div>
|
|
<div class="establish">
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
<div class="root assert-in"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="establish">
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
`,
|
|
`
|
|
<div class="establish"></div>
|
|
<div class="root assert-in"></div>
|
|
<div class="establish-self"></div>
|
|
<div class="root assert-activated"></div>
|
|
<div class="activate"></div>
|
|
`,
|
|
`
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
`,
|
|
`
|
|
<div class="root assert-out"></div>
|
|
<div class="establish-self">
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
`,
|
|
`
|
|
<div class="root assert-out"></div>
|
|
<div style="toggle-group: test-group self, extra-group">
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
`,
|
|
`
|
|
<div class="root assert-out"></div>
|
|
<div style="toggle-group: extra-group, test-group self">
|
|
<div class="root activate assert-activated"></div>
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
`,
|
|
`
|
|
<div class="root activate assert-activated">
|
|
<div class="establish">
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
`,
|
|
`
|
|
<div class="root activate assert-activated">
|
|
<div class="establish-self">
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
`,
|
|
`
|
|
<div class="root activate assert-activated">
|
|
<div class="root assert-in"></div>
|
|
<div>
|
|
<div class="root assert-in"></div>
|
|
<div class="establish">
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-out"></div>
|
|
</div>
|
|
<div class="root assert-in"></div>
|
|
</div>
|
|
`,
|
|
];
|
|
|
|
for (let t of finding_group_tests) {
|
|
promise_test(async function() {
|
|
document.getElementById("style").textContent = `
|
|
:toggle(test-group 0) { --v:0; }
|
|
:toggle(test-group 1) { --v:1; }
|
|
:toggle(test-group 2) { --v:2; }
|
|
`;
|
|
container.innerHTML = t;
|
|
|
|
for (let e of container.querySelectorAll('.establish')) {
|
|
e.style.toggleGroup = "test-group";
|
|
}
|
|
for (let e of container.querySelectorAll('.establish-self')) {
|
|
e.style.toggleGroup = "test-group self";
|
|
}
|
|
for (let e of container.querySelectorAll('.root')) {
|
|
e.style.toggleRoot = "test-group 1 at 1 cycle-on group";
|
|
}
|
|
for (let e of container.querySelectorAll('.root-nogroup')) {
|
|
e.style.toggleRoot = "test-group 1 at 1 cycle-on";
|
|
}
|
|
let activate = container.querySelector('.activate');
|
|
activate.style.toggleTrigger = "test-group set 2";
|
|
|
|
for (let e of container.querySelectorAll('.root, .root-nogroup')) {
|
|
await wait_for_toggle_creation(e);
|
|
}
|
|
|
|
activate.click();
|
|
for (let e of container.querySelectorAll('.assert-in')) {
|
|
assert_true(e.matches(":toggle(test-group 0)"), "element in group");
|
|
assert_equals(getComputedStyle(e).getPropertyValue("--v"), "0",
|
|
"style on element in group");
|
|
}
|
|
for (let e of container.querySelectorAll('.assert-out')) {
|
|
assert_true(e.matches(":toggle(test-group 1)"), "element not in group");
|
|
assert_equals(getComputedStyle(e).getPropertyValue("--v"), "1",
|
|
"style on element not in group");
|
|
}
|
|
for (let e of container.querySelectorAll('.assert-activated')) {
|
|
assert_true(e.matches(":toggle(test-group 2)"), "element was activated");
|
|
assert_equals(getComputedStyle(e).getPropertyValue("--v"), "2",
|
|
"style on activated element");
|
|
}
|
|
}, `toggle groups test: ${t}`);
|
|
}
|
|
|
|
promise_test(async () => {
|
|
container.innerHTML = `
|
|
<div id="e" style="toggle: tog [a b] at b self group"></div>
|
|
<div id="f" style="toggle: tog [a b] at a self group"></div>
|
|
`;
|
|
let e = document.getElementById("e");
|
|
let f = document.getElementById("f");
|
|
await Promise.all([wait_for_toggle_creation(e),
|
|
wait_for_toggle_creation(f)]);
|
|
|
|
let te = e.toggles.get("tog");
|
|
let tf = f.toggles.get("tog");
|
|
assert_equals(te.value, "b", "e value before first click");
|
|
assert_true(e.matches(':toggle(tog b):toggle(tog 1)'),
|
|
"e selector matching before first click");
|
|
assert_equals(tf.value, "a", "f value before first click");
|
|
assert_true(f.matches(':toggle(tog a):toggle(tog 0)'),
|
|
"f selector matching before first click");
|
|
f.click();
|
|
assert_equals(te.value, 0, "e value after first click");
|
|
assert_equals(tf.value, "b", "f value after first click");
|
|
f.click();
|
|
assert_equals(te.value, 0, "e value after second click");
|
|
assert_equals(tf.value, "a", "f value after second click");
|
|
te.value = "b";
|
|
assert_equals(te.value, "b", "e value after first value set");
|
|
assert_equals(tf.value, 0, "f value after first value set");
|
|
tf.value = "b";
|
|
assert_equals(te.value, 0, "e value after second value set");
|
|
assert_equals(tf.value, "b", "f value after second value set");
|
|
tf.value = "a";
|
|
assert_equals(te.value, 0, "e value after third value set");
|
|
assert_equals(tf.value, "a", "f value after third value set");
|
|
|
|
// Swap the order of the state names in 'toggle-root'. This does not affect
|
|
// the states on the toggle, but still affects the override specifier used
|
|
// in some algorithms.
|
|
e.style.toggleRoot = "tog [b a] at 0 self group";
|
|
f.style.toggleRoot = "tog [b a] at 0 self group";
|
|
await Promise.all([wait_for_toggle_creation(e),
|
|
wait_for_toggle_creation(f)]);
|
|
|
|
assert_equals(te.value, 0, "e value after changing toggle-root");
|
|
assert_equals(tf.value, "a", "f value after changing toggle-root");
|
|
e.click();
|
|
assert_equals(te.value, "a", "e value after third click");
|
|
assert_equals(tf.value, 0, "f value after third click");
|
|
e.click();
|
|
assert_equals(te.value, "b", "e value after fourth click");
|
|
assert_equals(tf.value, 0, "f value after fourth click");
|
|
assert_true(e.matches(':toggle(tog b):toggle(tog 1)'),
|
|
"e selector matching after changing toggle-root");
|
|
assert_true(f.matches(':toggle(tog a):toggle(tog 0)'),
|
|
"f selector matching after changing toggle-root");
|
|
tf.value = "a";
|
|
assert_equals(te.value, 0, "e value after fourth value set");
|
|
assert_equals(tf.value, "a", "f value after fourth value set");
|
|
tf.value = "b";
|
|
assert_equals(te.value, 0, "e value after fifth value set");
|
|
assert_equals(tf.value, "b", "f value after fifth value set");
|
|
te.value = "b";
|
|
assert_equals(te.value, "b", "e value after sixth value set");
|
|
assert_equals(tf.value, "b", "f value after sixth value set");
|
|
}, "zeroing toggle group uses states from override specifier");
|
|
|
|
// TODO(dbaron): This could probably use a few additional tests for multiple
|
|
// values of the list-valued properties. (But they're hard to auto-generate.)
|
|
|
|
</script>
|