Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 1933153002: Move self-collapse checking to LayoutBlockFlow and cache it completely. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: The winbots had a point. How do you like this, then, winbots? bool bitfields would probably look ev… Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 9e94f5d16f9e14357329886f428f2c56655cadc3..078c1b08de5eb473135d85436c0c0f17c311ee5e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -297,8 +297,74 @@ void LayoutBlockFlow::clearShouldBreakAtLineToAvoidWidow() const
bool LayoutBlockFlow::isSelfCollapsingBlock() const
{
- m_hasOnlySelfCollapsingChildren = LayoutBlock::isSelfCollapsingBlock();
- return m_hasOnlySelfCollapsingChildren;
+ if (needsLayout()) {
+ // Sometimes we don't lay out objects in DOM order (column spanners being one such relevant
+ // type of object right here). As long as the object in question establishes a new
+ // formatting context, that's nothing to worry about, though.
+ ASSERT(createsNewFormattingContext());
+ return false;
+ }
+ ASSERT(!m_isSelfCollapsing == !checkIfIsSelfCollapsingBlock());
+ return m_isSelfCollapsing;
+}
+
+bool LayoutBlockFlow::checkIfIsSelfCollapsingBlock() const
+{
+ // We are not self-collapsing if we
+ // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
+ // (b) have border/padding,
+ // (c) have a min-height
+ // (d) have specified that one of our margins can't collapse using a CSS extension
+ // (e) establish a new block formatting context.
+
+ // The early exit must be done before we check for clean layout.
+ // We should be able to give a quick answer if the box is a relayout boundary.
+ // Being a relayout boundary implies a block formatting context, and also
+ // our internal layout shouldn't affect our container in any way.
+ if (createsNewFormattingContext())
+ return false;
+
+ // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they
+ // don't get layout until their parent has had layout - this is unique in the layout tree and means
+ // when we call isSelfCollapsingBlock on them we find that they still need layout.
+ ASSERT(!needsLayout() || (node() && node()->isElementNode() && toElement(node())->shadowPseudoId() == "-webkit-input-placeholder"));
+
+ if (logicalHeight() > LayoutUnit()
+ || borderAndPaddingLogicalHeight()
+ || style()->logicalMinHeight().isPositive()
+ || style()->marginBeforeCollapse() == MarginCollapseSeparate || style()->marginAfterCollapse() == MarginCollapseSeparate)
+ return false;
+
+ Length logicalHeightLength = style()->logicalHeight();
+ bool hasAutoHeight = logicalHeightLength.isAuto();
+ if (logicalHeightLength.hasPercent() && !document().inQuirksMode()) {
+ hasAutoHeight = true;
+ for (LayoutBlock* cb = containingBlock(); !cb->isLayoutView(); cb = cb->containingBlock()) {
+ if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
+ hasAutoHeight = false;
+ }
+ }
+
+ // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
+ // on whether we have content that is all self-collapsing or not.
+ // TODO(alancutter): Make this work correctly for calc lengths.
+ if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.hasPercent()) && logicalHeightLength.isZero())) {
+ // If the block has inline children, see if we generated any line boxes. If we have any
+ // line boxes, then we can't be self-collapsing, since we have content.
+ if (childrenInline())
+ return !firstLineBox();
+
+ // Whether or not we collapse is dependent on whether all our normal flow children
+ // are also self-collapsing.
+ for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ if (child->isFloatingOrOutOfFlowPositioned())
+ continue;
+ if (!child->isSelfCollapsingBlock())
+ return false;
+ }
+ return true;
+ }
+ return false;
}
void LayoutBlockFlow::layoutBlock(bool relayoutChildren)
@@ -306,11 +372,6 @@ void LayoutBlockFlow::layoutBlock(bool relayoutChildren)
ASSERT(needsLayout());
ASSERT(isInlineBlockOrInlineTable() || !isInline());
- // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our
- // descendants every time in |isSelfCollapsingBlock|. We reset it here so that |isSelfCollapsingBlock| attempts to burrow
- // at least once and so that it always gives a reliable result reflecting the latest layout.
- m_hasOnlySelfCollapsingChildren = false;
-
if (!relayoutChildren && simplifiedLayout())
return;
@@ -347,6 +408,7 @@ void LayoutBlockFlow::layoutBlock(bool relayoutChildren)
positionDialog();
clearNeedsLayout();
+ m_isSelfCollapsing = checkIfIsSelfCollapsingBlock();
}
inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &pageLogicalHeight, SubtreeLayoutScope& layoutScope)
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698