[LFC] Layout::Box::parent() should return const ContainerBox&
https://bugs.webkit.org/show_bug.cgi?id=209400
<rdar://problem/60742432>
Reviewed by Antti Koivisto.
Layout tree is immutable during layout, so every box should be able to return a valid parent (except the ICB, but
class InitialContainingBlock deletes parent() function anyway).
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::staticVerticalPositionForOutOfFlowPositioned const):
(WebCore::Layout::FormattingContext::Geometry::staticHorizontalPositionForOutOfFlowPositioned const):
* layout/blockformatting/BlockFormattingContextQuirks.cpp:
(WebCore::Layout::BlockFormattingContext::Quirks::stretchedInFlowHeight):
* layout/blockformatting/BlockMarginCollapse.cpp:
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBeforeCollapsesWithParentMarginAfter const):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBeforeCollapsesWithParentMarginBefore const):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginAfterCollapsesWithParentMarginBefore const):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginAfterCollapsesWithParentMarginAfter const):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::nextInlineLevelBoxToLayout):
(WebCore::Layout::InlineFormattingContext::constraintsForLine):
* layout/layouttree/LayoutBox.cpp:
(WebCore::Layout::Box::containingBlock const):
(WebCore::Layout::Box::formattingContextRoot const):
(WebCore::Layout::Box::initialContainingBlock const):
(WebCore::Layout::Box::isOverflowVisible const):
* layout/layouttree/LayoutBox.h:
(WebCore::Layout::Box::parent const):
* layout/layouttree/LayoutIterator.h:
(WebCore::Layout::LayoutBoxTraversal::nextAncestorSibling):
(WebCore::Layout::LayoutBoxTraversal::next):
(WebCore::Layout::Traversal::firstWithin):
(WebCore::Layout::Traversal::next):
(WebCore::Layout::LayoutIterator<T>::traverseNext):
* layout/tableformatting/TableGrid.cpp:
(WebCore::Layout::TableGrid::appendCell):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259180 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 7f5a89b..1513a26 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,43 @@
+2020-03-29 Zalan Bujtas <zalan@apple.com>
+
+ [LFC] Layout::Box::parent() should return const ContainerBox&
+ https://bugs.webkit.org/show_bug.cgi?id=209400
+ <rdar://problem/60742432>
+
+ Reviewed by Antti Koivisto.
+
+ Layout tree is immutable during layout, so every box should be able to return a valid parent (except the ICB, but
+ class InitialContainingBlock deletes parent() function anyway).
+
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::FormattingContext::Geometry::staticVerticalPositionForOutOfFlowPositioned const):
+ (WebCore::Layout::FormattingContext::Geometry::staticHorizontalPositionForOutOfFlowPositioned const):
+ * layout/blockformatting/BlockFormattingContextQuirks.cpp:
+ (WebCore::Layout::BlockFormattingContext::Quirks::stretchedInFlowHeight):
+ * layout/blockformatting/BlockMarginCollapse.cpp:
+ (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBeforeCollapsesWithParentMarginAfter const):
+ (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBeforeCollapsesWithParentMarginBefore const):
+ (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginAfterCollapsesWithParentMarginBefore const):
+ (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginAfterCollapsesWithParentMarginAfter const):
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::nextInlineLevelBoxToLayout):
+ (WebCore::Layout::InlineFormattingContext::constraintsForLine):
+ * layout/layouttree/LayoutBox.cpp:
+ (WebCore::Layout::Box::containingBlock const):
+ (WebCore::Layout::Box::formattingContextRoot const):
+ (WebCore::Layout::Box::initialContainingBlock const):
+ (WebCore::Layout::Box::isOverflowVisible const):
+ * layout/layouttree/LayoutBox.h:
+ (WebCore::Layout::Box::parent const):
+ * layout/layouttree/LayoutIterator.h:
+ (WebCore::Layout::LayoutBoxTraversal::nextAncestorSibling):
+ (WebCore::Layout::LayoutBoxTraversal::next):
+ (WebCore::Layout::Traversal::firstWithin):
+ (WebCore::Layout::Traversal::next):
+ (WebCore::Layout::LayoutIterator<T>::traverseNext):
+ * layout/tableformatting/TableGrid.cpp:
+ (WebCore::Layout::TableGrid::appendCell):
+
2020-03-29 David Kilzer <ddkilzer@apple.com>
Windows build fix: Web Inspector: support editing cookie key/values from inspector
diff --git a/Source/WebCore/layout/FormattingContextGeometry.cpp b/Source/WebCore/layout/FormattingContextGeometry.cpp
index 2e1e727..7c10f53 100644
--- a/Source/WebCore/layout/FormattingContextGeometry.cpp
+++ b/Source/WebCore/layout/FormattingContextGeometry.cpp
@@ -232,15 +232,13 @@
// Add sibling offset
auto& previousInFlowBoxGeometry = formattingContext.geometryForBox(*layoutBox.previousInFlowSibling(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
top += previousInFlowBoxGeometry.bottom() + previousInFlowBoxGeometry.nonCollapsedMarginAfter();
- } else {
- ASSERT(layoutBox.parent());
- top = formattingContext.geometryForBox(*layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxTop();
- }
+ } else
+ top = formattingContext.geometryForBox(layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxTop();
// Resolve top all the way up to the containing block.
auto& containingBlock = layoutBox.containingBlock();
// Start with the parent since we pretend that this box is normal flow.
- for (auto* ancestor = layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
+ for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
auto& boxGeometry = formattingContext.geometryForBox(*ancestor, EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
// Display::Box::top is the border box top position in its containing block's coordinate system.
top += boxGeometry.top();
@@ -257,13 +255,12 @@
// Start with this box's border box offset from the parent's border box.
auto& formattingContext = this->formattingContext();
- ASSERT(layoutBox.parent());
- auto left = formattingContext.geometryForBox(*layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxLeft();
+ auto left = formattingContext.geometryForBox(layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxLeft();
// Resolve left all the way up to the containing block.
auto& containingBlock = layoutBox.containingBlock();
// Start with the parent since we pretend that this box is normal flow.
- for (auto* ancestor = layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
+ for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
auto& boxGeometry = formattingContext.geometryForBox(*ancestor, EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
// Display::Box::left is the border box left position in its containing block's coordinate system.
left += boxGeometry.left();
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp
index 2ae382d..ebfbb1fd 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp
@@ -86,7 +86,7 @@
usedVerticalMargin += collapsedMargin.isCollapsedThrough ? nonCollapsedMargin.after : collapsedMargin.after.valueOr(nonCollapsedMargin.after);
bodyBoxContentHeight -= usedVerticalMargin;
// Document box's padding and border also shrink the body box's content height.
- auto& documentBox = *layoutBox.parent();
+ auto& documentBox = layoutBox.parent();
auto& documentBoxGeometry = formattingContext.geometryForBox(documentBox, EscapeReason::BodyStrechesToViewportQuirk);
bodyBoxContentHeight -= documentBoxGeometry.verticalBorder() + documentBoxGeometry.verticalPadding().valueOr(0);
// However the non-in-flow document box's vertical margins are ignored. They don't affect the body box's content height.
diff --git a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp
index b49ea7d..4a70f32 100644
--- a/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp
@@ -97,7 +97,7 @@
// 1. This is the last in-flow child and its margins collapse through and the margin after collapses with parent's margin after or
// 2. This box's margin after collapses with the next sibling's margin before and that sibling collapses through and
// we can get to the last in-flow child like that.
- auto* lastInFlowChild = layoutBox.parent()->lastInFlowChild();
+ auto* lastInFlowChild = layoutBox.parent().lastInFlowChild();
for (auto* currentBox = &layoutBox; currentBox; currentBox = currentBox->nextInFlowSibling()) {
if (!marginsCollapseThrough(*currentBox))
return false;
@@ -132,7 +132,7 @@
if (layoutBox.previousInFlowSibling())
return false;
- auto& parent = *layoutBox.parent();
+ auto& parent = layoutBox.parent();
// Margins of elements that establish new block formatting contexts do not collapse with their in-flow children
if (establishesBlockFormattingContext(parent))
return false;
@@ -234,7 +234,7 @@
// 1. This is the first in-flow child and its margins collapse through and the margin before collapses with parent's margin before or
// 2. This box's margin before collapses with the previous sibling's margin after and that sibling collapses through and
// we can get to the first in-flow child like that.
- auto* firstInFlowChild = layoutBox.parent()->firstInFlowChild();
+ auto* firstInFlowChild = layoutBox.parent().firstInFlowChild();
for (auto* currentBox = &layoutBox; currentBox; currentBox = currentBox->previousInFlowSibling()) {
if (!marginsCollapseThrough(*currentBox))
return false;
@@ -267,7 +267,7 @@
if (layoutBox.nextInFlowSibling())
return false;
- auto& parent = *layoutBox.parent();
+ auto& parent = layoutBox.parent();
// Margins of elements that establish new block formatting contexts do not collapse with their in-flow children.
if (establishesBlockFormattingContext(parent))
return false;
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
index 59761ca..3a3c038 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
@@ -68,7 +68,7 @@
}
}
- for (auto* nextInPreOrder = &layoutBox; nextInPreOrder && nextInPreOrder != &stayWithin; nextInPreOrder = nextInPreOrder->parent()) {
+ for (auto* nextInPreOrder = &layoutBox; nextInPreOrder && nextInPreOrder != &stayWithin; nextInPreOrder = &nextInPreOrder->parent()) {
if (auto* nextSibling = nextInPreOrder->nextInFlowOrFloatingSibling())
return nextSibling;
}
@@ -427,7 +427,7 @@
// For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
isFormattingContextRootCandidateToTextIndent = RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()
? layoutState().isIntegratedRootBoxFirstChild()
- : root.parent()->firstInFlowChild() == &root;
+ : root.parent().firstInFlowChild() == &root;
}
if (!isFormattingContextRootCandidateToTextIndent)
return InlineLayoutUnit { };
diff --git a/Source/WebCore/layout/layouttree/LayoutBox.cpp b/Source/WebCore/layout/layouttree/LayoutBox.cpp
index 55afc8a..53c9aa4 100644
--- a/Source/WebCore/layout/layouttree/LayoutBox.cpp
+++ b/Source/WebCore/layout/layouttree/LayoutBox.cpp
@@ -192,8 +192,8 @@
// If the element has 'position: absolute', the containing block is established by the nearest ancestor with a
// 'position' of 'absolute', 'relative' or 'fixed'.
if (!isPositioned() || isInFlowPositioned()) {
- auto* ancestor = parent();
- for (; !is<InitialContainingBlock>(*ancestor); ancestor = ancestor->parent()) {
+ auto* ancestor = &parent();
+ for (; !is<InitialContainingBlock>(*ancestor); ancestor = &ancestor->parent()) {
if (ancestor->isBlockContainerBox() || ancestor->establishesFormattingContext())
return *ancestor;
}
@@ -201,8 +201,8 @@
}
if (isFixedPositioned()) {
- auto* ancestor = parent();
- for (; !is<InitialContainingBlock>(*ancestor); ancestor = ancestor->parent()) {
+ auto* ancestor = &parent();
+ for (; !is<InitialContainingBlock>(*ancestor); ancestor = &ancestor->parent()) {
if (ancestor->style().hasTransform())
return *ancestor;
}
@@ -210,8 +210,8 @@
}
if (isOutOfFlowPositioned()) {
- auto* ancestor = parent();
- for (; !is<InitialContainingBlock>(*ancestor); ancestor = ancestor->parent()) {
+ auto* ancestor = &parent();
+ for (; !is<InitialContainingBlock>(*ancestor); ancestor = &ancestor->parent()) {
if (ancestor->isPositioned() || ancestor->style().hasTransform())
return *ancestor;
}
@@ -235,7 +235,7 @@
// <div id=outer style="position: absolute"><div id=inner><span style="position: relative">content</span></div></div>
// While the relatively positioned inline container (span) is placed relative to its containing block "outer", it lives in the inline
// formatting context established by "inner".
- auto& ancestor = isInlineLevelBox() && isInFlowPositioned() ? *parent() : containingBlock();
+ auto& ancestor = isInlineLevelBox() && isInFlowPositioned() ? parent() : containingBlock();
if (ancestor.establishesFormattingContext())
return ancestor;
return ancestor.formattingContextRoot();
@@ -246,9 +246,8 @@
if (is<InitialContainingBlock>(*this))
return downcast<InitialContainingBlock>(*this);
- auto* ancestor = parent();
- for (; ancestor->parent(); ancestor = ancestor->parent()) { }
-
+ auto* ancestor = &parent();
+ for (; !is<InitialContainingBlock>(*ancestor); ancestor = &ancestor->parent()) { }
return downcast<InitialContainingBlock>(*ancestor);
}
@@ -353,11 +352,10 @@
// if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'.
// The element from which the value is propagated must have a used value for 'overflow' of 'visible'.
if (isBodyBox()) {
- auto* documentBox = parent();
- ASSERT(documentBox);
- if (!documentBox->isDocumentBox())
+ auto& documentBox = parent();
+ if (!documentBox.isDocumentBox())
return isOverflowVisible;
- if (!documentBox->isOverflowVisible())
+ if (!documentBox.isOverflowVisible())
return isOverflowVisible;
return true;
}
diff --git a/Source/WebCore/layout/layouttree/LayoutBox.h b/Source/WebCore/layout/layouttree/LayoutBox.h
index 86d1b8a..0bd4221 100644
--- a/Source/WebCore/layout/layouttree/LayoutBox.h
+++ b/Source/WebCore/layout/layouttree/LayoutBox.h
@@ -127,7 +127,7 @@
bool isIFrame() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::IFrame; }
bool isImage() const { return m_elementAttributes && m_elementAttributes.value().elementType == ElementType::Image; }
- const ContainerBox* parent() const { return m_parent; }
+ const ContainerBox& parent() const { return *m_parent; }
const Box* nextSibling() const { return m_nextSibling; }
const Box* nextInFlowSibling() const;
const Box* nextInFlowOrFloatingSibling() const;
diff --git a/Source/WebCore/layout/layouttree/LayoutInitialContainingBlock.h b/Source/WebCore/layout/layouttree/LayoutInitialContainingBlock.h
index a99ec95..902edaa 100644
--- a/Source/WebCore/layout/layouttree/LayoutInitialContainingBlock.h
+++ b/Source/WebCore/layout/layouttree/LayoutInitialContainingBlock.h
@@ -40,7 +40,7 @@
virtual ~InitialContainingBlock() = default;
private:
- const ContainerBox* parent() const = delete;
+ const ContainerBox& parent() const = delete;
const Box* nextSibling() const = delete;
const Box* nextInFlowSibling() const = delete;
const Box* nextInFlowOrFloatingSibling() const = delete;
diff --git a/Source/WebCore/layout/layouttree/LayoutIterator.h b/Source/WebCore/layout/layouttree/LayoutIterator.h
index cb0fcf4..8d85935 100644
--- a/Source/WebCore/layout/layouttree/LayoutIterator.h
+++ b/Source/WebCore/layout/layouttree/LayoutIterator.h
@@ -69,10 +69,10 @@
return nullptr;
}
-inline const Box* nextAncestorSibling(const Box& current, const ContainerBox* stayWithin)
+inline const Box* nextAncestorSibling(const Box& current, const ContainerBox& stayWithin)
{
- for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
- if (ancestor == stayWithin)
+ for (auto* ancestor = ¤t.parent(); !is<InitialContainingBlock>(*ancestor); ancestor = &ancestor->parent()) {
+ if (ancestor == &stayWithin)
return nullptr;
if (auto* sibling = ancestor->nextSibling())
return sibling;
@@ -81,12 +81,12 @@
}
template <typename U>
-inline const Box* next(const U& current, const ContainerBox* stayWithin)
+inline const Box* next(const U& current, const ContainerBox& stayWithin)
{
if (auto* child = firstChild(current))
return child;
- if (¤t == stayWithin)
+ if (¤t == &stayWithin)
return nullptr;
if (auto* sibling = current.nextSibling())
@@ -122,12 +122,12 @@
{
auto* descendant = LayoutBoxTraversal::firstChild(stayWithin);
while (descendant && !isLayoutBoxOfType<T>(*descendant))
- descendant = LayoutBoxTraversal::next(*descendant, &stayWithin);
+ descendant = LayoutBoxTraversal::next(*descendant, stayWithin);
return static_cast<const T*>(descendant);
}
template <typename T, typename U>
-inline const T* next(const U& current, const ContainerBox* stayWithin)
+inline const T* next(const U& current, const ContainerBox& stayWithin)
{
auto* descendant = LayoutBoxTraversal::next(current, stayWithin);
while (descendant && !isLayoutBoxOfType<T>(*descendant))
@@ -165,7 +165,7 @@
inline LayoutIterator<T>& LayoutIterator<T>::traverseNext()
{
ASSERT(m_current);
- m_current = Traversal::next<T>(*m_current, m_root);
+ m_current = Traversal::next<T>(*m_current, *m_root);
return *this;
}
diff --git a/Source/WebCore/layout/tableformatting/TableGrid.cpp b/Source/WebCore/layout/tableformatting/TableGrid.cpp
index d3f59ef..8018879 100644
--- a/Source/WebCore/layout/tableformatting/TableGrid.cpp
+++ b/Source/WebCore/layout/tableformatting/TableGrid.cpp
@@ -157,7 +157,7 @@
m_columnsContext.addColumn();
if (isInNewRow)
- m_rows.append({ *tableCellBox.parent() });
+ m_rows.append({ tableCellBox.parent() });
m_cellList.add(WTFMove(cellInfo));
}