Modified: trunk/Source/WebCore/ChangeLog (150086 => 150087)
--- trunk/Source/WebCore/ChangeLog 2013-05-14 20:37:09 UTC (rev 150086)
+++ trunk/Source/WebCore/ChangeLog 2013-05-14 20:37:13 UTC (rev 150087)
@@ -1,3 +1,62 @@
+2013-05-14 David Hyatt <hy...@apple.com>
+
+ REGRESSION: united.com has overlapping elements and is broken by flex box changes.
+ https://bugs.webkit.org/show_bug.cgi?id=115329
+ <rdar://problem/13690610>
+
+ The new flexbox spec says that flex-basis omitted in the flex shorthand defaults to
+ 0 when flex-grow/shrink are set. This has undesirable behavior when objects don't
+ end up flexing at all, and it's something the spec is going to eventually address.
+
+ For now, though, to fix the regression, I'm making a targeted "hack" to deliberately
+ violate the spec, but to do so as minimally as possible. This hack detects if there
+ is infinite available space on a line, and if so, it treats a flex-basis of 0 like
+ auto.
+
+ This means that when height is constrained and set by a container, flexing will do
+ the right thing. Basically any time you end up actually flexing, the spec behavior
+ should happen. If you're just laying out at intrinsic sizes, though, and no flexing
+ is going to occur, we ignore a flex-basis of 0 and just use the child's normal size.
+
+ Note that widths don't have to be patched because the preferred logical widths
+ algorithm is broken right now and not checking flex-basis. If it did, we'd have seen
+ the same bug in the width direction.
+
+ This width issue is covered by https://bugs.webkit.org/show_bug.cgi?id=116117
+
+ Reviewed by Simon Fraser.
+
+ Added fast/flexbox/auto-height-with-flex.html
+
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::mainAxisContentExtent):
+ Make sure we return LayoutUnit::max when you have infinite free space and not
+ max - borderPadding.
+
+ (WebCore::RenderFlexibleBox::preferredMainAxisContentExtentForChild):
+ Only clear override size if it was set. Only mark for relayout if we did
+ an override size clear (i.e., if we were actually flexed). Add a new parameter,
+ hasInfiniteLineLength, that - if set - causes us to special case flex-basis:0
+ and treat it like flex-basis:auto.
+
+ (WebCore::RenderFlexibleBox::layoutFlexItems):
+ Define hasInfiniteLineLength and pass it to all the functions that need it.
+
+ (WebCore::RenderFlexibleBox::computeMainAxisPreferredSizes):
+ Remove the code that marks for layout and does a layout so early. This code
+ is moving (and changing) to preferredMainAxisContentExtentForChild.
+
+ (WebCore::RenderFlexibleBox::computeNextFlexLine):
+ Computes whether or not we have infinite line length now.
+
+ (WebCore::RenderFlexibleBox::freezeViolations):
+ (WebCore::RenderFlexibleBox::resolveFlexibleLengths):
+ Propagate hasInfiniteLineLength through to preferredMainAxisContentExtentForChild.
+
+ * rendering/RenderFlexibleBox.h:
+ (RenderFlexibleBox):
+ Add hasInfiniteLineLength parameter to a bunch of functions.
+
2013-05-14 Andreas Kling <akl...@apple.com>
Assertion failure in GlyphPage::setGlyphDataForIndex: (!glyph || fontData == m_fontDataForAllGlyphs)
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (150086 => 150087)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2013-05-14 20:37:09 UTC (rev 150086)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2013-05-14 20:37:13 UTC (rev 150087)
@@ -164,6 +164,9 @@
void RenderFlexibleBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
+ // FIXME: We're ignoring flex-basis here and we shouldn't. We can't start honoring it though until
+ // the flex shorthand stops setting it to 0.
+ // See https://bugs.webkit.org/show_bug.cgi?id=116117,
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
if (child->isOutOfFlowPositioned())
continue;
@@ -525,6 +528,8 @@
// FIXME: Remove this std:max once we enable saturated layout arithmetic. It's just here to handle overflow.
LayoutUnit borderBoxLogicalHeight = std::max(contentLogicalHeight, contentLogicalHeight + borderPaddingAndScrollbar);
computeLogicalHeight(borderBoxLogicalHeight, logicalTop(), computedValues);
+ if (computedValues.m_extent == LayoutUnit::max())
+ return computedValues.m_extent;
return std::max(LayoutUnit(0), computedValues.m_extent - borderPaddingAndScrollbar);
}
return contentLogicalWidth();
@@ -734,10 +739,19 @@
return isHorizontalFlow() ? child->verticalScrollbarWidth() : child->horizontalScrollbarHeight();
}
-LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* child)
+LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength)
{
+ bool hasOverrideSize = child->hasOverrideWidth() || child->hasOverrideHeight();
+ if (hasOverrideSize)
+ child->clearOverrideSize();
+
Length flexBasis = flexBasisForChild(child);
- if (flexBasis.isAuto()) {
+ if (flexBasis.isAuto() || (flexBasis.isFixed() && !flexBasis.value() && hasInfiniteLineLength)) {
+ if (hasOrthogonalFlow(child)) {
+ if (hasOverrideSize)
+ child->setChildNeedsLayout(true, MarkOnlyThis);
+ child->layoutIfNeeded();
+ }
LayoutUnit mainAxisExtent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->maxPreferredLogicalWidth();
ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >= 0);
return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child);
@@ -755,12 +769,13 @@
m_orderIterator.first();
LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
- while (computeNextFlexLine(orderedChildren, preferredMainAxisExtent, totalFlexGrow, totalWeightedFlexShrink, minMaxAppliedMainAxisExtent)) {
+ bool hasInfiniteLineLength = false;
+ while (computeNextFlexLine(orderedChildren, preferredMainAxisExtent, totalFlexGrow, totalWeightedFlexShrink, minMaxAppliedMainAxisExtent, hasInfiniteLineLength)) {
LayoutUnit availableFreeSpace = mainAxisContentExtent(preferredMainAxisExtent) - preferredMainAxisExtent;
FlexSign flexSign = (minMaxAppliedMainAxisExtent < preferredMainAxisExtent + availableFreeSpace) ? PositiveFlexibility : NegativeFlexibility;
InflexibleFlexItemSize inflexibleItems;
Vector<LayoutUnit> childSizes;
- while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
+ while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes, hasInfiniteLineLength)) {
ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
ASSERT(inflexibleItems.size() > 0);
}
@@ -904,14 +919,6 @@
if (child->isOutOfFlowPositioned())
continue;
- child->clearOverrideSize();
-
- // Only need to layout here if we will need to get the logicalHeight of the child in computeNextFlexLine.
- if (hasOrthogonalFlow(child) && flexBasisForChild(child).isAuto()) {
- child->setChildNeedsLayout(true, MarkOnlyThis);
- child->layout();
- }
-
// 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()) {
@@ -940,7 +947,7 @@
return std::max(childSize, minExtent);
}
-bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent)
+bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent, bool& hasInfiniteLineLength)
{
orderedChildren.clear();
preferredMainAxisExtent = 0;
@@ -951,6 +958,8 @@
return false;
LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max());
+ hasInfiniteLineLength = lineBreakLength == LayoutUnit::max();
+
bool lineHasInFlowItem = false;
for (RenderBox* child = m_orderIterator.currentChild(); child; child = m_orderIterator.next()) {
@@ -959,7 +968,7 @@
continue;
}
- LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild(child);
+ LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild(child, hasInfiniteLineLength);
LayoutUnit childMainAxisMarginBoxExtent = mainAxisBorderAndPaddingExtentForChild(child) + childMainAxisExtent;
childMainAxisMarginBoxExtent += isHorizontalFlow() ? child->marginWidth() : child->marginHeight();
@@ -977,12 +986,12 @@
return true;
}
-void RenderFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
+void RenderFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, bool hasInfiniteLineLength)
{
for (size_t i = 0; i < violations.size(); ++i) {
RenderBox* child = violations[i].child;
LayoutUnit childSize = violations[i].childSize;
- LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child);
+ LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child, hasInfiniteLineLength);
availableFreeSpace -= childSize - preferredChildSize;
totalFlexGrow -= child->style()->flexGrow();
totalWeightedFlexShrink -= child->style()->flexShrink() * preferredChildSize;
@@ -991,7 +1000,7 @@
}
// Returns true if we successfully ran the algorithm and sized the flex items.
-bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit>& childSizes)
+bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit>& childSizes, bool hasInfiniteLineLength)
{
childSizes.clear();
LayoutUnit totalViolation = 0;
@@ -1008,7 +1017,7 @@
if (inflexibleItems.contains(child))
childSizes.append(inflexibleItems.get(child));
else {
- LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child);
+ LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChild(child, hasInfiniteLineLength);
LayoutUnit childSize = preferredChildSize;
double extraSpace = 0;
if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && std::isfinite(totalFlexGrow))
@@ -1032,7 +1041,7 @@
}
if (totalViolation)
- freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems);
+ freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, hasInfiniteLineLength);
else
availableFreeSpace -= usedFreeSpace;
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (150086 => 150087)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2013-05-14 20:37:09 UTC (rev 150086)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2013-05-14 20:37:13 UTC (rev 150087)
@@ -138,7 +138,7 @@
EAlignItems alignmentForChild(RenderBox* child) const;
LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox* child) const;
LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const;
- LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child);
+ LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength);
void layoutFlexItems(bool relayoutChildren, Vector<LineContext>&);
LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace);
@@ -156,10 +156,10 @@
LayoutUnit computeChildMarginValue(Length margin, RenderView*);
void computeMainAxisPreferredSizes(OrderHashSet&);
LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize);
- bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent);
+ bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent, bool& hasInfiniteLineLength);
- bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit>& childSizes);
- void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&);
+ bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit>& childSizes, bool hasInfiniteLineLength);
+ void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, bool hasInfiniteLineLength);
void resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox*);
bool needToStretchChild(RenderBox*);