2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "RenderGrid.h"
29 #include "LayoutRepainter.h"
30 #include "NotImplemented.h"
31 #include "RenderLayer.h"
32 #include "RenderView.h"
36 static const int infinity = intMaxForLayoutUnit;
46 void growUsedBreadth(LayoutUnit growth)
49 m_usedBreadth += growth;
51 LayoutUnit usedBreadth() const { return m_usedBreadth; }
53 void growMaxBreadth(LayoutUnit growth)
55 if (m_maxBreadth == infinity)
56 m_maxBreadth = m_usedBreadth + growth;
58 m_maxBreadth += growth;
60 LayoutUnit maxBreadthIfNotInfinite() const
62 return (m_maxBreadth == infinity) ? m_usedBreadth : m_maxBreadth;
65 LayoutUnit m_usedBreadth;
66 LayoutUnit m_maxBreadth;
69 class RenderGrid::GridIterator {
70 WTF_MAKE_NONCOPYABLE(GridIterator);
72 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g
73 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd column.
74 GridIterator(const Vector<Vector<Vector<RenderBox*, 1> > >& grid, TrackSizingDirection direction, size_t fixedTrackIndex)
76 , m_direction(direction)
77 , m_rowIndex((direction == ForColumns) ? 0 : fixedTrackIndex)
78 , m_columnIndex((direction == ForColumns) ? fixedTrackIndex : 0)
83 RenderBox* nextGridItem()
88 size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
89 const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
90 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
91 const Vector<RenderBox*>& children = m_grid[m_rowIndex][m_columnIndex];
92 if (m_childIndex < children.size())
93 return children[m_childIndex++];
100 const Vector<Vector<Vector<RenderBox*, 1> > >& m_grid;
101 TrackSizingDirection m_direction;
103 size_t m_columnIndex;
107 RenderGrid::RenderGrid(Element* element)
108 : RenderBlock(element)
110 // All of our children must be block level.
111 setChildrenInline(false);
114 RenderGrid::~RenderGrid()
118 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
120 ASSERT(needsLayout());
122 if (!relayoutChildren && simplifiedLayout())
125 // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
126 // It would be nice to refactor some of the duplicate code.
127 LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
128 LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
130 if (inRenderFlowThread()) {
131 // Regions changing widths can force us to relayout our children.
132 if (logicalWidthChangedInRegions())
133 relayoutChildren = true;
135 updateRegionsAndExclusionsLogicalSize();
137 LayoutSize previousSize = size();
140 updateLogicalWidth();
146 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
147 updateLogicalHeight();
149 if (size() != previousSize)
150 relayoutChildren = true;
152 layoutPositionedObjects(relayoutChildren || isRoot());
154 computeRegionRangeForBlock();
156 computeOverflow(oldClientAfterEdge);
159 updateLayerTransform();
161 // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
162 // we overflow or not.
163 if (hasOverflowClip())
164 layer()->updateScrollInfoAfterLayout();
166 repainter.repaintAfterLayout();
168 setNeedsLayout(false);
171 void RenderGrid::computePreferredLogicalWidths()
173 ASSERT(preferredLogicalWidthsDirty());
177 m_minPreferredLogicalWidth = 0;
178 m_maxPreferredLogicalWidth = 0;
180 // FIXME: We don't take our own logical width into account.
182 const Vector<GridTrackSize>& trackStyles = style()->gridColumns();
184 for (size_t i = 0; i < trackStyles.size(); ++i) {
185 LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackStyles[i].minTrackBreadth(), i);
186 LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackStyles[i].maxTrackBreadth(), i);
187 maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth);
189 m_minPreferredLogicalWidth += minTrackBreadth;
190 m_maxPreferredLogicalWidth += maxTrackBreadth;
192 // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexibleBox).
195 // FIXME: We should account for min / max logical width.
197 LayoutUnit borderAndPaddingInInlineDirection = borderAndPaddingLogicalWidth();
198 m_minPreferredLogicalWidth += borderAndPaddingInInlineDirection;
199 m_maxPreferredLogicalWidth += borderAndPaddingInInlineDirection;
201 setPreferredLogicalWidthsDirty(false);
205 LayoutUnit RenderGrid::computePreferredTrackWidth(const Length& length, size_t trackIndex) const
207 if (length.isFixed()) {
208 // Grid areas don't have borders, margins or paddings so we don't need to account for them.
209 return length.intValue();
212 if (length.isMinContent()) {
213 LayoutUnit minContentSize = 0;
214 GridIterator iterator(m_grid, ForColumns, trackIndex);
215 while (RenderBox* gridItem = iterator.nextGridItem()) {
216 // FIXME: We should include the child's fixed margins like RenderFlexibleBox.
217 minContentSize = std::max(minContentSize, gridItem->minPreferredLogicalWidth());
219 return minContentSize;
222 if (length.isMaxContent()) {
223 LayoutUnit maxContentSize = 0;
224 GridIterator iterator(m_grid, ForColumns, trackIndex);
225 while (RenderBox* gridItem = iterator.nextGridItem()) {
226 // FIXME: We should include the child's fixed margins like RenderFlexibleBox.
227 maxContentSize = std::max(maxContentSize, gridItem->maxPreferredLogicalWidth());
229 return maxContentSize;
232 // FIXME: css3-sizing mentions that we should resolve "definite sizes"
233 // (including <percentage> and calc()) but we don't do it elsewhere.
237 void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks)
239 const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();
240 LayoutUnit availableLogicalSpace = (direction == ForColumns) ? availableLogicalWidth() : availableLogicalHeight(IncludeMarginBorderPadding);
241 Vector<GridTrack>& tracks = (direction == ForColumns) ? columnTracks : rowTracks;
242 for (size_t i = 0; i < trackStyles.size(); ++i) {
243 GridTrack& track = tracks[i];
244 const Length& minTrackBreadth = trackStyles[i].minTrackBreadth();
245 const Length& maxTrackBreadth = trackStyles[i].maxTrackBreadth();
247 track.m_usedBreadth = computeUsedBreadthOfMinLength(direction, minTrackBreadth);
248 track.m_maxBreadth = computeUsedBreadthOfMaxLength(direction, maxTrackBreadth);
250 track.m_maxBreadth = std::max(track.m_maxBreadth, track.m_usedBreadth);
252 availableLogicalSpace -= track.m_usedBreadth;
255 // FIXME: We shouldn't call resolveContentBasedTrackSizingFunctions if we have no min-content / max-content tracks.
256 resolveContentBasedTrackSizingFunctions(direction, columnTracks, rowTracks, availableLogicalSpace);
258 if (availableLogicalSpace <= 0)
261 const size_t tracksSize = tracks.size();
262 Vector<GridTrack*> tracksForDistribution(tracksSize);
263 for (size_t i = 0; i < tracksSize; ++i)
264 tracksForDistribution[i] = tracks.data() + i;
266 distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, availableLogicalSpace);
269 LayoutUnit RenderGrid::computeUsedBreadthOfMinLength(TrackSizingDirection direction, const Length& trackLength) const
271 if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage())
272 return computeUsedBreadthOfSpecifiedLength(direction, trackLength);
274 ASSERT(trackLength.isMinContent() || trackLength.isMaxContent() || trackLength.isAuto());
278 LayoutUnit RenderGrid::computeUsedBreadthOfMaxLength(TrackSizingDirection direction, const Length& trackLength) const
280 if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage()) {
281 LayoutUnit computedBreadth = computeUsedBreadthOfSpecifiedLength(direction, trackLength);
282 // FIXME: We should ASSERT that computedBreadth cannot return infinity but it's currently
283 // possible. See https://bugs.webkit.org/show_bug.cgi?id=107053
284 return computedBreadth;
287 ASSERT(trackLength.isMinContent() || trackLength.isMaxContent() || trackLength.isAuto());
291 LayoutUnit RenderGrid::computeUsedBreadthOfSpecifiedLength(TrackSizingDirection direction, const Length& trackLength) const
293 // FIXME: We still need to support calc() here (https://webkit.org/b/103761).
294 ASSERT(trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage());
295 return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(MainOrPreferredSize, style()->logicalHeight()), view());
298 const GridTrackSize& RenderGrid::gridTrackSize(TrackSizingDirection direction, size_t i)
300 const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();
301 if (i >= trackStyles.size()) {
302 // FIXME: This should match the default grid sizing (https://webkit.org/b/103333)
303 DEFINE_STATIC_LOCAL(GridTrackSize, defaultAutoSize, (Auto));
304 return defaultAutoSize;
306 return trackStyles[i];
309 size_t RenderGrid::maximumIndexInDirection(TrackSizingDirection direction) const
311 const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();
313 size_t maximumIndex = trackStyles.size();
315 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
316 GridPosition position = (direction == ForColumns) ? child->style()->gridItemColumn() : child->style()->gridItemRow();
317 maximumIndex = std::max(maximumIndex, resolveGridPosition(position) + 1);
323 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<GridTrack>& columnTracks)
325 // FIXME: We shouldn't force a layout every time this function is called but
326 // 1) Return computeLogicalHeight's value if it's available. Unfortunately computeLogicalHeight
327 // doesn't return if the logical height is available so would need to be changed.
328 // 2) Relayout if the column track's used breadth changed OR the logical height is unavailable.
329 if (!child->needsLayout())
330 child->setNeedsLayout(true, MarkOnlyThis);
332 size_t columnTrack = resolveGridPosition(ForColumns, child);
333 child->setOverrideContainingBlockContentLogicalWidth(columnTracks[columnTrack].m_usedBreadth);
334 child->clearOverrideContainingBlockContentLogicalHeight();
336 return child->logicalHeight();
339 LayoutUnit RenderGrid::minContentForChild(RenderBox* child, TrackSizingDirection direction, Vector<GridTrack>& columnTracks)
341 bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
342 // FIXME: Properly support orthogonal writing mode.
343 if (hasOrthogonalWritingMode)
346 if (direction == ForColumns) {
347 // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
348 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
349 return child->minPreferredLogicalWidth();
352 return logicalContentHeightForChild(child, columnTracks);
355 LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, TrackSizingDirection direction, Vector<GridTrack>& columnTracks)
357 bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
358 // FIXME: Properly support orthogonal writing mode.
359 if (hasOrthogonalWritingMode)
362 if (direction == ForColumns) {
363 // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
364 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
365 return child->maxPreferredLogicalWidth();
368 return logicalContentHeightForChild(child, columnTracks);
371 void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, LayoutUnit& availableLogicalSpace)
373 // FIXME: Split the grid tracks once we support spanning or fractions (step 1 and 2 of the algorithm).
375 Vector<GridTrack>& tracks = (direction == ForColumns) ? columnTracks : rowTracks;
377 for (size_t i = 0; i < tracks.size(); ++i) {
378 const GridTrackSize& trackSize = gridTrackSize(direction, i);
379 GridTrack& track = tracks[i];
380 const Length& minTrackBreadth = trackSize.minTrackBreadth();
381 if (minTrackBreadth.isMinContent() || minTrackBreadth.isMaxContent()) {
382 LayoutUnit oldUsedBreadth = track.m_usedBreadth;
383 resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, i, &RenderGrid::minContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
384 availableLogicalSpace -= (track.m_usedBreadth - oldUsedBreadth);
387 if (minTrackBreadth.isMaxContent()) {
388 LayoutUnit oldUsedBreadth = track.m_usedBreadth;
389 resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, i, &RenderGrid::maxContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
390 availableLogicalSpace -= (track.m_usedBreadth - oldUsedBreadth);
393 const Length& maxTrackBreadth = trackSize.maxTrackBreadth();
394 if (maxTrackBreadth.isMinContent() || maxTrackBreadth.isMaxContent())
395 resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, i, &RenderGrid::minContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
397 if (maxTrackBreadth.isMaxContent())
398 resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, i, &RenderGrid::maxContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
400 if (track.m_maxBreadth == infinity)
401 track.m_maxBreadth = track.m_usedBreadth;
405 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, size_t trackIndex, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
407 GridTrack& track = (direction == ForColumns) ? columnTracks[trackIndex] : rowTracks[trackIndex];
408 GridIterator iterator(m_grid, direction, trackIndex);
409 while (RenderBox* gridItem = iterator.nextGridItem()) {
410 LayoutUnit contentSize = (this->*sizingFunction)(gridItem, direction, columnTracks);
411 LayoutUnit additionalBreadthSpace = contentSize - (track.*trackGetter)();
412 Vector<GridTrack*> tracks;
413 tracks.append(&track);
414 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadth|.
415 distributeSpaceToTracks(tracks, &tracks, trackGetter, trackGrowthFunction, additionalBreadthSpace);
419 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTrack* track2)
421 return (track1->m_maxBreadth - track1->m_usedBreadth) < (track2->m_maxBreadth - track2->m_usedBreadth);
424 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, LayoutUnit& availableLogicalSpace)
426 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
428 size_t tracksSize = tracks.size();
429 Vector<LayoutUnit> updatedTrackBreadths(tracksSize);
431 for (size_t i = 0; i < tracksSize; ++i) {
432 GridTrack& track = *tracks[i];
433 LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i);
434 LayoutUnit trackBreadth = (tracks[i]->*trackGetter)();
435 LayoutUnit growthShare = std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBreadth);
436 updatedTrackBreadths[i] = trackBreadth + growthShare;
437 availableLogicalSpace -= growthShare;
440 if (availableLogicalSpace > 0 && tracksForGrowthAboveMaxBreadth) {
441 tracksSize = tracksForGrowthAboveMaxBreadth->size();
442 for (size_t i = 0; i < tracksSize; ++i) {
443 LayoutUnit growthShare = availableLogicalSpace / (tracksSize - i);
444 updatedTrackBreadths[i] += growthShare;
445 availableLogicalSpace -= growthShare;
449 for (size_t i = 0; i < tracksSize; ++i) {
450 LayoutUnit growth = updatedTrackBreadths[i] - (tracks[i]->*trackGetter)();
452 (tracks[i]->*trackGrowthFunction)(growth);
457 bool RenderGrid::tracksAreWiderThanMinTrackBreadth(TrackSizingDirection direction, const Vector<GridTrack>& tracks)
459 for (size_t i = 0; i < tracks.size(); ++i) {
460 const GridTrackSize& trackSize = gridTrackSize(direction, i);
461 const Length& minTrackBreadth = trackSize.minTrackBreadth();
462 if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i].m_usedBreadth)
469 void RenderGrid::placeItemsOnGrid()
471 ASSERT(m_grid.isEmpty());
472 m_grid.grow(maximumIndexInDirection(ForRows));
473 size_t maximumColumnIndex = maximumIndexInDirection(ForColumns);
474 for (size_t i = 0; i < gridRowCount(); ++i)
475 m_grid[i].grow(maximumColumnIndex);
477 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
478 size_t columnTrack = resolveGridPosition(child->style()->gridItemColumn());
479 size_t rowTrack = resolveGridPosition(child->style()->gridItemRow());
481 m_grid[rowTrack][columnTrack].append(child);
485 void RenderGrid::layoutGridItems()
489 Vector<GridTrack> columnTracks(gridColumnCount());
490 Vector<GridTrack> rowTracks(gridRowCount());
491 computedUsedBreadthOfGridTracks(ForColumns, columnTracks, rowTracks);
492 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, columnTracks));
493 computedUsedBreadthOfGridTracks(ForRows, columnTracks, rowTracks);
494 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, rowTracks));
496 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
497 LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
499 size_t columnTrack = resolveGridPosition(child->style()->gridItemColumn());
500 size_t rowTrack = resolveGridPosition(child->style()->gridItemRow());
502 // Because the grid area cannot be styled, we don't need to adjust
503 // the grid breadth to account for 'box-sizing'.
504 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWidth() : LayoutUnit();
505 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOverrideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogicalHeight() : LayoutUnit();
507 // FIXME: For children in a content sized track, we clear the overrideContainingBlockContentLogicalHeight
508 // in minContentForChild / maxContentForChild which means that we will always relayout the child.
509 if (oldOverrideContainingBlockContentLogicalWidth != columnTracks[columnTrack].m_usedBreadth || oldOverrideContainingBlockContentLogicalHeight != rowTracks[rowTrack].m_usedBreadth)
510 child->setNeedsLayout(true, MarkOnlyThis);
512 child->setOverrideContainingBlockContentLogicalWidth(columnTracks[columnTrack].m_usedBreadth);
513 child->setOverrideContainingBlockContentLogicalHeight(rowTracks[rowTrack].m_usedBreadth);
515 // FIXME: Grid items should stretch to fill their cells. Once we
516 // implement grid-{column,row}-align, we can also shrink to fit. For
517 // now, just size as if we were a regular child.
518 child->layoutIfNeeded();
520 // FIXME: Handle border & padding on the grid element.
521 child->setLogicalLocation(childPosition);
524 for (size_t i = 0; i < rowTracks.size(); ++i)
525 setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);
527 // FIXME: We should handle min / max logical height.
529 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight());
533 size_t RenderGrid::resolveGridPosition(TrackSizingDirection direction, const RenderObject* gridItem) const
535 const GridPosition& position = (direction == ForColumns) ? gridItem->style()->gridItemColumn() : gridItem->style()->gridItemRow();
536 return resolveGridPosition(position);
539 size_t RenderGrid::resolveGridPosition(const GridPosition& position) const
541 // FIXME: Handle other values for grid-{row,column} like ranges or line names.
542 switch (position.type()) {
543 case IntegerPosition:
544 // FIXME: What does a non-positive integer mean for a column/row?
545 if (!position.isPositive())
548 return position.integerPosition() - 1;
550 // FIXME: We should follow 'grid-auto-flow' for resolution.
551 // Until then, we use the 'grid-auto-flow: none' behavior (which is the default)
552 // and resolve 'auto' as the first row / column.
555 ASSERT_NOT_REACHED();
559 LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks)
561 size_t columnTrack = resolveGridPosition(child->style()->gridItemColumn());
562 size_t rowTrack = resolveGridPosition(child->style()->gridItemRow());
565 // FIXME: |columnTrack| and |rowTrack| should be smaller than our column / row count.
566 for (size_t i = 0; i < columnTrack && i < columnTracks.size(); ++i)
567 offset.setX(offset.x() + columnTracks[i].m_usedBreadth);
568 for (size_t i = 0; i < rowTrack && i < rowTracks.size(); ++i)
569 offset.setY(offset.y() + rowTracks[i].m_usedBreadth);
571 // FIXME: Handle margins on the grid item.
575 const char* RenderGrid::renderName() const
578 return "RenderGrid (floating)";
579 if (isOutOfFlowPositioned())
580 return "RenderGrid (positioned)";
582 return "RenderGrid (generated)";
583 if (isRelPositioned())
584 return "RenderGrid (relative positioned)";
588 } // namespace WebCore