| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <title>CSS Pseudo-Elements Test: Text selection</title> | |
| <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#treelike"> | |
| <link rel="help" href="https://drafts.csswg.org/css-ui/#user-interaction"> | |
| <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> | |
| <meta name="assert" content="This test checks that text in a ::before or ::marker pseudo-element can't be selected." /> | |
| <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> | |
| <style> | |
| .test { | |
| font: 10px/1 Ahem; | |
| margin-left: 200px; | |
| } | |
| #before::before { | |
| content: "::before"; | |
| display: inline-block; | |
| margin-left: -80px; | |
| } | |
| #marker { | |
| display: list-item; | |
| list-style-type: "::marker"; | |
| } | |
| #before-marker::before { | |
| content: ""; | |
| display: list-item; | |
| list-style-type: "::marker"; | |
| height: 0; | |
| } | |
| </style> | |
| <div class="test" id="before"><span>helloworld</span></div> | |
| <div class="test" id="marker"><span>helloworld</span></div> | |
| <div class="test" id="before-marker"><span>helloworld</span></div> | |
| <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> | |
| function createSelection(element, start, end, step) { | |
| getSelection().empty(); | |
| step = Math.abs(step); | |
| const actions = new test_driver.Actions(); | |
| actions.pointerMove(start, 0, {origin: element}); | |
| actions.pointerDown(); | |
| if (start < end) { | |
| for (let x = start + step; x < end; x += step) | |
| actions.pointerMove(x, 0, {origin: element}); | |
| } else { | |
| for (let x = start - step; x > end; x -= step) | |
| actions.pointerMove(x, 0, {origin: element}); | |
| } | |
| actions.pointerMove(end, 0, {origin: element}); | |
| actions.pointerUp(); | |
| return actions.send(); | |
| } | |
| (async function() { | |
| setup({ explicit_done: true }); | |
| for (let target of document.querySelectorAll(".test")) { | |
| const contents = target.querySelector("span"); | |
| const text = contents.firstChild; | |
| const s = getSelection(); | |
| // Create a selection that starts in the middle of the element contents | |
| // and ends in the middle of the pseudo-element | |
| await createSelection(contents, 0, -90, 10); | |
| test(function(t) { | |
| assert_equals(s.toString(), "hello", "toString"); | |
| assert_equals(s.anchorNode, text, "anchorNode"); | |
| assert_equals(s.anchorOffset, 5, "anchorOffset"); | |
| assert_equals(s.focusNode, text, "focusNode"); | |
| assert_equals(s.focusOffset, 0, "focusOffset"); | |
| }, "Selection ending in ::" + target.id); | |
| // Create a selection that starts and ends inside the pseudo-element. | |
| await createSelection(contents, -80, -110, 10); | |
| test(function(t) { | |
| assert_equals(s.toString(), "", "toString"); | |
| assert_in_array(s.anchorNode, [text, null], "anchorNode"); | |
| assert_equals(s.anchorOffset, 0, "anchorOffset"); | |
| assert_in_array(s.focusNode, [text, null], "focusNode"); | |
| assert_equals(s.focusOffset, 0, "focusOffset"); | |
| }, "Selection contained in ::" + target.id); | |
| } | |
| done(); | |
| })(); | |
| </script> | |