Diff
Modified: trunk/LayoutTests/ChangeLog (234799 => 234800)
--- trunk/LayoutTests/ChangeLog 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/LayoutTests/ChangeLog 2018-08-13 14:48:10 UTC (rev 234800)
@@ -1,3 +1,13 @@
+2018-08-13 Zalan Bujtas <[email protected]>
+
+ [LFC][Floating] Add basic clearance support
+ https://bugs.webkit.org/show_bug.cgi?id=188492
+
+ Reviewed by Antti Koivisto.
+
+ * fast/block/block-only/floating-left-and-right-with-clearance-expected.txt: Added.
+ * fast/block/block-only/floating-left-and-right-with-clearance.html: Added.
+
2018-08-13 Zan Dobersek <[email protected]>
Unreviewed WPE gardening. Cleaned up test expectations for tests under
Added: trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance-expected.txt (0 => 234800)
--- trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance-expected.txt 2018-08-13 14:48:10 UTC (rev 234800)
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x518
+ RenderBlock {HTML} at (0,0) size 800x518
+ RenderBody {BODY} at (8,8) size 784x502
+ RenderBlock {DIV} at (0,0) size 502x502 [border: (1px solid #000000)]
+ RenderBlock {DIV} at (1,1) size 12x12 [border: (1px solid #000000)]
+ RenderBlock (floating) {DIV} at (1,13) size 52x102 [border: (1px solid #000000)]
+ RenderBlock {DIV} at (1,13) size 500x115 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (11,102) size 12x12 [border: (1px solid #000000)]
+ RenderBlock {DIV} at (1,178) size 12x12 [border: (1px solid #000000)]
+ RenderBlock (floating) {DIV} at (449,190) size 52x22 [border: (1px solid #000000)]
+ RenderBlock {DIV} at (1,275) size 12x12 [border: (1px solid #000000)]
+ RenderBlock (floating) {DIV} at (1,287) size 52x102 [border: (1px solid #000000)]
+ RenderBlock (floating) {DIV} at (449,287) size 52x112 [border: (1px solid #000000)]
+ RenderBlock {DIV} at (1,399) size 12x12 [border: (1px solid #000000)]
+layer at (9,213) size 500x35
+ RenderBlock (relative positioned) {DIV} at (1,190) size 500x35 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,22) size 12x12 [border: (1px solid #000000)]
Added: trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance.html (0 => 234800)
--- trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance.html (rev 0)
+++ trunk/LayoutTests/fast/block/block-only/floating-left-and-right-with-clearance.html 2018-08-13 14:48:10 UTC (rev 234800)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+ border: 1px solid black;
+}
+</style>
+</head>
+<body>
+<div style="width: 500px; height: 500px;">
+ <div style="width: 10px; height: 10px;"></div>
+ <div style="float: left; width: 50px; height: 100px;"></div>
+ <div style="padding-left: 10px; border: 1px solid green">
+ <div style="clear: left; width: 10px; height: 10px;"></div>
+ </div>
+
+ <div style="width: 10px; height: 10px; margin-top: 50px;"></div>
+ <div style="float: right; width: 50px; height: 20px;"></div>
+ <div style="position: relative; top: 15px; 10px; border: 1px solid green">
+ <div style="clear: right; width: 10px; height: 10px;"></div>
+ </div>
+
+
+ <div style="width: 10px; height: 10px; margin-top: 50px;"></div>
+ <div style="float: left; width: 50px; height: 100px;"></div>
+ <div style="float: right; width: 50px; height: 110px;"></div>
+ <div style="clear: both; width: 10px; height: 10px;"></div>
+</div>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (234799 => 234800)
--- trunk/Source/WebCore/ChangeLog 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/ChangeLog 2018-08-13 14:48:10 UTC (rev 234800)
@@ -1,3 +1,38 @@
+2018-08-13 Zalan Bujtas <[email protected]>
+
+ [LFC][Floating] Add basic clearance support
+ https://bugs.webkit.org/show_bug.cgi?id=188492
+
+ Reviewed by Antti Koivisto.
+
+ Adjust final position of a block level box with clearance when float is present.
+
+ Test: fast/block/block-only/floating-left-and-right-with-clearance.html
+
+ * layout/FloatingContext.cpp:
+ (WebCore::Layout::FloatingContext::positionForFloat const):
+ (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
+ (WebCore::Layout::FloatingContext::alignWithContainingBlock const):
+ (WebCore::Layout::FloatingContext::toContainingBlock const):
+ (WebCore::Layout::FloatingContext::computePosition const): Deleted.
+ * layout/FloatingContext.h:
+ * layout/FloatingState.cpp:
+ (WebCore::Layout::FloatingState::bottom const):
+ * layout/FloatingState.h:
+ (WebCore::Layout::FloatingState::leftBottom const):
+ (WebCore::Layout::FloatingState::rightBottom const):
+ (WebCore::Layout::FloatingState::bottom const):
+ * layout/Verification.cpp:
+ (WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree const):
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::layout const):
+ (WebCore::Layout::BlockFormattingContext::computeFloatingPosition const):
+ (WebCore::Layout::BlockFormattingContext::computeVerticalPositionWithClearance const):
+ * layout/blockformatting/BlockFormattingContext.h:
+ * layout/layouttree/LayoutBox.cpp:
+ (WebCore::Layout::Box::hasClearance const):
+ * layout/layouttree/LayoutBox.h:
+
2018-08-13 Yusuke Suzuki <[email protected]>
Expose CloseEvent and CustomEvent to workers
Modified: trunk/Source/WebCore/layout/FloatingContext.cpp (234799 => 234800)
--- trunk/Source/WebCore/layout/FloatingContext.cpp 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/FloatingContext.cpp 2018-08-13 14:48:10 UTC (rev 234800)
@@ -113,7 +113,7 @@
{
}
-Position FloatingContext::computePosition(const Box& layoutBox) const
+Position FloatingContext::positionForFloat(const Box& layoutBox) const
{
ASSERT(layoutBox.isFloatingPositioned());
FloatingState::FloatItem floatItem = { layoutBox, m_floatingState };
@@ -131,6 +131,50 @@
return toContainingBlock(floatItem, floatPosition);
}
+std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
+{
+ ASSERT(layoutBox.hasClearance());
+ ASSERT(layoutBox.isBlockLevelBox());
+
+ if (m_floatingState.isEmpty())
+ return { };
+
+ auto bottom = [&](std::optional<LayoutUnit> floatBottom) -> std::optional<LayoutUnit> {
+ // 'bottom' is in the formatting root's coordinate system.
+ if (!floatBottom)
+ return { };
+
+ // 9.5.2 Controlling flow next to floats: the 'clear' property
+ // Then the amount of clearance is set to the greater of:
+ //
+ // 1. The amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
+ // 2. The amount necessary to place the top border edge of the block at its hypothetical position.
+
+ auto absoluteDisplayBox = FormattingContext::mapToAncestor(layoutContext(), layoutBox, downcast<Container>(m_floatingState.root()));
+ if (floatBottom <= absoluteDisplayBox.rectWithMargin().top())
+ return { };
+
+ // The return vertical position is in the containing block's coordinate system.
+ auto* containingBlockDisplayBox = layoutContext().displayBoxForLayoutBox(*layoutBox.containingBlock());
+ return *floatBottom - containingBlockDisplayBox->top();
+ };
+
+ auto clear = layoutBox.style().clear();
+ auto& formattingContextRoot = layoutBox.formattingContextRoot();
+
+ if (clear == Clear::Left)
+ return bottom(m_floatingState.leftBottom(formattingContextRoot));
+
+ if (clear == Clear::Right)
+ return bottom(m_floatingState.rightBottom(formattingContextRoot));
+
+ if (clear == Clear::Both)
+ return bottom(m_floatingState.bottom(formattingContextRoot));
+
+ ASSERT_NOT_REACHED();
+ return { };
+}
+
Position FloatingContext::floatingPosition(const FloatingState::FloatItem& floatItem) const
{
auto initialVerticalPosition = this->initialVerticalPosition(floatItem);
@@ -176,13 +220,13 @@
{
// If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
// (Either there's no floats at all or this box does not fit at any vertical positions where the floats are.)
- auto& containgBlockDisplayBox = floatItem.containingBlockDisplayBox();
- auto containingBlockContentBoxLeft = containgBlockDisplayBox.left() + containgBlockDisplayBox.contentBoxLeft();
+ auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
+ auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft();
if (floatItem.layoutBox().isLeftFloatingPositioned())
return containingBlockContentBoxLeft;
- return containingBlockContentBoxLeft + containgBlockDisplayBox.contentBoxWidth() - floatItem.displayBox().marginBox().width();
+ return containingBlockContentBoxLeft + containingBlockDisplayBox.contentBoxWidth() - floatItem.displayBox().marginBox().width();
}
LayoutUnit FloatingContext::alignWithFloatings(const FloatingPair& floatingPair, const FloatingState::FloatItem& floatItem) const
@@ -227,8 +271,8 @@
if (&floatItem.containingBlock() == &m_floatingState.root())
return position;
- auto& containgBlockDisplayBox = floatItem.containingBlockDisplayBox();
- return { position.x - containgBlockDisplayBox.left(), position.y - containgBlockDisplayBox.top() };
+ auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox();
+ return { position.x - containingBlockDisplayBox.left(), position.y - containingBlockDisplayBox.top() };
}
FloatingPair::FloatingPair(const FloatingState::FloatList& floats)
Modified: trunk/Source/WebCore/layout/FloatingContext.h (234799 => 234800)
--- trunk/Source/WebCore/layout/FloatingContext.h 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/FloatingContext.h 2018-08-13 14:48:10 UTC (rev 234800)
@@ -49,7 +49,8 @@
FloatingState& floatingState() const { return m_floatingState; }
- Position computePosition(const Box&) const;
+ Position positionForFloat(const Box&) const;
+ std::optional<LayoutUnit> verticalPositionWithClearance(const Box&) const;
private:
LayoutContext& layoutContext() const { return m_floatingState.layoutContext(); }
Modified: trunk/Source/WebCore/layout/FloatingState.cpp (234799 => 234800)
--- trunk/Source/WebCore/layout/FloatingState.cpp 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/FloatingState.cpp 2018-08-13 14:48:10 UTC (rev 234800)
@@ -90,7 +90,7 @@
m_floats.append({ layoutBox, *this });
}
-std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot) const
+std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot, Clear type) const
{
if (m_floats.isEmpty())
return { };
@@ -103,6 +103,10 @@
if (&formattingContextRoot != &floatItem.layoutBox().formattingContextRoot())
continue;
+ if ((type == Clear::Left && !floatItem.layoutBox().isLeftFloatingPositioned())
+ || (type == Clear::Right && !floatItem.layoutBox().isRightFloatingPositioned()))
+ continue;
+
auto floatsBottom = floatItem.displayBox().rectWithMargin().bottom();
if (bottom) {
bottom = std::max(*bottom, floatsBottom);
Modified: trunk/Source/WebCore/layout/FloatingState.h (234799 => 234800)
--- trunk/Source/WebCore/layout/FloatingState.h 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/FloatingState.h 2018-08-13 14:48:10 UTC (rev 234800)
@@ -51,6 +51,9 @@
void remove(const Box& layoutBox);
bool isEmpty() const { return m_floats.isEmpty(); }
+
+ std::optional<LayoutUnit> leftBottom(const Box& formattingContextRoot) const;
+ std::optional<LayoutUnit> rightBottom(const Box& formattingContextRoot) const;
std::optional<LayoutUnit> bottom(const Box& formattingContextRoot) const;
class FloatItem {
@@ -81,11 +84,28 @@
LayoutContext& layoutContext() const { return m_layoutContext; }
const Box& root() const { return *m_formattingContextRoot; }
+ std::optional<LayoutUnit> bottom(const Box& formattingContextRoot, Clear) const;
+
LayoutContext& m_layoutContext;
WeakPtr<Box> m_formattingContextRoot;
FloatList m_floats;
};
+inline std::optional<LayoutUnit> FloatingState::leftBottom(const Box& formattingContextRoot) const
+{
+ return bottom(formattingContextRoot, Clear::Left);
}
+
+inline std::optional<LayoutUnit> FloatingState::rightBottom(const Box& formattingContextRoot) const
+{
+ return bottom(formattingContextRoot, Clear::Right);
}
+
+inline std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot) const
+{
+ return bottom(formattingContextRoot, Clear::Both);
+}
+
+}
+}
#endif
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (234799 => 234800)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-08-13 14:48:10 UTC (rev 234800)
@@ -110,8 +110,10 @@
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Height][Margin] -> for layoutBox(" << &layoutBox << ")");
// Formatting root boxes are special-cased and they don't come here.
ASSERT(!layoutBox.establishesFormattingContext());
-
computeHeightAndMargin(layoutContext, layoutBox, displayBox);
+ // Finalize position with clearance.
+ if (layoutBox.hasClearance())
+ computeVerticalPositionWithClearance(floatingContext, layoutBox, displayBox);
if (!is<Container>(layoutBox))
continue;
auto& container = downcast<Container>(layoutBox);
@@ -157,10 +159,17 @@
void BlockFormattingContext::computeFloatingPosition(FloatingContext& floatingContext, const Box& layoutBox, Display::Box& displayBox) const
{
ASSERT(layoutBox.isFloatingPositioned());
- displayBox.setTopLeft(floatingContext.computePosition(layoutBox));
+ displayBox.setTopLeft(floatingContext.positionForFloat(layoutBox));
floatingContext.floatingState().append(layoutBox);
}
+void BlockFormattingContext::computeVerticalPositionWithClearance(const FloatingContext& floatingContext, const Box& layoutBox, Display::Box& displayBox) const
+{
+ ASSERT(layoutBox.hasClearance());
+ if (auto verticalPositionWithClearance = floatingContext.verticalPositionWithClearance(layoutBox))
+ displayBox.setTop(*verticalPositionWithClearance);
+}
+
void BlockFormattingContext::computeInFlowPositionedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
{
displayBox.setTopLeft(Geometry::inFlowPositionedPosition(layoutContext, layoutBox));
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (234799 => 234800)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2018-08-13 14:48:10 UTC (rev 234800)
@@ -57,6 +57,7 @@
void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override;
void computeFloatingPosition(FloatingContext&, const Box&, Display::Box&) const;
+ void computeVerticalPositionWithClearance(const FloatingContext&, const Box&, Display::Box&) const;
void computeInFlowPositionedPosition(LayoutContext&, const Box&, Display::Box&) const override;
void computeInFlowWidthAndMargin(LayoutContext&, const Box&, Display::Box&) const;
void computeInFlowHeightAndMargin(LayoutContext&, const Box&, Display::Box&) const;
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (234799 => 234800)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-08-13 14:48:10 UTC (rev 234800)
@@ -114,6 +114,11 @@
return m_style.floating() == Float::Right;
}
+bool Box::hasClearance() const
+{
+ return m_style.clear() != Clear::None;
+}
+
const Container* Box::containingBlock() const
{
// The containing block in which the root element lives is a rectangle called the initial containing block.
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (234799 => 234800)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-08-13 14:48:10 UTC (rev 234800)
@@ -62,6 +62,7 @@
bool isFloatingPositioned() const;
bool isLeftFloatingPositioned() const;
bool isRightFloatingPositioned() const;
+ bool hasClearance() const;
bool isFloatingOrOutOfFlowPositioned() const { return isFloatingPositioned() || isOutOfFlowPositioned(); }
Modified: trunk/Tools/ChangeLog (234799 => 234800)
--- trunk/Tools/ChangeLog 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Tools/ChangeLog 2018-08-13 14:48:10 UTC (rev 234800)
@@ -1,3 +1,12 @@
+2018-08-13 Zalan Bujtas <[email protected]>
+
+ [LFC][Floating] Add basic clearance support
+ https://bugs.webkit.org/show_bug.cgi?id=188492
+
+ Reviewed by Antti Koivisto.
+
+ * LayoutReloaded/misc/LFC-passing-tests.txt:
+
2018-08-12 Zalan Bujtas <[email protected]>
[LFC] Float prev/next sibling should prevent top/bottom margin collapsing with parent.
Modified: trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt (234799 => 234800)
--- trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt 2018-08-13 13:31:50 UTC (rev 234799)
+++ trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt 2018-08-13 14:48:10 UTC (rev 234800)
@@ -47,3 +47,4 @@
fast/block/block-only/floating-multiple-lefts-multiple-lines.html
fast/block/block-only/floating-multiple-lefts.html
fast/block/block-only/floating-and-next-previous-inflow-with-margin.html
+fast/block/block-only/floating-left-and-right-with-clearance.html