https://bugs.webkit.org/show_bug.cgi?id=67432
Reviewed by Ojan Vafai.
Source/WebCore:
flex-order can be an int (including negative), but we disallow the two
smallest values so we can put the numbers into a hash set.
Also, create two iterators: one that goes in render tree order (we use
this for the first pass and to collect the possible flex order values)
and one that goes in flex order.
Test: css3/flexbox/flex-order.html
* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue):
* rendering/RenderFlexibleBox.cpp:
(WebCore::FlexOrderHashTraits::emptyValue):
(WebCore::FlexOrderHashTraits::constructDeletedValue):
(WebCore::FlexOrderHashTraits::isDeletedValue):
(WebCore::RenderFlexibleBox::TreeOrderIterator::TreeOrderIterator): A simple iterator
that goes in render tree order.
(WebCore::RenderFlexibleBox::TreeOrderIterator::next):
(WebCore::RenderFlexibleBox::TreeOrderIterator::reset):
(WebCore::RenderFlexibleBox::TreeOrderIterator::flexOrderValues):
(WebCore::RenderFlexibleBox::FlexOrderIterator::FlexOrderIterator): An iterator that
goes in flex-order order. Creating this involves sorting, so only create it once
and pass it around.
(WebCore::RenderFlexibleBox::FlexOrderIterator::first):
(WebCore::RenderFlexibleBox::FlexOrderIterator::next):
(WebCore::RenderFlexibleBox::FlexOrderIterator::reset):
(WebCore::RenderFlexibleBox::layoutHorizontalBlock):
(WebCore::RenderFlexibleBox::computePreferredLogicalWidth):
(WebCore::RenderFlexibleBox::runFreeSpaceAllocationAlgorithmInlineDirection):
(WebCore::RenderFlexibleBox::layoutAndPlaceChildrenInlineDirection):
* rendering/RenderFlexibleBox.h:
LayoutTests:
* css3/flexbox/flex-order-expected.png: Added.
* css3/flexbox/flex-order-expected.txt: Added.
* css3/flexbox/flex-order.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95783
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-09-22 Tony Chang <tony@chromium.org>
+
+ implement -webkit-flex-order
+ https://bugs.webkit.org/show_bug.cgi?id=67432
+
+ Reviewed by Ojan Vafai.
+
+ * css3/flexbox/flex-order-expected.png: Added.
+ * css3/flexbox/flex-order-expected.txt: Added.
+ * css3/flexbox/flex-order.html: Added.
+
2011-09-22 Ben Wells <benwells@chromium.org>
Rebaseline for bug 65583 (path based border radius drawing on skia) part 6
--- /dev/null
+You should see identical green bars going from light green (left) to dark green (right).
--- /dev/null
+<!DOCTYPE html>
+<html>
+<style>
+body {
+ margin: 0;
+}
+.horizontal-box div {
+ height: 30px;
+ border: 0;
+ margin-bottom: 10px;
+}
+
+.first {
+ background-color: #0f0;
+}
+.second {
+ background-color: #0d0;
+}
+.third {
+ background-color: #090;
+}
+.fourth {
+ background-color: #060;
+}
+.fifth {
+ background-color: #030;
+}
+</style>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText(true);
+</script>
+<body>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: 1"></div>
+ <div class="second" style="width: -webkit-flex(1);"></div>
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 3"></div>
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 20"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 4"></div>
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 3"></div>
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 2"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: 1"></div>
+</div>
+
+<!-- The example from the spec. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 2"></div>
+ <div class="first" style="width: -webkit-flex(1)"></div>
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 2"></div>
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 1"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 2"></div>
+ <div class="second" style="width: -webkit-flex(1)"></div>
+ <div class="third" style="width: -webkit-flex(1)"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: -10"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 2000000000"></div>
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 1000000000"></div>
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 1000000000"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: -1000000000"></div>
+</div>
+
+<!-- Floating numbers are ignored and we use the default of 1 instead. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 2.5"></div>
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 2"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: -1"></div>
+ <div class="third" style="width: -webkit-flex(1)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 0"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: -1"></div>
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 1"></div>
+ <div class="fourth" style="width: -webkit-flex(1)"></div>
+</div>
+
+<!-- Values greater than what can be stored in an int are clamped from
+ -2,147,483,646 (int min + 2) to 2,147,483,647. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 4000000000"></div>
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 3000000000"></div>
+ <div class="first" style="width: -webkit-flex(1);"></div>
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 2147483646"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: 4000000000"></div>
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: 3000000000"></div>
+ <div class="first" style="width: -webkit-flex(1);"></div>
+ <div class="fourth" style="width: -webkit-flex(1); -webkit-flex-order: 2147483647"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div class="third" style="width: -webkit-flex(1); -webkit-flex-order: -2147483645"></div>
+ <div class="first" style="width: -webkit-flex(1); -webkit-flex-order: -2147483646"></div>
+ <div class="second" style="width: -webkit-flex(1); -webkit-flex-order: -2147483647"></div>
+ <div class="fourth" style="width: -webkit-flex(1);"></div>
+</div>
+
+<!-- This should not crash. -->
+<div style="display: -webkit-flexbox" class="horizontal-box"></div>
+
+<div style="position:absolute; left: -10000px;">You should see identical green bars going from light green
+(left) to dark green (right).</div>
+
+</body>
+</html>
+2011-09-22 Tony Chang <tony@chromium.org>
+
+ implement -webkit-flex-order
+ https://bugs.webkit.org/show_bug.cgi?id=67432
+
+ Reviewed by Ojan Vafai.
+
+ flex-order can be an int (including negative), but we disallow the two
+ smallest values so we can put the numbers into a hash set.
+
+ Also, create two iterators: one that goes in render tree order (we use
+ this for the first pass and to collect the possible flex order values)
+ and one that goes in flex order.
+
+ Test: css3/flexbox/flex-order.html
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::FlexOrderHashTraits::emptyValue):
+ (WebCore::FlexOrderHashTraits::constructDeletedValue):
+ (WebCore::FlexOrderHashTraits::isDeletedValue):
+ (WebCore::RenderFlexibleBox::TreeOrderIterator::TreeOrderIterator): A simple iterator
+ that goes in render tree order.
+ (WebCore::RenderFlexibleBox::TreeOrderIterator::next):
+ (WebCore::RenderFlexibleBox::TreeOrderIterator::reset):
+ (WebCore::RenderFlexibleBox::TreeOrderIterator::flexOrderValues):
+ (WebCore::RenderFlexibleBox::FlexOrderIterator::FlexOrderIterator): An iterator that
+ goes in flex-order order. Creating this involves sorting, so only create it once
+ and pass it around.
+ (WebCore::RenderFlexibleBox::FlexOrderIterator::first):
+ (WebCore::RenderFlexibleBox::FlexOrderIterator::next):
+ (WebCore::RenderFlexibleBox::FlexOrderIterator::reset):
+ (WebCore::RenderFlexibleBox::layoutHorizontalBlock):
+ (WebCore::RenderFlexibleBox::computePreferredLogicalWidth):
+ (WebCore::RenderFlexibleBox::runFreeSpaceAllocationAlgorithmInlineDirection):
+ (WebCore::RenderFlexibleBox::layoutAndPlaceChildrenInlineDirection):
+ * rendering/RenderFlexibleBox.h:
+
2011-09-22 Darin Adler <darin@apple.com>
Use AffineTransform scale functions in ShadowBlur::adjustBlurRadius
break;
#if ENABLE(CSS3_FLEXBOX)
case CSSPropertyWebkitFlexOrder:
- validPrimitive = validUnit(value, FInteger, true);
+ if (validUnit(value, FInteger, true)) {
+ // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
+ parsedValue = primitiveValueCache()->createValue(max(static_cast<double>(std::numeric_limits<int>::min() + 2), value->fValue),
+ static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
+ m_valueList->next();
+ }
break;
case CSSPropertyWebkitFlexPack:
validPrimitive = id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter || id == CSSValueJustify;
namespace WebCore {
-class RenderFlexibleBox::FlexibleBoxIterator {
+// Normally, -1 and 0 are not valid in a HashSet, but these are relatively likely flex-order values. Instead,
+// we make the two smallest int values invalid flex-order values (in the css parser code we clamp them to
+// int min + 2).
+struct FlexOrderHashTraits : 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; }
+};
+
+typedef HashSet<int, DefaultHash<int>::Hash, FlexOrderHashTraits> FlexOrderHashSet;
+
+class RenderFlexibleBox::TreeOrderIterator {
public:
- explicit FlexibleBoxIterator(RenderFlexibleBox* flexibleBox)
+ explicit TreeOrderIterator(RenderFlexibleBox* flexibleBox)
: m_flexibleBox(flexibleBox)
, m_currentChild(0)
{
while (child && !child->isBox())
child = child->nextSibling();
+ if (child)
+ m_flexOrderValues.add(child->style()->flexOrder());
+
+ m_currentChild = toRenderBox(child);
+ return m_currentChild;
+ }
+
+ void reset()
+ {
+ m_currentChild = 0;
+ }
+
+ const FlexOrderHashSet& flexOrderValues()
+ {
+ return m_flexOrderValues;
+ }
+
+private:
+ RenderFlexibleBox* m_flexibleBox;
+ RenderBox* m_currentChild;
+ FlexOrderHashSet m_flexOrderValues;
+};
+
+class RenderFlexibleBox::FlexOrderIterator {
+public:
+ FlexOrderIterator(RenderFlexibleBox* flexibleBox, const FlexOrderHashSet& flexOrderValues)
+ : m_flexibleBox(flexibleBox)
+ , m_currentChild(0)
+ , m_orderValuesIterator(0)
+ {
+ copyToVector(flexOrderValues, m_orderValues);
+ std::sort(m_orderValues.begin(), m_orderValues.end());
+ }
+
+ RenderBox* first()
+ {
+ reset();
+ return next();
+ }
+
+ RenderBox* next()
+ {
+ RenderObject* child = m_currentChild;
+ do {
+ if (!child) {
+ if (m_orderValuesIterator == m_orderValues.end())
+ return 0;
+ if (m_orderValuesIterator) {
+ ++m_orderValuesIterator;
+ if (m_orderValuesIterator == m_orderValues.end())
+ return 0;
+ } else
+ m_orderValuesIterator = m_orderValues.begin();
+
+ child = m_flexibleBox->firstChild();
+ } else
+ child = child->nextSibling();
+ } while (!child || !child->isBox() || child->style()->flexOrder() != *m_orderValuesIterator);
+
m_currentChild = toRenderBox(child);
return m_currentChild;
}
void reset()
{
m_currentChild = 0;
+ m_orderValuesIterator = 0;
}
private:
RenderFlexibleBox* m_flexibleBox;
RenderBox* m_currentChild;
+ Vector<int> m_orderValues;
+ Vector<int>::const_iterator m_orderValuesIterator;
};
LayoutUnit preferredLogicalWidth;
float totalPositiveFlexibility;
float totalNegativeFlexibility;
- FlexibleBoxIterator iterator(this);
+ TreeOrderIterator treeIterator(this);
- computePreferredLogicalWidth(relayoutChildren, iterator, preferredLogicalWidth, totalPositiveFlexibility, totalNegativeFlexibility);
+ computePreferredLogicalWidth(relayoutChildren, treeIterator, preferredLogicalWidth, totalPositiveFlexibility, totalNegativeFlexibility);
LayoutUnit availableFreeSpace = contentLogicalWidth() - preferredLogicalWidth;
+ FlexOrderIterator flexIterator(this, treeIterator.flexOrderValues());
InflexibleFlexItemSize inflexibleItems;
WTF::Vector<LayoutUnit> childSizes;
- while (!runFreeSpaceAllocationAlgorithmInlineDirection(availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
+ while (!runFreeSpaceAllocationAlgorithmInlineDirection(flexIterator, availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
ASSERT(totalPositiveFlexibility >= 0 && totalNegativeFlexibility >= 0);
ASSERT(inflexibleItems.size() > 0);
}
- layoutAndPlaceChildrenInlineDirection(childSizes, availableFreeSpace, totalPositiveFlexibility);
+ layoutAndPlaceChildrenInlineDirection(flexIterator, childSizes, availableFreeSpace, totalPositiveFlexibility);
// FIXME: Handle distribution of cross-axis space (third distribution round).
}
return isHorizontalWritingMode() ? child->style()->flexboxWidthNegativeFlex() : child->style()->flexboxHeightNegativeFlex();
}
-void RenderFlexibleBox::computePreferredLogicalWidth(bool relayoutChildren, FlexibleBoxIterator& iterator, LayoutUnit& preferredLogicalWidth, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
+void RenderFlexibleBox::computePreferredLogicalWidth(bool relayoutChildren, TreeOrderIterator& iterator, LayoutUnit& preferredLogicalWidth, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
{
preferredLogicalWidth = 0;
totalPositiveFlexibility = totalNegativeFlexibility = 0;
}
// Returns true if we successfully ran the algorithm and sized the flex items.
-bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithmInlineDirection(LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
+bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithmInlineDirection(FlexOrderIterator& iterator, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
{
- FlexibleBoxIterator iterator(this);
childSizes.clear();
LayoutUnit flexboxAvailableLogicalWidth = availableLogicalWidth();
child->isHorizontalWritingMode() ? child->setOverrideHeight(childPreferredSize) : child->setOverrideWidth(childPreferredSize);
}
-void RenderFlexibleBox::layoutAndPlaceChildrenInlineDirection(const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility)
+void RenderFlexibleBox::layoutAndPlaceChildrenInlineDirection(FlexOrderIterator& iterator, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility)
{
- FlexibleBoxIterator iterator(this);
LayoutUnit startEdge = borderStart() + paddingStart();
if (hasPackingSpace(availableFreeSpace, totalPositiveFlexibility)) {
virtual void layoutBlock(bool relayoutChildren, int pageLogicalHeight = 0, BlockLayoutPass = NormalLayoutPass);
private:
- class FlexibleBoxIterator;
+ class TreeOrderIterator;
+ class FlexOrderIterator;
typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
LayoutUnit logicalBorderAndPaddingWidthForChild(RenderBox* child);
float logicalPositiveFlexForChild(RenderBox* child);
float logicalNegativeFlexForChild(RenderBox* child);
- void computePreferredLogicalWidth(bool relayoutChildren, FlexibleBoxIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
- bool runFreeSpaceAllocationAlgorithmInlineDirection(LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
+ void computePreferredLogicalWidth(bool relayoutChildren, TreeOrderIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
+ bool runFreeSpaceAllocationAlgorithmInlineDirection(FlexOrderIterator&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
- void layoutAndPlaceChildrenInlineDirection(const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility);
+ void layoutAndPlaceChildrenInlineDirection(FlexOrderIterator&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility);
};
} // namespace WebCore