Index: Source/core/rendering/RenderGrid.cpp |
diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp |
index 11474d6b9153b483983e0f05f4bbff8f4b23fdc0..2af5895e9b5d4196f31dbcaa0c4782122ee85918 100644 |
--- a/Source/core/rendering/RenderGrid.cpp |
+++ b/Source/core/rendering/RenderGrid.cpp |
@@ -224,6 +224,10 @@ void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild) |
return; |
} |
+ // Positioned items that shouldn't take up space or otherwise participate in the layout of the grid. |
Julien - ping for review
2014/11/24 21:44:40
s/that//
Manuel Rego
2014/12/01 11:10:37
Done.
|
+ if (newChild->isOutOfFlowPositioned()) |
+ return; |
+ |
// If the new child has been inserted inside an existent anonymous block, we can simply ignore it as the anonymous |
// block is an already known grid item. |
if (newChild->parent() != this) |
@@ -252,18 +256,18 @@ void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild) |
void RenderGrid::addChildToIndexesMap(RenderBox& child) |
{ |
ASSERT(!m_gridItemsIndexesMap.contains(&child)); |
- RenderBox* sibling = child.nextSiblingBox(); |
+ RenderBox* sibling = child.nextInFlowSiblingBox(); |
bool lastSibling = !sibling; |
if (lastSibling) |
- sibling = child.previousSiblingBox(); |
+ sibling = child.previousInFlowSiblingBox(); |
size_t index = 0; |
if (sibling) |
index = lastSibling ? m_gridItemsIndexesMap.get(sibling) + 1 : m_gridItemsIndexesMap.get(sibling); |
if (sibling && !lastSibling) { |
- for (; sibling; sibling = sibling->nextSiblingBox()) |
+ for (; sibling; sibling = sibling->nextInFlowSiblingBox()) |
m_gridItemsIndexesMap.set(sibling, m_gridItemsIndexesMap.get(sibling) + 1); |
} |
@@ -286,6 +290,9 @@ void RenderGrid::removeChild(RenderObject* child) |
return; |
} |
+ if (child->isOutOfFlowPositioned()) |
+ return; |
+ |
const RenderBox* childBox = toRenderBox(child); |
GridCoordinate coordinate = m_gridItemCoordinate.take(childBox); |
@@ -898,6 +905,10 @@ void RenderGrid::placeItemsOnGrid() |
Vector<RenderBox*> autoMajorAxisAutoGridItems; |
Vector<RenderBox*> specifiedMajorAxisAutoGridItems; |
for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) { |
+ if (child->isOutOfFlowPositioned()) { |
+ continue; |
+ } |
+ |
// FIXME: We never re-resolve positions if the grid is grown during auto-placement which may lead auto / <integer> |
// positions to not match the author's intent. The specification is unclear on what should be done in this case. |
OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows); |
@@ -939,7 +950,8 @@ void RenderGrid::populateExplicitGridAndOrderIterator() |
ASSERT(m_gridItemsIndexesMap.isEmpty()); |
size_t childIndex = 0; |
- for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
+ for (RenderBox* child = firstChildBox(); child; child = child->nextInFlowSiblingBox()) { |
+ |
populator.collectChild(child); |
m_gridItemsIndexesMap.set(child, childIndex++); |
@@ -1098,10 +1110,9 @@ void RenderGrid::layoutGridItems() |
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
if (child->isOutOfFlowPositioned()) { |
- // FIXME: Absolute positioned grid items should have a special |
- // behavior as described in the spec (crbug.com/273898): |
- // http://www.w3.org/TR/css-grid-1/#abspos-items |
child->containingBlock()->insertPositionedObject(child); |
+ adjustPositionedGridItem(child); |
+ continue; |
} |
// Because the grid area cannot be styled, we don't need to adjust |
@@ -1145,6 +1156,83 @@ void RenderGrid::layoutGridItems() |
setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); |
} |
+void RenderGrid::adjustPositionedGridItem(RenderBox* child) |
+{ |
+ RenderLayer* childLayer = child->layer(); |
+ childLayer->setStaticInlinePosition(borderAndPaddingStart()); |
+ childLayer->setStaticBlockPosition(borderAndPaddingBefore()); |
+} |
Julien - ping for review
2014/11/24 21:44:40
Do we still need this as we place the items correc
Manuel Rego
2014/12/01 11:10:37
You were right, I've moved it to layoutPositionedO
|
+ |
+void RenderGrid::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info) |
+{ |
+ TrackedRendererListHashSet* positionedDescendants = positionedObjects(); |
+ if (!positionedDescendants) |
+ return; |
+ |
+ bool containerHasHorizontalWritingMode = isHorizontalWritingMode(); |
+ TrackedRendererListHashSet::iterator end = positionedDescendants->end(); |
+ for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) { |
+ RenderBox* child = *it; |
+ |
+ bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != containerHasHorizontalWritingMode; |
+ if (hasOrthogonalWritingMode) { |
+ // FIXME: Properly support orthogonal writing mode. |
+ continue; |
+ } |
+ |
+ LayoutUnit columnBreadth = clientLogicalWidth(); |
+ LayoutUnit columnOffset = offsetAndBreadthForPositionedChild(*child, ForColumns, columnBreadth); |
+ LayoutUnit rowBreadth = clientLogicalHeight(); |
+ LayoutUnit rowOffset = offsetAndBreadthForPositionedChild(*child, ForRows, rowBreadth); |
+ |
+ RenderLayer* childLayer = child->layer(); |
+ childLayer->setStaticInlinePosition(childLayer->staticInlinePosition() + (containerHasHorizontalWritingMode ? columnOffset : rowOffset)); |
+ childLayer->setStaticBlockPosition(childLayer->staticBlockPosition() + (containerHasHorizontalWritingMode ? rowOffset : columnOffset)); |
+ |
+ child->setOverrideContainingBlockContentLogicalWidth(columnBreadth); |
+ child->setOverrideContainingBlockContentLogicalHeight(rowBreadth); |
+ } |
+ |
+ RenderBlock::layoutPositionedObjects(relayoutChildren, info); |
+} |
+ |
+LayoutUnit RenderGrid::offsetAndBreadthForPositionedChild(const RenderBox& child, GridTrackSizingDirection direction, LayoutUnit& breadth) |
+{ |
+ ASSERT(child.isHorizontalWritingMode() == isHorizontalWritingMode()); |
+ |
+ OwnPtr<GridSpan> positions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), child, direction); |
+ if (!positions) |
+ return LayoutUnit(0); |
+ |
+ LayoutUnit offset = LayoutUnit(0); |
+ if ((direction == ForColumns && !child.style()->gridColumnStart().isAuto()) || (direction == ForRows && !child.style()->gridRowStart().isAuto())) { |
+ breadth -= (direction == ForColumns) ? paddingStart() : paddingBefore(); |
+ |
+ GridResolvedPosition firstPosition = GridResolvedPosition(0); |
+ if (positions->resolvedInitialPosition != firstPosition) { |
+ for (GridResolvedPosition position = firstPosition; position < positions->resolvedInitialPosition; ++position) { |
+ LayoutUnit trackBreadth = (direction == ForColumns) ? m_columnPositions[position.toInt() + 1] - m_columnPositions[position.toInt()] : m_rowPositions[position.toInt() + 1] - m_rowPositions[position.toInt()]; |
+ breadth -= trackBreadth; |
+ offset += trackBreadth; |
+ } |
+ } |
+ } |
+ |
+ if ((direction == ForColumns && !child.style()->gridColumnEnd().isAuto()) || (direction == ForRows && !child.style()->gridRowEnd().isAuto())) { |
+ breadth -= (direction == ForColumns) ? paddingEnd() : paddingAfter(); |
+ |
+ GridResolvedPosition lastPosition = GridResolvedPosition(direction == ForColumns ? gridColumnCount() : gridRowCount()); |
+ if (positions->resolvedFinalPosition.next() != lastPosition) { |
+ for (GridResolvedPosition position = positions->resolvedFinalPosition.next(); position < lastPosition; ++position) { |
+ LayoutUnit trackBreadth = (direction == ForColumns) ? m_columnPositions[position.toInt() + 1] - m_columnPositions[position.toInt()] : m_rowPositions[position.toInt() + 1] - m_rowPositions[position.toInt()]; |
+ breadth -= trackBreadth; |
+ } |
+ } |
+ } |
+ |
+ return offset; |
+} |
+ |
GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox& gridItem) const |
{ |
ASSERT(m_gridItemCoordinate.contains(&gridItem)); |