Fix hover area for divs with css transforms
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Nov 2013 15:17:08 +0000 (15:17 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Nov 2013 15:17:08 +0000 (15:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124647

Patch by Mihai Maerean <mmaerean@adobe.com> on 2013-11-21
Reviewed by Allan Sandfeld Jensen.

Source/WebCore:

Non transformed layers are now being hit last, not through or in-between transformed layers.
The paint order says that the divs creating stacking contexts (including transforms) are painted after the
other siblings so they should be hit tested in the reverse order. Also, a rotated div in a non-rotated parent
should be hit in its entire area, not hit its parent's background, even if the z-coordinate is negative where
the mouse is located.

Test: transforms/3d/hit-testing/hover-rotated-negative-z.html

* rendering/RenderLayer.cpp:
(WebCore::computeZOffset):

LayoutTests:

* transforms/3d/hit-testing/hover-rotated-negative-z.html: Added.
* transforms/3d/hit-testing/hover-rotated-negative-z-expected.txt: Added.

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

LayoutTests/ChangeLog
LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z-expected.txt [new file with mode: 0644]
LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp

index 2a29ddc..213f5ca 100644 (file)
@@ -1,3 +1,13 @@
+2013-11-21  Mihai Maerean  <mmaerean@adobe.com>
+
+        Fix hover area for divs with css transforms
+        https://bugs.webkit.org/show_bug.cgi?id=124647
+
+        Reviewed by Allan Sandfeld Jensen.
+
+        * transforms/3d/hit-testing/hover-rotated-negative-z.html: Added.
+        * transforms/3d/hit-testing/hover-rotated-negative-z-expected.txt: Added.
+
 2013-11-21  Radu Stavila  <stavila@adobe.com>
 
         Created test for positioned fragmented content which overflows the regions.
diff --git a/LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z-expected.txt b/LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z-expected.txt
new file mode 100644 (file)
index 0000000..18c8230
--- /dev/null
@@ -0,0 +1,8 @@
+transformed
+Test passes if the hover state of a transformed div is activated on the entire surface of the div.
+
+Element at 70, 70 has id "transformed": PASS
+Element at 630, 130 has id "transformed": PASS
+Element at 40, 130 has id "transformed": PASS
+Element at 620, 270 has id "transformed": PASS
+
diff --git a/LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z.html b/LayoutTests/transforms/3d/hit-testing/hover-rotated-negative-z.html
new file mode 100644 (file)
index 0000000..dd23690
--- /dev/null
@@ -0,0 +1,42 @@
+<html>
+       <head>
+               <title>Test - Bug #124647: Fix hover area for divs with css transforms</title>
+               <style>
+                       #transformed {
+                               -webkit-transform: translateY(50px) rotateX(20deg) rotateZ(10deg);
+                               border: solid 5px rgba(128,128,128,0.5);
+                               padding: 10px;
+                               margin: 15px;
+                       }
+                       #transformed:hover {
+                               box-shadow: 0px 0px 0px 10px rgba(0,128,0,0.5);
+                       }
+                       #parent {
+                               outline: dotted 1px #888;
+                       }
+                       #transformed, #parent {
+                               width: 600px;
+                               height: 150px;
+                       }
+               </style>
+
+               <script src="resources/hit-test-utils.js"></script>
+               <script>
+                       const hitTestData = [
+                               { 'point': [70, 70], 'target' : 'transformed' },
+                               { 'point': [630, 130], 'target' : 'transformed' },
+                               { 'point': [40, 130], 'target' : 'transformed' },
+                               { 'point': [620, 270], 'target' : 'transformed' }
+                       ];
+
+                       window.addEventListener('load', runTest, false);
+                 </script>
+       </head>
+       <body id="body">
+               <div id="parent"><div id="transformed">transformed</div></div>
+
+               <p>Test passes if the hover state of a transformed div is activated on the entire surface of the div.</p>
+
+               <div id="results"></div>
+       </body>
+</html>
\ No newline at end of file
index 0e1d7a3..8be01fb 100644 (file)
@@ -1,3 +1,21 @@
+2013-11-21  Mihai Maerean  <mmaerean@adobe.com>
+
+        Fix hover area for divs with css transforms
+        https://bugs.webkit.org/show_bug.cgi?id=124647
+
+        Reviewed by Allan Sandfeld Jensen.
+
+        Non transformed layers are now being hit last, not through or in-between transformed layers.
+        The paint order says that the divs creating stacking contexts (including transforms) are painted after the
+        other siblings so they should be hit tested in the reverse order. Also, a rotated div in a non-rotated parent
+        should be hit in its entire area, not hit its parent's background, even if the z-coordinate is negative where
+        the mouse is located.
+
+        Test: transforms/3d/hit-testing/hover-rotated-negative-z.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::computeZOffset):
+
 2013-11-21  Andres Gomez  <agomez@igalia.com>
 
         [GTK] Release compilation fails when defining "LOG_DISABLED=0"
index 3a51fa2..00ce546 100644 (file)
@@ -4545,8 +4545,14 @@ bool RenderLayer::isFlowThreadCollectingGraphicsLayersUnderRegions() const
 static double computeZOffset(const HitTestingTransformState& transformState)
 {
     // We got an affine transform, so no z-offset
-    if (transformState.m_accumulatedTransform.isAffine())
-        return 0;
+    if (transformState.m_accumulatedTransform.isAffine()) {
+        // Non transformed layers are being hit last, not through or in-between transformed layers.
+        // The paint order says that the divs creating stacking contexts (including transforms) are painted after the
+        // other siblings so they should be hit tested in the reverse order. Also, a rotated div in a non-rotated parent
+        // should be hit in its entire area, not hit its parent's background, even if the z-coordinate is negative where
+        // the mouse is located.
+        return -std::numeric_limits<int>::max();
+    }
 
     // Flatten the point into the target plane
     FloatPoint targetPoint = transformState.mappedPoint();