[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

simon.fraser at apple.com simon.fraser at apple.com
Thu Apr 8 01:03:07 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 3f428dab5aced66fc5d8d0b0dba83fea0017b169
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 13 02:08:10 2010 +0000

    2010-01-12  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            position:fixed and transform on same element breaks fixed behavior
            https://bugs.webkit.org/show_bug.cgi?id=31283
    
            Fix interactions of transforms and fixed positioning, namely that fixed position
            elements with a transformed ancestor are positioned relative to that ancestor,
            and an element with both a transform and fixed position respects that positioning.
    
            Test: transforms/2d/transform-fixed-container.html
    
            * rendering/RenderBox.cpp:
            (WebCore::RenderBox::mapLocalToContainer):
            (WebCore::RenderBox::mapAbsoluteToLocalPoint):
            Transforms should not unconditionally stop the propagation of the 'fixed' flag to ancestors,
            but only if the transformed element is not itself fixed.
    
            * rendering/RenderLayer.cpp:
            (WebCore::RenderLayer::convertToLayerCoords):
            Fix this method to behave correctly for fixed position layers whose container is not
            the root, but some other (probably transformed) ancestor. In that case, we can fall into
            the "position: absolute" code path.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53173 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 6cc315d..dc85980 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2010-01-12  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        position:fixed and transform on same element breaks fixed behavior
+        https://bugs.webkit.org/show_bug.cgi?id=31283
+
+        Test for transforms combined with fixed positioning.
+
+        * platform/mac/transforms/2d/transform-fixed-container-expected.checksum: Added.
+        * platform/mac/transforms/2d/transform-fixed-container-expected.png: Added.
+        * platform/mac/transforms/2d/transform-fixed-container-expected.txt: Added.
+        * transforms/2d/transform-fixed-container.html: Added.
+
 2010-01-12  Dumitru Daniliuc  <dumi at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.checksum b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.checksum
new file mode 100644
index 0000000..90c383a
--- /dev/null
+++ b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.checksum
@@ -0,0 +1 @@
+05d9d1096dd096c0b90015f79a2ad6a8
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.png b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.png
new file mode 100644
index 0000000..eba120f
Binary files /dev/null and b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.png differ
diff --git a/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.txt b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.txt
new file mode 100644
index 0000000..72c1c8e
--- /dev/null
+++ b/LayoutTests/platform/mac/transforms/2d/transform-fixed-container-expected.txt
@@ -0,0 +1,21 @@
+layer at (0,0) size 785x1150
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x1150
+  RenderBlock {HTML} at (0,0) size 785x1150
+    RenderBody {BODY} at (0,150) size 785x1000
+      RenderBlock {P} at (0,250) size 785x18
+        RenderText {#text} at (0,0) size 546x18
+          text run at (0,0) width 546: "Tests fixed position elements combined with transforms. You should see no red above."
+layer at (50,200) size 100x100
+  RenderBlock (positioned) {DIV} at (50,200) size 100x100 [bgcolor=#FF0000]
+layer at (250,200) size 100x100
+  RenderBlock (positioned) {DIV} at (250,200) size 100x100 [bgcolor=#FF0000]
+layer at (50,150) size 100x100
+  RenderBlock {DIV} at (50,0) size 100x100
+layer at (50,200) size 100x100
+  RenderBlock (positioned) {DIV} at (0,50) size 100x100 [bgcolor=#008000]
+layer at (250,150) size 100x100
+  RenderBlock (positioned) {DIV} at (250,50) size 100x100
+layer at (250,200) size 100x100
+  RenderBlock {DIV} at (0,50) size 100x100 [bgcolor=#008000]
+scrolled to 0,100
diff --git a/LayoutTests/transforms/2d/transform-fixed-container.html b/LayoutTests/transforms/2d/transform-fixed-container.html
new file mode 100644
index 0000000..79818cc
--- /dev/null
+++ b/LayoutTests/transforms/2d/transform-fixed-container.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    body {
+      margin: 0;
+      height: 1000px;
+    }
+    
+    .box {
+      width: 100px;
+      height: 100px;
+      outline: 1px solid black;
+    }
+
+    .fixed {
+      position: fixed;
+    }
+
+    .transformed {
+      -webkit-transform: rotate(0);
+    }
+    
+    .indicator {
+      position: absolute;
+      background-color: red;
+    }
+    
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    // Scroll on load to test fixed positioning.
+    window.addEventListener('load', function() {
+      window.scrollTo(0, 100);
+    }, false)
+  </script>
+</head>
+<body>
+
+  <div class="indicator box" style="left: 50px; top: 200px;"></div>
+  <div class="indicator box" style="left: 250px; top: 200px;"></div>
+
+  <div class="transformed box" style="margin: 150px 50px;">
+    <div class="fixed box" style="background-color: green; margin-top: 50px;">
+    </div>
+  </div>
+
+  <div class="transformed fixed box" style="left: 250px; top: 50px;">
+    <div class="transformed box" style="margin-top: 50px; background-color: green;">
+    </div>
+  </div>
+
+  <p>Tests fixed position elements combined with transforms. You should see no red above.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 96900e3..b9baad0 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-12  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        position:fixed and transform on same element breaks fixed behavior
+        https://bugs.webkit.org/show_bug.cgi?id=31283
+
+        Fix interactions of transforms and fixed positioning, namely that fixed position
+        elements with a transformed ancestor are positioned relative to that ancestor,
+        and an element with both a transform and fixed position respects that positioning.
+        
+        Test: transforms/2d/transform-fixed-container.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::mapLocalToContainer):
+        (WebCore::RenderBox::mapAbsoluteToLocalPoint):
+        Transforms should not unconditionally stop the propagation of the 'fixed' flag to ancestors,
+        but only if the transformed element is not itself fixed.
+        
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::convertToLayerCoords):
+        Fix this method to behave correctly for fixed position layers whose container is not
+        the root, but some other (probably transformed) ancestor. In that case, we can fall into
+        the "position: absolute" code path.
+
 2010-01-12  Tony Chang  <tony at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 339193a..0c3423c 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -941,18 +941,20 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
         }
     }
 
-    if (style()->position() == FixedPosition)
-        fixed = true;
-
     bool containerSkipped;
     RenderObject* o = container(repaintContainer, &containerSkipped);
     if (!o)
         return;
 
+    bool isFixedPos = style()->position() == FixedPosition;
     bool hasTransform = hasLayer() && layer()->transform();
-    if (hasTransform)
-        fixed = false;  // Elements with transforms act as a containing block for fixed position descendants
-
+    if (hasTransform) {
+        // If this box has a transform, it acts as a fixed position container for fixed descendants,
+        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
+        fixed &= isFixedPos;
+    } else
+        fixed |= isFixedPos;
+    
     IntSize containerOffset = offsetFromContainer(o);
 
     bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
@@ -979,12 +981,14 @@ void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Transfor
     // We don't expect absoluteToLocal() to be called during layout (yet)
     ASSERT(!view() || !view()->layoutStateEnabled());
     
-    if (style()->position() == FixedPosition)
-        fixed = true;
-
+    bool isFixedPos = style()->position() == FixedPosition;
     bool hasTransform = hasLayer() && layer()->transform();
-    if (hasTransform)
-        fixed = false;  // Elements with transforms act as a containing block for fixed position descendants
+    if (hasTransform) {
+        // If this box has a transform, it acts as a fixed position container for fixed descendants,
+        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
+        fixed &= isFixedPos;
+    } else
+        fixed |= isFixedPos;
     
     RenderObject* o = container();
     if (!o)
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 0063ea3..93d0299 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -986,9 +986,10 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
 {
     if (ancestorLayer == this)
         return;
-        
-    if (renderer()->style()->position() == FixedPosition) {
-        // Add in the offset of the view.  We can obtain this by calling
+
+    EPosition position = renderer()->style()->position();
+    if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer()) {
+        // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
         // localToAbsolute() on the RenderView.
         FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
         xPos += absPos.x();
@@ -997,8 +998,11 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
     }
  
     RenderLayer* parentLayer;
-    if (renderer()->style()->position() == AbsolutePosition) {
-        // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way
+    // For a fixed layer, if we're asking for coords relative to some other ancestor, then it must be
+    // enclosed in a fixed position container (e.g. a transformed element), so it behaves like an absolutely
+    // positioned element.
+    if (position == AbsolutePosition || position == FixedPosition) {
+        // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
         parentLayer = parent();
         bool foundAncestorFirst = false;
         while (parentLayer) {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list