Index: third_party/WebKit/Source/core/layout/LayoutDeprecatedFlexibleBox.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutDeprecatedFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutDeprecatedFlexibleBox.cpp |
index ed3942e2c946921f27add396f22f623c55659e18..a525e0c9622fd8574d38b8b00395e7570efaaddf 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutDeprecatedFlexibleBox.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutDeprecatedFlexibleBox.cpp |
@@ -121,6 +121,120 @@ private: |
int m_ordinalIteration; |
}; |
+// Helper methods for obtaining the last line, computing line counts and heights for line counts |
+// (crawling into blocks). |
+static bool shouldCheckLines(LayoutBlockFlow* blockFlow) |
+{ |
+ return !blockFlow->isFloatingOrOutOfFlowPositioned() && blockFlow->style()->height().isAuto(); |
+} |
+ |
+static int getHeightForLineCount(const LayoutBlockFlow* blockFlow, int lineCount, bool includeBottom, int& count) |
+{ |
+ if (blockFlow->style()->visibility() != VISIBLE) |
+ return -1; |
+ if (blockFlow->childrenInline()) { |
+ for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nextRootBox()) { |
+ if (++count == lineCount) |
+ return box->lineBottom() + (includeBottom ? (blockFlow->borderBottom() + blockFlow->paddingBottom()) : LayoutUnit()); |
+ } |
+ return -1; |
+ } |
+ |
+ LayoutBox* normalFlowChildWithoutLines = nullptr; |
+ for (LayoutBox* obj = blockFlow->firstChildBox(); obj; obj = obj->nextSiblingBox()) { |
+ if (obj->isLayoutBlockFlow() && shouldCheckLines(toLayoutBlockFlow(obj))) { |
+ int result = getHeightForLineCount(toLayoutBlockFlow(obj), lineCount, false, count); |
+ if (result != -1) |
+ return result + obj->location().y() + (includeBottom ? (blockFlow->borderBottom() + blockFlow->paddingBottom()) : LayoutUnit()); |
+ } else if (!obj->isFloatingOrOutOfFlowPositioned()) { |
+ normalFlowChildWithoutLines = obj; |
+ } |
+ } |
+ if (normalFlowChildWithoutLines && lineCount == 0) |
+ return normalFlowChildWithoutLines->location().y() + normalFlowChildWithoutLines->size().height(); |
+ |
+ return -1; |
+} |
+ |
+static RootInlineBox* lineAtIndex(const LayoutBlockFlow* blockFlow, int i) |
+{ |
+ ASSERT(i >= 0); |
+ |
+ if (blockFlow->style()->visibility() != VISIBLE) |
+ return nullptr; |
+ |
+ if (blockFlow->childrenInline()) { |
+ for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nextRootBox()) { |
+ if (!i--) |
+ return box; |
+ } |
+ return nullptr; |
+ } |
+ for (LayoutObject* child = blockFlow->firstChild(); child; child = child->nextSibling()) { |
+ if (!child->isLayoutBlockFlow()) |
+ continue; |
+ LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(child); |
+ if (!shouldCheckLines(childBlockFlow)) |
+ continue; |
+ if (RootInlineBox* box = lineAtIndex(childBlockFlow, i)) |
+ return box; |
+ } |
+ |
+ return nullptr; |
+} |
+ |
+static int lineCount(const LayoutBlockFlow* blockFlow, const RootInlineBox* stopRootInlineBox = nullptr, bool* found = nullptr) |
+{ |
+ if (blockFlow->style()->visibility() != VISIBLE) |
+ return 0; |
+ int count = 0; |
+ if (blockFlow->childrenInline()) { |
+ for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nextRootBox()) { |
+ count++; |
+ if (box == stopRootInlineBox) { |
+ if (found) |
+ *found = true; |
+ break; |
+ } |
+ } |
+ return count; |
+ } |
+ for (LayoutObject* obj = blockFlow->firstChild(); obj; obj = obj->nextSibling()) { |
+ if (!obj->isLayoutBlockFlow()) |
+ continue; |
+ LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(obj); |
+ if (!shouldCheckLines(childBlockFlow)) |
+ continue; |
+ bool recursiveFound = false; |
+ count += lineCount(childBlockFlow, stopRootInlineBox, &recursiveFound); |
+ if (recursiveFound) { |
+ if (found) |
+ *found = true; |
+ break; |
+ } |
+ } |
+ return count; |
+} |
+ |
+static void clearTruncation(LayoutBlockFlow* blockFlow) |
+{ |
+ if (blockFlow->style()->visibility() != VISIBLE) |
+ return; |
+ if (blockFlow->childrenInline() && blockFlow->hasMarkupTruncation()) { |
+ blockFlow->setHasMarkupTruncation(false); |
+ for (RootInlineBox* box = blockFlow->firstRootBox(); box; box = box->nextRootBox()) |
+ box->clearTruncation(); |
+ return; |
+ } |
+ for (LayoutObject* obj = blockFlow->firstChild(); obj; obj = obj->nextSibling()) { |
+ if (!obj->isLayoutBlockFlow()) |
+ continue; |
+ LayoutBlockFlow* childBlockFlow = toLayoutBlockFlow(obj); |
+ if (shouldCheckLines(childBlockFlow)) |
+ clearTruncation(childBlockFlow); |
+ } |
+} |
+ |
LayoutDeprecatedFlexibleBox::LayoutDeprecatedFlexibleBox(Element& element) |
: LayoutBlock(&element) |
{ |
@@ -852,14 +966,14 @@ void LayoutDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool |
child->setChildNeedsLayout(MarkOnlyThis); |
// Dirty all the positioned objects. |
- if (child->isLayoutBlock()) { |
- toLayoutBlock(child)->markPositionedObjectsForLayout(); |
- toLayoutBlock(child)->clearTruncation(); |
+ if (child->isLayoutBlockFlow()) { |
+ toLayoutBlockFlow(child)->markPositionedObjectsForLayout(); |
+ clearTruncation(toLayoutBlockFlow(child)); |
} |
} |
child->layoutIfNeeded(); |
- if (child->style()->height().isAuto() && child->isLayoutBlock()) |
- maxLineCount = std::max(maxLineCount, toLayoutBlock(child)->lineCount()); |
+ if (child->style()->height().isAuto() && child->isLayoutBlockFlow()) |
+ maxLineCount = std::max(maxLineCount, lineCount(toLayoutBlockFlow(child))); |
} |
// Get the number of lines and then alter all block flow children with auto height to use the |
@@ -870,15 +984,16 @@ void LayoutDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool |
return; |
for (LayoutBox* child = iterator.first(); child; child = iterator.next()) { |
- if (childDoesNotAffectWidthOrFlexing(child) || !child->style()->height().isAuto() || !child->isLayoutBlock()) |
+ if (childDoesNotAffectWidthOrFlexing(child) || !child->style()->height().isAuto() || !child->isLayoutBlockFlow()) |
continue; |
- LayoutBlock* blockChild = toLayoutBlock(child); |
- int lineCount = blockChild->lineCount(); |
+ LayoutBlockFlow* blockChild = toLayoutBlockFlow(child); |
+ int lineCount = blink::lineCount(blockChild); |
if (lineCount <= numVisibleLines) |
continue; |
- LayoutUnit newHeight(blockChild->heightForLineCount(numVisibleLines)); |
+ int dummyCount = 0; |
+ LayoutUnit newHeight(getHeightForLineCount(blockChild, numVisibleLines, true, dummyCount)); |
if (newHeight == child->size().height()) |
continue; |
@@ -890,11 +1005,11 @@ void LayoutDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool |
continue; |
// Get the last line |
- RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount - 1); |
+ RootInlineBox* lastLine = lineAtIndex(blockChild, lineCount - 1); |
if (!lastLine) |
continue; |
- RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines - 1); |
+ RootInlineBox* lastVisibleLine = lineAtIndex(blockChild, numVisibleLines - 1); |
if (!lastVisibleLine) |
continue; |
@@ -938,9 +1053,9 @@ void LayoutDeprecatedFlexibleBox::clearLineClamp() |
|| (child->style()->height().isAuto() && child->isLayoutBlock())) { |
child->setChildNeedsLayout(); |
- if (child->isLayoutBlock()) { |
- toLayoutBlock(child)->markPositionedObjectsForLayout(); |
- toLayoutBlock(child)->clearTruncation(); |
+ if (child->isLayoutBlockFlow()) { |
+ toLayoutBlockFlow(child)->markPositionedObjectsForLayout(); |
+ clearTruncation(toLayoutBlockFlow(child)); |
} |
} |
} |