Title: [169110] trunk
Revision
169110
Author
[email protected]
Date
2014-05-20 07:34:56 -0700 (Tue, 20 May 2014)

Log Message

[CSS Regions] Block incorrectly sized when containing an unsplittable box
https://bugs.webkit.org/show_bug.cgi?id=132601

Reviewed by Antti Koivisto.

Source/WebCore:
When laying out elements in a region, when an inline element is encountered
the size of its parent must not be increased beyond the bottom of the current region,
unless if its the last region. This will ensure that the next sibling of the
inline element is correctly laid out at the top of the next region, instead
of leaving an empty space equal to the height of the overflow, as it did until now.

Tests: fast/regions/inline-block-inside-anonymous-overflow.html
       fast/regions/inline-block-overflow.html

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::adjustLinePositionForPagination):
(WebCore::RenderBlockFlow::hasNextPage):
* rendering/RenderBlockFlow.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange):
(WebCore::RenderBlockFlow::linkToEndLineIfNeeded):
(WebCore::RenderBlockFlow::determineStartPosition):
(WebCore::RenderBlockFlow::checkPaginationAndFloatsAtEndLine):

LayoutTests:
Added tests for the layout of elements following inline-block elements
that overflow their region, with and without anonymous blocks.

* fast/regions/inline-block-inside-anonymous-overflow-expected.html: Added.
* fast/regions/inline-block-inside-anonymous-overflow.html: Added.
* fast/regions/inline-block-overflow-expected.html: Added.
* fast/regions/inline-block-overflow.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (169109 => 169110)


--- trunk/LayoutTests/ChangeLog	2014-05-20 13:56:27 UTC (rev 169109)
+++ trunk/LayoutTests/ChangeLog	2014-05-20 14:34:56 UTC (rev 169110)
@@ -1,3 +1,18 @@
+2014-05-20  Radu Stavila  <[email protected]>
+
+        [CSS Regions] Block incorrectly sized when containing an unsplittable box
+        https://bugs.webkit.org/show_bug.cgi?id=132601
+
+        Reviewed by Antti Koivisto.
+
+        Added tests for the layout of elements following inline-block elements 
+        that overflow their region, with and without anonymous blocks.
+
+        * fast/regions/inline-block-inside-anonymous-overflow-expected.html: Added.
+        * fast/regions/inline-block-inside-anonymous-overflow.html: Added.
+        * fast/regions/inline-block-overflow-expected.html: Added.
+        * fast/regions/inline-block-overflow.html: Added.
+
 2014-05-20  Zoltan Horvath  <[email protected]>
 
         [CSS Regions] Add polygon tests for shapes on regions and shapes on the content flow

Added: trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow-expected.html (0 => 169110)


--- trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow-expected.html	2014-05-20 14:34:56 UTC (rev 169110)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            .region {
+                border: 3px solid blue;
+                float: left;
+            }
+            #region1 {
+                height: 250px;
+            }
+            #region2 {
+                width: 300px;
+                height: 200px;
+                margin-left: 50px;
+            }
+            .article {
+                background-color: #009999;
+            }
+            #article1 {
+                height: 230px;
+            }
+            #video {
+                width: 320px;
+                height: 300px;
+                background-color: salmon;
+                border: 3px solid black;
+            }
+        </style>
+    </head>
+
+    <body>
+        <a href="" 132601 - [CSS Regions] Block incorrectly sized when containing an unsplittable box</a>
+        <p>This test passes if the <span style="color:#00BB00">green text</span> is positioned at the very top of the second <span style="color:blue">region</span> and the <span style="color:blue">blue text</span> immediately after it.</p>
+        <div class="region" id="region1">
+            <div class="article" id="article1">
+                <video id="video" controls></video><span style="color:#00FF00">
+            </div>
+        </div>
+        
+        <div class="region" id="region2">
+            <div class="article" id="article2">
+                <span style="color:#00FF00">This text, together with the video element, are inside an anonymouse block</span>
+                <div id="after" style="color:blue">This div is after the anonymous block</div>
+            </div>
+        </div>
+        
+    </body>
+</html>

Added: trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow.html (0 => 169110)


--- trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/inline-block-inside-anonymous-overflow.html	2014-05-20 14:34:56 UTC (rev 169110)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            .region {
+                -webkit-flow-from: flow;
+                border: 3px solid blue;
+                float: left;
+            }
+            #region1 {
+                height: 250px;
+            }
+            #region2 {
+                width: 300px;
+                height: 200px;
+                margin-left: 50px;
+            }
+            #article {
+                -webkit-flow-into: flow;
+                background-color: #009999;
+            }
+            #video {
+                width: 320px;
+                height: 300px;
+                background-color: salmon;
+                border: 3px solid black;
+            }
+        </style>
+    </head>
+
+    <body>
+        <a href="" 132601 - [CSS Regions] Block incorrectly sized when containing an unsplittable box</a>
+        <p>This test passes if the <span style="color:#00BB00">green text</span> is positioned at the very top of the second <span style="color:blue">region</span> and the <span style="color:blue">blue text</span> immediately after it.</p>
+        <div class="region" id="region1"></div>
+        <div class="region" id="region2"></div>
+        <div id="article">
+            <video id="video" controls></video><span style="color:#00FF00">This text, together with the video element, are inside an anonymouse block</span>
+            <div id="after" style="color:blue">This div is after the anonymous block</div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/regions/inline-block-overflow-expected.html (0 => 169110)


