489127.html (8357B)
1 <!DOCTYPE HTML> 2 <title>nsIDOMWindowUtils::nodesFromRect test - bug 489127</title> 3 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 4 <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"> 5 <script> 6 var SimpleTest = window.opener.SimpleTest; 7 function ok() { window.opener.ok.apply(window.opener, arguments); } 8 function done() { window.opener.done.apply(window.opener, arguments); } 9 function info() { window.opener.info.apply(window.opener, arguments); } 10 11 let e = {}; 12 13 let dwu = window.windowUtils; 14 15 function check(x, y, top, right, bottom, left, onlyVisible, list, aListIsComplete = false, aOpacityThreshold = 1.0) { 16 let nodes = dwu.nodesFromRect(x, y, top, right, bottom, left, /* aIgnoreRootScrollFrame = */ true, /* aFlushLayout = */ true, onlyVisible, aOpacityThreshold); 17 18 if (!aListIsComplete) { 19 list.push(e.body); 20 list.push(e.html); 21 } 22 23 if (nodes.length != list.length) { 24 ok(false, "Different number of nodes (" + nodes.length + " vs. " + list.length + 25 ") for rect [" + x + "," + y + "], " + 26 "[" + top + "," + right + "," + bottom + "," + left + "]"); 27 return; 28 } 29 30 for (var i = 0; i < nodes.length; i++) { 31 if (nodes[i] != list[i]) { 32 ok(false, `Unexpected node #${i} (${nodes[i].id} vs. ${list[i].id}) ` + 33 `[${x}, ${y}] [${top}, ${right}, ${bottom}, ${left}]`); 34 return; 35 } 36 } 37 ok(true, "All correct nodes found for rect " + 38 "[" + x + "," + y + "], " + 39 "[" + top + "," + right + "," + bottom + "," + left + "]"); 40 } 41 42 function doTest() { 43 // Set up shortcut access to elements 44 e.html = document.documentElement; 45 ['h1', 'd1', 'd2', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'span', 46 'a1', 'a2', 'a3', 'transf', 'iframe1', 'body', 'opacity', 'host'].forEach(function(a) { 47 e[a] = document.getElementById(a); 48 }); 49 50 let shadow = e.host.attachShadow({ mode: "open" }); 51 shadow.innerHTML = ` 52 <style> 53 #host-inner { height: 100px; width: 100px; background-color: blue } 54 </style> 55 <div id="host-inner"></div> 56 `; 57 58 window.scrollTo(0, 0); 59 60 // Top, Right, Bottom, Left directions: 61 check(53, 71, 0, 0, 0, 0, false, []); 62 check(53, 71, 10, 0, 0, 0, false, [e.h1]); 63 check(53, 71, 0, 10, 0, 0, false, [e.p3]); 64 check(53, 71, 0, 0, 10, 0, false, [e.d1]); 65 check(152, 105, 0, 0, 0, 10, false, [e.d1]); 66 check(152, 105, 10, 10, 10, 10, false, [e.p4, e.p3, e.d1]); 67 68 // e.p1 is invisible and shouldn't appear: 69 check(153,193,0,0,0,0,false,[e.p5]); 70 check(153,193,0,20,0,20, false, [e.p5, e.d2]); 71 72 // Precise pixel checks: 73 check(144, 183, 0, 0, 0, 0, false, []); 74 check(144, 183, 0, 0, 1, 0, false, [e.p5]); 75 check(144, 183, 0, 0, 0, 1, false, [e.d2]); 76 check(144, 183, 0, 0, 1, 1, false, [e.p5, e.d2]); 77 check(77, 240, 0, 0, 0, 0, false, [e.p2]); 78 check(77, 240, 1, 0, 0, 0, false, [e.p5, e.p2]); 79 check(77, 240, 0, 0, 1, 0, false, [e.span, e.p2]); 80 check(77, 240, 1, 0, 1, 0, false, [e.p5, e.span, e.p2]); 81 82 // Expanding area checks: 83 check(39, 212, 0, 0, 0, 0, false, []); 84 check(39, 212, 10, 0, 0, 0, false, [e.d2]); 85 check(39, 212, 0, 0, 10, 0, false, [e.p2]); 86 check(39, 212, 10, 1, 30, 0, false, [e.d2, e.p2]); 87 check(39, 212, 10, 5, 30, 0, false, [e.span, e.d2, e.p2]); 88 check(39, 212, 10, 15, 30, 0, false, [e.p5, e.span, e.d2, e.p2]); 89 90 // Elements inside iframe shouldn't be returned: 91 check(15, 410, 0, 30, 50, 0, false, [e.iframe1]); 92 93 // Area with links and text nodes: 94 let [x1, y1] = getCenterFor(e.a1); 95 let [x2, y2] = getCenterFor(e.a2); 96 let [x3, y3] = getCenterFor(e.a3); 97 let [xt, yt] = [(x2 + x1) / 2, y1]; //text node between a1 and a2 98 99 check(x1, y1, 0, 0, 0, 0, false, [e.a1.firstChild, e.a1, e.p6]); 100 check(x1, y1, 0, 0, y3 - y1, 0, false, [e.a3.firstChild, e.a3, e.a1.firstChild, e.a1, e.p6]); 101 check(x1, y1, 0, xt - x1, 0, 0, false, [e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]); 102 check(x1, y1, 0, x2 - x1, 0, 0, false, [e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]); 103 check(x1, y1, 0, x2 - x1, y3 - y1, 0, false, [e.a3.firstChild, e.a3, e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]); 104 105 // 2d transform: 106 check(61, 671, 0, 0, 0, 0, false, []); 107 check(61, 671, 0, 30, 0, 10, false, [e.transf]); 108 check(61, 671, 0, 30, 90, 10, false, [e.transf.firstChild, e.transf]); 109 110 { 111 info("opacity: with and without aVisibleOnly = true"); 112 let [x, y] = getCenterFor(e.opacity); 113 check(x, y, 1, 1, 1, 1, false, [e.opacity]); 114 check(x, y, 1, 1, 1, 1, true, []); 115 } 116 117 // Check elements behind opaque backgrounds of other elements don't show up 118 // in the list when aVisibleOnly = true. 119 { 120 info("elements behind opaque backgrounds of other elements with aVisibleOnly=true"); 121 let container = document.getElementById('obscured-test'); 122 let fg = document.getElementById('obscured-test-foreground'); 123 let bg = document.getElementById('obscured-test-background'); 124 125 let [x, y] = getCenterFor(container); 126 check(x, y, 1, 1, 1, 1, false, [fg, bg, container]); 127 128 const kListIsComplete = true; 129 130 check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete); 131 check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.5); 132 133 info("Occluded with different opacity thresholds, with background colors and opacity"); 134 fg.style.backgroundColor = "rgba(0, 255, 0, 0.5)"; 135 check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.4); 136 check(x, y, 1, 1, 1, 1, true, [fg, bg], kListIsComplete, 0.6); 137 138 fg.style.backgroundColor = ""; 139 fg.style.opacity = "0.5"; 140 141 check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.4); 142 check(x, y, 1, 1, 1, 1, true, [fg, bg], kListIsComplete, 0.6); 143 } 144 145 { 146 info("Shadow DOM retargeting"); 147 148 let [x, y] = getCenterFor(e.host); 149 let inner = shadow.getElementById("host-inner"); 150 check(x, y, 1, 1, 1, 1, false, [inner, e.host]); 151 } 152 153 done(); 154 } 155 156 function getCenterFor(element) { 157 let rect = element.getBoundingClientRect(); 158 return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2]; 159 } 160 161 addLoadEvent(doTest); 162 </script> 163 <style> 164 body { 165 margin: 8px; 166 padding: 0; 167 } 168 169 h1, div, p, span, iframe { 170 display: block; 171 width: 100px; 172 height: 30px; 173 border: 3px solid black; 174 padding: 10px; 175 margin: 10px; 176 } 177 178 span { 179 display: inline-block; 180 } 181 182 #iframe1 { 183 height: 100px; 184 margin-top: 60px; 185 } 186 187 #p6 { 188 height: 50px; 189 margin-top: 30px; 190 } 191 192 #transf { 193 margin-top: 60px; 194 transform: rotate(-45deg); 195 } 196 197 #opacity { 198 opacity: 0; 199 margin-top: 60px; 200 } 201 202 #decimal { 203 position: relative; 204 left: 0.5px; 205 top: 50.5px; 206 } 207 208 #obscured-test { 209 position: relative; 210 width: 500px; 211 height: 500px; 212 } 213 214 #obscured-test-background { 215 position: absolute; 216 width: 100%; 217 height: 100%; 218 z-index: 0; 219 background: red; 220 } 221 222 #obscured-test-foreground { 223 position: absolute; 224 width: 100%; 225 height: 100%; 226 z-index: 1; 227 background: green; 228 } 229 </style> 230 <body id="body"> 231 <h1 id="h1"></h1> 232 <div id="d1"></div> 233 234 <!-- floated element --> 235 <div id="d2" style="float: left"></div> 236 237 <!-- hidden element --> 238 <p id="p1" style="float: left; visibility: hidden"></p> 239 240 <p id="p2" style="clear: left"><span id="span"></span></p> 241 242 <!-- absolute position --> 243 <p id="p3" style="position:absolute; top: 10px; left:50px; height:50px;"></p> 244 245 <!-- fixed position --> 246 <p id="p4" style="position: fixed; top: 30px; left: 150px; height: 50px; background-color: blue;"></p> 247 248 <!-- relative position --> 249 <p id="p5" style="position:relative; top: -100px; left: 30px; margin-bottom: -70px; background-color: green"></p> 250 251 <!-- decimal CSS pixels --> 252 <div id="decimal"></div> 253 254 <iframe id="iframe1" src="data:text/html,<div>div</div><p>p</p>"></iframe> 255 256 <p id="p6"><a href="#" id="a1">A</a> / <a href="#" id="a2">A</a><br/><a href="#" id="a3">A</a></p> 257 258 <div id="transf">text</div> 259 260 <div id="opacity">text</div> 261 262 <div id="host"></div> 263 264 <div id="obscured-test"> 265 <div id="obscured-test-background"></div> 266 <div id="obscured-test-foreground"></div> 267 </div> 268 </body>