https://bugs.webkit.org/show_bug.cgi?id=189377
Reviewed by Antti Koivisto.
Source/WebCore:
See https://www.w3.org/TR/CSS22/visudet.html#min-max-heights for details.
Tests: fast/block/block-only/absolute-position-min-max-height.html
fast/block/block-only/float-min-max-height.html
fast/block/block-only/inflow-min-max-height.html
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
* layout/blockformatting/BlockFormattingContext.h:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
Tools:
* LayoutReloaded/misc/LFC-passing-tests.txt:
LayoutTests:
* fast/block/block-only/absolute-position-min-max-height-expected.txt: Added.
* fast/block/block-only/absolute-position-min-max-height.html: Added.
* fast/block/block-only/float-min-max-height-expected.txt: Added.
* fast/block/block-only/float-min-max-height.html: Added.
* fast/block/block-only/inflow-min-max-height-expected.txt: Added.
* fast/block/block-only/inflow-min-max-height.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235763
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-09-06 Zalan Bujtas <zalan@apple.com>
+
+ [LFC][BFC] Add support for min(max)-height
+ https://bugs.webkit.org/show_bug.cgi?id=189377
+
+ Reviewed by Antti Koivisto.
+
+ * fast/block/block-only/absolute-position-min-max-height-expected.txt: Added.
+ * fast/block/block-only/absolute-position-min-max-height.html: Added.
+ * fast/block/block-only/float-min-max-height-expected.txt: Added.
+ * fast/block/block-only/float-min-max-height.html: Added.
+ * fast/block/block-only/inflow-min-max-height-expected.txt: Added.
+ * fast/block/block-only/inflow-min-max-height.html: Added.
+
2018-09-06 Daniel Bates <dabates@apple.com>
[iOS] Add a test to ensure that DOM keyup events have the correct details
--- /dev/null
+layer at (0,0) size 785x602
+ RenderView at (0,0) size 785x600
+layer at (0,0) size 785x8
+ RenderBlock {HTML} at (0,0) size 785x8
+ RenderBody {BODY} at (8,8) size 769x0
+layer at (8,8) size 102x54
+ RenderBlock (positioned) {DIV} at (8,8) size 102x54 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 102x52 [border: (1px solid #FF0000)]
+layer at (8,100) size 102x102
+ RenderBlock (positioned) {DIV} at (8,100) size 102x102 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 102x152 [border: (1px solid #FF0000)]
+layer at (8,300) size 102x302
+ RenderBlock (positioned) {DIV} at (8,300) size 102x302 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 102x52 [border: (1px solid #FF0000)]
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+ border: 1px solid green;
+}
+
+div > div {
+ border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="position: absolute; width: 100px;">
+ <div style="height: 50px; width: 100px;"></div>
+</div>
+
+<div style="position: absolute; top: 100px; width: 100px; max-height: 100px;">
+ <div style="height: 150px; width: 100px;"></div>
+</div>
+
+<div style="position: absolute; top: 300px; width: 100px; min-height: 300px">
+ <div style="height: 50px; width: 100px;"></div>
+</div>
+</body>
+</html>
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x412
+ RenderBlock {HTML} at (0,0) size 800x412
+ RenderBody {BODY} at (8,8) size 784x0
+ RenderBlock (floating) {DIV} at (0,0) size 202x54 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+ RenderBlock (floating) {DIV} at (302,0) size 202x102 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x152 [border: (1px solid #FF0000)]
+ RenderBlock (floating) {DIV} at (0,102) size 202x302 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+ border: 1px solid green;
+}
+
+div > div {
+ border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="float: left; width: 200px;">
+ <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="float: left; margin-left: 100px; margin-right: 200px; width: 200px; max-height: 100px;">
+ <div style="height: 150px; width: 200px;"></div>
+</div>
+
+<div style="float: left; width: 200px; min-height: 300px">
+ <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x424
+ RenderBlock {HTML} at (0,0) size 800x424
+ RenderBody {BODY} at (8,8) size 784x408
+ RenderBlock {DIV} at (0,0) size 202x54 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+ RenderBlock {DIV} at (0,54) size 202x52 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x202 [border: (1px solid #FF0000)]
+ RenderBlock {DIV} at (0,106) size 202x302 [border: (1px solid #008000)]
+ RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+ border: 1px solid green;
+}
+
+div > div {
+ border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="width: 200px;">
+ <div style="width: 200px; height: 50px"></div>
+</div>
+
+<div style="width: 200px; max-height: 50px;">
+ <div style="height: 200px; width: 200px;"></div>
+</div>
+
+<div style="width: 200px; min-height: 300px">
+ <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
+2018-09-06 Zalan Bujtas <zalan@apple.com>
+
+ [LFC][BFC] Add support for min(max)-height
+ https://bugs.webkit.org/show_bug.cgi?id=189377
+
+ Reviewed by Antti Koivisto.
+
+ See https://www.w3.org/TR/CSS22/visudet.html#min-max-heights for details.
+
+ Tests: fast/block/block-only/absolute-position-min-max-height.html
+ fast/block/block-only/float-min-max-height.html
+ fast/block/block-only/inflow-min-max-height.html
+
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
+ * layout/FormattingContext.h:
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+ (WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
+ * layout/blockformatting/BlockFormattingContext.h:
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+
2018-09-06 Eric Carlson <eric.carlson@apple.com>
[MediaStream] Include supported frame rates in video capture presets
void FormattingContext::computeOutOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox) const
{
- auto verticalGeometry = Geometry::outOfFlowVerticalGeometry(layoutContext, layoutBox);
+ auto compute = [&](std::optional<LayoutUnit> precomputedHeight) {
+ return Geometry::outOfFlowVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
+ };
+
+ auto verticalGeometry = compute({ });
+ // FIXME: Add support for percentage values where the containing block's height is explicitly specified.
+ if (auto maxHeight = Geometry::fixedValue(layoutBox.style().logicalMaxHeight())) {
+ auto maxVerticalGeometry = compute(maxHeight);
+ if (verticalGeometry.heightAndMargin.height > maxVerticalGeometry.heightAndMargin.height)
+ verticalGeometry = maxVerticalGeometry;
+ }
+
+ if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+ auto minVerticalGeometry = compute(minHeight);
+ if (verticalGeometry.heightAndMargin.height < minVerticalGeometry.heightAndMargin.height)
+ verticalGeometry = minVerticalGeometry;
+ }
auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setTop(verticalGeometry.top + verticalGeometry.heightAndMargin.margin.top);
// This class implements generic positioning and sizing.
class Geometry {
public:
- static VerticalGeometry outOfFlowVerticalGeometry(const LayoutContext&, const Box&);
+ static VerticalGeometry outOfFlowVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static HorizontalGeometry outOfFlowHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
- static HeightAndMargin floatingHeightAndMargin(const LayoutContext&, const Box&);
+ static HeightAndMargin floatingHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static WidthAndMargin floatingWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
- static HeightAndMargin inlineReplacedHeightAndMargin(const LayoutContext&, const Box&);
+ static HeightAndMargin inlineReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static WidthAndMargin inlineReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { },
std::optional<LayoutUnit> precomputedMarginLeft = { }, std::optional<LayoutUnit> precomputedMarginRight = { });
- static HeightAndMargin complicatedCases(const LayoutContext&, const Box&);
+ static HeightAndMargin complicatedCases(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static Edges computedBorder(const LayoutContext&, const Box&);
static std::optional<Edges> computedPadding(const LayoutContext&, const Box&);
static std::optional<LayoutUnit> fixedValue(const Length& geometryProperty);
private:
- static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&);
+ static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
- static VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const LayoutContext&, const Box&);
+ static VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
- static HeightAndMargin floatingReplacedHeightAndMargin(const LayoutContext&, const Box&);
+ static HeightAndMargin floatingReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static WidthAndMargin floatingReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
return std::min(std::max(instrinsicWidthConstraints.minimum, availableWidth), instrinsicWidthConstraints.maximum);
}
-VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
- auto height = computedValueIfNotAuto(style.logicalHeight(), containingBlockHeight);
+ auto height = computedValueIfNotAuto(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight(), containingBlockHeight);
auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
auto paddingTop = displayBox.paddingTop().value_or(0);
return { *left, *right, { *width, { *marginLeft, *marginRight }, { nonComputedMarginLeft, nonComputedMarginRight } } };
}
-VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
- auto height = inlineReplacedHeightAndMargin(layoutContext, layoutBox).height;
+ auto height = inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight).height;
auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
auto paddingTop = displayBox.paddingTop().value_or(0);
return { *left, *right, { width, { *marginLeft, *marginRight }, { nonComputedMarginLeft, nonComputedMarginRight } } };
}
-HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(!layoutBox.replaced());
// TODO: Use complicated-case for document renderer for now (see BlockFormattingContext::Geometry::inFlowHeightAndMargin).
auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(containingBlock);
auto containingBlockWidth = containingBlockDisplayBox.contentBoxWidth();
- auto height = fixedValue(style.logicalHeight());
+ auto height = fixedValue(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight());
auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
return WidthAndMargin { *width, margin, margin };
}
-HeightAndMargin FormattingContext::Geometry::floatingReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::floatingReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isFloatingPositioned() && layoutBox.replaced());
// 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
// replaced elements in normal flow and floating replaced elements
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
- return inlineReplacedHeightAndMargin(layoutContext, layoutBox);
+ return inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
}
WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
return inlineReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth, margin.left, margin.right);
}
-VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isOutOfFlowPositioned());
if (!layoutBox.replaced())
- return outOfFlowNonReplacedVerticalGeometry(layoutContext, layoutBox);
- return outOfFlowReplacedVerticalGeometry(layoutContext, layoutBox);
+ return outOfFlowNonReplacedVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
+ return outOfFlowReplacedVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
}
HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
return outOfFlowReplacedHorizontalGeometry(layoutContext, layoutBox, precomputedWidth);
}
-HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isFloatingPositioned());
if (!layoutBox.replaced())
- return complicatedCases(layoutContext, layoutBox);
- return floatingReplacedHeightAndMargin(layoutContext, layoutBox);
+ return complicatedCases(layoutContext, layoutBox, precomputedHeight);
+ return floatingReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
}
WidthAndMargin FormattingContext::Geometry::floatingWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
return floatingReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
}
-HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
auto containingBlockWidth = containingBlockDisplayBox.width();
- auto height = fixedValue(style.logicalHeight());
+ auto height = fixedValue(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight());
auto heightIsAuto = style.logicalHeight().isAuto();
auto width = computedValueIfNotAuto(style.logicalWidth(), containingBlockWidth);
void BlockFormattingContext::computeHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox) const
{
- HeightAndMargin heightAndMargin;
- std::optional<LayoutUnit> marginTopOffset;
- auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto compute = [&](std::optional<LayoutUnit> precomputedHeight) -> HeightAndMargin {
- if (layoutBox.isInFlow()) {
- heightAndMargin = Geometry::inFlowHeightAndMargin(layoutContext, layoutBox);
+ if (layoutBox.isInFlow())
+ return Geometry::inFlowHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
- // If this box has already been moved by the estimated vertical margin, no need to move it again.
- if (!displayBox.estimatedMarginTop())
- marginTopOffset = heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin).top;
- } else if (layoutBox.isFloatingPositioned()) {
- heightAndMargin = Geometry::floatingHeightAndMargin(layoutContext, layoutBox);
- ASSERT(!heightAndMargin.collapsedMargin);
+ if (layoutBox.isFloatingPositioned())
+ return Geometry::floatingHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
- marginTopOffset = heightAndMargin.margin.top;
- } else
ASSERT_NOT_REACHED();
+ return { };
+ };
+ auto heightAndMargin = compute({ });
+ // FIXME: Add support for percentage values where the containing block's height is explicitly specified.
+ if (auto maxHeight = Geometry::fixedValue(layoutBox.style().logicalMaxHeight())) {
+ auto maxHeightAndMargin = compute(maxHeight);
+ if (heightAndMargin.height > maxHeightAndMargin.height)
+ heightAndMargin = maxHeightAndMargin;
+ }
+
+ if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+ auto minHeightAndMargin = compute(minHeight);
+ if (heightAndMargin.height < minHeightAndMargin.height)
+ heightAndMargin = minHeightAndMargin;
+ }
+
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setContentBoxHeight(heightAndMargin.height);
displayBox.setVerticalNonCollapsedMargin(heightAndMargin.margin);
displayBox.setVerticalMargin(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin));
- if (marginTopOffset)
- displayBox.moveVertically(*marginTopOffset);
+
+ // If this box has already been moved by the estimated vertical margin, no need to move it again.
+ if (layoutBox.isFloatingPositioned() || !displayBox.estimatedMarginTop())
+ displayBox.moveVertically(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin).top);
}
FormattingContext::InstrinsicWidthConstraints BlockFormattingContext::instrinsicWidthConstraints(LayoutContext& layoutContext, const Box& layoutBox) const
// This class implements positioning and sizing for boxes participating in a block formatting context.
class Geometry : public FormattingContext::Geometry {
public:
- static HeightAndMargin inFlowHeightAndMargin(const LayoutContext&, const Box&);
+ static HeightAndMargin inFlowHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static WidthAndMargin inFlowWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
static Position staticPosition(const LayoutContext&, const Box&);
static LayoutUnit nonCollapsedMarginTop(const LayoutContext&, const Box&);
};
- static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutContext&, const Box&);
+ static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
static WidthAndMargin inFlowNonReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
static WidthAndMargin inFlowReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
static Position staticPositionForOutOfFlowPositioned(const LayoutContext&, const Box&);
return widthAndMargin;
}
-HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
ASSERT(layoutBox.isOverflowVisible());
VerticalEdges collapsedMargin = { MarginCollapse::marginTop(layoutContext, layoutBox), MarginCollapse::marginBottom(layoutContext, layoutBox) };
auto borderAndPaddingTop = displayBox.borderTop() + displayBox.paddingTop().value_or(0);
- auto height = style.logicalHeight();
+ auto height = precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight();
if (!height.isAuto()) {
if (height.isFixed())
- return { style.logicalHeight().value(), nonCollapsedMargin, collapsedMargin };
+ return { height.value(), nonCollapsedMargin, collapsedMargin };
// Most notably height percentage.
ASSERT_NOT_IMPLEMENTED_YET();
return { newLeftPosition, newTopPosition };
}
-HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
{
ASSERT(layoutBox.isInFlow());
// 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
// replaced elements in normal flow and floating replaced elements
if (layoutBox.replaced())
- return inlineReplacedHeightAndMargin(layoutContext, layoutBox);
+ return inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
HeightAndMargin heightAndMargin;
// TODO: Figure out the case for the document element. Let's just complicated-case it for now.
if (layoutBox.isOverflowVisible() && !layoutBox.isDocumentBox())
- heightAndMargin = inFlowNonReplacedHeightAndMargin(layoutContext, layoutBox);
+ heightAndMargin = inFlowNonReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
else {
// 10.6.6 Complicated cases
// Block-level, non-replaced elements in normal flow when 'overflow' does not compute to 'visible' (except if the 'overflow' property's value has been propagated to the viewport).
- heightAndMargin = complicatedCases(layoutContext, layoutBox);
+ heightAndMargin = complicatedCases(layoutContext, layoutBox, precomputedHeight);
}
if (!isStretchedToInitialContainingBlock(layoutContext, layoutBox))
+2018-09-06 Zalan Bujtas <zalan@apple.com>
+
+ [LFC][BFC] Add support for min(max)-height
+ https://bugs.webkit.org/show_bug.cgi?id=189377
+
+ Reviewed by Antti Koivisto.
+
+ * LayoutReloaded/misc/LFC-passing-tests.txt:
+
2018-09-06 Dewei Zhu <dewei_zhu@apple.com>
BenchmarkResults.format should support specifying depth of tests to show.
fast/block/block-only/inflow-min-max-width.html
fast/block/block-only/absolute-position-min-max-width.html
fast/block/block-only/float-min-max-width.html
+fast/block/block-only/inflow-min-max-height.html
+fast/block/block-only/absolute-position-min-max-height.html
+fast/block/block-only/float-min-max-height.html