Diff
Modified: trunk/LayoutTests/ChangeLog (92627 => 92628)
--- trunk/LayoutTests/ChangeLog 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/LayoutTests/ChangeLog 2011-08-08 20:29:40 UTC (rev 92628)
@@ -1,3 +1,16 @@
+2011-08-08 Tony Chang <[email protected]>
+
+ implement basic horizontal flexing
+ https://bugs.webkit.org/show_bug.cgi?id=65045
+
+ Reviewed by David Hyatt.
+
+ * css3/flexbox/001-expected.txt: Added.
+ * css3/flexbox/001.html: Added.
+ * css3/flexbox/resources/flexbox.js: Added. I plan on using this file for other tests.
+ (insertAfter):
+ (checkHorizontalBoxen):
+
2011-08-08 Ryosuke Niwa <[email protected]>
Remove redundant inline styles from the pasted contents more aggressively
Added: trunk/LayoutTests/css3/flexbox/001-expected.txt (0 => 92628)
--- trunk/LayoutTests/css3/flexbox/001-expected.txt (rev 0)
+++ trunk/LayoutTests/css3/flexbox/001-expected.txt 2011-08-08 20:29:40 UTC (rev 92628)
@@ -0,0 +1,18 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Property changes on: trunk/LayoutTests/css3/flexbox/001-expected.txt
___________________________________________________________________
Added: svn:eol-style
Added: trunk/LayoutTests/css3/flexbox/001.html (0 => 92628)
--- trunk/LayoutTests/css3/flexbox/001.html (rev 0)
+++ trunk/LayoutTests/css3/flexbox/001.html 2011-08-08 20:29:40 UTC (rev 92628)
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html>
+<style>
+body {
+ margin: 0;
+}
+.horizontal-box {
+ width: 600px;
+}
+.horizontal-box div {
+ height: 20px;
+ border: 0;
+}
+
+.horizontal-box :nth-child(1) {
+ background-color: blue;
+}
+.horizontal-box :nth-child(2) {
+ background-color: green;
+}
+.horizontal-box :nth-child(3) {
+ background-color: red;
+}
+</style>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<script src=""
+<body _onload_="checkHorizontalBoxen()">
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(1)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(.5)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(.5)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(.5)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="300" style="width: -webkit-flex(3)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(2)"></div>
+ <div data-expected-width="100" style="width: -webkit-flex(1)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="250" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="250" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="100" style="width: 100px"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="150" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="150" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="300" style="width: 50%"></div>
+</div>
+
+<!-- The first two boxes should fill the extra 300px evenly (each gets 150px extra). -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="150" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="350" style="width: -webkit-flex(1 200px)"></div>
+ <div data-expected-width="100" style="width: 100px"></div>
+</div>
+
+<!-- Like the last test, except the middle box gets more space than the first box. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="100" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="400" style="width: -webkit-flex(2 33.333333%)"></div>
+ <div data-expected-width="100" style="width: 100px"></div>
+</div>
+
+<!-- Test some negative flexing. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1 1 300px)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(2 1 300px)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(3 1 300px)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="250" style="width: -webkit-flex(1 1 300px)"></div>
+ <div data-expected-width="150" style="width: -webkit-flex(2 3 300px)"></div>
+ <div data-expected-width="200" style="width: 200px"></div>
+</div>
+
+<!-- Test flexitem borders. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="250" style="width: -webkit-flex(1); border-left: 150px solid black"></div>
+ <div data-expected-width="250" style="width: -webkit-flex(1 0 0px); border-right: 150px solid orange"></div>
+ <div data-expected-width="100" style="width: -webkit-flex(1 0 0px)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="300" style="width: 100px; border: 100px solid black"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(2)"></div>
+ <div data-expected-width="100" style="width: -webkit-flex(1)"></div>
+</div>
+
+<!-- Test flexitem padding. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="250" style="width: -webkit-flex(1); padding-left: 150px"></div>
+ <div data-expected-width="250" style="width: -webkit-flex(1 0 0px); padding-right: 150px"></div>
+ <div data-expected-width="100" style="width: -webkit-flex(1 0 0px)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="300" style="width: 100px; padding: 100px"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(2)"></div>
+ <div data-expected-width="100" style="width: -webkit-flex(1)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1); padding-left: 25%"></div>
+ <div data-expected-width="150" style="width: -webkit-flex(3);"></div>
+ <div data-expected-width="250" style="width: 100px; padding-right: 25%"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1); padding-left: 50px; border-right: 50px solid black"></div>
+ <div data-expected-width="250" style="width: -webkit-flex(2); border-right: 50px solid orange"></div>
+ <div data-expected-width="150" style="width: -webkit-flex(1); padding-right: 50px;"></div>
+</div>
+
+<!-- Test items with an intrinsic size. -->
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1)">
+ <div style="width: 100px; height: 100%;"></div>
+ </div>
+ <div data-expected-width="200" style="width: -webkit-flex(2)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(2)"></div>
+</div>
+
+<div style="display: -webkit-flexbox" class="horizontal-box">
+ <div data-expected-width="200" style="width: -webkit-flex(1 0 0)">
+ <div style="width: 100px; height: 100%;"></div>
+ </div>
+ <div data-expected-width="200" style="width: -webkit-flex(1)"></div>
+ <div data-expected-width="200" style="width: -webkit-flex(1)"></div>
+</div>
+
+</body>
+</html>
Property changes on: trunk/LayoutTests/css3/flexbox/001.html
___________________________________________________________________
Added: svn:eol-style
Added: trunk/LayoutTests/css3/flexbox/resources/flexbox.js (0 => 92628)
--- trunk/LayoutTests/css3/flexbox/resources/flexbox.js (rev 0)
+++ trunk/LayoutTests/css3/flexbox/resources/flexbox.js 2011-08-08 20:29:40 UTC (rev 92628)
@@ -0,0 +1,28 @@
+function insertAfter(nodeToAdd, referenceNode)
+{
+ if (referenceNode.nextSibling)
+ referenceNode.parentNode.insertBefore(nodeToAdd, referenceNode.nextSibling);
+ else
+ referenceNode.parentNode.appendChild(nodeToAdd);
+}
+
+function checkHorizontalBoxen()
+{
+ var flexboxen = document.getElementsByClassName("horizontal-box");
+ Array.prototype.forEach.call(flexboxen, function(flexbox) {
+ var failures = "";
+ var child = flexbox.firstChild;
+ while (child) {
+ var expectedWidth = child.getAttribute && child.getAttribute("data-expected-width");
+ if (child.offsetWidth && expectedWidth) {
+ if (child.offsetWidth != parseInt(expectedWidth)) {
+ failures += "Expected " + expectedWidth + " but got " + child.offsetWidth + ". ";
+ }
+ }
+ child = child.nextSibling;
+ }
+
+ insertAfter(document.createElement("p"), flexbox);
+ insertAfter(document.createTextNode(failures ? failures : "PASS"), flexbox);
+ });
+}
Property changes on: trunk/LayoutTests/css3/flexbox/resources/flexbox.js
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/ChangeLog (92627 => 92628)
--- trunk/Source/WebCore/ChangeLog 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/ChangeLog 2011-08-08 20:29:40 UTC (rev 92628)
@@ -1,3 +1,32 @@
+2011-08-08 Tony Chang <[email protected]>
+
+ implement basic horizontal flexing
+ https://bugs.webkit.org/show_bug.cgi?id=65045
+
+ Reviewed by David Hyatt.
+
+ Test: css3/flexbox/001.html
+
+ * css/CSSPrimitiveValueMappings.h:
+ (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::computeLogicalWidth):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::FlexibleBoxIterator::FlexibleBoxIterator): flexitem iterator
+ (WebCore::RenderFlexibleBox::FlexibleBoxIterator::first):
+ (WebCore::RenderFlexibleBox::FlexibleBoxIterator::next):
+ (WebCore::RenderFlexibleBox::FlexibleBoxIterator::reset):
+ (WebCore::RenderFlexibleBox::layoutBlock):
+ (WebCore::preferredFlexItemContentWidth): Returns the intrinsic size of a flex item's content.
+ (WebCore::RenderFlexibleBox::layoutHorizontalBlock): Runs the flex algorithm
+ (WebCore::preferredSizeForMarginsAndPadding):
+ (WebCore::RenderFlexibleBox::computePreferredSize): Calculate the preferred size of the
+ flex items.
+ * rendering/RenderFlexibleBox.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::createObject):
+ * rendering/style/RenderStyleConstants.h:
+
2011-08-08 David Grogan <[email protected]>
Add detail to ASSERT message in IDBTransaction::enqueueEvent
Modified: trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h (92627 => 92628)
--- trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h 2011-08-08 20:29:40 UTC (rev 92628)
@@ -970,6 +970,14 @@
case INLINE_BOX:
m_value.ident = CSSValueWebkitInlineBox;
break;
+#if ENABLE(CSS3_FLEXBOX)
+ case FLEXBOX:
+ m_value.ident = CSSValueWebkitFlexbox;
+ break;
+ case INLINE_FLEXBOX:
+ m_value.ident = CSSValueWebkitInlineFlexbox;
+ break;
+#endif
case NONE:
m_value.ident = CSSValueNone;
break;
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (92627 => 92628)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2011-08-08 20:29:40 UTC (rev 92628)
@@ -1560,6 +1560,13 @@
setLogicalWidth(overrideWidth());
return;
}
+#if ENABLE(CSS3_FLEXBOX)
+ // FIXME: Check direction once flex-direction is implemented.
+ if (hasOverrideSize() && parent()->isFlexibleBox()) {
+ setLogicalWidth(overrideWidth());
+ return;
+ }
+#endif
// FIXME: Account for block-flow in flexible boxes.
// https://bugs.webkit.org/show_bug.cgi?id=46418
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (92627 => 92628)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2011-08-08 20:29:40 UTC (rev 92628)
@@ -31,12 +31,46 @@
#include "config.h"
#include "RenderFlexibleBox.h"
-#include "NotImplemented.h"
-
#if ENABLE(CSS3_FLEXBOX)
namespace WebCore {
+class RenderFlexibleBox::FlexibleBoxIterator {
+public:
+ explicit FlexibleBoxIterator(RenderFlexibleBox* flexibleBox)
+ : m_flexibleBox(flexibleBox)
+ , m_currentChild(0)
+ {
+ }
+
+ RenderBox* first()
+ {
+ reset();
+ return next();
+ }
+
+ RenderBox* next()
+ {
+ RenderObject* child = m_currentChild ? m_currentChild->nextSibling() : m_flexibleBox->firstChild();
+ // FIXME: Inline nodes (like <img> or <input>) should also be treated as boxes.
+ while (child && !child->isBox())
+ child = child->nextSibling();
+
+ m_currentChild = toRenderBox(child);
+ return m_currentChild;
+ }
+
+ void reset()
+ {
+ m_currentChild = 0;
+ }
+
+private:
+ RenderFlexibleBox* m_flexibleBox;
+ RenderBox* m_currentChild;
+};
+
+
RenderFlexibleBox::RenderFlexibleBox(Node* node)
: RenderBlock(node)
{
@@ -51,11 +85,112 @@
return "RenderFlexibleBox";
}
-void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int pageLogicalHeight, BlockLayoutPass layoutPass)
+void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int, BlockLayoutPass)
{
- notImplemented();
+ ASSERT(needsLayout());
+
+ if (!relayoutChildren && simplifiedLayout())
+ return;
+
+ IntSize previousSize = size();
+
+ computeLogicalWidth();
+ computeLogicalHeight();
+
+ m_overflow.clear();
+
+ // FIXME: Assume horizontal layout until flex-direction is added.
+ layoutHorizontalBlock(relayoutChildren);
+
+ computeLogicalHeight();
+
+ if (size() != previousSize)
+ relayoutChildren = true;
+
+ layoutPositionedObjects(relayoutChildren || isRoot());
+
+ updateLayerTransform();
+
+ setNeedsLayout(false);
}
+static LayoutUnit preferredFlexItemContentWidth(RenderBox* child)
+{
+ if (child->style()->width().isAuto())
+ return child->maxPreferredLogicalWidth() - child->borderLeft() - child->borderRight() - child->verticalScrollbarWidth() - child->paddingLeft() - child->paddingRight();
+ return child->contentWidth();
}
+void RenderFlexibleBox::layoutHorizontalBlock(bool relayoutChildren)
+{
+ LayoutUnit preferredSize;
+ float totalPositiveFlexibility;
+ float totalNegativeFlexibility;
+ FlexibleBoxIterator iterator(this);
+
+ computePreferredSize(relayoutChildren, iterator, preferredSize, totalPositiveFlexibility, totalNegativeFlexibility);
+ LayoutUnit availableFreeSpace = contentWidth() - preferredSize;
+
+ LayoutUnit xOffset = borderLeft() + paddingLeft();
+ LayoutUnit yOffset = borderTop() + paddingTop();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ LayoutUnit childPreferredSize = preferredFlexItemContentWidth(child);
+ // FIXME: Handle max-width and min-width (we should clamp to the max/min value and restart the algorithm).
+ if (availableFreeSpace > 0 && totalPositiveFlexibility > 0)
+ childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthPositiveFlex() / totalPositiveFlexibility);
+ else if (availableFreeSpace < 0 && totalNegativeFlexibility > 0)
+ childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthNegativeFlex() / totalNegativeFlexibility);
+
+ childPreferredSize += child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight();
+ child->setOverrideSize(LayoutSize(childPreferredSize, 0));
+ child->setChildNeedsLayout(true);
+ child->layoutIfNeeded();
+
+ setHeight(std::max(height(), borderTop() + paddingTop() + child->marginTop() + child->height() + child->marginBottom() + paddingBottom() + borderBottom() + horizontalScrollbarHeight()));
+
+ // FIXME: Handle child margins.
+ child->setLocation(IntPoint(xOffset, yOffset));
+ xOffset += child->width();
+ }
+
+ // FIXME: Distribute leftover space to the packing space (second distribution round).
+ // FIXME: Handle distribution of vertical space (third distribution round).
+}
+
+static LayoutUnit preferredSizeForMarginsAndPadding(Length length, LayoutUnit containerLength)
+{
+ return length.calcMinValue(containerLength);
+}
+
+void RenderFlexibleBox::computePreferredSize(bool relayoutChildren, FlexibleBoxIterator& iterator, LayoutUnit& preferredSize, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
+{
+ preferredSize = 0;
+ totalPositiveFlexibility = totalNegativeFlexibility = 0;
+
+ LayoutUnit flexboxAvailableLogicalWidth = availableLogicalWidth();
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ // We always have to lay out flexible objects again, since the flex distribution
+ // may have changed, and we need to reallocate space.
+ child->clearOverrideSize();
+ if (!relayoutChildren)
+ child->setChildNeedsLayout(true);
+ child->layoutIfNeeded();
+
+ // FIXME: Margins and paddings set to auto have a positive flexibility of 1.
+ preferredSize += preferredSizeForMarginsAndPadding(child->style()->marginLeft(), flexboxAvailableLogicalWidth);
+ preferredSize += preferredSizeForMarginsAndPadding(child->style()->marginRight(), flexboxAvailableLogicalWidth);
+ preferredSize += preferredSizeForMarginsAndPadding(child->style()->paddingLeft(), flexboxAvailableLogicalWidth);
+ preferredSize += preferredSizeForMarginsAndPadding(child->style()->paddingRight(), flexboxAvailableLogicalWidth);
+
+ preferredSize += child->borderLeft() + child->borderRight();
+
+ preferredSize += preferredFlexItemContentWidth(child);
+
+ totalPositiveFlexibility += child->style()->flexboxWidthPositiveFlex();
+ totalNegativeFlexibility += child->style()->flexboxWidthNegativeFlex();
+ }
+}
+
+}
+
#endif // ENABLE(CSS3_FLEXBOX)
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (92627 => 92628)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2011-08-08 20:29:40 UTC (rev 92628)
@@ -47,6 +47,13 @@
virtual bool isFlexibleBox() const { return true; }
virtual void layoutBlock(bool relayoutChildren, int pageLogicalHeight = 0, BlockLayoutPass = NormalLayoutPass);
+
+private:
+ class FlexibleBoxIterator;
+
+ void layoutHorizontalBlock(bool relayoutChildren);
+
+ void computePreferredSize(bool relayoutChildren, FlexibleBoxIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (92627 => 92628)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2011-08-08 20:29:40 UTC (rev 92628)
@@ -44,6 +44,7 @@
#include "RenderArena.h"
#include "RenderCounter.h"
#include "RenderDeprecatedFlexibleBox.h"
+#include "RenderFlexibleBox.h"
#include "RenderImage.h"
#include "RenderImageResourceStyleImage.h"
#include "RenderInline.h"
@@ -169,6 +170,11 @@
case BOX:
case INLINE_BOX:
return new (arena) RenderDeprecatedFlexibleBox(node);
+#if ENABLE(CSS3_FLEXBOX)
+ case FLEXBOX:
+ case INLINE_FLEXBOX:
+ return new (arena) RenderFlexibleBox(node);
+#endif
}
return 0;
Modified: trunk/Source/WebCore/rendering/style/RenderStyleConstants.h (92627 => 92628)
--- trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2011-08-08 20:18:33 UTC (rev 92627)
+++ trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2011-08-08 20:29:40 UTC (rev 92628)
@@ -399,6 +399,9 @@
#if ENABLE(WCSS)
WAP_MARQUEE,
#endif
+#if ENABLE(CSS3_FLEXBOX)
+ FLEXBOX, INLINE_FLEXBOX,
+#endif
NONE
};