Title: [135670] trunk
Revision
135670
Author
[email protected]
Date
2012-11-25 10:35:10 -0800 (Sun, 25 Nov 2012)

Log Message

Changing position:relative to position:static results in mis-positioned div
https://bugs.webkit.org/show_bug.cgi?id=26397

Reviewed by Ojan Vafai.

Source/WebCore:

When a block changes position from relative to static it is no longer the containing block for any
positioned objects it may have. If any of those positioned objects actually have a position specified
they are going to need a layout as their new containing block will likely have a different location they
need to offset from. Positioned objects without a specified position always get a layout anyway
in layoutPositionedObjects() so no need to worry about them in this situation.

Test: fast/block/abspos-child-container-changes-from-relative-to-static-expected.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::styleWillChange):
(WebCore::RenderBlock::layoutPositionedObjects):
(WebCore::RenderBlock::removePositionedObjects):
* rendering/RenderBlock.h:
(RenderBlock):

LayoutTests:

* fast/block/abspos-child-container-changes-from-relative-to-static-expected.html: Added
* fast/block/abspos-child-container-changes-from-relative-to-static.html: Added

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (135669 => 135670)


--- trunk/LayoutTests/ChangeLog	2012-11-25 18:30:14 UTC (rev 135669)
+++ trunk/LayoutTests/ChangeLog	2012-11-25 18:35:10 UTC (rev 135670)
@@ -1,3 +1,13 @@
+2012-10-08  Robert Hogan  <[email protected]>
+
+        Changing position:relative to position:static results in mis-positioned div
+        https://bugs.webkit.org/show_bug.cgi?id=26397
+
+        Reviewed by Ojan Vafai.
+
+        * fast/block/abspos-child-container-changes-from-relative-to-static-expected.html: Added
+        * fast/block/abspos-child-container-changes-from-relative-to-static.html: Added
+
 2012-11-25  Mikhail Pozdnyakov  <[email protected]>
 
         [WK2] TiledBackingStore: page contents is scaled wrongly

Added: trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static-expected.html (0 => 135670)


--- trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static-expected.html	2012-11-25 18:35:10 UTC (rev 135670)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+<style>
+  body {
+      margin-left: 100px;
+      width: 400px;
+  }
+
+  #container {
+      top: 200px;
+      left: 100px;
+      height: 100px;
+      border: 1px solid black;
+  }
+
+  #inner, #marker {
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 100px;
+      height: 100px;
+      background-color: green;
+  }
+  
+  #marker {
+      background-color: red;
+  }
+</style>
+</head>
+
+<body>
+    <p><a href=""
+    <p>Changing position: relative to position: static results in mis-positioned descendant.</p>
+    <p>You should see no red on this page. There should be a green box in the top right-hand corner</p>
+    <div id="marker"></div>
+    <div id="container">
+        <div id="inner"></div>
+    </div>
+    </body>
+</html>
Property changes on: trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static-expected.html
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static.html (0 => 135670)


--- trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static.html	2012-11-25 18:35:10 UTC (rev 135670)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<head>
+<style>
+  body {
+      margin-left: 100px;
+      width: 400px;
+  }
+
+  #container {
+      position: relative;
+      top: 200px;
+      left: 100px;
+      height: 100px;
+      border: 1px solid black;
+  }
+
+  #inner, #marker {
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 100px;
+      height: 100px;
+      background-color: green;
+  }
+  
+  #marker {
+      background-color: red;
+  }
+</style>
+</head>
+
+<body>
+    <p><a href=""
+    <p>Changing position: relative to position: static results in mis-positioned descendant.</p>
+    <p>You should see no red on this page. There should be a green box in the top right-hand corner</p>
+    <div id="marker"></div>
+    <div id="container">
+        <div id="inner"></div>
+    </div>
+    <script>
+        var testEl = document.getElementById('container');
+        testEl.offsetHeight;
+        testEl.style.position = 'static';
+    </script>
+    </body>
+</html>
Property changes on: trunk/LayoutTests/fast/block/abspos-child-container-changes-from-relative-to-static.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (135669 => 135670)


--- trunk/Source/WebCore/ChangeLog	2012-11-25 18:30:14 UTC (rev 135669)
+++ trunk/Source/WebCore/ChangeLog	2012-11-25 18:35:10 UTC (rev 135670)
@@ -1,3 +1,25 @@
+2012-10-08  Robert Hogan  <[email protected]>
+
+        Changing position:relative to position:static results in mis-positioned div
+        https://bugs.webkit.org/show_bug.cgi?id=26397
+
+        Reviewed by Ojan Vafai.
+
+        When a block changes position from relative to static it is no longer the containing block for any
+        positioned objects it may have. If any of those positioned objects actually have a position specified
+        they are going to need a layout as their new containing block will likely have a different location they
+        need to offset from. Positioned objects without a specified position always get a layout anyway 
+        in layoutPositionedObjects() so no need to worry about them in this situation. 
+
+        Test: fast/block/abspos-child-container-changes-from-relative-to-static-expected.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::styleWillChange):
+        (WebCore::RenderBlock::layoutPositionedObjects):
+        (WebCore::RenderBlock::removePositionedObjects):
+        * rendering/RenderBlock.h:
+        (RenderBlock):
+
 2012-11-24  Antti Koivisto  <[email protected]>
 
         Make renderer construction less generic

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (135669 => 135670)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-11-25 18:30:14 UTC (rev 135669)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-11-25 18:35:10 UTC (rev 135670)
@@ -298,7 +298,7 @@
         if (newStyle->position() == StaticPosition)
             // Clear our positioned objects list. Our absolutely positioned descendants will be
             // inserted into our containing block's positioned objects list during layout.
-            removePositionedObjects(0);
+            removePositionedObjects(0, NewContainingBlock);
         else if (oldStyle->position() == StaticPosition) {
             // Remove our absolutely positioned descendants from their current containing block.
             // They will be inserted into our positioned objects list during layout.
@@ -312,7 +312,7 @@
             }
             
             if (cb->isRenderBlock())
-                toRenderBlock(cb)->removePositionedObjects(this);
+                toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
         }
 
         if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition())
@@ -3727,7 +3727,7 @@
     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
 }
 
-void RenderBlock::removePositionedObjects(RenderBlock* o)
+void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
 {
     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
     if (!positionedDescendants)
@@ -3742,7 +3742,7 @@
     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
         r = *it;
         if (!o || r->isDescendantOf(o)) {
-            if (o)
+            if (containingBlockState == NewContainingBlock)
                 r->setChildNeedsLayout(true, MarkOnlyThis);
             
             // It is parent blocks job to add positioned child to positioned objects list of its containing block

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (135669 => 135670)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2012-11-25 18:30:14 UTC (rev 135669)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2012-11-25 18:35:10 UTC (rev 135670)
@@ -67,6 +67,7 @@
 typedef Vector<WordMeasurement, 64> WordMeasurements;
 
 enum CaretType { CursorCaret, DragCaret };
+enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
 
 enum TextRunFlag {
     DefaultTextRunFlags = 0,
@@ -114,7 +115,7 @@
 
     void insertPositionedObject(RenderBox*);
     static void removePositionedObject(RenderBox*);
-    void removePositionedObjects(RenderBlock*);
+    void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
 
     TrackedRendererListHashSet* positionedObjects() const;
     bool hasPositionedObjects() const
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to