| 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));
|
| }
|
| }
|
| }
|
|
|