Title: [162960] trunk
Revision
162960
Author
commit-qu...@webkit.org
Date
2014-01-28 14:21:47 -0800 (Tue, 28 Jan 2014)

Log Message

Sticky positioning is broken for table rows
https://bugs.webkit.org/show_bug.cgi?id=112024

Patch by Viatcheslav Ostapenko <sl.ostape...@samsung.com> on 2014-01-28
Reviewed by Simon Fraser.

Source/WebCore:

Enable sticky positioning for table elements.
Also includes fix for bug ​wkb.ug/105654
I don't have access to this bug, but from related commit message I
assume it says about "Heap use after free problem".
Debugging showed that it wasn't heap use after free.
The real problem that RenderObject::container() returns object which is
not RenderBlock and it is used as RenderBlock in
RenderBox::containingBlockLogicalHeightForPositioned() method.
Added extra isRenderBlock check and search for containingBlock if
current block is not RenderBlock.

Tests: fast/css/sticky/sticky-table-row-top.html
       fast/css/sticky/sticky-table-thead-top.html

* css/StyleResolver.cpp:
(WebCore::StyleResolver::adjustRenderStyle):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::containingBlockLogicalHeightForPositioned):
* rendering/RenderTableRow.h:

LayoutTests:

Add layout tests for sticky positioned table row and table thead.

* fast/css/sticky/sticky-table-row-top-expected.html: Added.
* fast/css/sticky/sticky-table-row-top.html: Added.
* fast/css/sticky/sticky-table-thead-top-expected.html: Added.
* fast/css/sticky/sticky-table-thead-top.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (162959 => 162960)


--- trunk/LayoutTests/ChangeLog	2014-01-28 22:20:04 UTC (rev 162959)
+++ trunk/LayoutTests/ChangeLog	2014-01-28 22:21:47 UTC (rev 162960)
@@ -1,3 +1,17 @@
+2014-01-28  Viatcheslav Ostapenko  <sl.ostape...@samsung.com>
+
+        Sticky positioning is broken for table rows
+        https://bugs.webkit.org/show_bug.cgi?id=112024
+
+        Reviewed by Simon Fraser.
+
+        Add layout tests for sticky positioned table row and table thead.
+
+        * fast/css/sticky/sticky-table-row-top-expected.html: Added.
+        * fast/css/sticky/sticky-table-row-top.html: Added.
+        * fast/css/sticky/sticky-table-thead-top-expected.html: Added.
+        * fast/css/sticky/sticky-table-thead-top.html: Added.
+
 2014-01-28  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Fixing several incorrect assumptions with handling isolated inlines.

Added: trunk/LayoutTests/fast/css/sticky/sticky-table-row-top-expected.html (0 => 162960)


--- trunk/LayoutTests/fast/css/sticky/sticky-table-row-top-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/sticky/sticky-table-row-top-expected.html	2014-01-28 22:21:47 UTC (rev 162960)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<style>
+    body {
+        margin: 0;
+        height: 2000px;
+        overflow: hidden; /* hide scrollbars */
+    }
+
+    .group {
+        display: inline-block;
+        position: relative;
+        width: 250px;
+        height: 500px;
+    }
+
+    .container {
+        width: 200px;
+        height: 400px;
+        outline: 2px solid black;
+    }
+
+    .box {
+        width: 200px;
+        height: 200px;
+    }
+
+    .sticky {
+        position: absolute;
+        background-color: green;
+    }
+
+    .indicator {
+        position: absolute;
+        top: 0;
+        left: 0;
+        background-color: red;
+    }
+</style>
+</head>
+<body>
+    <div class="group" style="top: -100px;">
+        <div class="indicator box" style="top: 200px;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 200px;"></div>
+        </div>
+    </div>
+
+    <div class="group" style="top: 0">
+        <div class="indicator box" style="top: 100px;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 100px;"></div>
+        </div>
+    </div>
+
+    <div class="group" style="top: 100px">
+        <div class="indicator box" style="top: 0;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 0;"></div>
+        </div>
+    </div>
+    <div style="position: absolute; top: 520px;">
+    This test checks that sticky positioned table rows are contained by their table.
+    There should be no red.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/sticky/sticky-table-row-top.html (0 => 162960)


