Changeset 92628 in webkit


Ignore:
Timestamp:
Aug 8, 2011 1:29:40 PM (13 years ago)
Author:
tony@chromium.org
Message:

implement basic horizontal flexing
https://bugs.webkit.org/show_bug.cgi?id=65045

Reviewed by David Hyatt.

Source/WebCore:

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:

LayoutTests:

  • 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):

Location:
trunk
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r92620 r92628  
     12011-08-08  Tony Chang  <tony@chromium.org>
     2
     3        implement basic horizontal flexing
     4        https://bugs.webkit.org/show_bug.cgi?id=65045
     5
     6        Reviewed by David Hyatt.
     7
     8        * css3/flexbox/001-expected.txt: Added.
     9        * css3/flexbox/001.html: Added.
     10        * css3/flexbox/resources/flexbox.js: Added. I plan on using this file for other tests.
     11        (insertAfter):
     12        (checkHorizontalBoxen):
     13
    1142011-08-08  Ryosuke Niwa  <rniwa@webkit.org>
    215
  • trunk/Source/WebCore/ChangeLog

    r92627 r92628  
     12011-08-08  Tony Chang  <tony@chromium.org>
     2
     3        implement basic horizontal flexing
     4        https://bugs.webkit.org/show_bug.cgi?id=65045
     5
     6        Reviewed by David Hyatt.
     7
     8        Test: css3/flexbox/001.html
     9
     10        * css/CSSPrimitiveValueMappings.h:
     11        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
     12        * rendering/RenderBox.cpp:
     13        (WebCore::RenderBox::computeLogicalWidth):
     14        * rendering/RenderFlexibleBox.cpp:
     15        (WebCore::RenderFlexibleBox::FlexibleBoxIterator::FlexibleBoxIterator): flexitem iterator
     16        (WebCore::RenderFlexibleBox::FlexibleBoxIterator::first):
     17        (WebCore::RenderFlexibleBox::FlexibleBoxIterator::next):
     18        (WebCore::RenderFlexibleBox::FlexibleBoxIterator::reset):
     19        (WebCore::RenderFlexibleBox::layoutBlock):
     20        (WebCore::preferredFlexItemContentWidth): Returns the intrinsic size of a flex item's content.
     21        (WebCore::RenderFlexibleBox::layoutHorizontalBlock): Runs the flex algorithm
     22        (WebCore::preferredSizeForMarginsAndPadding):
     23        (WebCore::RenderFlexibleBox::computePreferredSize): Calculate the preferred size of the
     24            flex items.
     25        * rendering/RenderFlexibleBox.h:
     26        * rendering/RenderObject.cpp:
     27        (WebCore::RenderObject::createObject):
     28        * rendering/style/RenderStyleConstants.h:
     29
    1302011-08-08  David Grogan  <dgrogan@chromium.org>
    231
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r92378 r92628  
    971971            m_value.ident = CSSValueWebkitInlineBox;
    972972            break;
     973#if ENABLE(CSS3_FLEXBOX)
     974        case FLEXBOX:
     975            m_value.ident = CSSValueWebkitFlexbox;
     976            break;
     977        case INLINE_FLEXBOX:
     978            m_value.ident = CSSValueWebkitInlineFlexbox;
     979            break;
     980#endif
    973981        case NONE:
    974982            m_value.ident = CSSValueNone;
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r92438 r92628  
    15611561        return;
    15621562    }
     1563#if ENABLE(CSS3_FLEXBOX)
     1564    // FIXME: Check direction once flex-direction is implemented.
     1565    if (hasOverrideSize() && parent()->isFlexibleBox()) {
     1566        setLogicalWidth(overrideWidth());
     1567        return;
     1568    }
     1569#endif
    15631570
    15641571    // FIXME: Account for block-flow in flexible boxes.
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r92072 r92628  
    3232#include "RenderFlexibleBox.h"
    3333
    34 #include "NotImplemented.h"
    35 
    3634#if ENABLE(CSS3_FLEXBOX)
    3735
    3836namespace WebCore {
     37
     38class RenderFlexibleBox::FlexibleBoxIterator {
     39public:
     40    explicit FlexibleBoxIterator(RenderFlexibleBox* flexibleBox)
     41        : m_flexibleBox(flexibleBox)
     42        , m_currentChild(0)
     43    {
     44    }
     45
     46    RenderBox* first()
     47    {
     48        reset();
     49        return next();
     50    }
     51
     52    RenderBox* next()
     53    {
     54        RenderObject* child = m_currentChild ? m_currentChild->nextSibling() : m_flexibleBox->firstChild();
     55        // FIXME: Inline nodes (like <img> or <input>) should also be treated as boxes.
     56        while (child && !child->isBox())
     57            child = child->nextSibling();
     58
     59        m_currentChild = toRenderBox(child);
     60        return m_currentChild;
     61    }
     62
     63    void reset()
     64    {
     65        m_currentChild = 0;
     66    }
     67
     68private:
     69    RenderFlexibleBox* m_flexibleBox;
     70    RenderBox* m_currentChild;
     71};
     72
    3973
    4074RenderFlexibleBox::RenderFlexibleBox(Node* node)
     
    5286}
    5387
    54 void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int pageLogicalHeight, BlockLayoutPass layoutPass)
     88void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int, BlockLayoutPass)
    5589{
    56     notImplemented();
     90    ASSERT(needsLayout());
     91
     92    if (!relayoutChildren && simplifiedLayout())
     93        return;
     94
     95    IntSize previousSize = size();
     96
     97    computeLogicalWidth();
     98    computeLogicalHeight();
     99
     100    m_overflow.clear();
     101
     102    // FIXME: Assume horizontal layout until flex-direction is added.
     103    layoutHorizontalBlock(relayoutChildren);
     104
     105    computeLogicalHeight();
     106
     107    if (size() != previousSize)
     108        relayoutChildren = true;
     109
     110    layoutPositionedObjects(relayoutChildren || isRoot());
     111
     112    updateLayerTransform();
     113
     114    setNeedsLayout(false);
     115}
     116
     117static LayoutUnit preferredFlexItemContentWidth(RenderBox* child)
     118{
     119    if (child->style()->width().isAuto())
     120        return child->maxPreferredLogicalWidth() - child->borderLeft() - child->borderRight() - child->verticalScrollbarWidth() - child->paddingLeft() - child->paddingRight();
     121    return child->contentWidth();
     122}
     123
     124void RenderFlexibleBox::layoutHorizontalBlock(bool relayoutChildren)
     125{
     126    LayoutUnit preferredSize;
     127    float totalPositiveFlexibility;
     128    float totalNegativeFlexibility;
     129    FlexibleBoxIterator iterator(this);
     130
     131    computePreferredSize(relayoutChildren, iterator, preferredSize, totalPositiveFlexibility, totalNegativeFlexibility);
     132    LayoutUnit availableFreeSpace = contentWidth() - preferredSize;
     133
     134    LayoutUnit xOffset = borderLeft() + paddingLeft();
     135    LayoutUnit yOffset = borderTop() + paddingTop();
     136    for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
     137        LayoutUnit childPreferredSize = preferredFlexItemContentWidth(child);
     138        // FIXME: Handle max-width and min-width (we should clamp to the max/min value and restart the algorithm).
     139        if (availableFreeSpace > 0 && totalPositiveFlexibility > 0)
     140            childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthPositiveFlex() / totalPositiveFlexibility);
     141        else if (availableFreeSpace < 0 && totalNegativeFlexibility > 0)
     142            childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthNegativeFlex() / totalNegativeFlexibility);
     143
     144        childPreferredSize += child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight();
     145        child->setOverrideSize(LayoutSize(childPreferredSize, 0));
     146        child->setChildNeedsLayout(true);
     147        child->layoutIfNeeded();
     148
     149        setHeight(std::max(height(), borderTop() + paddingTop() + child->marginTop() + child->height() + child->marginBottom() + paddingBottom() + borderBottom() + horizontalScrollbarHeight()));
     150
     151        // FIXME: Handle child margins.
     152        child->setLocation(IntPoint(xOffset, yOffset));
     153        xOffset += child->width();
     154    }
     155
     156    // FIXME: Distribute leftover space to the packing space (second distribution round).
     157    // FIXME: Handle distribution of vertical space (third distribution round).
     158}
     159
     160static LayoutUnit preferredSizeForMarginsAndPadding(Length length, LayoutUnit containerLength)
     161{
     162    return length.calcMinValue(containerLength);
     163}
     164
     165void RenderFlexibleBox::computePreferredSize(bool relayoutChildren, FlexibleBoxIterator& iterator, LayoutUnit& preferredSize, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
     166{
     167    preferredSize = 0;
     168    totalPositiveFlexibility = totalNegativeFlexibility = 0;
     169
     170    LayoutUnit flexboxAvailableLogicalWidth = availableLogicalWidth();
     171    for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
     172        // We always have to lay out flexible objects again, since the flex distribution
     173        // may have changed, and we need to reallocate space.
     174        child->clearOverrideSize();
     175        if (!relayoutChildren)
     176            child->setChildNeedsLayout(true);
     177        child->layoutIfNeeded();
     178
     179        // FIXME: Margins and paddings set to auto have a positive flexibility of 1.
     180        preferredSize += preferredSizeForMarginsAndPadding(child->style()->marginLeft(), flexboxAvailableLogicalWidth);
     181        preferredSize += preferredSizeForMarginsAndPadding(child->style()->marginRight(), flexboxAvailableLogicalWidth);
     182        preferredSize += preferredSizeForMarginsAndPadding(child->style()->paddingLeft(), flexboxAvailableLogicalWidth);
     183        preferredSize += preferredSizeForMarginsAndPadding(child->style()->paddingRight(), flexboxAvailableLogicalWidth);
     184
     185        preferredSize += child->borderLeft() + child->borderRight();
     186
     187        preferredSize += preferredFlexItemContentWidth(child);
     188
     189        totalPositiveFlexibility += child->style()->flexboxWidthPositiveFlex();
     190        totalNegativeFlexibility += child->style()->flexboxWidthNegativeFlex();
     191    }
    57192}
    58193
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.h

    r92004 r92628  
    4848
    4949    virtual void layoutBlock(bool relayoutChildren, int pageLogicalHeight = 0, BlockLayoutPass = NormalLayoutPass);
     50
     51private:
     52    class FlexibleBoxIterator;
     53
     54    void layoutHorizontalBlock(bool relayoutChildren);
     55
     56    void computePreferredSize(bool relayoutChildren, FlexibleBoxIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
    5057};
    5158
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r92434 r92628  
    4545#include "RenderCounter.h"
    4646#include "RenderDeprecatedFlexibleBox.h"
     47#include "RenderFlexibleBox.h"
    4748#include "RenderImage.h"
    4849#include "RenderImageResourceStyleImage.h"
     
    170171        case INLINE_BOX:
    171172            return new (arena) RenderDeprecatedFlexibleBox(node);
     173#if ENABLE(CSS3_FLEXBOX)
     174        case FLEXBOX:
     175        case INLINE_FLEXBOX:
     176            return new (arena) RenderFlexibleBox(node);
     177#endif
    172178    }
    173179
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r91702 r92628  
    400400    WAP_MARQUEE,
    401401#endif
     402#if ENABLE(CSS3_FLEXBOX)
     403    FLEXBOX, INLINE_FLEXBOX,
     404#endif
    402405    NONE
    403406};
Note: See TracChangeset for help on using the changeset viewer.