Modified: trunk/LayoutTests/ChangeLog (267699 => 267700)
--- trunk/LayoutTests/ChangeLog 2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/LayoutTests/ChangeLog 2020-09-28 15:00:14 UTC (rev 267700)
@@ -1,3 +1,13 @@
+2020-09-28 Zalan Bujtas <[email protected]>
+
+ [LFC][Floats] Add support for clear on float box
+ https://bugs.webkit.org/show_bug.cgi?id=217045
+
+ Reviewed by Antti Koivisto.
+
+ * fast/layoutformattingcontext/float-with-clear-simple-expected.html: Added.
+ * fast/layoutformattingcontext/float-with-clear-simple.html: Added.
+
2020-09-28 Angelos Oikonomopoulos <[email protected]>
Fix test failures inadventently introduced in r267644
Added: trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html (0 => 267700)
--- trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple-expected.html 2020-09-28 15:00:14 UTC (rev 267700)
@@ -0,0 +1,22 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+.float {
+ width: 20px;
+ height: 20px;
+ background-color: blue;
+ position: relative;
+}
+</style>
+<div style="position: absolute; top: 8px; left: 8px; background-color: green; width: 40px; height: 240px"></div>
+<div class=float></div>
+<div class=float></div>
+<div class=float style="left: 20px;"></div>
+<div class=float style="left: 20px;"></div>
+<div class=float style="left: 20px;"></div>
+<div class=float></div>
+<div class=float></div>
+<div class=float style="left: 20px;"></div>
+<div class=float></div>
+<div class=float style="top: -20px; left: 20px;"></div>
+<div class=float></div>
+<div class=float style="top: -20px; left: 20px;"></div>
Added: trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html (0 => 267700)
--- trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/float-with-clear-simple.html 2020-09-28 15:00:14 UTC (rev 267700)
@@ -0,0 +1,38 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+ overflow: hidden;
+ width: 40px;
+ height: 40px;
+ background-color: green;
+}
+.float {
+ background-color: blue;
+ width: 20px;
+ height: 20px;
+}
+</style>
+<div>
+ <div class=float style="float: left;"></div>
+ <div class=float style="float: left; clear: left"></div>
+</div>
+<div>
+ <div class=float style="float: right;"></div>
+ <div class=float style="float: right; clear: right"></div>
+</div>
+<div>
+ <div class=float style="float: right;"></div>
+ <div class=float style="float: left; clear: right"></div>
+</div>
+<div>
+ <div class=float style="float: left;"></div>
+ <div class=float style="float: right; clear: left"></div>
+</div>
+<div>
+ <div class=float style="float: left;"></div>
+ <div class=float style="float: right; clear: right"></div>
+</div>
+<div>
+ <div class=float style="float: right;"></div>
+ <div class=float style="float: left; clear: left"></div>
+</div>
Modified: trunk/Source/WebCore/ChangeLog (267699 => 267700)
--- trunk/Source/WebCore/ChangeLog 2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/ChangeLog 2020-09-28 15:00:14 UTC (rev 267700)
@@ -1,3 +1,23 @@
+2020-09-28 Zalan Bujtas <[email protected]>
+
+ [LFC][Floats] Add support for clear on float box
+ https://bugs.webkit.org/show_bug.cgi?id=217045
+
+ Reviewed by Antti Koivisto.
+
+ When the float box also has to clear other floats, we need to adjust the initial
+ vertical position from where we start searching for available space.
+ (This patch also fixes a previous find&replace renaming and addresses a post-landing comment.)
+
+ Test: fast/layoutformattingcontext/float-with-clear-simple.html
+
+ * layout/floats/FloatingContext.cpp:
+ (WebCore::Layout::FloatingContext::positionForFloat const):
+ (WebCore::Layout::FloatingContext::positionForNonFloatingFloatAvoider const):
+ (WebCore::Layout::FloatingContext::absoluteCoordinates const):
+ (WebCore::Layout::FloatingContext::absoluteBoxGeometryCoordinates const): Deleted.
+ * layout/floats/FloatingContext.h:
+
2020-09-28 Aditya Keerthi <[email protected]>
Crash under DateTimeEditElement::blurFromField
Modified: trunk/Source/WebCore/layout/FormattingState.cpp (267699 => 267700)
--- trunk/Source/WebCore/layout/FormattingState.cpp 2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/FormattingState.cpp 2020-09-28 15:00:14 UTC (rev 267700)
@@ -52,7 +52,7 @@
{
// Should never need to mutate a display box outside of the formatting context.
ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
- // Anonymous text wrappers do not need display boxes.
+ // Anonymous text wrappers do not need to compute box geometry. They initiate inline runs.
ASSERT(!layoutBox.isInlineTextBox());
return layoutState().ensureGeometryForBox(layoutBox);
}
Modified: trunk/Source/WebCore/layout/floats/FloatingContext.cpp (267699 => 267700)
--- trunk/Source/WebCore/layout/floats/FloatingContext.cpp 2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.cpp 2020-09-28 15:00:14 UTC (rev 267700)
@@ -227,15 +227,12 @@
if (isEmpty()) {
auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-
auto alignWithContainingBlock = [&]() -> Position {
// If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
if (layoutBox.isLeftFloatingPositioned())
return { horizontalConstraints.logicalLeft + boxGeometry.marginStart() };
-
return { horizontalConstraints.logicalRight() - boxGeometry.marginEnd() - boxGeometry.logicalWidth() };
};
-
// No float box on the context yet -> align it with the containing block's left/right edge.
return { alignWithContainingBlock(), boxGeometry.logicalTop() };
}
@@ -242,20 +239,42 @@
// Find the top most position where the float box fits.
ASSERT(!isEmpty());
- auto previousFloatAbsoluteTop = floatingState().floats().last().rectWithMargin().top();
- auto absoluteBoxGeometryCoordinates = this->absoluteBoxGeometryCoordinates(layoutBox);
- auto absoluteTopLeft = absoluteBoxGeometryCoordinates.topLeft;
- // Incoming float cannot be placed higher than existing floats (margin box of the last float).
- // Take the static position (where the box would go if it wasn't floating) and adjust it with the last float.
+ auto absoluteCoordinates = this->absoluteCoordinates(layoutBox);
+ auto absoluteTopLeft = absoluteCoordinates.topLeft;
+ auto verticalPositionCandidate = absoluteTopLeft.y();
+
auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
- if (absoluteTopLeft.y() - boxGeometry.marginBefore() < previousFloatAbsoluteTop)
- absoluteTopLeft.setY(previousFloatAbsoluteTop + boxGeometry.marginBefore());
+ if (layoutBox.hasFloatClear()) {
+ // The vertical position candidate needs to clear the existing floats in this context.
+ auto floatBottom = [&]() -> Optional<PositionInContextRoot> {
+ switch (layoutBox.style().clear()) {
+ case Clear::Left:
+ return floatingState().leftBottom(root());
+ case Clear::Right:
+ return floatingState().rightBottom(root());
+ case Clear::Both:
+ return floatingState().bottom(root());
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return { };
+ };
+ if (auto bottomWithClear = floatBottom())
+ verticalPositionCandidate = *bottomWithClear + boxGeometry.marginBefore();
+ } else {
+ // Incoming float cannot be placed higher than existing floats (margin box of the last float).
+ // Take the static position (where the box would go if it wasn't floating) and adjust it with the last float.
+ auto previousFloatAbsoluteTop = floatingState().floats().last().rectWithMargin().top();
+ if (verticalPositionCandidate - boxGeometry.marginBefore() < previousFloatAbsoluteTop)
+ verticalPositionCandidate = previousFloatAbsoluteTop + boxGeometry.marginBefore();
+ }
+ absoluteTopLeft.setY(verticalPositionCandidate);
auto horizontalMargin = computedHorizontalMargin(layoutBox, horizontalConstraints.logicalWidth);
auto margins = Edges { { *horizontalMargin.start, *horizontalMargin.end }, { boxGeometry.marginBefore(), boxGeometry.marginAfter() } };
- auto floatBox = FloatAvoider { layoutBox, absoluteTopLeft, boxGeometry.logicalWidth(), margins, absoluteBoxGeometryCoordinates.containingBlockContentBox };
+ auto floatBox = FloatAvoider { layoutBox, absoluteTopLeft, boxGeometry.logicalWidth(), margins, absoluteCoordinates.containingBlockContentBox };
findAvailablePosition(floatBox, m_floatingState.floats());
- // From formatting root coordinate system back to containing block's.
- auto containingBlockTopLeft = absoluteBoxGeometryCoordinates.containingBlockTopLeft;
+ // Convert box coordinates from formatting root back to containing block.
+ auto containingBlockTopLeft = absoluteCoordinates.containingBlockTopLeft;
return { floatBox.left() + margins.horizontal.left - containingBlockTopLeft.x(), floatBox.top() + margins.vertical.top - containingBlockTopLeft.y() };
}
@@ -269,13 +288,13 @@
if (isEmpty())
return formattingContext().geometryForBox(layoutBox).logicalTopLeft();
- auto absoluteBoxGeometryCoordinates = this->absoluteBoxGeometryCoordinates(layoutBox);
+ auto absoluteCoordinates = this->absoluteCoordinates(layoutBox);
auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
auto horizontalMargin = computedHorizontalMargin(layoutBox, horizontalConstraints.logicalWidth);
auto margins = Edges { { *horizontalMargin.start, *horizontalMargin.end }, { boxGeometry.marginBefore(), boxGeometry.marginAfter() } };
- auto floatAvoider = FloatAvoider { layoutBox, absoluteBoxGeometryCoordinates.topLeft, boxGeometry.logicalWidth(), margins, absoluteBoxGeometryCoordinates.containingBlockContentBox };
+ auto floatAvoider = FloatAvoider { layoutBox, absoluteCoordinates.topLeft, boxGeometry.logicalWidth(), margins, absoluteCoordinates.containingBlockContentBox };
findPositionForFormattingContextRoot(floatAvoider);
- auto containingBlockTopLeft = absoluteBoxGeometryCoordinates.containingBlockTopLeft;
+ auto containingBlockTopLeft = absoluteCoordinates.containingBlockTopLeft;
return { floatAvoider.left() - containingBlockTopLeft.x(), floatAvoider.top() - containingBlockTopLeft.y() };
}
@@ -455,7 +474,7 @@
}
}
-FloatingContext::AbsoluteCoordinateValuesForFloatAvoider FloatingContext::absoluteBoxGeometryCoordinates(const Box& floatAvoider) const
+FloatingContext::AbsoluteCoordinateValuesForFloatAvoider FloatingContext::absoluteCoordinates(const Box& floatAvoider) const
{
auto& containingBlock = floatAvoider.containingBlock();
auto& containingBlockGeometry = formattingContext().geometryForBox(containingBlock, FormattingContext::EscapeReason::FloatBoxNeedsToBeInAbsoluteCoordinates);
Modified: trunk/Source/WebCore/layout/floats/FloatingContext.h (267699 => 267700)
--- trunk/Source/WebCore/layout/floats/FloatingContext.h 2020-09-28 14:55:51 UTC (rev 267699)
+++ trunk/Source/WebCore/layout/floats/FloatingContext.h 2020-09-28 15:00:14 UTC (rev 267700)
@@ -74,7 +74,7 @@
void findPositionForFormattingContextRoot(FloatAvoider&) const;
struct AbsoluteCoordinateValuesForFloatAvoider;
- AbsoluteCoordinateValuesForFloatAvoider absoluteBoxGeometryCoordinates(const Box&) const;
+ AbsoluteCoordinateValuesForFloatAvoider absoluteCoordinates(const Box&) const;
LayoutPoint mapTopLeftToFloatingStateRoot(const Box&) const;
Point mapPointFromFormattingContextRootToFloatingStateRoot(Point) const;