void GridResolvedPosition::initialAndFinalPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition) { initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnStart() : gridItem.style()->gridRowStart(); finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd() : gridItem.style()->gridRowEnd(); GridPositionSide initialPositionSide = calculateInitialPositionSide(direction); GridPositionSide finalPositionSide = calculateFinalPositionSide(direction); // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to // overwrite the specified values. if (initialPosition.isSpan() && finalPosition.isSpan()) finalPosition.setAutoPosition(); // Try to early detect the case of non existing named grid lines. This way we could assume later that // GridResolvedPosition::resolveGrisPositionFromStyle() always return a valid resolved position. if (initialPosition.isNamedGridArea() && !isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide)) initialPosition.setAutoPosition(); if (finalPosition.isNamedGridArea() && !isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide)) finalPosition.setAutoPosition(); // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one. if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull()) finalPosition.setSpanPosition(1, String()); if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull()) initialPosition.setSpanPosition(1, String()); }
static void adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition) { bool isForColumns = direction == ForColumns; initialPosition = isForColumns ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); finalPosition = isForColumns ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to // overwrite the specified values. if (initialPosition.isSpan() && finalPosition.isSpan()) finalPosition.setAutoPosition(); if (gridItem.isOutOfFlowPositioned()) { // Early detect the case of non existing named grid lines for positioned items. if (initialPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide(direction))) initialPosition.setAutoPosition(); if (finalPosition.isNamedGridArea() && !NamedLineCollection::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide(direction))) finalPosition.setAutoPosition(); } // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one. if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull()) finalPosition.setSpanPosition(1, String()); if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull()) initialPosition.setSpanPosition(1, String()); }
PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) { GridPosition initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnStart() : gridItem.style()->gridRowStart(); const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; GridPosition finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd() : gridItem.style()->gridRowEnd(); const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to // overwrite the specified values. if (initialPosition.isSpan() && finalPosition.isSpan()) finalPosition.setAutoPosition(); if (initialPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea().contains(initialPosition.namedGridLine())) initialPosition.setAutoPosition(); if (finalPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea().contains(finalPosition.namedGridLine())) finalPosition.setAutoPosition(); if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) { if (gridContainerStyle.gridAutoFlow() == AutoFlowNone) return adoptPtr(new GridSpan(0, 0)); // We can't get our grid positions without running the auto placement algorithm. return nullptr; } if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case). GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialPositionSide); } if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). GridResolvedPosition initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalPositionSide); } GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); // If 'grid-after' specifies a line at or before that specified by 'grid-before', it computes to 'span 1'. if (resolvedFinalPosition < resolvedInitialPosition) resolvedFinalPosition = resolvedInitialPosition; return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition)); }
static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) { ASSERT(position.isSpan()); ASSERT(!position.namedGridLine().isNull()); // Negative positions are not allowed per the specification and should have been handled during parsing. ASSERT(position.spanPosition() > 0); unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount); NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount); return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, lastLine, linesCollection); }
GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition) { GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart(); const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd(); const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide); // This method will only be used when both positions need to be resolved against the opposite one. ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()); GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition; if (initialPosition.isSpan()) resolvedFinalPosition = resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalPositionSide)->resolvedFinalPosition; else if (finalPosition.isSpan()) resolvedFinalPosition = resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalPositionSide)->resolvedFinalPosition; return GridSpan(resolvedInitialPosition, resolvedFinalPosition); }
void GridResolvedPosition::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, GridPosition& initialPosition, GridPosition& finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide) { ASSERT(isColumnSide(initialPositionSide) == isColumnSide(finalPositionSide)); // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to // overwrite the specified values. if (initialPosition.isSpan() && finalPosition.isSpan()) finalPosition.setAutoPosition(); // Try to early detect the case of non existing named grid lines. This way we could assume later that // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the autoplacement to run, i.e., it'll always return a // valid resolved position. if (initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide)) initialPosition.setAutoPosition(); if (finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide)) finalPosition.setAutoPosition(); // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one. if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull()) finalPosition.setSpanPosition(1, String()); if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull()) initialPosition.setSpanPosition(1, String()); }
PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) { if (position.isAuto()) return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition); ASSERT(position.isSpan()); ASSERT(position.spanPosition() > 0); if (!position.namedGridLine().isNull()) { // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side); } return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, position, side); }
unsigned GridPositionsResolver::spanSizeForAutoPlacedItem(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) { GridPosition initialPosition, finalPosition; adjustGridPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition); // This method will only be used when both positions need to be resolved against the opposite one. ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()); if (initialPosition.isAuto() && finalPosition.isAuto()) return 1; GridPosition position = initialPosition.isSpan() ? initialPosition : finalPosition; ASSERT(position.isSpan()); ASSERT(position.spanPosition()); return position.spanPosition(); }
PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) { ASSERT(position.isSpan()); ASSERT(!position.namedGridLine().isNull()); // Negative positions are not allowed per the specification and should have been handled during parsing. ASSERT(position.spanPosition() > 0); const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines(); NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case). // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html. if (it == gridLinesNames.end()) return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition); return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value); }
GridSpan GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) { if (position.isAuto()) { if ((side == ColumnStartSide || side == RowStartSide) && resolvedOppositePosition.toInt()) return GridSpan::definiteGridSpan(resolvedOppositePosition.prev(), resolvedOppositePosition); return GridSpan::definiteGridSpan(resolvedOppositePosition, resolvedOppositePosition.next()); } ASSERT(position.isSpan()); ASSERT(position.spanPosition() > 0); if (!position.namedGridLine().isNull()) { // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side); } return GridSpan::definiteGridSpanWithSpanAgainstOpposite(resolvedOppositePosition, position, side); }
std::unique_ptr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side) { if (position.isAuto()) return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition); ASSERT(position.isSpan()); ASSERT(position.spanPosition() > 0); if (!position.namedGridLine().isNull()) { // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side); } // 'span 1' is contained inside a single grid track regardless of the direction. // That's why the CSS span value is one more than the offset we apply. size_t positionOffset = position.spanPosition() - 1; if (isStartSide(side)) { size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset); return std::make_unique<GridSpan>(initialResolvedPosition, resolvedOppositePosition); } return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset); }
static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount) { if (position.isAuto()) { if (isStartSide(side)) return GridSpan::untranslatedDefiniteGridSpan(oppositeLine - 1, oppositeLine); return GridSpan::untranslatedDefiniteGridSpan(oppositeLine, oppositeLine + 1); } ASSERT(position.isSpan()); ASSERT(position.spanPosition() > 0); if (!position.namedGridLine().isNull()) { // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position. return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side, autoRepeatTracksCount); } // 'span 1' is contained inside a single grid track regardless of the direction. // That's why the CSS span value is one more than the offset we apply. unsigned positionOffset = position.spanPosition(); if (isStartSide(side)) return GridSpan::untranslatedDefiniteGridSpan(oppositeLine - positionOffset, oppositeLine); return GridSpan::untranslatedDefiniteGridSpan(oppositeLine, oppositeLine + positionOffset); }