Diff
Modified: trunk/Source/WebCore/ChangeLog (232290 => 232291)
--- trunk/Source/WebCore/ChangeLog 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/ChangeLog 2018-05-30 15:26:51 UTC (rev 232291)
@@ -1,3 +1,34 @@
+2018-05-30 Zalan Bujtas <za...@apple.com>
+
+ [LFC] Miscellaneous fixes to get closer to geometry correctness
+ https://bugs.webkit.org/show_bug.cgi?id=186083
+
+ Reviewed by Antti Koivisto.
+
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::FormattingContext::Geometry::computedBorder):
+ * layout/LayoutContext.cpp:
+ (WebCore::Layout::LayoutContext::initializeRoot):
+ * layout/Verification.cpp:
+ (WebCore::Layout::outputMismatchingBoxInformationIfNeeded):
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::isStretchedToViewport):
+ (WebCore::Layout::initialContainingBlock):
+ (WebCore::Layout::computedInFlowNonReplacedComputedHeight):
+ (WebCore::Layout::inFlowNonReplacedComputedWidth):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeight): lambda should capture the specification part.
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidth):
+ * layout/displaytree/DisplayBox.cpp:
+ (WebCore::Display::Box::marginBox const):
+ (WebCore::Display::Box::paddingBox const):
+ (WebCore::Display::Box::contentBox const):
+ * layout/layouttree/LayoutBox.cpp:
+ (WebCore::Layout::Box::isDocumentBox const):
+ (WebCore::Layout::Box::isBodyBox const):
+ * layout/layouttree/LayoutBox.h:
+ * rendering/style/BorderValue.h: ignore border-width when type is hidden or none.
+ (WebCore::BorderValue::boxModelWidth const):
+
2018-05-30 Stephen McGruer <smcgr...@chromium.org>
iOS: setting 'defaultValue' of input type=date from script should cause a UI update
Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -529,10 +529,10 @@
{
auto& style = layoutBox.style();
return {
- style.borderTop().width(),
- style.borderLeft().width(),
- style.borderBottom().width(),
- style.borderRight().width()
+ style.borderTop().boxModelWidth(),
+ style.borderLeft().boxModelWidth(),
+ style.borderBottom().boxModelWidth(),
+ style.borderRight().boxModelWidth()
};
}
Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/LayoutContext.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -61,12 +61,12 @@
displayBox.setMargin({ });
auto& style = root.style();
- // FIXME: m_root could very well be a formatting context root with ancestors and resolvable border and padding (as opposed to the topmost root)
+ // FIXME: m_root could very well be a formatting context root with ancestors and resolvable border and padding (as opposed to the topmost root)
displayBox.setBorder({
- style.borderTop().width(),
- style.borderLeft().width(),
- style.borderBottom().width(),
- style.borderRight().width()
+ style.borderTop().boxModelWidth(),
+ style.borderLeft().boxModelWidth(),
+ style.borderBottom().boxModelWidth(),
+ style.borderRight().boxModelWidth()
});
displayBox.setPadding({
Modified: trunk/Source/WebCore/layout/Verification.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/Verification.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/Verification.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -68,7 +68,7 @@
if (renderer.paddingBoxRect() != displayBox->paddingBox())
outputRect("paddingBox", renderer.paddingBoxRect(), displayBox->paddingBox());
- if (renderer.marginBoxRect() != displayBox->contentBox())
+ if (renderer.contentBoxRect() != displayBox->contentBox())
outputRect("contentBox", renderer.contentBoxRect(), displayBox->contentBox());
stream.nextLine();
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -33,55 +33,84 @@
namespace WebCore {
namespace Layout {
+static bool isStretchedToViewport(const Box& layoutBox)
+{
+ ASSERT(layoutBox.isInFlow());
+ // In quirks mode, body and html stretch to the viewport.
+ // if (!layoutBox.document().inQuirksMode())
+ // return false;
+
+ if (!layoutBox.isDocumentBox() || !layoutBox.isBodyBox())
+ return false;
+
+ return layoutBox.style().logicalHeight().isAuto();
+}
+
+static const Container& initialContainingBlock(const Box& layoutBox)
+{
+ auto* containingBlock = layoutBox.containingBlock();
+ while (containingBlock->containingBlock())
+ containingBlock = containingBlock->containingBlock();
+ return *containingBlock;
+}
+
LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
{
ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
- // https://www.w3.org/TR/CSS22/visudet.html
- // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
- // The element's height is the distance from its top content edge to the first applicable of the following:
- // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
- // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
- // does not collapse with the element's bottom margin
- // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
- // 4. zero, otherwise
- // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
- // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
- if (!layoutBox.style().logicalHeight().isAuto()) {
- // FIXME: Only fixed values yet.
- return layoutBox.style().logicalHeight().value();
- }
+ auto compute = [&]() -> LayoutUnit {
+ // https://www.w3.org/TR/CSS22/visudet.html
+ // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
+ // The element's height is the distance from its top content edge to the first applicable of the following:
+ // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+ // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
+ // does not collapse with the element's bottom margin
+ // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+ // 4. zero, otherwise
+ // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
+ // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
+ if (!layoutBox.style().logicalHeight().isAuto()) {
+ // FIXME: Only fixed values yet.
+ return layoutBox.style().logicalHeight().value();
+ }
- if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
- return 0;
+ if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
+ return 0;
- // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
- if (layoutBox.establishesInlineFormattingContext()) {
- // height = lastLineBox().bottom();
- return 0;
- }
+ // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+ if (layoutBox.establishesInlineFormattingContext()) {
+ // height = lastLineBox().bottom();
+ return 0;
+ }
- // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
- auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
- ASSERT(lastInFlowChild);
- if (!BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
- auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
- ASSERT(lastInFlowDisplayBox);
- return lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom();
- }
+ // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
+ auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
+ ASSERT(lastInFlowChild);
+ if (!BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
+ auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
+ ASSERT(lastInFlowDisplayBox);
+ return lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom();
+ }
- // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
- auto* inFlowChild = lastInFlowChild;
- while (inFlowChild && BlockFormattingContext::MarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
- inFlowChild = inFlowChild->previousInFlowSibling();
- if (inFlowChild) {
- auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
- ASSERT(inFlowDisplayBox);
- return inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height();
- }
+ // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+ auto* inFlowChild = lastInFlowChild;
+ while (inFlowChild && BlockFormattingContext::MarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
+ inFlowChild = inFlowChild->previousInFlowSibling();
+ if (inFlowChild) {
+ auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
+ ASSERT(inFlowDisplayBox);
+ return inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height();
+ }
- // 4. zero, otherwise
- return 0;
+ // 4. zero, otherwise
+ return 0;
+ };
+
+ auto computedHeight = compute();
+ if (!isStretchedToViewport(layoutBox))
+ return computedHeight;
+ auto initialContainingBlockHeight = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBox().height();
+ return std::max(computedHeight, initialContainingBlockHeight);
}
LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
@@ -88,32 +117,40 @@
{
ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
- // 10.3.3 Block-level, non-replaced elements in normal flow
- // The following constraints must hold among the used values of the other properties:
- // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
+ auto compute = [&]() {
+ // 10.3.3 Block-level, non-replaced elements in normal flow
+ // The following constraints must hold among the used values of the other properties:
+ // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
- // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
- auto& style = layoutBox.style();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+ // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
+ auto& style = layoutBox.style();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
- LayoutUnit computedWidthValue;
- auto width = style.logicalWidth();
- if (width.isAuto()) {
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
- auto marginLeft = displayBox.marginLeft();
- auto marginRight = displayBox.marginRight();
+ LayoutUnit computedWidthValue;
+ auto width = style.logicalWidth();
+ if (width.isAuto()) {
+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto marginLeft = displayBox.marginLeft();
+ auto marginRight = displayBox.marginRight();
- auto paddingLeft = displayBox.paddingLeft();
- auto paddingRight = displayBox.paddingRight();
+ auto paddingLeft = displayBox.paddingLeft();
+ auto paddingRight = displayBox.paddingRight();
- auto borderLeft = displayBox.borderLeft();
- auto borderRight = displayBox.borderRight();
+ auto borderLeft = displayBox.borderLeft();
+ auto borderRight = displayBox.borderRight();
- computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
- } else
- computedWidthValue = valueForLength(width, containingBlockWidth);
+ computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
+ } else
+ computedWidthValue = valueForLength(width, containingBlockWidth);
- return computedWidthValue;
+ return computedWidthValue;
+ };
+
+ auto computedWidth = compute();
+ if (!isStretchedToViewport(layoutBox))
+ return computedWidth;
+ auto initialContainingBlockWidth = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBox().width();
+ return std::max(computedWidth, initialContainingBlockWidth);
}
LayoutPoint BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox)
Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -56,7 +56,7 @@
auto marginBox = borderBox();
marginBox.shiftLeftTo(marginBox.left() + m_margin.left);
- marginBox.shiftBottomTo(marginBox.top() + m_margin.top);
+ marginBox.shiftTopTo(marginBox.top() + m_margin.top);
marginBox.shiftRightTo(marginBox.right() - m_margin.right);
marginBox.shiftBottomTo(marginBox.bottom() - m_margin.bottom);
@@ -85,7 +85,7 @@
paddingBox.shiftLeftTo(paddingBox.left() + m_border.left);
paddingBox.shiftTopTo(paddingBox.top() + m_border.top);
- paddingBox.shiftRightTo(paddingBox.left() - m_border.right);
+ paddingBox.shiftRightTo(paddingBox.right() - m_border.right);
paddingBox.shiftBottomTo(paddingBox.bottom() - m_border.bottom);
return paddingBox;
@@ -105,8 +105,8 @@
contentBox.shiftLeftTo(contentBox.left() + m_padding.left);
contentBox.shiftTopTo(contentBox.top() + m_padding.top);
+ contentBox.shiftRightTo(contentBox.right() - m_padding.right);
contentBox.shiftBottomTo(contentBox.bottom() - m_padding.bottom);
- contentBox.shiftRightTo(contentBox.right() - m_padding.right);
return contentBox;
}
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (232290 => 232291)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2018-05-30 15:26:51 UTC (rev 232291)
@@ -181,6 +181,18 @@
return !parent();
}
+bool Box::isDocumentBox() const
+{
+ // return document().documentElement() == &element();
+ return false;
+}
+
+bool Box::isBodyBox() const
+{
+ // return element().hasTagName(HTMLNames::bodyTag);
+ return false;
+}
+
const Box* Box::nextInFlowSibling() const
{
if (auto* nextSibling = this->nextSibling()) {
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (232290 => 232291)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-05-30 15:26:51 UTC (rev 232291)
@@ -74,6 +74,9 @@
bool isBlockContainerBox() const;
bool isInitialContainingBlock() const;
+ bool isDocumentBox() const;
+ bool isBodyBox() const;
+
const Container* parent() const { return m_parent; }
const Box* nextSibling() const { return m_nextSibling; }
const Box* nextInFlowSibling() const;
Modified: trunk/Source/WebCore/rendering/style/BorderValue.h (232290 => 232291)
--- trunk/Source/WebCore/rendering/style/BorderValue.h 2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/rendering/style/BorderValue.h 2018-05-30 15:26:51 UTC (rev 232291)
@@ -72,6 +72,8 @@
float width() const { return m_width; }
BorderStyle style() const { return static_cast<BorderStyle>(m_style); }
+
+ float boxModelWidth() const;
protected:
float m_width { 3 };
@@ -83,4 +85,13 @@
unsigned m_isAuto : 1; // OutlineIsAuto
};
+inline float BorderValue::boxModelWidth() const
+{
+ auto style = this->style();
+ if (style == BorderStyle::None || style == BorderStyle::Hidden)
+ return 0;
+
+ return width();
+}
+
} // namespace WebCore