Fix hit testing on display:block <svg> elements
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Sep 2016 18:09:59 +0000 (18:09 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Sep 2016 18:09:59 +0000 (18:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162717
rdar://problem/23261130

Reviewed by Zalan Bujtas.
Source/WebCore:

RenderSVGRoot::nodeAtPoint() needs to test for both the HitTestBlockBackground and
HitTestChildBlockBackground phases, since we only get the HitTestChildBlockBackground
phase when the <svg> is a block. This is similar to code in RenderTable::nodeAtPoint(),
and matches Blink code.

This fixes the point dragging on http://anthonydugois.com/svg-path-builder/.

Test: svg/hittest/block-svg.html

* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::nodeAtPoint):

LayoutTests:

Test hit testing on inline and block <svg> elements.

* svg/hittest/block-svg-expected.txt: Added.
* svg/hittest/block-svg.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206591 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/svg/hittest/block-svg-expected.txt [new file with mode: 0644]
LayoutTests/svg/hittest/block-svg.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGRoot.cpp

index a82b47e..f343c7a 100644 (file)
@@ -1,3 +1,16 @@
+2016-09-29  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix hit testing on display:block <svg> elements
+        https://bugs.webkit.org/show_bug.cgi?id=162717
+        rdar://problem/23261130
+
+        Reviewed by Zalan Bujtas.
+        
+        Test hit testing on inline and block <svg> elements.
+
+        * svg/hittest/block-svg-expected.txt: Added.
+        * svg/hittest/block-svg.html: Added.
+
 2016-09-29  Saam Barati  <sbarati@apple.com>
 
         We don't properly propagate non-simple-parameter-list when parsing a setter
diff --git a/LayoutTests/svg/hittest/block-svg-expected.txt b/LayoutTests/svg/hittest/block-svg-expected.txt
new file mode 100644 (file)
index 0000000..ce9e29c
--- /dev/null
@@ -0,0 +1,3 @@
+ PASS: element at 28, 20 is svg
+PASS: element at 28, 130 is svg
+
diff --git a/LayoutTests/svg/hittest/block-svg.html b/LayoutTests/svg/hittest/block-svg.html
new file mode 100644 (file)
index 0000000..c7cc308
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .container {
+            height: 100px;
+            width: 200px;
+            margin: 10px;
+        }
+        
+        svg {
+            background-color: silver;
+        }
+
+        svg:hover {
+            background-color: green;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function doTest()
+        {
+            var svgElements = document.getElementsByTagName('svg');
+            var result = '';
+
+            for (var i = 0; i < svgElements.length; ++i) {
+                var element = svgElements[i];
+                
+                var rect = element.getBoundingClientRect();
+                var left = rect.left + 10;
+                var top = rect.top + 10;
+                var hitElement = document.elementFromPoint(left, top);
+                
+                if (element === hitElement)
+                    result += 'PASS: element at ' + left + ', ' + top + ' is ' + element.tagName + '\n';
+                else
+                    result += 'FAIL: expected to hit ' + element.tagName + ' at ' + left + ', ' + top + ' but hit ' + hitElement.tagName + '\n';
+            }
+            
+            document.getElementById('result').textContent = result;
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<div class="container">
+       <svg  width="200" height="100"></svg>
+</div>
+
+<div class="container">
+       <svg width="200" height="100" style="display: block;"></svg>
+</div>
+<pre id="result"></pre>
+</body>
+</html>
index 156ec48..16e28cb 100644 (file)
@@ -1,3 +1,23 @@
+2016-09-29  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix hit testing on display:block <svg> elements
+        https://bugs.webkit.org/show_bug.cgi?id=162717
+        rdar://problem/23261130
+
+        Reviewed by Zalan Bujtas.
+
+        RenderSVGRoot::nodeAtPoint() needs to test for both the HitTestBlockBackground and
+        HitTestChildBlockBackground phases, since we only get the HitTestChildBlockBackground
+        phase when the <svg> is a block. This is similar to code in RenderTable::nodeAtPoint(),
+        and matches Blink code.
+        
+        This fixes the point dragging on http://anthonydugois.com/svg-path-builder/.
+
+        Test: svg/hittest/block-svg.html
+
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::nodeAtPoint):
+
 2016-09-29  Chris Dumez  <cdumez@apple.com>
 
         Assigning non-numeric to input.minlength should set minlength to 0
index 2ab5524..1aca4e5 100644 (file)
@@ -444,7 +444,7 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
     }
 
     // If we didn't early exit above, we've just hit the container <svg> element. Unlike SVG 1.1, 2nd Edition allows container elements to be hit.
-    if (hitTestAction == HitTestBlockBackground && visibleToHitTesting()) {
+    if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && visibleToHitTesting()) {
         // Only return true here, if the last hit testing phase 'BlockBackground' is executed. If we'd return true in the 'Foreground' phase,
         // hit testing would stop immediately. For SVG only trees this doesn't matter. Though when we have a <foreignObject> subtree we need
         // to be able to detect hits on the background of a <div> element. If we'd return true here in the 'Foreground' phase, we are not able