| 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>
 | 
| 
 |