|  | <!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> | 
|  |  |