--- trunk/LayoutTests/fast/css/sticky/sticky-table-row-top.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/sticky/sticky-table-row-top.html	2014-01-28 22:21:47 UTC (rev 162960)
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<style>
+    body {
+        margin: 0;
+        height: 2000px;
+        overflow: hidden; /* hide scrollbars */
+    }
+
+    .group {
+        display: inline-block;
+        position: relative;
+        width: 250px;
+        height: 500px;
+    }
+
+    .container {
+        width: 200px;
+        height: 400px;
+        outline: 2px solid black;
+        border: hidden;
+        border-width: 0px;
+        border-spacing: 0px !important;
+        border-collapse:collapse;
+        cellspacing: 0;
+        cellpadding: 0;
+        padding: 0;
+    }
+
+    .box {
+        width: 200px;
+        height: 198px;
+    }
+
+    .sticky {
+        position: -webkit-sticky;
+        top: 100px;
+        background-color: green;
+    }
+
+    .indicator {
+        position: absolute;
+        top: 0;
+        left: 0;
+        background-color: red;
+    }
+</style>
+<script>
+    function doTest()
+    {
+        window.scrollTo(0, 100);
+    }
+    window.addEventListener('load', doTest, false);
+</script>
+</head>
+<body>
+    <div class="group">
+        <div class="indicator box" style="top: 200px;"></div>
+        <table class="container">
+            <tbody>
+                <tr class="sticky">
+                    <td class="box"></td>
+                </tr>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="group" style="top: 100px">
+        <div class="indicator box" style="top: 100px;"></div>
+        <table class="container" style="">
+            <tbody>
+                <tr class="sticky">
+                    <td class="box"></td>
+                </tr>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="group" style="top: 200px">
+        <div class="indicator box" style="top: 0;"></div>
+        <table class="container" style="">
+            <tbody>
+                <tr class="sticky">
+                    <td class="box"></td>
+                </tr>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div style="position: absolute; top: 620px;">
+    This test checks that sticky positioned table rows are contained by their table.
+    There should be no red.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top-expected.html (0 => 162960)


--- trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top-expected.html	2014-01-28 22:21:47 UTC (rev 162960)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<style>
+    body {
+        margin: 0;
+        height: 2000px;
+        overflow: hidden; /* hide scrollbars */
+    }
+
+    .group {
+        display: inline-block;
+        position: relative;
+        width: 250px;
+        height: 500px;
+    }
+
+    .container {
+        width: 200px;
+        height: 400px;
+        outline: 2px solid black;
+    }
+
+    .box {
+        width: 200px;
+        height: 200px;
+    }
+
+    .sticky {
+        position: absolute;
+        background-color: green;
+    }
+
+    .indicator {
+        position: absolute;
+        top: 0;
+        left: 0;
+        background-color: red;
+    }
+</style>
+</head>
+<body>
+    <div class="group" style="top: -100px;">
+        <div class="indicator box" style="top: 200px;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 200px;"></div>
+        </div>
+    </div>
+
+    <div class="group" style="top: 0">
+        <div class="indicator box" style="top: 100px;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 100px;"></div>
+        </div>
+    </div>
+
+    <div class="group" style="top: 100px">
+        <div class="indicator box" style="top: 0;"></div>
+        <div class="container">
+            <div class="sticky box" style="top: 0;"></div>
+        </div>
+    </div>
+    <div style="position: absolute; top: 520px;">
+    This test checks that sticky positioned table theads are contained by their table.
+    There should be no red.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top.html (0 => 162960)


--- trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/sticky/sticky-table-thead-top.html	2014-01-28 22:21:47 UTC (rev 162960)
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<style>
+    body {
+        margin: 0;
+        height: 2000px;
+        overflow: hidden; /* hide scrollbars */
+    }
+
+    .group {
+        display: inline-block;
+        position: relative;
+        width: 250px;
+        height: 500px;
+    }
+
+    .container {
+        width: 200px;
+        height: 400px;
+        outline: 2px solid black;
+        border: hidden;
+        border-width: 0px;
+        border-spacing: 0px !important;
+        border-collapse:collapse;
+        cellspacing: 0;
+        cellpadding: 0;
+        padding: 0;
+    }
+
+    .box {
+        width: 200px;
+        height: 198px;
+    }
+
+    .sticky {
+        position: -webkit-sticky;
+        top: 100px;
+        background-color: green;
+    }
+
+    .indicator {
+        position: absolute;
+        top: 0;
+        left: 0;
+        background-color: red;
+    }
+</style>
+<script>
+    function doTest()
+    {
+        window.scrollTo(0, 100);
+    }
+    window.addEventListener('load', doTest, false);
+</script>
+</head>
+<body>
+    <div class="group">
+        <div class="indicator box" style="top: 200px;"></div>
+        <table class="container">
+            <thead class="sticky">
+                <tr>
+                    <td class="box"></td>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="group" style="top: 100px">
+        <div class="indicator box" style="top: 100px;"></div>
+        <table class="container" style="">
+            <thead class="sticky">
+                <tr>
+                    <td class="box"></td>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="group" style="top: 200px">
+        <div class="indicator box" style="top: 0;"></div>
+        <table class="container" style="">
+            <thead class="sticky">
+                <tr>
+                    <td class="box"></td>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div style="position: absolute; top: 620px;">
+    This test checks that sticky positioned table theads are contained by their table.
+    There should be no red.
+    </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (162959 => 162960)


