Ignore:
Timestamp:
Jul 16, 2012, 12:09:57 PM (13 years ago)
Author:
tony@chromium.org
Message:

Position grid items by row/column index
https://bugs.webkit.org/show_bug.cgi?id=91293

Reviewed by Ojan Vafai.

Source/WebCore:

Do some initial grid positioning. Only handle the simple case where tracks are
fixed values and don't properly size the grid items. This gives us something to
work with and starts implementing the "Grid Track Sizing Algorithm":
http://dev.w3.org/csswg/css3-grid-layout/#grid-track-sizing-algorithm0

Test: fast/css-grid-layout/place-cell-by-index.html

  • rendering/RenderGrid.cpp:

(RenderGrid::GridTrack): Data structure for holding the track size. UsedBreadth matches the terminology
used in the spec.
(WebCore::RenderGrid::layoutBlock): Pull in some boiler plate code and put the
grid specific code in layoutGridItems.
(WebCore::RenderGrid::computedUsedBreadthOfGridTracks): Implement part of the grid track sizing algorithm.
(WebCore::RenderGrid::layoutGridItems): Compute the size of grid tracks, layout and position children.
(WebCore::RenderGrid::findChildLogicalPosition): Map track sizes to the actual position of the child.

  • rendering/RenderGrid.h:
  • rendering/style/RenderStyle.h: Just return a copy of Length rather than a reference to Length. This seems

more consistent with other getters that return a Length.

LayoutTests:

Add a test for grid layout in each writing mode direction. The height in vertical writing mode is incorrect for now.

  • fast/css-grid-layout/containing-block-grids-expected.html: Scope <p> around text only.
  • fast/css-grid-layout/containing-block-grids.html: Fix missing closing </div>.
  • fast/css-grid-layout/place-cell-by-index-expected.txt: Added.
  • fast/css-grid-layout/place-cell-by-index.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r121123 r122747  
    2525
    2626#include "config.h"
    27 
    2827#include "RenderGrid.h"
    2928
     29#include "LayoutRepainter.h"
     30#include "NotImplemented.h"
     31#include "RenderLayer.h"
     32#include "RenderView.h"
     33
    3034namespace WebCore {
     35
     36class RenderGrid::GridTrack {
     37public:
     38    GridTrack()
     39        : m_usedBreadth(0)
     40    {
     41    }
     42
     43    LayoutUnit m_usedBreadth;
     44};
    3145
    3246RenderGrid::RenderGrid(Node* node)
     
    4155}
    4256
    43 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
     57void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
    4458{
    45     // For now just call the base class.
    46     RenderBlock::layoutBlock(relayoutChildren, pageLogicalHeight);
     59    ASSERT(needsLayout());
     60
     61    if (!relayoutChildren && simplifiedLayout())
     62        return;
     63
     64    // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
     65    // It would be nice to refactor some of the duplicate code.
     66    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
     67    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
     68
     69    if (inRenderFlowThread()) {
     70        // Regions changing widths can force us to relayout our children.
     71        if (logicalWidthChangedInRegions())
     72            relayoutChildren = true;
     73    }
     74    computeInitialRegionRangeForBlock();
     75
     76    LayoutSize previousSize = size();
     77
     78    setLogicalHeight(0);
     79    computeLogicalWidth();
     80
     81    m_overflow.clear();
     82
     83    if (scrollsOverflow()) {
     84        if (style()->overflowX() == OSCROLL)
     85            layer()->setHasHorizontalScrollbar(true);
     86        if (style()->overflowY() == OSCROLL)
     87            layer()->setHasVerticalScrollbar(true);
     88    }
     89
     90    layoutGridItems();
     91
     92    LayoutUnit oldClientAfterEdge = clientLogicalBottom();
     93    computeLogicalHeight();
     94
     95    if (size() != previousSize)
     96        relayoutChildren = true;
     97
     98    layoutPositionedObjects(relayoutChildren || isRoot());
     99
     100    computeRegionRangeForBlock();
     101
     102    computeOverflow(oldClientAfterEdge);
     103    statePusher.pop();
     104
     105    updateLayerTransform();
     106
     107    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
     108    // we overflow or not.
     109    if (hasOverflowClip())
     110        layer()->updateScrollInfoAfterLayout();
     111
     112    repainter.repaintAfterLayout();
     113
     114    setNeedsLayout(false);
     115}
     116
     117void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, Vector<GridTrack>& tracks)
     118{
     119    const Vector<Length>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();
     120    for (size_t i = 0; i < trackStyles.size(); ++i) {
     121        GridTrack track;
     122        if (trackStyles[i].isFixed())
     123            track.m_usedBreadth = trackStyles[i].getFloatValue();
     124        else
     125            notImplemented();
     126
     127        tracks.append(track);
     128    }
     129}
     130
     131void RenderGrid::layoutGridItems()
     132{
     133    Vector<GridTrack> columnTracks, rowTracks;
     134    computedUsedBreadthOfGridTracks(ForColumns, columnTracks);
     135    // FIXME: The logical width of Grid Columns from the prior step is used in
     136    // the formatting of Grid items in content-sized Grid Rows to determine
     137    // their required height. We will probably need to pass columns through.
     138    computedUsedBreadthOfGridTracks(ForRows, rowTracks);
     139
     140    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
     141        LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
     142        // FIXME: Grid items should stretch to fill their cells. Once we
     143        // implement grid-{column,row}-align, we can also shrink to fit. For
     144        // now, just size as if we were a regular child.
     145        child->layoutIfNeeded();
     146
     147        // FIXME: Handle border & padding on the grid element.
     148        child->setLogicalLocation(childPosition);
     149    }
     150
     151    // FIXME: Handle border & padding on the grid element.
     152    for (size_t i = 0; i < rowTracks.size(); ++i)
     153        setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);
     154}
     155
     156LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks)
     157{
     158    Length column = child->style()->gridItemColumn();
     159    Length row = child->style()->gridItemRow();
     160
     161    // FIXME: What does a non-positive integer mean for a column/row?
     162    if (!column.isPositive() || !row.isPositive())
     163        return LayoutPoint();
     164
     165    // FIXME: Handle other values for grid-{row,column} like ranges or line names.
     166    if (!column.isFixed() || !row.isFixed())
     167        return LayoutPoint();
     168
     169    size_t columnTrack = static_cast<size_t>(column.intValue()) - 1;
     170    size_t rowTrack = static_cast<size_t>(row.intValue()) - 1;
     171
     172    LayoutPoint offset;
     173    for (size_t i = 0; i < columnTrack && i < columnTracks.size(); ++i)
     174        offset.setX(offset.x() + columnTracks[i].m_usedBreadth);
     175    for (size_t i = 0; i < rowTrack && i < rowTracks.size(); ++i)
     176        offset.setY(offset.y() + rowTracks[i].m_usedBreadth);
     177
     178    // FIXME: Handle margins on the grid item.
     179    return offset;
    47180}
    48181
Note: See TracChangeset for help on using the changeset viewer.