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

Side by Side Diff: 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: Created 5 years, 4 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 | « 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 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 // the grid breadth to account for 'box-sizing'. 1330 // the grid breadth to account for 'box-sizing'.
1331 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit(); 1331 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit();
1332 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit(); 1332 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit();
1333 1333
1334 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChildIncludingAlignmentOffsets(*child, ForColumns, sizingData); 1334 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChildIncludingAlignmentOffsets(*child, ForColumns, sizingData);
1335 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChildIncludingAlignmentOffsets(*child, ForRows, sizingData); 1335 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChildIncludingAlignmentOffsets(*child, ForRows, sizingData);
1336 1336
1337 SubtreeLayoutScope layoutScope(*child); 1337 SubtreeLayoutScope layoutScope(*child);
1338 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight())) 1338 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
1339 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged); 1339 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged);
1340 else
1341 resetAutoMarginsAndLogicalTopInColumnAxis(*child);
1340 1342
1341 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1343 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1342 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1344 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1343 1345
1344 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded 1346 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded
1345 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly 1347 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly
1346 // determine the available space before stretching, are not set yet. 1348 // determine the available space before stretching, are not set yet.
1347 applyStretchAlignmentToChildIfNeeded(*child); 1349 applyStretchAlignmentToChildIfNeeded(*child);
1348 1350
1349 child->layoutIfNeeded(); 1351 child->layoutIfNeeded();
1350 1352
1353 // We need pending layouts to be done in order to compute auto-margins p roperly.
1354 updateAutoMarginsInColumnAxisIfNeeded(*child);
1355 updateAutoMarginsInRowAxisIfNeeded(*child);
1356
1351 #if ENABLE(ASSERT) 1357 #if ENABLE(ASSERT)
1352 const GridCoordinate& coordinate = cachedGridCoordinate(*child); 1358 const GridCoordinate& coordinate = cachedGridCoordinate(*child);
1353 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); 1359 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size());
1354 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); 1360 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size());
1355 #endif 1361 #endif
1356 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); 1362 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
1357 1363
1358 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is 1364 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is
1359 // not visible 1365 // not visible
1360 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight 1366 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); 1658 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight());
1653 if (desiredLogicalHeight != child.logicalHeight()) { 1659 if (desiredLogicalHeight != child.logicalHeight()) {
1654 // 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.
1655 child.setLogicalHeight(0); 1661 child.setLogicalHeight(0);
1656 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 1662 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1657 } 1663 }
1658 } 1664 }
1659 } 1665 }
1660 } 1666 }
1661 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::resetAutoMarginsAndLogicalTopInColumnAxis(LayoutBox& child)
1686 {
1687 if (hasAutoMarginsInColumnAxis(child) || child.needsLayout()) {
1688 child.clearOverrideLogicalContentHeight();
cbiesinger 2015/08/17 23:50:40 Why do you have this line?
jfernandez 2015/08/24 10:28:23 Good you realized about this "obscure" change. The
cbiesinger 2015/08/26 23:07:44 Is your link correct? It does not point to compute
1689 child.updateLogicalHeight();
1690 if (isHorizontalWritingMode()) {
1691 if (child.style()->marginTop().isAuto())
1692 child.setMarginTop(0);
1693 if (child.style()->marginBottom().isAuto())
1694 child.setMarginBottom(0);
1695 } else {
1696 if (child.style()->marginLeft().isAuto())
1697 child.setMarginLeft(0);
1698 if (child.style()->marginRight().isAuto())
1699 child.setMarginRight(0);
1700 }
1701
1702 }
1703 }
1704
1705 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1706 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child)
1707 {
1708 ASSERT(!child.isOutOfFlowPositioned());
1709
1710 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalWidth() - child.logicalWidth();
1711 if (availableAlignmentSpace <= 0)
1712 return;
1713
1714 bool isHorizontal = isHorizontalWritingMode();
1715 Length topOrLeft = isHorizontal ? child.style()->marginLeft() : child.style( )->marginTop();
1716 Length bottomOrRight = isHorizontal ? child.style()->marginRight() : child.s tyle()->marginBottom();
1717 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) {
1718 if (isHorizontal) {
1719 child.setMarginLeft(availableAlignmentSpace / 2);
1720 child.setMarginRight(availableAlignmentSpace / 2);
1721 } else {
1722 child.setMarginTop(availableAlignmentSpace / 2);
1723 child.setMarginBottom(availableAlignmentSpace / 2);
1724 }
1725 } else if (topOrLeft.isAuto()) {
1726 if (isHorizontal)
1727 child.setMarginLeft(availableAlignmentSpace);
1728 else
1729 child.setMarginTop(availableAlignmentSpace);
1730 } else if (bottomOrRight.isAuto()) {
1731 if (isHorizontal)
1732 child.setMarginRight(availableAlignmentSpace);
1733 else
1734 child.setMarginBottom(availableAlignmentSpace);
1735 }
1736 }
1737
1738 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1739 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child)
1740 {
1741 ASSERT(!child.isOutOfFlowPositioned());
1742
1743 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalHeight() - child.logicalHeight();
1744 if (availableAlignmentSpace <= 0)
1745 return;
1746
1747 bool isHorizontal = isHorizontalWritingMode();
1748 Length topOrLeft = isHorizontal ? child.style()->marginTop() : child.style() ->marginLeft();
1749 Length bottomOrRight = isHorizontal ? child.style()->marginBottom() : child. style()->marginRight();
1750 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) {
1751 if (isHorizontal) {
1752 child.setMarginTop(availableAlignmentSpace / 2);
1753 child.setMarginBottom(availableAlignmentSpace / 2);
1754 } else {
1755 child.setMarginLeft(availableAlignmentSpace / 2);
1756 child.setMarginRight(availableAlignmentSpace / 2);
1757 }
1758 } else if (topOrLeft.isAuto()) {
1759 if (isHorizontal)
1760 child.setMarginTop(availableAlignmentSpace);
1761 else
1762 child.setMarginLeft(availableAlignmentSpace);
1763 } else if (bottomOrRight.isAuto()) {
1764 if (isHorizontal)
1765 child.setMarginBottom(availableAlignmentSpace);
1766 else
1767 child.setMarginRight(availableAlignmentSpace);
1768 }
1769 }
1770
1662 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const 1771 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const
1663 { 1772 {
1664 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); 1773 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1665 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); 1774 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode();
1666 1775
1667 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { 1776 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) {
1668 case ItemPositionSelfStart: 1777 case ItemPositionSelfStart:
1669 // If orthogonal writing-modes, this computes to 'start'. 1778 // If orthogonal writing-modes, this computes to 'start'.
1670 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. 1779 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet.
1671 // 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. 1780 // 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
1749 1858
1750 ASSERT_NOT_REACHED(); 1859 ASSERT_NOT_REACHED();
1751 return GridAxisStart; 1860 return GridAxisStart;
1752 } 1861 }
1753 1862
1754 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const 1863 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const
1755 { 1864 {
1756 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1865 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1757 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; 1866 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()];
1758 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 1867 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1868 if (hasAutoMarginsInColumnAxis(child))
1869 return startPosition;
1759 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 1870 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1760 switch (axisPosition) { 1871 switch (axisPosition) {
1761 case GridAxisStart: 1872 case GridAxisStart:
1762 return startPosition; 1873 return startPosition;
1763 case GridAxisEnd: 1874 case GridAxisEnd:
1764 case GridAxisCenter: { 1875 case GridAxisCenter: {
1765 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; 1876 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()];
1766 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); 1877 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight());
1767 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1878 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1768 } 1879 }
1769 } 1880 }
1770 1881
1771 ASSERT_NOT_REACHED(); 1882 ASSERT_NOT_REACHED();
1772 return 0; 1883 return 0;
1773 } 1884 }
1774 1885
1775 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const 1886 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const
1776 { 1887 {
1777 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1888 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1778 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; 1889 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()];
1779 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 1890 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1891 if (hasAutoMarginsInRowAxis(child))
1892 return startPosition;
1780 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 1893 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1781 switch (axisPosition) { 1894 switch (axisPosition) {
1782 case GridAxisStart: 1895 case GridAxisStart:
1783 return startPosition; 1896 return startPosition;
1784 case GridAxisEnd: 1897 case GridAxisEnd:
1785 case GridAxisCenter: { 1898 case GridAxisCenter: {
1786 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; 1899 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()];
1787 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); 1900 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth());
1788 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1901 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1789 } 1902 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 2032
1920 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); 2033 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child));
1921 } 2034 }
1922 2035
1923 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) 2036 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset)
1924 { 2037 {
1925 GridPainter(*this).paintChildren(paintInfo, paintOffset); 2038 GridPainter(*this).paintChildren(paintInfo, paintOffset);
1926 } 2039 }
1927 2040
1928 } // namespace blink 2041 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698