--- trunk/Source/WebCore/ChangeLog	2014-01-28 22:20:04 UTC (rev 162959)
+++ trunk/Source/WebCore/ChangeLog	2014-01-28 22:21:47 UTC (rev 162960)
@@ -1,3 +1,30 @@
+2014-01-28  Viatcheslav Ostapenko  <sl.ostape...@samsung.com>
+
+        Sticky positioning is broken for table rows
+        https://bugs.webkit.org/show_bug.cgi?id=112024
+
+        Reviewed by Simon Fraser.
+
+        Enable sticky positioning for table elements. 
+        Also includes fix for bug ​wkb.ug/105654
+        I don't have access to this bug, but from related commit message I 
+        assume it says about "Heap use after free problem".
+        Debugging showed that it wasn't heap use after free. 
+        The real problem that RenderObject::container() returns object which is
+        not RenderBlock and it is used as RenderBlock in 
+        RenderBox::containingBlockLogicalHeightForPositioned() method.
+        Added extra isRenderBlock check and search for containingBlock if 
+        current block is not RenderBlock.
+        
+        Tests: fast/css/sticky/sticky-table-row-top.html
+               fast/css/sticky/sticky-table-thead-top.html
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::adjustRenderStyle):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::containingBlockLogicalHeightForPositioned):
+        * rendering/RenderTableRow.h:
+
 2014-01-28  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         Fixing several incorrect assumptions with handling isolated inlines.

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (162959 => 162960)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2014-01-28 22:20:04 UTC (rev 162959)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2014-01-28 22:21:47 UTC (rev 162960)
@@ -1252,7 +1252,7 @@
         // on some sites).
         if ((style.display() == TABLE_HEADER_GROUP || style.display() == TABLE_ROW_GROUP
             || style.display() == TABLE_FOOTER_GROUP || style.display() == TABLE_ROW)
-            && style.hasInFlowPosition())
+            && style.position() == RelativePosition)
             style.setPosition(StaticPosition);
 
         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (162959 => 162960)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2014-01-28 22:20:04 UTC (rev 162959)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2014-01-28 22:21:47 UTC (rev 162960)
@@ -3090,7 +3090,7 @@
         if (isFixedPosition && containingBlock->isRenderView())
             return toRenderView(containingBlock)->clientLogicalHeightForFixedPosition();
 
-        const RenderBlock* cb = toRenderBlock(containingBlock);
+        const RenderBlock* cb = containingBlock->isRenderBlock() ? toRenderBlock(containingBlock) : containingBlock->containingBlock();
         LayoutUnit result = cb->clientLogicalHeight();
         RenderFlowThread* flowThread = flowThreadContainingBlock();
         if (flowThread && containingBlock->isRenderFlowThread() && flowThread->isHorizontalWritingMode() == containingBlock->isHorizontalWritingMode()) {

Modified: trunk/Source/WebCore/rendering/RenderTableRow.h (162959 => 162960)


--- trunk/Source/WebCore/rendering/RenderTableRow.h	2014-01-28 22:20:04 UTC (rev 162959)
+++ trunk/Source/WebCore/rendering/RenderTableRow.h	2014-01-28 22:21:47 UTC (rev 162960)
@@ -103,7 +103,7 @@
     virtual void layout() override;
     virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override;
 
-    virtual bool requiresLayer() const override { return hasOverflowClip() || hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup(); }
+    virtual bool requiresLayer() const override { return hasOverflowClip() || hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup() || isStickyPositioned(); }
 
     virtual void paint(PaintInfo&, const LayoutPoint&) override;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to