Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutGrid.cpp

Issue 1298623002: [CSS Grid Layout] Implement auto-margins alignment of grid items (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Using start/end and before/after logical terms. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1348 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1349 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1349 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1350 1350
1351 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded 1351 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded
1352 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly 1352 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly
1353 // determine the available space before stretching, are not set yet. 1353 // determine the available space before stretching, are not set yet.
1354 applyStretchAlignmentToChildIfNeeded(*child); 1354 applyStretchAlignmentToChildIfNeeded(*child);
1355 1355
1356 child->layoutIfNeeded(); 1356 child->layoutIfNeeded();
1357 1357
1358 // We need pending layouts to be done in order to compute auto-margins p roperly.
1359 updateAutoMarginsInColumnAxisIfNeeded(*child);
1360 updateAutoMarginsInRowAxisIfNeeded(*child);
1361
1358 #if ENABLE(ASSERT) 1362 #if ENABLE(ASSERT)
1359 const GridCoordinate& coordinate = cachedGridCoordinate(*child); 1363 const GridCoordinate& coordinate = cachedGridCoordinate(*child);
1360 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); 1364 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size());
1361 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); 1365 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size());
1362 #endif 1366 #endif
1363 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); 1367 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
1364 1368
1365 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is 1369 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is
1366 // not visible 1370 // not visible
1367 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight 1371 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 LayoutUnit marginAfter; 1608 LayoutUnit marginAfter;
1605 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, 1609 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter,
1606 child.style()->marginBeforeUsing(style()), 1610 child.style()->marginBeforeUsing(style()),
1607 child.style()->marginAfterUsing(style())); 1611 child.style()->marginAfterUsing(style()));
1608 1612
1609 return marginBefore + marginAfter; 1613 return marginBefore + marginAfter;
1610 } 1614 }
1611 1615
1612 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const 1616 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const
1613 { 1617 {
1614 LayoutUnit childMarginLogicalHeight = marginLogicalHeightForChild(child);
1615
1616 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before 1618 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before
1617 // children are laid out, so we can't use the child cached values. Hence, we need to 1619 // children are laid out, so we can't use the child cached values. Hence, we need to
1618 // compute margins in order to determine the available height before stretch ing. 1620 // compute margins in order to determine the available height before stretch ing.
1619 if (childMarginLogicalHeight == 0) 1621 return gridAreaBreadthForChild - (child.needsLayout() ? computeMarginLogical HeightForChild(child) : marginLogicalHeightForChild(child));
1620 childMarginLogicalHeight = computeMarginLogicalHeightForChild(child);
1621
1622 return gridAreaBreadthForChild - childMarginLogicalHeight;
1623 } 1622 }
1624 1623
1625 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox. 1624 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox.
1626 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) 1625 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child)
1627 { 1626 {
1628 // We clear both width and height override values because we will decide now whether they 1627 // We clear both width and height override values because we will decide now whether they
1629 // are allowed or not, evaluating the conditions which might have changed si nce the old 1628 // are allowed or not, evaluating the conditions which might have changed si nce the old
1630 // values were set. 1629 // values were set.
1631 child.clearOverrideSize(); 1630 child.clearOverrideSize();
1632 1631
(...skipping 26 matching lines...) Expand all
1659 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); 1658 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight());
1660 if (desiredLogicalHeight != child.logicalHeight()) { 1659 if (desiredLogicalHeight != child.logicalHeight()) {
1661 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905. 1660 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905.
1662 child.setLogicalHeight(0); 1661 child.setLogicalHeight(0);
1663 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 1662 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1664 } 1663 }
1665 } 1664 }
1666 } 1665 }
1667 } 1666 }
1668 1667
1668 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1669 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const
1670 {
1671 if (isHorizontalWritingMode())
1672 return child.style()->marginTop().isAuto() || child.style()->marginBotto m().isAuto();
1673 return child.style()->marginLeft().isAuto() || child.style()->marginRight(). isAuto();
1674 }
1675
1676 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1677 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const
1678 {
1679 if (isHorizontalWritingMode())
1680 return child.style()->marginLeft().isAuto() || child.style()->marginRigh t().isAuto();
1681 return child.style()->marginTop().isAuto() || child.style()->marginBottom(). isAuto();
1682 }
1683
1684 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1685 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child)
1686 {
1687 ASSERT(!child.isOutOfFlowPositioned());
1688
1689 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalWidth() - child.logicalWidth();
1690 if (availableAlignmentSpace <= 0)
1691 return;
1692
1693 Length marginStart = child.style()->marginStartUsing(style());
1694 Length marginEnd = child.style()->marginEndUsing(style());
1695 if (marginStart.isAuto() && marginEnd.isAuto()) {
1696 child.setMarginStart(availableAlignmentSpace / 2, style());
1697 child.setMarginEnd(availableAlignmentSpace / 2, style());
1698 } else if (marginStart.isAuto()) {
1699 child.setMarginStart(availableAlignmentSpace, style());
1700 } else if (marginEnd.isAuto()) {
1701 child.setMarginEnd(availableAlignmentSpace, style());
1702 }
1703 }
1704
1705 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1706 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child)
1707 {
1708 ASSERT(!child.isOutOfFlowPositioned());
1709
1710 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalHeight() - child.logicalHeight();
1711 if (availableAlignmentSpace <= 0)
1712 return;
1713
1714 Length marginBefore = child.style()->marginBeforeUsing(style());
1715 Length marginAfter = child.style()->marginAfterUsing(style());
1716 if (marginBefore.isAuto() && marginAfter.isAuto()) {
1717 child.setMarginBefore(availableAlignmentSpace / 2, style());
1718 child.setMarginAfter(availableAlignmentSpace / 2, style());
1719 } else if (marginBefore.isAuto()) {
1720 child.setMarginBefore(availableAlignmentSpace, style());
1721 } else if (marginAfter.isAuto()) {
1722 child.setMarginAfter(availableAlignmentSpace, style());
1723 }
1724 }
1725
1669 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const 1726 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const
1670 { 1727 {
1671 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); 1728 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1672 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); 1729 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode();
1673 1730
1674 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { 1731 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) {
1675 case ItemPositionSelfStart: 1732 case ItemPositionSelfStart:
1676 // If orthogonal writing-modes, this computes to 'start'. 1733 // If orthogonal writing-modes, this computes to 'start'.
1677 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. 1734 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet.
1678 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow. 1735 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 1813
1757 ASSERT_NOT_REACHED(); 1814 ASSERT_NOT_REACHED();
1758 return GridAxisStart; 1815 return GridAxisStart;
1759 } 1816 }
1760 1817
1761 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const 1818 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const
1762 { 1819 {
1763 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1820 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1764 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; 1821 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()];
1765 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 1822 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1823 if (hasAutoMarginsInColumnAxis(child))
1824 return startPosition;
1766 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 1825 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1767 switch (axisPosition) { 1826 switch (axisPosition) {
1768 case GridAxisStart: 1827 case GridAxisStart:
1769 return startPosition; 1828 return startPosition;
1770 case GridAxisEnd: 1829 case GridAxisEnd:
1771 case GridAxisCenter: { 1830 case GridAxisCenter: {
1772 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; 1831 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()];
1773 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); 1832 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight());
1774 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1833 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1775 } 1834 }
1776 } 1835 }
1777 1836
1778 ASSERT_NOT_REACHED(); 1837 ASSERT_NOT_REACHED();
1779 return 0; 1838 return 0;
1780 } 1839 }
1781 1840
1782 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const 1841 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const
1783 { 1842 {
1784 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1843 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1785 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; 1844 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()];
1786 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 1845 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1846 if (hasAutoMarginsInRowAxis(child))
1847 return startPosition;
1787 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 1848 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1788 switch (axisPosition) { 1849 switch (axisPosition) {
1789 case GridAxisStart: 1850 case GridAxisStart:
1790 return startPosition; 1851 return startPosition;
1791 case GridAxisEnd: 1852 case GridAxisEnd:
1792 case GridAxisCenter: { 1853 case GridAxisCenter: {
1793 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; 1854 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()];
1794 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); 1855 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth());
1795 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1856 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1796 } 1857 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 1987
1927 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); 1988 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child));
1928 } 1989 }
1929 1990
1930 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) 1991 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset)
1931 { 1992 {
1932 GridPainter(*this).paintChildren(paintInfo, paintOffset); 1993 GridPainter(*this).paintChildren(paintInfo, paintOffset);
1933 } 1994 }
1934 1995
1935 } // namespace blink 1996 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698