diff options
Diffstat (limited to '')
-rw-r--r-- | dom/tests/mochitest/chrome/489127.html | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/dom/tests/mochitest/chrome/489127.html b/dom/tests/mochitest/chrome/489127.html new file mode 100644 index 0000000000..3198edf195 --- /dev/null +++ b/dom/tests/mochitest/chrome/489127.html @@ -0,0 +1,268 @@ +<!DOCTYPE HTML> +<title>nsIDOMWindowUtils::nodesFromRect test - bug 489127</title> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"> +<script> + var SimpleTest = window.opener.SimpleTest; + function ok() { window.opener.ok.apply(window.opener, arguments); } + function done() { window.opener.done.apply(window.opener, arguments); } + function info() { window.opener.info.apply(window.opener, arguments); } + + let e = {}; + + let dwu = window.windowUtils; + + function check(x, y, top, right, bottom, left, onlyVisible, list, aListIsComplete = false, aOpacityThreshold = 1.0) { + let nodes = dwu.nodesFromRect(x, y, top, right, bottom, left, /* aIgnoreRootScrollFrame = */ true, /* aFlushLayout = */ true, onlyVisible, aOpacityThreshold); + + if (!aListIsComplete) { + list.push(e.body); + list.push(e.html); + } + + if (nodes.length != list.length) { + ok(false, "Different number of nodes (" + nodes.length + " vs. " + list.length + + ") for rect [" + x + "," + y + "], " + + "[" + top + "," + right + "," + bottom + "," + left + "]"); + return; + } + + for (var i = 0; i < nodes.length; i++) { + if (nodes[i] != list[i]) { + ok(false, `Unexpected node #${i} (${nodes[i].id} vs. ${list[i].id}) ` + + `[${x}, ${y}] [${top}, ${right}, ${bottom}, ${left}]`); + return; + } + } + ok(true, "All correct nodes found for rect " + + "[" + x + "," + y + "], " + + "[" + top + "," + right + "," + bottom + "," + left + "]"); + } + + function doTest() { + // Set up shortcut access to elements + e.html = document.documentElement; + ['h1', 'd1', 'd2', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'span', + 'a1', 'a2', 'a3', 'transf', 'iframe1', 'body', 'opacity', 'host'].forEach(function(a) { + e[a] = document.getElementById(a); + }); + + let shadow = e.host.attachShadow({ mode: "open" }); + shadow.innerHTML = ` + <style> + #host-inner { height: 100px; width: 100px; background-color: blue } + </style> + <div id="host-inner"></div> + `; + + window.scrollTo(0, 0); + + // Top, Right, Bottom, Left directions: + check(53, 71, 0, 0, 0, 0, false, []); + check(53, 71, 10, 0, 0, 0, false, [e.h1]); + check(53, 71, 0, 10, 0, 0, false, [e.p3]); + check(53, 71, 0, 0, 10, 0, false, [e.d1]); + check(152, 105, 0, 0, 0, 10, false, [e.d1]); + check(152, 105, 10, 10, 10, 10, false, [e.p4, e.p3, e.d1]); + + // e.p1 is invisible and shouldn't appear: + check(153,193,0,0,0,0,false,[e.p5]); + check(153,193,0,20,0,20, false, [e.p5, e.d2]); + + // Precise pixel checks: + check(144, 183, 0, 0, 0, 0, false, []); + check(144, 183, 0, 0, 1, 0, false, [e.p5]); + check(144, 183, 0, 0, 0, 1, false, [e.d2]); + check(144, 183, 0, 0, 1, 1, false, [e.p5, e.d2]); + check(77, 240, 0, 0, 0, 0, false, [e.p2]); + check(77, 240, 1, 0, 0, 0, false, [e.p5, e.p2]); + check(77, 240, 0, 0, 1, 0, false, [e.span, e.p2]); + check(77, 240, 1, 0, 1, 0, false, [e.p5, e.span, e.p2]); + + // Expanding area checks: + check(39, 212, 0, 0, 0, 0, false, []); + check(39, 212, 10, 0, 0, 0, false, [e.d2]); + check(39, 212, 0, 0, 10, 0, false, [e.p2]); + check(39, 212, 10, 1, 30, 0, false, [e.d2, e.p2]); + check(39, 212, 10, 5, 30, 0, false, [e.span, e.d2, e.p2]); + check(39, 212, 10, 15, 30, 0, false, [e.p5, e.span, e.d2, e.p2]); + + // Elements inside iframe shouldn't be returned: + check(15, 410, 0, 30, 50, 0, false, [e.iframe1]); + + // Area with links and text nodes: + let [x1, y1] = getCenterFor(e.a1); + let [x2, y2] = getCenterFor(e.a2); + let [x3, y3] = getCenterFor(e.a3); + let [xt, yt] = [(x2 + x1) / 2, y1]; //text node between a1 and a2 + + check(x1, y1, 0, 0, 0, 0, false, [e.a1.firstChild, e.a1, e.p6]); + check(x1, y1, 0, 0, y3 - y1, 0, false, [e.a3.firstChild, e.a3, e.a1.firstChild, e.a1, e.p6]); + check(x1, y1, 0, xt - x1, 0, 0, false, [e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]); + 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]); + 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]); + + // 2d transform: + check(61, 671, 0, 0, 0, 0, false, []); + check(61, 671, 0, 30, 0, 10, false, [e.transf]); + check(61, 671, 0, 30, 90, 10, false, [e.transf.firstChild, e.transf]); + + { + info("opacity: with and without aVisibleOnly = true"); + let [x, y] = getCenterFor(e.opacity); + check(x, y, 1, 1, 1, 1, false, [e.opacity]); + check(x, y, 1, 1, 1, 1, true, []); + } + + // Check elements behind opaque backgrounds of other elements don't show up + // in the list when aVisibleOnly = true. + { + info("elements behind opaque backgrounds of other elements with aVisibleOnly=true"); + let container = document.getElementById('obscured-test'); + let fg = document.getElementById('obscured-test-foreground'); + let bg = document.getElementById('obscured-test-background'); + + let [x, y] = getCenterFor(container); + check(x, y, 1, 1, 1, 1, false, [fg, bg, container]); + + const kListIsComplete = true; + + check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete); + check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.5); + + info("Occluded with different opacity thresholds, with background colors and opacity"); + fg.style.backgroundColor = "rgba(0, 255, 0, 0.5)"; + check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.4); + check(x, y, 1, 1, 1, 1, true, [fg, bg], kListIsComplete, 0.6); + + fg.style.backgroundColor = ""; + fg.style.opacity = "0.5"; + + check(x, y, 1, 1, 1, 1, true, [fg], kListIsComplete, 0.4); + check(x, y, 1, 1, 1, 1, true, [fg, bg], kListIsComplete, 0.6); + } + + { + info("Shadow DOM retargeting"); + + let [x, y] = getCenterFor(e.host); + let inner = shadow.getElementById("host-inner"); + check(x, y, 1, 1, 1, 1, false, [inner, e.host]); + } + + done(); + } + + function getCenterFor(element) { + let rect = element.getBoundingClientRect(); + return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2]; + } + + addLoadEvent(doTest); +</script> +<style> +body { + margin: 8px; + padding: 0; +} + +h1, div, p, span, iframe { + display: block; + width: 100px; + height: 30px; + border: 3px solid black; + padding: 10px; + margin: 10px; +} + +span { + display: inline-block; +} + +#iframe1 { + height: 100px; + margin-top: 60px; +} + +#p6 { + height: 50px; + margin-top: 30px; +} + +#transf { + margin-top: 60px; + transform: rotate(-45deg); +} + +#opacity { + opacity: 0; + margin-top: 60px; +} + +#decimal { + position: relative; + left: 0.5px; + top: 50.5px; +} + +#obscured-test { + position: relative; + width: 500px; + height: 500px; +} + +#obscured-test-background { + position: absolute; + width: 100%; + height: 100%; + z-index: 0; + background: red; +} + +#obscured-test-foreground { + position: absolute; + width: 100%; + height: 100%; + z-index: 1; + background: green; +} +</style> +<body id="body"> + <h1 id="h1"></h1> + <div id="d1"></div> + + <!-- floated element --> + <div id="d2" style="float: left"></div> + + <!-- hidden element --> + <p id="p1" style="float: left; visibility: hidden"></p> + + <p id="p2" style="clear: left"><span id="span"></span></p> + + <!-- absolute position --> + <p id="p3" style="position:absolute; top: 10px; left:50px; height:50px;"></p> + + <!-- fixed position --> + <p id="p4" style="position: fixed; top: 30px; left: 150px; height: 50px; background-color: blue;"></p> + + <!-- relative position --> + <p id="p5" style="position:relative; top: -100px; left: 30px; margin-bottom: -70px; background-color: green"></p> + + <!-- decimal CSS pixels --> + <div id="decimal"></div> + + <iframe id="iframe1" src="data:text/html,<div>div</div><p>p</p>"></iframe> + + <p id="p6"><a href="#" id="a1">A</a> / <a href="#" id="a2">A</a><br/><a href="#" id="a3">A</a></p> + + <div id="transf">text</div> + + <div id="opacity">text</div> + + <div id="host"></div> + + <div id="obscured-test"> + <div id="obscured-test-background"></div> + <div id="obscured-test-foreground"></div> + </div> +</body> |