| <!DOCTYPE html> |
| <html> |
| <body> |
| <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> |
| <meta name="assert" content="Selection's getComposedRanges should return a sequence of static ranges"> |
| <link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-getcomposedrange"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <div id="container"></div> |
| <script> |
| |
| test(() => { |
| getSelection().removeAllRanges(); |
| assert_array_equals(getSelection().getComposedRanges(), []); |
| }, 'getComposedRanges returns an empty sequence when there is no selection'); |
| |
| test(() => { |
| container.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(container.firstChild, 0, container.firstChild, 5); |
| const ranges = getSelection().getComposedRanges(); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, container.firstChild); |
| assert_equals(ranges[0].startOffset, 0); |
| assert_equals(ranges[0].endContainer, container.firstChild); |
| assert_equals(ranges[0].endOffset, 5); |
| }, 'getComposedRanges returns a sequence with a static range when there is a forward-direction selection in the document tree'); |
| |
| test(() => { |
| container.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(container.firstChild, 4, container.firstChild, 3); |
| const ranges = getSelection().getComposedRanges(); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, container.firstChild); |
| assert_equals(ranges[0].startOffset, 3); |
| assert_equals(ranges[0].endContainer, container.firstChild); |
| assert_equals(ranges[0].endOffset, 4); |
| }, 'getComposedRanges returns a sequence with a static range when there is a backward-direction selection in the document tree'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="host"></div>b'; |
| const shadowRoot = host.attachShadow({mode: 'closed'}); |
| shadowRoot.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(shadowRoot.firstChild, 0, shadowRoot.firstChild, 5); |
| const ranges = getSelection().getComposedRanges(shadowRoot); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, shadowRoot.firstChild); |
| assert_equals(ranges[0].startOffset, 0); |
| assert_equals(ranges[0].endContainer, shadowRoot.firstChild); |
| assert_equals(ranges[0].endOffset, 5); |
| }, 'getComposedRanges returns a sequence with a static range pointing to a shadaw tree when there is a selection in the shadow tree and the shadow tree is specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="host"></div>b'; |
| const shadowRoot = host.attachShadow({mode: 'closed'}); |
| shadowRoot.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(shadowRoot.firstChild, 0, shadowRoot.firstChild, 5); |
| const ranges = getSelection().getComposedRanges(); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, container); |
| assert_equals(ranges[0].startOffset, 1); |
| assert_equals(ranges[0].endContainer, container); |
| assert_equals(ranges[0].endOffset, 2); |
| }, 'getComposedRanges returns a sequence with a static range pointing to the shadow host when there is a selection in a shadow tree and the shadow tree is not specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="host"></div>b'; |
| const shadowRoot = host.attachShadow({mode: 'closed'}); |
| shadowRoot.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(shadowRoot.firstChild, 7, container, 2); |
| const ranges = getSelection().getComposedRanges(); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, container); |
| assert_equals(ranges[0].startOffset, 1); |
| assert_equals(ranges[0].endContainer, container); |
| assert_equals(ranges[0].endOffset, 2); |
| }, 'getComposedRanges a sequence with a static range pointing to the shadow host when there is a forward selection that crosses shadow boundaries and the shadow tree is not specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="host"></div>b'; |
| const shadowRoot = host.attachShadow({mode: 'closed'}); |
| shadowRoot.innerHTML = 'hello, world'; |
| getSelection().setBaseAndExtent(shadowRoot.firstChild, 7, container, 2); |
| const ranges = getSelection().getComposedRanges(shadowRoot); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, shadowRoot.firstChild); |
| assert_equals(ranges[0].startOffset, 7); |
| assert_equals(ranges[0].endContainer, container); |
| assert_equals(ranges[0].endOffset, 2); |
| }, 'getComposedRanges a sequence with a static range that crosses shadow boundaries when there is a forward selection that crosses shadow boundaries and the shadow tree is specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="outerHost"></div>b'; |
| const outerShadowRoot = outerHost.attachShadow({mode: 'closed'}); |
| outerShadowRoot.innerHTML = '<div id="innerHost">hello</div><div>world</div>'; |
| const innerHost = outerShadowRoot.getElementById('innerHost'); |
| const innerShadowRoot = innerHost.attachShadow({mode: 'closed'}); |
| innerShadowRoot.innerHTML = 'some text'; |
| getSelection().setBaseAndExtent(innerShadowRoot.firstChild, 5, innerShadowRoot.firstChild, 9); |
| const ranges = getSelection().getComposedRanges(); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, container); |
| assert_equals(ranges[0].startOffset, 1); |
| assert_equals(ranges[0].endContainer, container); |
| assert_equals(ranges[0].endOffset, 2); |
| }, 'getComposedRanges returns a sequence with a static range pointing to the outer shadow host when there is a selection in an inner shadow tree and no shadow tree is specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="outerHost"></div>b'; |
| const outerShadowRoot = outerHost.attachShadow({mode: 'closed'}); |
| outerShadowRoot.innerHTML = '<div id="innerHost">hello</div><div>world</div>'; |
| const innerHost = outerShadowRoot.getElementById('innerHost'); |
| const innerShadowRoot = innerHost.attachShadow({mode: 'closed'}); |
| innerShadowRoot.innerHTML = 'some text'; |
| getSelection().setBaseAndExtent(innerShadowRoot.firstChild, 5, innerShadowRoot.firstChild, 9); |
| const ranges = getSelection().getComposedRanges(innerShadowRoot); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, innerShadowRoot.firstChild); |
| assert_equals(ranges[0].startOffset, 5); |
| assert_equals(ranges[0].endContainer, innerShadowRoot.firstChild); |
| assert_equals(ranges[0].endOffset, 9); |
| }, 'getComposedRanges returns a sequence with a static range pointing to the inner shadow tree when there is a selection in an inner shadow tree and the inner shadow tree is specified as an argument'); |
| |
| test(() => { |
| container.innerHTML = 'a<div id="outerHost"></div>b'; |
| const outerShadowRoot = outerHost.attachShadow({mode: 'closed'}); |
| outerShadowRoot.innerHTML = '<div id="innerHost">hello</div><div>world</div>'; |
| const innerHost = outerShadowRoot.getElementById('innerHost'); |
| const innerShadowRoot = innerHost.attachShadow({mode: 'closed'}); |
| innerShadowRoot.innerHTML = 'some text'; |
| getSelection().setBaseAndExtent(innerShadowRoot.firstChild, 5, innerShadowRoot.firstChild, 9); |
| const ranges = getSelection().getComposedRanges(outerShadowRoot); |
| assert_equals(ranges.length, 1); |
| assert_equals(ranges[0].startContainer, outerShadowRoot); |
| assert_equals(ranges[0].startOffset, 0); |
| assert_equals(ranges[0].endContainer, outerShadowRoot); |
| assert_equals(ranges[0].endOffset, 1); |
| }, 'getComposedRanges returns a sequence with a static range pointing to the outer shadow tree when there is a selection in an inner shadow tree and the outer shadow tree is specified as an argument'); |
| |
| </script> |
| </body> |
| </html> |