Fixed position element is truncated if moved onscreen by a transform
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Apr 2015 17:55:07 +0000 (17:55 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Apr 2015 17:55:07 +0000 (17:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143655
Source/WebCore:

rdar://problem/15020044

Reviewed by Darin Adler.

Our "don't do layout if transform changes" code was too aggressive.
If an element changes between having a transform and not having one, we
really need to do a layout since so much else depends on transforms. In
this particular case, we clip position:fixed elements to the viewport if
they are not transformed, and were failing to re-evaluate this when a
transform was added. Doing a layout fixes this.

Test: compositing/geometry/fixed-transformed.html

* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresLayout):
* rendering/style/StyleTransformData.h:
(WebCore::StyleTransformData::hasTransform):

LayoutTests:

Reviewed by Darin Adler.

Test that moves a position:fixed element on-screen using a transform.

* compositing/geometry/fixed-transformed.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/geometry/fixed-transformed.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/StyleTransformData.h

index 0cbd852..1cb78be 100644 (file)
@@ -1,3 +1,14 @@
+2015-04-13  Simon Fraser  <simon.fraser@apple.com>
+
+        Fixed position element is truncated if moved onscreen by a transform
+        https://bugs.webkit.org/show_bug.cgi?id=143655
+
+        Reviewed by Darin Adler.
+        
+        Test that moves a position:fixed element on-screen using a transform.
+
+        * compositing/geometry/fixed-transformed.html: Added.
+
 2015-04-13  Alexey Proskuryakov  <ap@apple.com>
 
         js/regress-141098.html often times out in debug builds.
diff --git a/LayoutTests/compositing/geometry/fixed-transformed.html b/LayoutTests/compositing/geometry/fixed-transformed.html
new file mode 100644 (file)
index 0000000..4bdfa07
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        #slider {
+            position: fixed;
+            top: 100px;
+            left: -100px;
+            width: 200px;
+            height: 100px;
+            background-color: blue;
+            border: 10px solid gray;
+        }
+        #slider.out {
+            -webkit-transform: translateX(100px);
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+        window.addEventListener('load', function() {
+            window.setTimeout(function() {
+                document.getElementById('slider').classList.add('out');
+                if (window.testRunner) {
+                    document.getElementById('layertree').innerText = window.internals.layerTreeAsText(document);
+                    testRunner.notifyDone();
+                }
+            }, 0);
+        }, false);
+        
+    </script>
+</head>
+<body>
+<div id="slider"></div>
+<pre id="layertree"></pre>
+</body>
+</html>
index 4e04dc6..bcea040 100644 (file)
@@ -1,3 +1,25 @@
+2015-04-13  Simon Fraser  <simon.fraser@apple.com>
+
+        Fixed position element is truncated if moved onscreen by a transform
+        https://bugs.webkit.org/show_bug.cgi?id=143655
+        rdar://problem/15020044
+
+        Reviewed by Darin Adler.
+        
+        Our "don't do layout if transform changes" code was too aggressive.
+        If an element changes between having a transform and not having one, we
+        really need to do a layout since so much else depends on transforms. In
+        this particular case, we clip position:fixed elements to the viewport if
+        they are not transformed, and were failing to re-evaluate this when a
+        transform was added. Doing a layout fixes this.
+
+        Test: compositing/geometry/fixed-transformed.html
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresLayout):
+        * rendering/style/StyleTransformData.h:
+        (WebCore::StyleTransformData::hasTransform):
+
 2015-04-12  Darin Adler  <darin@apple.com>
 
         [Cocoa] Localizable strings are inconsistent and need to be regenerated
index 35ec7f1..958ff02 100644 (file)
@@ -482,10 +482,13 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& chang
             && *rareNonInheritedData->m_multiCol.get() != *other.rareNonInheritedData->m_multiCol.get())
             return true;
 
-        if (rareNonInheritedData->m_transform.get() != other.rareNonInheritedData->m_transform.get()
-            && *rareNonInheritedData->m_transform.get() != *other.rareNonInheritedData->m_transform.get()) {
-            changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
-            // Don't return; keep looking for another change
+        if (rareNonInheritedData->m_transform != other.rareNonInheritedData->m_transform) {
+            if (rareNonInheritedData->m_transform->hasTransform() != other.rareNonInheritedData->m_transform->hasTransform())
+                return true;
+            if (*rareNonInheritedData->m_transform != *other.rareNonInheritedData->m_transform) {
+                changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
+                // Don't return; keep looking for another change
+            }
         }
 
 #if ENABLE(CSS_GRID_LAYOUT)
index 5a45253..b8fb090 100644 (file)
@@ -42,6 +42,8 @@ public:
     {
         return !(*this == o);
     }
+    
+    bool hasTransform() const { return m_operations.size(); }
 
     TransformOperations m_operations;
     Length m_x;