Index: LayoutTests/svg/hittest/update-ellipse.html |
diff --git a/LayoutTests/svg/hittest/update-ellipse.html b/LayoutTests/svg/hittest/update-ellipse.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7b57b11701344dbfe3dede57b85f061fc7ad20cd |
--- /dev/null |
+++ b/LayoutTests/svg/hittest/update-ellipse.html |
@@ -0,0 +1,214 @@ |
+<!DOCTYPE html> |
+<html> |
+<body onload="onPageLoad()"> |
+Regression test for <a href="http://crbug.com/436214">http://crbug.com/436214</a>. This tests updating SVG <circle> and <ellipse> elements having various stroke styles. If this test passes, you will see "PASS" below. |
+<p id="result">WAITING - click within each of the elliptical areas for results</p> |
+<svg id="svg" width="800" height="500" version="1.1"> |
+ <rect fill="none" stroke="black" x="0.5" y="0.5" width="799" height="499"/> |
+ |
+ |
+ |
+ <circle pointer-events="none" stroke-width="10px" stroke="#888" stroke-opacity="0.2" fill="none" cx="380" cy="100" r="20"/> |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#00a0f0" stroke-dasharray="30, 10" stroke-opacity="0.2" fill="none" cx="130" cy="110" rx="100" ry="50"/> |
+ <ellipse pointer-events="none" stroke-width="30px" stroke="#9000f0" stroke-linejoin="bevel" stroke-opacity="0.2" fill="none" cx="150" cy="400" rx="70" ry="50"/> |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#0000f0" stroke-opacity="0.2" fill="none" cx="400" cy="370" rx="40" ry="70"/> |
+ |
+ <circle id="ell0" cursor="move" stroke-width="10px" stroke="#888" stroke-linecap="square" fill="none" cx="380" cy="100" r="20"/> |
+ <ellipse id="ell1" cursor="move" stroke-width="20px" stroke="#00a0f0" stroke-dasharray="30, 10" fill="none" cx="130" cy="110" rx="100" ry="50"/> |
+ <ellipse id="ell2" cursor="move" stroke-width="30px" stroke="#9000f0" stroke-linejoin="bevel" fill="none" cx="150" cy="400" rx="70" ry="50"/> |
+ <ellipse id="ell3" cursor="move" stroke-width="20px" stroke="#0000f0" stroke-linecap="round" fill="none" cx="400" cy="370" rx="40" ry="70"/> |
+ |
+ |
+ |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#0c0" stroke-opacity="0.2" fill="none" cx="625" cy="100" rx="80" ry="30"/> |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#090" stroke-opacity="0.2" fill="none" cx="625" cy="200" rx="80" ry="30"/> |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#060" stroke-opacity="0.2" fill="none" cx="625" cy="300" rx="80" ry="30"/> |
+ <ellipse pointer-events="none" stroke-width="20px" stroke="#030" stroke-opacity="0.2" fill="none" cx="625" cy="400" rx="80" ry="30"/> |
+ |
+ <ellipse id="ell10" cursor="move" stroke-width="20px" stroke="#0c0" fill="none" cx="625" cy="100" rx="80" ry="30"/> |
+ <ellipse id="ell11" cursor="move" stroke-width="20px" stroke="#090" fill="none" cx="625" cy="200" rx="80" ry="30"/> |
+ <ellipse id="ell12" cursor="move" stroke-width="20px" stroke="#060" fill="none" cx="625" cy="300" rx="80" ry="30"/> |
+ <ellipse id="ell13" cursor="move" stroke-width="20px" stroke="#030" fill="none" cx="625" cy="400" rx="80" ry="30"/> |
+</svg> |
+<script type="text/javascript"> |
+if (window.testRunner) { |
+ testRunner.dumpAsText(); |
+ testRunner.waitUntilDone(); |
+} |
+ |
+function withinEllipse(x, y, cx, cy, rx, ry) { |
+ var t1 = (x - cx) / rx, |
+ t2 = (y - cy) / ry; |
+ return t1 * t1 + t2 * t2 <= 1; |
+} |
+ |
+var result = document.getElementById("result"), |
+ svg = document.getElementById("svg"), |
+ ell0 = document.getElementById("ell0"), |
+ ell1 = document.getElementById("ell1"), |
+ ell2 = document.getElementById("ell2"), |
+ ell3 = document.getElementById("ell3"), |
+ ell10 = document.getElementById("ell10"), |
+ ell11 = document.getElementById("ell11"), |
+ ell12 = document.getElementById("ell12"), |
+ ell13 = document.getElementById("ell13"); |
+function onPageLoad() { |
+ var activeAreas = [{ |
+ ellipse: ell0, |
+ click: function () { |
+ this.ellipse.setAttribute("r", "50"); |
+ } |
+ }, { |
+ ellipse: ell1, |
+ click: function () { |
+ this.ellipse.setAttribute("cx", "170"); |
+ } |
+ }, { |
+ ellipse: ell2, |
+ click: function () { |
+ this.ellipse.setAttribute("cy", "350"); |
+ } |
+ }, { |
+ ellipse: ell3, |
+ click: function () { |
+ this.ellipse.setAttribute("cx", "390"); |
+ this.ellipse.setAttribute("cy", "340"); |
+ } |
+ }, { |
+ ellipse: ell10, |
+ click: function () { |
+ this.ellipse.setAttribute("stroke-dasharray", "30, 10"); |
+ } |
+ }, { |
+ ellipse: ell11, |
+ click: function () { |
+ this.ellipse.setAttribute("cx", "655"); |
+ this.ellipse.setAttribute("stroke-miterlimit", "0"); |
+ } |
+ }, { |
+ ellipse: ell12, |
+ click: function () { |
+ this.ellipse.setAttribute("stroke-linejoin", "bevel"); |
+ this.ellipse.setAttribute("cx", "655"); // intentionally swapped to test whether setting 'cx' after changing the stroke makes a difference |
+ } |
+ }, { |
+ ellipse: ell13, |
+ click: function () { |
+ this.ellipse.setAttribute("cx", "655"); |
+ this.ellipse.setAttribute("stroke-linecap", "square"); |
+ } |
+ }]; |
+ |
+ for (var i = 0; i < activeAreas.length; ++i) { |
+ var aa = activeAreas[i]; |
+ aa.cx = +aa.ellipse.getAttribute("cx"); |
+ aa.cy = +aa.ellipse.getAttribute("cy"); |
+ if (aa.ellipse.localName == "circle") { |
+ aa.rx = aa.ry = +aa.ellipse.getAttribute("r"); |
+ } else { |
+ aa.rx = +aa.ellipse.getAttribute("rx"); |
+ aa.ry = +aa.ellipse.getAttribute("ry"); |
+ } |
+ } |
+ |
+ var bcr = svg.getBoundingClientRect(), |
+ x0 = bcr.left << 0, |
+ y0 = bcr.top << 0; |
+ |
+ requestAnimationFrame(function () { |
+ document.addEventListener("mousedown", function onMouseDown(event) { |
+ var x = event.clientX - x0, |
+ y = event.clientY - y0; |
+ for (var i = 0; i < activeAreas.length; ++i) { |
+ var aa = activeAreas[i]; |
+ if (withinEllipse(x, y, aa.cx, aa.cy, aa.rx, aa.ry)) { |
+ aa.click(); |
+ activeAreas.splice(i, 1); |
+ break; |
+ } |
+ } |
+ |
+ if (activeAreas.length == 0) { |
+ document.removeEventListener("mousedown", onMouseDown, false); |
+ |
+ result.textContent = "Running tests..."; |
+ |
+ var tests = [ |
+ { x: 383, y: 120, expectedElem: svg }, |
+ { x: 429, y: 103, expectedElem: ell0 }, |
+ |
+ { x: 225, y: 116, expectedElem: svg }, |
+ { x: 263, y: 87, expectedElem: ell1 }, |
+ |
+ { x: 119, y: 355, expectedElem: svg }, |
+ { x: 150, y: 455, expectedElem: svg }, |
+ { x: 223, y: 392, expectedElem: svg }, |
+ { x: 201, y: 309, expectedElem: ell2 }, |
+ |
+ { x: 364, y: 345, expectedElem: svg }, |
+ { x: 402, y: 269, expectedElem: ell3 }, |
+ |
+ { x: 549, y: 88, expectedElem: svg }, |
+ { x: 662, y: 127, expectedElem: ell10 }, |
+ |
+ { x: 705, y: 202, expectedElem: svg }, |
+ { x: 727, y: 184, expectedElem: ell11 }, |
+ |
+ { x: 705, y: 302, expectedElem: svg }, |
+ { x: 727, y: 284, expectedElem: ell12 }, |
+ |
+ { x: 705, y: 402, expectedElem: svg }, |
+ { x: 727, y: 384, expectedElem: ell13 } |
+ ]; |
+ |
+ for (var i = 0; i < tests.length; ++i) { |
+ var test = tests[i], |
+ elem = document.elementFromPoint(x0 + test.x, y0 + test.y), |
+ success; |
+ if (elem !== test.expectedElem) { |
+ success = false; |
+ result.textContent = "FAIL - unexpected element at (" + test.x + ", " + test.y + ")"; |
+ } else { |
+ success = true; |
+ } |
+ |
+ // Draw a dot and a label at the test point (helps with identification). |
+ var dot = document.createElementNS("http://www.w3.org/2000/svg", "circle"); |
+ dot.setAttribute("pointer-events", "none"); |
+ dot.setAttribute("cx", test.x); |
+ dot.setAttribute("cy", test.y); |
+ dot.setAttribute("r", "2"); |
+ if (!success) dot.setAttribute("fill", "red"); |
+ svg.appendChild(dot); |
+ var label = document.createElementNS("http://www.w3.org/2000/svg", "text"); |
+ label.setAttribute("pointer-events", "none"); |
+ label.setAttribute("x", test.x + 4); |
+ label.setAttribute("y", test.y); |
+ label.textContent = "(" + test.x + ", " + test.y + ")"; |
+ if (!success) label.setAttribute("fill", "red"); |
+ svg.appendChild(label); |
+ } |
+ |
+ if (result.textContent == "Running tests...") |
+ result.textContent = "PASS"; |
+ |
+ if (window.testRunner) |
+ testRunner.notifyDone(); |
+ } |
+ }, false); |
+ |
+ if (window.eventSender) { |
+ // The bug would only occur if the shape attributes were modified |
+ // within a mouse event handler when the mouse cursor was within |
+ // the shape. |
+ activeAreas.slice(0).map(function (aa, i, activeAreas) { |
+ eventSender.mouseMoveTo((x0 + aa.cx) << 0, (y0 + aa.cy) << 0); |
+ eventSender.mouseDown(); |
+ eventSender.mouseUp(); |
+ }); |
+ } |
+ }); |
+} |
+</script> |
+</body> |
+</html> |