diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-12 09:27:39 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-12 09:27:39 +0200 |
commit | 3749d61e1f7a59f5ec5067e560af1eb610c82015 (patch) | |
tree | 73dc228333948738bbe02976cacca8cd382bc978 /Source/WebCore/rendering/RenderFlexibleBox.cpp | |
parent | b32b4dcd9a51ab8de6afc53d9e17f8707e1f7a5e (diff) | |
download | qtwebkit-3749d61e1f7a59f5ec5067e560af1eb610c82015.tar.gz |
Imported WebKit commit a77350243e054f3460d1137301d8b3faee3d2052 (http://svn.webkit.org/repository/webkit/trunk@125365)
New snapshot with build fixes for latest API changes in Qt and all WK1 Win MSVC fixes upstream
Diffstat (limited to 'Source/WebCore/rendering/RenderFlexibleBox.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderFlexibleBox.cpp | 108 |
1 files changed, 60 insertions, 48 deletions
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp index 3b1d4737c..5de6425f2 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp @@ -39,6 +39,16 @@ namespace WebCore { +// Normally, -1 and 0 are not valid in a HashSet, but these are relatively likely order: values. Instead, +// we make the two smallest int values invalid order: values (in the css parser code we clamp them to +// int min + 2). +struct RenderFlexibleBox::OrderHashTraits : WTF::GenericHashTraits<int> { + static const bool emptyValueIsZero = false; + static int emptyValue() { return std::numeric_limits<int>::min(); } + static void constructDeletedValue(int& slot) { slot = std::numeric_limits<int>::min() + 1; } + static bool isDeletedValue(int value) { return value == std::numeric_limits<int>::min() + 1; } +}; + class RenderFlexibleBox::OrderIterator { public: OrderIterator(RenderFlexibleBox* flexibleBox, const OrderHashSet& orderValues) @@ -89,8 +99,8 @@ public: private: RenderFlexibleBox* m_flexibleBox; RenderBox* m_currentChild; - Vector<float> m_orderValues; - Vector<float>::const_iterator m_orderValuesIterator; + Vector<int> m_orderValues; + Vector<int>::const_iterator m_orderValuesIterator; }; struct RenderFlexibleBox::LineContext { @@ -194,10 +204,10 @@ void RenderFlexibleBox::computePreferredLogicalWidths() LayoutUnit scrollbarWidth = 0; if (hasOverflowClip()) { if (isHorizontalWritingMode() && styleToUse->overflowY() == OSCROLL) { - layer()->setHasVerticalScrollbar(true); + ASSERT(layer()->hasVerticalScrollbar()); scrollbarWidth = verticalScrollbarWidth(); } else if (!isHorizontalWritingMode() && styleToUse->overflowX() == OSCROLL) { - layer()->setHasHorizontalScrollbar(true); + ASSERT(layer()->hasHorizontalScrollbar()); scrollbarWidth = horizontalScrollbarHeight(); } } @@ -248,14 +258,6 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) m_overflow.clear(); - // For overflow:scroll blocks, ensure we have both scrollbars in place always. - if (scrollsOverflow()) { - if (style()->overflowX() == OSCROLL) - layer()->setHasHorizontalScrollbar(true); - if (style()->overflowY() == OSCROLL) - layer()->setHasVerticalScrollbar(true); - } - WTF::Vector<LineContext> lineContexts; OrderHashSet orderValues; computeMainAxisPreferredSizes(relayoutChildren, orderValues); @@ -358,11 +360,6 @@ Length RenderFlexibleBox::flexBasisForChild(RenderBox* child) const return flexLength; } -Length RenderFlexibleBox::crossAxisLength() const -{ - return isHorizontalFlow() ? style()->height() : style()->width(); -} - void RenderFlexibleBox::setCrossAxisExtent(LayoutUnit extent) { if (isHorizontalFlow()) @@ -399,10 +396,19 @@ LayoutUnit RenderFlexibleBox::crossAxisContentExtent() const LayoutUnit RenderFlexibleBox::mainAxisContentExtent() { if (isColumnFlow()) - return std::max(LayoutUnit(0), computeContentLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight())); + return std::max(LayoutUnit(0), computeLogicalClientHeight(MainOrPreferredSize, style()->logicalHeight())); return contentLogicalWidth(); } +LayoutUnit RenderFlexibleBox::computeMainAxisExtentForChild(RenderBox* child, SizeType sizeType, const Length& size, LayoutUnit maximumValue) +{ + // FIXME: This is wrong for orthogonal flows. It should use the flexbox's writing-mode, not the child's in order + // to figure out the logical height/width. + if (isColumnFlow()) + return child->computeLogicalClientHeight(sizeType, size); + return child->computeContentBoxLogicalWidth(valueForLength(size, maximumValue, view())); +} + WritingMode RenderFlexibleBox::transformedWritingMode() const { WritingMode mode = style()->writingMode(); @@ -599,7 +605,7 @@ LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* LayoutUnit mainAxisExtent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->maxPreferredLogicalWidth(); return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child); } - return std::max(LayoutUnit(0), minimumValueForLength(flexBasis, mainAxisContentExtent(), view())); + return std::max(LayoutUnit(0), computeMainAxisExtentForChild(child, MainOrPreferredSize, flexBasis, mainAxisContentExtent())); } LayoutUnit RenderFlexibleBox::computeAvailableFreeSpace(LayoutUnit preferredMainAxisExtent) @@ -610,11 +616,11 @@ LayoutUnit RenderFlexibleBox::computeAvailableFreeSpace(LayoutUnit preferredMain else if (hasOverrideHeight()) contentExtent = overrideLogicalContentHeight(); else { - LayoutUnit heightResult = computeContentLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight()); + LayoutUnit heightResult = computeLogicalClientHeight(MainOrPreferredSize, style()->logicalHeight()); if (heightResult == -1) heightResult = preferredMainAxisExtent; - LayoutUnit minHeight = computeContentLogicalHeightUsing(MinSize, style()->logicalMinHeight()); // Leave as -1 if unset. - LayoutUnit maxHeight = style()->logicalMaxHeight().isUndefined() ? heightResult : computeContentLogicalHeightUsing(MaxSize, style()->logicalMaxHeight()); + LayoutUnit minHeight = computeLogicalClientHeight(MinSize, style()->logicalMinHeight()); // Leave as -1 if unset. + LayoutUnit maxHeight = style()->logicalMaxHeight().isUndefined() ? heightResult : computeLogicalClientHeight(MaxSize, style()->logicalMaxHeight()); if (maxHeight == -1) maxHeight = heightResult; heightResult = std::min(maxHeight, heightResult); @@ -751,6 +757,14 @@ LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox* child) return ascent + flowAwareMarginBeforeForChild(child); } +LayoutUnit RenderFlexibleBox::computeMarginValue(Length margin, LayoutUnit availableSize, RenderView* view) +{ + // CSS always computes percent margins with respect to the containing block's width, even for margin-top/margin-bottom. + if (margin.isPercent()) + availableSize = logicalWidth(); + return minimumValueForLength(margin, availableSize, view); +} + void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet& orderValues) { LayoutUnit flexboxAvailableContentExtent = mainAxisContentExtent(); @@ -766,18 +780,18 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Ord Length childMainAxisMin = isHorizontalFlow() ? child->style()->minWidth() : child->style()->minHeight(); if (hasOrthogonalFlow(child) && (flexBasisForChild(child).isAuto() || childMainAxisMin.isAuto())) { if (!relayoutChildren) - child->setChildNeedsLayout(true); + child->setChildNeedsLayout(true, MarkOnlyThis); child->layoutIfNeeded(); } // Before running the flex algorithm, 'auto' has a margin of 0. // Also, if we're not auto sizing, we don't do a layout that computes the start/end margins. if (isHorizontalFlow()) { - child->setMarginLeft(minimumValueForLength(child->style()->marginLeft(), flexboxAvailableContentExtent, renderView)); - child->setMarginRight(minimumValueForLength(child->style()->marginRight(), flexboxAvailableContentExtent, renderView)); + child->setMarginLeft(computeMarginValue(child->style()->marginLeft(), flexboxAvailableContentExtent, renderView)); + child->setMarginRight(computeMarginValue(child->style()->marginRight(), flexboxAvailableContentExtent, renderView)); } else { - child->setMarginTop(minimumValueForLength(child->style()->marginTop(), flexboxAvailableContentExtent, renderView)); - child->setMarginBottom(minimumValueForLength(child->style()->marginBottom(), flexboxAvailableContentExtent, renderView)); + child->setMarginTop(computeMarginValue(child->style()->marginTop(), flexboxAvailableContentExtent, renderView)); + child->setMarginBottom(computeMarginValue(child->style()->marginBottom(), flexboxAvailableContentExtent, renderView)); } } } @@ -787,10 +801,10 @@ LayoutUnit RenderFlexibleBox::lineBreakLength() if (!isColumnFlow()) return mainAxisContentExtent(); - LayoutUnit height = computeContentLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight()); + LayoutUnit height = computeLogicalClientHeight(MainOrPreferredSize, style()->logicalHeight()); if (height == -1) height = MAX_LAYOUT_UNIT; - LayoutUnit maxHeight = computeContentLogicalHeightUsing(MaxSize, style()->logicalMaxHeight()); + LayoutUnit maxHeight = computeLogicalClientHeight(MaxSize, style()->logicalMaxHeight()); if (maxHeight != -1) height = std::min(height, maxHeight); return height; @@ -798,25 +812,23 @@ LayoutUnit RenderFlexibleBox::lineBreakLength() LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox* child, LayoutUnit childSize, LayoutUnit flexboxAvailableContentExtent) { + // FIXME: Support intrinsic min/max lengths. Length max = isHorizontalFlow() ? child->style()->maxWidth() : child->style()->maxHeight(); - Length min = isHorizontalFlow() ? child->style()->minWidth() : child->style()->minHeight(); - RenderView* renderView = view(); - // FIXME: valueForLength isn't quite right in quirks mode: percentage heights should check parents until a value is found. - // https://bugs.webkit.org/show_bug.cgi?id=81809 - if (max.isSpecified() && childSize > valueForLength(max, flexboxAvailableContentExtent, renderView)) - childSize = valueForLength(max, flexboxAvailableContentExtent, renderView); - - if (min.isSpecified() && childSize < valueForLength(min, flexboxAvailableContentExtent, renderView)) - return valueForLength(min, flexboxAvailableContentExtent, renderView); - - // FIXME: Support min/max sizes of fit-content, max-content and fill-available. - if (min.isAuto()) { - LayoutUnit minContent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->minPreferredLogicalWidth(); - minContent -= mainAxisBorderAndPaddingExtentForChild(child); - return std::max(childSize, minContent); + if (max.isSpecified()) { + LayoutUnit maxExtent = computeMainAxisExtentForChild(child, MaxSize, max, flexboxAvailableContentExtent); + if (maxExtent != -1 && childSize > maxExtent) + childSize = maxExtent; } - return childSize; + Length min = isHorizontalFlow() ? child->style()->minWidth() : child->style()->minHeight(); + LayoutUnit minExtent = 0; + if (min.isSpecified()) + minExtent = computeMainAxisExtentForChild(child, MinSize, min, flexboxAvailableContentExtent); + else if (min.isAuto()) { + minExtent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->minPreferredLogicalWidth(); + minExtent -= mainAxisBorderAndPaddingExtentForChild(child); + } + return std::max(childSize, minExtent); } bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent) @@ -1007,7 +1019,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(child); setLogicalOverrideSize(child, childPreferredSize); // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905. - child->setChildNeedsLayout(true); + child->setChildNeedsLayout(true, MarkOnlyThis); child->layoutIfNeeded(); updateAutoMarginsInMainAxis(child, autoMarginOffset); @@ -1231,14 +1243,14 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni if (child->logicalHeight() != logicalHeightBefore) { child->setOverrideLogicalContentHeight(child->logicalHeight() - child->borderAndPaddingLogicalHeight()); child->setLogicalHeight(0); - child->setChildNeedsLayout(true); + child->setChildNeedsLayout(true, MarkOnlyThis); child->layoutIfNeeded(); } } else if (isColumnFlow() && child->style()->logicalWidth().isAuto() && isMultiline()) { // FIXME: Handle min-width and max-width. LayoutUnit childWidth = lineCrossAxisExtent - crossAxisMarginExtentForChild(child); child->setOverrideLogicalContentWidth(std::max(ZERO_LAYOUT_UNIT, childWidth)); - child->setChildNeedsLayout(true); + child->setChildNeedsLayout(true, MarkOnlyThis); child->layoutIfNeeded(); } } |