--- trunk/LayoutTests/fast/regions/inline-block-overflow-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/inline-block-overflow-expected.html	2014-05-20 14:34:56 UTC (rev 169110)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            .region {
+                border: 3px solid blue;
+                float: left;
+            }
+            #region1 {
+                height: 250px;
+            }
+            #region2 {
+                width: 300px;
+                height: 200px;
+                margin-left: 50px;
+            }
+            .article {
+                background-color: #009999;
+            }
+            #article1 {
+                height: 230px;
+            }
+            #video {
+                width: 320px;
+                height: 300px;
+                background-color: salmon;
+                border: 3px solid black;
+                display: inline-block;
+            }
+        </style>
+    </head>
+
+    <body>
+        <a href="" 132601 - [CSS Regions] Block incorrectly sized when containing an unsplittable box</a>
+        <p>This test passes if the <span style="color:#00BB00">green text</span> is positioned at the very top of the second <span style="color:blue">region</span>.</p>
+        <div class="region" id="region1">
+            <div class="article" id="article1">
+                <video id="video" controls></video>
+            </div>
+        </div>
+
+        <div class="region" id="region2">
+            <div class="article" id="article2">
+                <div id="after" style="color:#00FF00">This div is flowed after the video element.</div>
+            </div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/regions/inline-block-overflow.html (0 => 169110)


--- trunk/LayoutTests/fast/regions/inline-block-overflow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/inline-block-overflow.html	2014-05-20 14:34:56 UTC (rev 169110)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style>
+            .region {
+                -webkit-flow-from: flow;
+                border: 3px solid blue;
+                float: left;
+            }
+            #region1 {
+                height: 250px;
+            }
+            #region2 {
+                width: 300px;
+                height: 200px;
+                margin-left: 50px;
+            }
+            .article {
+                -webkit-flow-into: flow;
+                background-color: #009999;
+            }
+            #video {
+                width: 320px;
+                height: 300px;
+                background-color: salmon;
+                border: 3px solid black;
+                display: inline-block;
+            }
+        </style>
+    </head>
+
+    <body>
+        <a href="" 132601 - [CSS Regions] Block incorrectly sized when containing an unsplittable box</a>
+        <p>This test passes if the <span style="color:#00BB00">green text</span> is positioned at the very top of the second <span style="color:blue">region</span>.</p>
+        <div class="region" id="region1"></div>
+        <div class="region" id="region2"></div>
+        <div class="article" id="article1">
+            <video id="video" controls></video>
+        </div>
+        <div class="article" id="article2">
+            <div id="after" style="color:#00FF00">This div is flowed after the video element.</div>
+        </div>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (169109 => 169110)


--- trunk/Source/WebCore/ChangeLog	2014-05-20 13:56:27 UTC (rev 169109)
+++ trunk/Source/WebCore/ChangeLog	2014-05-20 14:34:56 UTC (rev 169110)
@@ -1,3 +1,29 @@
+2014-05-20  Radu Stavila  <[email protected]>
+
+        [CSS Regions] Block incorrectly sized when containing an unsplittable box
+        https://bugs.webkit.org/show_bug.cgi?id=132601
+
+        Reviewed by Antti Koivisto.
+
+        When laying out elements in a region, when an inline element is encountered
+        the size of its parent must not be increased beyond the bottom of the current region,
+        unless if its the last region. This will ensure that the next sibling of the
+        inline element is correctly laid out at the top of the next region, instead
+        of leaving an empty space equal to the height of the overflow, as it did until now.
+
+        Tests: fast/regions/inline-block-inside-anonymous-overflow.html
+               fast/regions/inline-block-overflow.html
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::adjustLinePositionForPagination):
+        (WebCore::RenderBlockFlow::hasNextPage):
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange):
+        (WebCore::RenderBlockFlow::linkToEndLineIfNeeded):
+        (WebCore::RenderBlockFlow::determineStartPosition):
+        (WebCore::RenderBlockFlow::checkPaginationAndFloatsAtEndLine):
+
 2014-05-20  Mihnea Ovidenie  <[email protected]>
 
         [CSS Regions] Crash while painting block selection gaps in regions

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (169109 => 169110)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-05-20 13:56:27 UTC (rev 169109)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-05-20 14:34:56 UTC (rev 169110)
@@ -1620,7 +1620,7 @@
     return lineBottom - lineTop;
 }
 
