WebKit Bugzilla
Attachment 339967 Details for
Bug 185474
: [LFC] Implement height computation for non-replaced inflow elements.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185474-20180509090139.patch (text/plain), 16.39 KB, created by
zalan
on 2018-05-09 09:01:40 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-05-09 09:01:40 PDT
Size:
16.39 KB
patch
obsolete
>Subversion Revision: 231538 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 6c074041d160c03003dff520ecd31fc1737f8d06..df516ff1673b46aee7ffd30a01d9e9736cd6ffdb 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,33 @@ >+2018-05-09 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC] Implement height computation for non-replaced inflow elements. >+ https://bugs.webkit.org/show_bug.cgi?id=185474 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Initial implementation. Does not cover all the cases. >+ >+ * layout/FormattingContext.cpp: >+ (WebCore::Layout::FormattingContext::computeHeight const): >+ * layout/FormattingContext.h: >+ * layout/blockformatting/BlockFormattingContext.cpp: >+ (WebCore::Layout::BlockFormattingContext::layout const): >+ (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const): >+ (WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const): >+ * layout/blockformatting/BlockFormattingContext.h: >+ * layout/blockformatting/BlockMarginCollapse.cpp: >+ (WebCore::Layout::collapsedMarginBottomFromLastChild): >+ (WebCore::Layout::BlockMarginCollapse::isMarginBottomCollapsedWithParent): >+ (WebCore::Layout::BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom): >+ (WebCore::Layout::isMarginBottomCollapsedWithParent): Deleted. >+ * layout/blockformatting/BlockMarginCollapse.h: >+ * layout/inlineformatting/InlineFormattingContext.cpp: >+ (WebCore::Layout::InlineFormattingContext::computeInFlowHeight const): >+ * layout/inlineformatting/InlineFormattingContext.h: >+ * layout/layouttree/LayoutBox.cpp: >+ (WebCore::Layout::Box::isReplaced const): >+ * layout/layouttree/LayoutBox.h: >+ > 2018-05-08 Dean Jackson <dino@apple.com> > > Disable system preview link fetching >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index 79f61ee95b7076d4c0e9c7ab49e2ac62fb217bc3..3c1189cad8037eabc196f22e68cdc9fa312f5808 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -68,13 +68,13 @@ void FormattingContext::computeWidth(const Box& layoutBox, Display::Box& display > return computeInFlowWidth(layoutBox, displayBox); > } > >-void FormattingContext::computeHeight(const Box& layoutBox, Display::Box& displayBox) const >+void FormattingContext::computeHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { > if (layoutBox.isOutOfFlowPositioned()) > return computeOutOfFlowHeight(layoutBox, displayBox); > if (layoutBox.isFloatingPositioned()) > return computeFloatingHeight(layoutBox, displayBox); >- return computeInFlowHeight(layoutBox, displayBox); >+ return computeInFlowHeight(layoutContext, layoutBox, displayBox); > } > > void FormattingContext::computeOutOfFlowWidth(const Box&, Display::Box&) const >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index 6f4dfe56f340f5dda1edf38e205645e4355ce7e8..3e5e87061c179999ae626b3fc3a9c6e9469f8d34 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -69,7 +69,7 @@ protected: > virtual void computeOutOfFlowPosition(const Box&, Display::Box&) const; > > virtual void computeWidth(const Box&, Display::Box&) const; >- virtual void computeHeight(const Box&, Display::Box&) const; >+ virtual void computeHeight(LayoutContext&, const Box&, Display::Box&) const; > > virtual void computeOutOfFlowWidth(const Box&, Display::Box&) const; > virtual void computeFloatingWidth(const Box&, Display::Box&) const; >@@ -77,7 +77,7 @@ protected: > > virtual void computeOutOfFlowHeight(const Box&, Display::Box&) const; > virtual void computeFloatingHeight(const Box&, Display::Box&) const; >- virtual void computeInFlowHeight(const Box&, Display::Box&) const = 0; >+ virtual void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const = 0; > > virtual LayoutUnit marginTop(const Box&) const; > virtual LayoutUnit marginLeft(const Box&) const; >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >index 47bf590996e8997204e3b3e0d0de1b5397c30ce7..e2c9c2dae4cae4aec87378fea7c72b5e00f6508f 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >@@ -94,7 +94,7 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > auto& layoutBox = layoutPair->layoutBox; > auto& displayBox = layoutPair->displayBox; > >- computeHeight(layoutBox, displayBox); >+ computeHeight(layoutContext, layoutBox, displayBox); > // Adjust position now that we have all the previous floats placed in this context -if needed. > floatingContext.computePosition(layoutBox, displayBox); > if (!is<Container>(layoutBox)) >@@ -147,8 +147,13 @@ void BlockFormattingContext::computeInFlowWidth(const Box&, Display::Box&) const > { > } > >-void BlockFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const >+void BlockFormattingContext::computeInFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { >+ if (!layoutBox.isReplaced()) { >+ computeInFlowNonReplacedHeight(layoutContext, layoutBox, displayBox); >+ return; >+ } >+ ASSERT_NOT_REACHED(); > } > > LayoutUnit BlockFormattingContext::marginTop(const Box& layoutBox) const >@@ -161,6 +166,61 @@ LayoutUnit BlockFormattingContext::marginBottom(const Box& layoutBox) const > return BlockMarginCollapse::marginBottom(layoutBox); > } > >+void BlockFormattingContext::computeInFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >+{ >+ // 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. >+ displayBox.setHeight(layoutBox.style().logicalHeight().value()); >+ return; >+ } >+ >+ if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild()) { >+ displayBox.setHeight(0); >+ return; >+ } >+ >+ // 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(); >+ displayBox.setHeight(0); >+ return; >+ } >+ >+ // 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 (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) { >+ auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild); >+ ASSERT(lastInFlowDisplayBox); >+ displayBox.setHeight(lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom()); >+ return; >+ } >+ >+ // 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 && BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild)) >+ inFlowChild = inFlowChild->previousInFlowSibling(); >+ if (inFlowChild) { >+ auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild); >+ ASSERT(inFlowDisplayBox); >+ displayBox.setHeight(inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height()); >+ return; >+ } >+ >+ // 4. zero, otherwise >+ displayBox.setHeight(0); >+} >+ > } > } > >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >index 691c4693afba9555b6e664383a14c45cf79adf79..e2ac84a027af5b24fec28981dfdf7c158f3d1739 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >@@ -49,10 +49,11 @@ public: > std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const override; > Ref<FloatingState> createOrFindFloatingState(LayoutContext&) const override; > >-protected: >+private: > void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override; > void computeInFlowWidth(const Box&, Display::Box&) const override; >- void computeInFlowHeight(const Box&, Display::Box&) const override; >+ void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override; >+ void computeInFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; > > LayoutUnit marginTop(const Box&) const override; > LayoutUnit marginBottom(const Box&) const override; >diff --git a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp >index 8ecfcbe3f91b1c7a7945a798bdbb358b026ac298..584f43af8afec7f52d19fca745b169272dd73e9c 100644 >--- a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp >@@ -114,42 +114,6 @@ static bool isMarginTopCollapsedWithParent(const Box& layoutBox) > return true; > } > >-static bool isMarginBottomCollapsedWithParent(const Box& layoutBox) >-{ >- // last inflow box to parent. >- // https://www.w3.org/TR/CSS21/box.html#collapsing-margins >- if (layoutBox.isAnonymous()) >- return false; >- >- if (layoutBox.isFloatingOrOutOfFlowPositioned()) >- return false; >- >- // We never margin collapse the initial containing block. >- ASSERT(layoutBox.parent()); >- auto& parent = *layoutBox.parent(); >- // Is this the last inlflow child? >- if (parent.lastInFlowChild() != &layoutBox) >- return false; >- >- if (parent.establishesBlockFormattingContext()) >- return false; >- >- // Margins of the root element's box do not collapse. >- if (parent.isInitialContainingBlock()) >- return false; >- >- if (!parent.style().borderTop().nonZero()) >- return false; >- >- if (!parent.style().paddingTop().isZero()) >- return false; >- >- if (!parent.style().height().isAuto()) >- return false; >- >- return true; >-} >- > static LayoutUnit collapsedMarginTopFromFirstChild(const Box& layoutBox) > { > // Check if the first child collapses its margin top. >@@ -171,7 +135,7 @@ static LayoutUnit collapsedMarginBottomFromLastChild(const Box& layoutBox) > return 0; > > auto& lastInFlowChild = *downcast<Container>(layoutBox).lastInFlowChild(); >- if (!isMarginBottomCollapsedWithParent(lastInFlowChild)) >+ if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(lastInFlowChild)) > return 0; > > // Collect collapsed margin bottom recursively. >@@ -249,6 +213,47 @@ LayoutUnit BlockMarginCollapse::marginBottom(const Box& layoutBox) > return nonCollapsedMarginBottom(layoutBox); > } > >+bool BlockMarginCollapse::isMarginBottomCollapsedWithParent(const Box& layoutBox) >+{ >+ // last inflow box to parent. >+ // https://www.w3.org/TR/CSS21/box.html#collapsing-margins >+ if (layoutBox.isAnonymous()) >+ return false; >+ >+ if (layoutBox.isFloatingOrOutOfFlowPositioned()) >+ return false; >+ >+ // We never margin collapse the initial containing block. >+ ASSERT(layoutBox.parent()); >+ auto& parent = *layoutBox.parent(); >+ // Is this the last inlflow child? >+ if (parent.lastInFlowChild() != &layoutBox) >+ return false; >+ >+ if (parent.establishesBlockFormattingContext()) >+ return false; >+ >+ // Margins of the root element's box do not collapse. >+ if (parent.isInitialContainingBlock()) >+ return false; >+ >+ if (!parent.style().borderTop().nonZero()) >+ return false; >+ >+ if (!parent.style().paddingTop().isZero()) >+ return false; >+ >+ if (!parent.style().height().isAuto()) >+ return false; >+ >+ return true; >+} >+ >+bool BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(const Box&) >+{ >+ return false; >+} >+ > } > } > #endif >diff --git a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h >index 72fe57c53551a37be5395da65b1e0cd06e3aab40..9de8b2d6ead368e20904b7799382d5a8cd594134 100644 >--- a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h >+++ b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h >@@ -42,6 +42,9 @@ class BlockMarginCollapse { > public: > static LayoutUnit marginTop(const Box&); > static LayoutUnit marginBottom(const Box&); >+ >+ static bool isMarginBottomCollapsedWithParent(const Box&); >+ static bool isMarginTopCollapsedWithParentMarginBottom(const Box&); > }; > > } >diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >index 49c73e81f4c03cffa8ea17b390f342c53a78b8d9..bb8a390c126df098761da0240b3c3197e5366e2a 100644 >--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp >@@ -70,7 +70,7 @@ void InlineFormattingContext::computeInFlowWidth(const Box&, Display::Box&) cons > { > } > >-void InlineFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const >+void InlineFormattingContext::computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const > { > } > >diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >index 3b1f25836027d1557714d21b369631372f559f3f..4437bd8ce02508133451ec416534586cf0162ca8 100644 >--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h >@@ -49,7 +49,7 @@ public: > > private: > void computeInFlowWidth(const Box&, Display::Box&) const override; >- void computeInFlowHeight(const Box&, Display::Box&) const override; >+ void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override; > > }; > >diff --git a/Source/WebCore/layout/layouttree/LayoutBox.cpp b/Source/WebCore/layout/layouttree/LayoutBox.cpp >index 44797af8ec71a028e68baee13d31282f54f0f65a..fe0d5caee28ef5a5f845dd95b0561af7dfec19c8 100644 >--- a/Source/WebCore/layout/layouttree/LayoutBox.cpp >+++ b/Source/WebCore/layout/layouttree/LayoutBox.cpp >@@ -179,6 +179,12 @@ bool Box::isInitialContainingBlock() const > return !parent(); > } > >+bool Box::isReplaced() const >+{ >+ // HTMLAudioElement || HTMLCanvasElement || HTMLEmbedElement || HTMLIFrameElement || HTMLImageElement || HTMLInputElement || HTMLObjectElement || HTMLVideoElement >+ return false; >+} >+ > const Box* Box::nextInFlowSibling() const > { > if (auto* nextSibling = this->nextSibling()) { >diff --git a/Source/WebCore/layout/layouttree/LayoutBox.h b/Source/WebCore/layout/layouttree/LayoutBox.h >index 5c4563c642525ea0d82bf2774cdf5d5014932e9f..23af846149179cc07ad08e8be7e4ce123e670167 100644 >--- a/Source/WebCore/layout/layouttree/LayoutBox.h >+++ b/Source/WebCore/layout/layouttree/LayoutBox.h >@@ -72,6 +72,7 @@ public: > bool isInlineBlockBox() const; > bool isBlockContainerBox() const; > bool isInitialContainingBlock() const; >+ bool isReplaced() const; > > const Container* parent() const { return m_parent; } > const Box* nextSibling() const { return m_nextSibling; }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185474
: 339967