Selection-getComposedRanges-slot.html (6754B)
1 <!DOCTYPE html> 2 <html> 3 <body> 4 <meta name="author" href="mailto:dizhangg@chromium.org"> 5 <meta name="assert" content="Selection's getComposedRanges should return a sequence of static ranges, selecting from slotted content"> 6 <link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-getcomposedranges"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 10 <div id="container"></div> 11 12 <script> 13 14 test(() => { 15 container.innerHTML = '<div id=host>Second</div>'; 16 const shadowRoot = host.attachShadow({ mode:"open" }); 17 shadowRoot.innerHTML = 'First <slot></slot> Third'; 18 const second = host.firstChild; 19 const third = shadowRoot.querySelector('slot').nextSibling; 20 21 const sel = getSelection(); 22 // Select from slotted second to shadowed third. 23 sel.setBaseAndExtent(second, 3, third, 4); 24 25 assert_equals(sel.getRangeAt(0).startContainer, second); 26 assert_equals(sel.getRangeAt(0).startOffset, 3); 27 assert_equals(sel.getRangeAt(0).endContainer, second, 'Collapsed because crossing shadow tree is not supported for getRangeAt.'); 28 assert_equals(sel.getRangeAt(0).endOffset, 3); 29 30 assert_equals(sel.getComposedRanges()[0].startContainer, container); 31 assert_equals(sel.getComposedRanges()[0].startOffset, 0, 'Rescoped because no shadow roots were provided'); 32 assert_equals(sel.getComposedRanges()[0].endContainer, second); 33 assert_equals(sel.getComposedRanges()[0].endOffset, 3); 34 35 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); 36 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); 37 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); 38 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); 39 40 // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. 41 sel.setBaseAndExtent(third, 4, second, 3); 42 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); 43 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); 44 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); 45 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); 46 }, 'Setting the range to start on slotted content and end in shadow tree, should follow DOM tree order.'); 47 48 test(() => { 49 container.innerHTML = [ 50 '<div id=host>', 51 '<div id=div1 slot=slot2>slotted content 1</div>', 52 '<div id=div2 slot=slot1>slotted content 2</div>', 53 '</div>' 54 ].join(''); 55 const shadowRoot = host.attachShadow({mode: 'open'}); 56 shadowRoot.innerHTML = [ 57 '<span>before</span>', 58 '<slot name=slot1></slot>', 59 '<span>between</span>', 60 '<slot name=slot2></slot>', 61 '<span>after</span>', 62 ].join(''); 63 64 const sel = getSelection(); 65 // Select from slotted div1 to slotted div2. 66 sel.setBaseAndExtent(div1.firstChild, 2, div2.firstChild, 2); 67 68 assert_equals(sel.getRangeAt(0).startContainer, div1.firstChild); 69 assert_equals(sel.getRangeAt(0).startOffset, 2); 70 assert_equals(sel.getRangeAt(0).endContainer, div2.firstChild, 'Not collapsed because we are not crossing shadow trees.'); 71 assert_equals(sel.getRangeAt(0).endOffset, 2); 72 73 assert_equals(sel.getComposedRanges()[0].startContainer, div1.firstChild); 74 assert_equals(sel.getComposedRanges()[0].startOffset, 2); 75 assert_equals(sel.getComposedRanges()[0].endContainer, div2.firstChild, 'Not rescoped because we are not crossing shadow trees.'); 76 assert_equals(sel.getComposedRanges()[0].endOffset, 2); 77 78 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, div1.firstChild); 79 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 2); 80 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, div2.firstChild); 81 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 2); 82 83 // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. 84 sel.setBaseAndExtent(div2.firstChild, 2, div1.firstChild, 2); 85 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, div1.firstChild); 86 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 2); 87 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, div2.firstChild); 88 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 2); 89 }, 'Setting the range to start and end on slotted content, should follow DOM tree order.'); 90 91 test(() => { 92 container.innerHTML = '<div id=host>Second</div>'; 93 const shadowRoot = host.attachShadow({ mode:"open" }); 94 shadowRoot.innerHTML = '<span id="first">First</span><span id=third>Third</span>'; 95 const second = host.firstChild; 96 const third = shadowRoot.getElementById('third').firstChild; 97 98 const sel = getSelection(); 99 // Select from unslotted second to shadowed third. 100 sel.setBaseAndExtent(second, 3, third, 4); 101 102 assert_equals(sel.getRangeAt(0).startContainer, second); 103 assert_equals(sel.getRangeAt(0).startOffset, 3); 104 assert_equals(sel.getRangeAt(0).endContainer, second, 'Collapsed because crossing shadow tree is not supported for getRangeAt.'); 105 assert_equals(sel.getRangeAt(0).endOffset, 3); 106 107 assert_equals(sel.getComposedRanges()[0].startContainer, container); 108 assert_equals(sel.getComposedRanges()[0].startOffset, 0, 'Rescoped because no shadow roots were provided'); 109 assert_equals(sel.getComposedRanges()[0].endContainer, second); 110 assert_equals(sel.getComposedRanges()[0].endOffset, 3); 111 112 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); 113 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); 114 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); 115 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); 116 117 // Repeat the test, but reversing base and extent. This should not affect the range's start and end positions. 118 sel.setBaseAndExtent(third, 4, second, 3); 119 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startContainer, third); 120 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].startOffset, 4); 121 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endContainer, second); 122 assert_equals(sel.getComposedRanges({ shadowRoots: [shadowRoot] })[0].endOffset, 3); 123 }, 'Setting the range to start on unslotted content and end in shadow tree, should follow DOM tree order.'); 124 </script>