<!doctype HTML> <html> <meta charset="utf8"> <title>Content Visibility: off-screen selection</title> <link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> <link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility"> <meta name="assert" content="content-visibility auto element remains non-skipped when elements in its subtree have selection."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> body, html { padding: 0; margin: 0; } .spacer { height: 3000px; } .container { width: 10px; contain-intrinsic-size: 10px 20px; content-visibility: auto; } .child { width: 10px; height: 10px; } </style> <div class=spacer></div> <div id=container_1 class=container><div id=child_1 class=child>hello</div></div> <div id=container_2 class=container><div id=child_2 class=child>hello</div></div> <div id=container_3 class=container><div id=child_3 class=child>hello</div></div> <div id=container_4 class=container><div id=child_4 class=child>hello</div></div> <div id=container_5 class=container><div id=child_5 class=child>hello</div></div> <script> function isLocked(container) { const height = container.getBoundingClientRect().height; assert_true(height == 20 || height == 10); return container.getBoundingClientRect().height == 20; } const selection = window.getSelection(); function resetSelection() { selection.removeAllRanges(); assert_true(isLocked(container_1)); assert_true(isLocked(container_2)); assert_true(isLocked(container_3)); assert_true(isLocked(container_4)); assert_true(isLocked(container_5)); } test(() => { resetSelection(); const range = document.createRange(); range.selectNodeContents(child_2); selection.addRange(range); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_true(isLocked(container_3), "3"); assert_true(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); }, "One elements selected: "); test(() => { resetSelection(); const range = document.createRange(); range.selectNodeContents(child_2); selection.addRange(range); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_true(isLocked(container_3), "3"); assert_true(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); selection.extend(child_4, 0); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_false(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); }, "Range extended to cover more elements: "); test(() => { resetSelection(); const range = document.createRange(); range.setStart(child_2, 0); range.setEnd(child_4, 0); selection.addRange(range); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_false(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); selection.extend(child_2, 1); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_true(isLocked(container_3), "3"); assert_true(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); }, "Range shrunk to cover fewer elements: "); test(() => { resetSelection(); const range = document.createRange(); range.setStart(child_3, 0); range.setEnd(child_3, 0); selection.addRange(range); selection.extend(child_2, 0); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_true(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); selection.extend(child_4, 0); assert_true(isLocked(container_1), "1"); assert_true(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_false(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); }, "Range flipped from back to front: "); test(() => { resetSelection(); const range = document.createRange(); range.setStart(child_3, 0); range.setEnd(child_4, 0); selection.addRange(range); assert_true(isLocked(container_1), "1"); assert_true(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_false(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); selection.extend(child_2, 0); assert_true(isLocked(container_1), "1"); assert_false(isLocked(container_2), "2"); assert_false(isLocked(container_3), "3"); assert_true(isLocked(container_4), "4"); assert_true(isLocked(container_5), "5"); }, "Range flipped from front to back: "); test(() => { resetSelection(); const range = document.createRange(); range.setStart(child_1, 0); range.setEnd(child_1, 0); selection.addRange(range); let state = 0; const states = [2, 4, 3, 5, 1]; for (let i = 0; i < 10; ++i) { const id = states[state]; selection.extend(document.getElementById(`child_${id}`), 1); for (let check_id = 1; check_id <= 5; ++check_id) { if (check_id <= id) { assert_false( isLocked(document.getElementById(`container_${check_id}`)), `test_${i}, container_${check_id}`); } else { assert_true( isLocked(document.getElementById(`container_${check_id}`)), `test_${i}, container_${check_id}`); } } state = (state + 1) % states.length; } }, "Range goes back and forth: "); </script> </html>