-void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
+void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, bool& overflowsRegion, RenderFlowThread* flowThread)
 {
     // FIXME: For now we paginate using line overflow. This ensures that lines don't overlap at all when we
     // put a strut between them for pagination purposes. However, this really isn't the desired rendering, since
@@ -1641,6 +1641,7 @@
     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
     // line and all following lines.
+    overflowsRegion = false;
     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
     LayoutUnit logicalOffset = std::min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
     LayoutUnit logicalBottom = std::max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
@@ -1659,6 +1660,7 @@
         // From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
         return;
     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
+    overflowsRegion = (lineHeight > remainingLogicalHeight);
 
     int lineIndex = lineCount(lineBox);
     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
@@ -1673,6 +1675,8 @@
             // Split the top margin in order to avoid splitting the visible part of the line.
             remainingLogicalHeight -= std::min(lineHeight - pageLogicalHeight, std::max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
         }
+        LayoutUnit remainingLogicalHeightAtNewOffset = pageRemainingLogicalHeightForOffset(logicalOffset + remainingLogicalHeight, ExcludePageBoundary);
+        overflowsRegion = (lineHeight > remainingLogicalHeightAtNewOffset);
         LayoutUnit totalLogicalHeight = lineHeight + std::max<LayoutUnit>(0, logicalOffset);
         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
@@ -1758,7 +1762,7 @@
     RenderRegion* startRegion = nullptr;
     RenderRegion* endRegion = nullptr;
     flowThread->getRegionRangeForBox(this, startRegion, endRegion);
-    return region != endRegion;
+    return (endRegion && region != endRegion);
 }
 
 LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins)

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (169109 => 169110)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2014-05-20 13:56:27 UTC (rev 169109)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2014-05-20 14:34:56 UTC (rev 169110)
@@ -590,7 +590,7 @@
 
 public:
     // FIXME-BLOCKFLOW: These can be made protected again once all callers have been moved here.
-    void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
+    void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, bool& overflowsRegion, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
     void updateRegionForLine(RootInlineBox*) const;
     void createRenderNamedFlowFragmentIfNeeded();
 

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (169109 => 169110)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2014-05-20 13:56:27 UTC (rev 169109)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2014-05-20 14:34:56 UTC (rev 169110)
@@ -1134,7 +1134,8 @@
 
                 if (paginated) {
                     LayoutUnit adjustment = 0;
-                    adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
+                    bool overflowsRegion;
+                    adjustLinePositionForPagination(lineBox, adjustment, overflowsRegion, layoutState.flowThread());
                     if (adjustment) {
                         LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
                         lineBox->adjustBlockDirectionPosition(adjustment);
@@ -1150,6 +1151,16 @@
 
                         setLogicalHeight(lineBox->lineBottomWithLeading());
                     }
+                    
+                    if (RenderFlowThread* flowThread = flowThreadContainingBlock()) {
+                        if (flowThread->isRenderNamedFlowThread() && overflowsRegion && hasNextPage(lineBox->lineTop())) {
+                            // Limit the height of this block to the end of the current region because
+                            // it is also fragmented into the next region.
+                            LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalTop(), ExcludePageBoundary);
+                            if (logicalHeight() > remainingLogicalHeight)
+                                setLogicalHeight(remainingLogicalHeight);
+                        }
+                    }
 
                     if (layoutState.flowThread())
                         updateRegionForLine(lineBox);
@@ -1265,7 +1276,8 @@
                 line->attachLine();
                 if (paginated) {
                     delta -= line->paginationStrut();
-                    adjustLinePositionForPagination(line, delta, layoutState.flowThread());
+                    bool overflowsRegion;
+                    adjustLinePositionForPagination(line, delta, overflowsRegion, layoutState.flowThread());
                 }
                 if (delta) {
                     layoutState.updateRepaintRangeFromBox(line, delta);
@@ -1505,7 +1517,8 @@
                     break;
                 }
                 paginationDelta -= curr->paginationStrut();
-                adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
+                bool overflowsRegion;
+                adjustLinePositionForPagination(curr, paginationDelta, overflowsRegion, layoutState.flowThread());
                 if (paginationDelta) {
                     if (containsFloats() || !layoutState.floats().isEmpty()) {
                         // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
@@ -1653,8 +1666,9 @@
                 // This isn't the real move we're going to do, so don't update the line box's pagination
                 // strut yet.
                 LayoutUnit oldPaginationStrut = lineBox->paginationStrut();
+                bool overflowsRegion;
                 lineDelta -= oldPaginationStrut;
-                adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
+                adjustLinePositionForPagination(lineBox, lineDelta, overflowsRegion, layoutState.flowThread());
                 lineBox->setPaginationStrut(oldPaginationStrut);
             }
             if (lineWidthForPaginatedLineChanged(lineBox, lineDelta, layoutState.flowThread()))
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to