HighlightRegistry-highlightsFromPoint.html (11067B)
1 <!doctype html> 2 <body> 3 <meta name="author" title="Fernando Fiori" href="mailto:ffiori@microsoft.com"> 4 <meta name="assert" content="HighlightRegistry.highlightsFromPoint returns HighlightHitResults with the Highlights and their corresponding ranges present at a given point inside the shadow roots passed as argument."> 5 <link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/highlight/HighlightsFromPointsExplainer.md"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <style> 9 ::highlight(example-highlight) { 10 background-color: rgba(0, 255, 255, 0.5); 11 } 12 ::highlight(example-highlight-2) { 13 background-color: rgba(255, 255, 0, 0.5); 14 } 15 body { 16 font-family: monospace; 17 } 18 </style> 19 <span id="container"></span> 20 <script> 21 test(() => { 22 assert_throws_js(TypeError, () => { CSS.highlights.highlightsFromPoint(10, 10, {shadowRoots: [container]}); }); 23 container.setHTMLUnsafe(` 24 <div id="host"> 25 <template shadowrootmode=open></template> 26 </div>`); 27 const shadowRoot = host.shadowRoot; 28 assert_throws_js(TypeError, () => { CSS.highlights.highlightsFromPoint(10, 10, {shadowRoots: [shadowRoot, container]}); }); 29 }, 'CSS.highlights.highlightsFromPoint() should throw when called with nodes that are not ShadowRoot objects in options.'); 30 31 test(() => { 32 container.setHTMLUnsafe(` 33 <div id="host"> 34 <template shadowrootmode=open> 35 <span>0123456789</span> 36 </template> 37 </div>`); 38 const shadowRoot = host.shadowRoot; 39 const spanInShadowDOM = shadowRoot.querySelector("span"); 40 41 let range = new Range(); 42 range.setStart(spanInShadowDOM.childNodes[0], 2); 43 range.setEnd(spanInShadowDOM.childNodes[0], 10); 44 let range2 = new Range(); 45 range2.setStart(spanInShadowDOM.childNodes[0], 5); 46 range2.setEnd(spanInShadowDOM.childNodes[0], 10); 47 48 // Set two Highlights in the shadow tree in this way: 01[234[56789]] 49 let highlight = new Highlight(range); 50 CSS.highlights.set("example-highlight", highlight); 51 let highlight2 = new Highlight(range2); 52 CSS.highlights.set("example-highlight-2", highlight2); 53 54 const spanBoundingRectangle = spanInShadowDOM.getBoundingClientRect(); 55 const characterWidth = spanBoundingRectangle.width / spanInShadowDOM.textContent.length; 56 57 // Get x and y coordinates between '0' and '1'. 58 let x = spanBoundingRectangle.left + characterWidth; 59 let y = spanBoundingRectangle.top + spanBoundingRectangle.height / 2; 60 let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 61 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights'); 62 63 // Get x and y coordinates between '2' and '3'. 64 x = spanBoundingRectangle.left + 3 * characterWidth; 65 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 66 assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the given coordinates point at a Highlight under the shadow root provided'); 67 assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates when it\'s under the shadow root provided'); 68 assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); 69 70 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); 71 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at one Highlight in the shadow DOM but shadowRoots provided is empty'); 72 73 // Get x and y coordinates between '6' and '7'. 74 // Same priority for the Highlights, break tie by order of registration. 75 x = spanBoundingRectangle.left + 7 * characterWidth; 76 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 77 assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights'); 78 assert_equals(highlight_hit_results[0].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority'); 79 assert_equals(highlight_hit_results[1].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority'); 80 assert_array_equals(highlight_hit_results[0].ranges, [range2], 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the ranges of the Highlight present on top at the coordinates provided'); 81 assert_array_equals(highlight_hit_results[1].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the ranges of the Highlight present at the bottom at the coordinates provided'); 82 }, 'CSS.highlights.highlightsFromPoint() returns Highlights present at a given point inside a shadow tree in the right order.'); 83 84 test(() => { 85 container.setHTMLUnsafe( 86 `0123456789<div id=host> 87 <template shadowrootmode=open> 88 <span>0123456789</span> 89 </template> 90 </div>0123456789`); 91 92 const host = document.querySelector("#host"); 93 const shadowRoot = host.shadowRoot; 94 const spanInShadowDOM = shadowRoot.querySelector("span"); 95 96 const spanBoundingRectangle = spanInShadowDOM.getBoundingClientRect(); 97 const characterWidth = spanBoundingRectangle.width / spanInShadowDOM.textContent.length; 98 const characterHeight = spanBoundingRectangle.height; 99 100 let range = new Range(); 101 range.setStart(container.childNodes[0], 0); 102 range.setEnd(container.childNodes[2], 5); 103 104 // Set a Highlight with a range like this one: 105 // [0123456789 106 // 0123456789 107 // 01234]56789 108 // But only the first and third lines are highlighted because the second line belongs on a shadow tree. 109 const highlight = new Highlight(range); 110 CSS.highlights.set("example-highlight", highlight); 111 112 // Get x and y coordinates between '0' and '1' in the first line. 113 let x = spanBoundingRectangle.left + characterWidth; 114 let y = container.getBoundingClientRect().top + characterHeight / 2.0; 115 let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); 116 assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); 117 assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates even when no shadowRoots are provided because it\'s outside the shadow DOM'); 118 assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); 119 120 // Now move y to the second line (inside shadow DOM). 121 y += characterHeight; 122 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 123 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it, even when shadowRoots are provided'); 124 125 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); 126 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it'); 127 128 // Now move y to the third line. 129 y += characterHeight; 130 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y); 131 assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided'); 132 assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates because it\'s outside of the shadow DOM'); 133 assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided'); 134 135 // Set a Highlight with a range like this one: 136 // [0123456789 137 // 01234]56789 138 // 0123456789 139 // Here nothing is highlighted since the range starts in the light DOM and ends in the shadow DOM. 140 CSS.highlights.clear(); 141 const staticRange = new StaticRange({startContainer: container.childNodes[0], startOffset: 0, endContainer: spanInShadowDOM.childNodes[0], endOffset: 5}) 142 CSS.highlights.set("example-highlight", new Highlight(staticRange)); 143 144 // Set x and y coordinates between '0' and '1' in the first line. 145 y = container.getBoundingClientRect().top + characterHeight / 2.0; 146 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 147 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the light DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); 148 149 // Now move y to the second line (inside shadow DOM). 150 y += characterHeight; 151 highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]}); 152 assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the shadow DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it'); 153 }, 'CSS.highlights.highlightsFromPoint() doesn\'t return Highlights that are not painted at the given coordinates even when they fall inside the Highlights\' ranges'); 154 </script> 155 </body>