OLD | NEW |
---|---|
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 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1345 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); | 1345 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); |
1346 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); | 1346 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); |
1347 | 1347 |
1348 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded | 1348 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded |
1349 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly | 1349 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly |
1350 // determine the available space before stretching, are not set yet. | 1350 // determine the available space before stretching, are not set yet. |
1351 applyStretchAlignmentToChildIfNeeded(*child); | 1351 applyStretchAlignmentToChildIfNeeded(*child); |
1352 | 1352 |
1353 child->layoutIfNeeded(); | 1353 child->layoutIfNeeded(); |
1354 | 1354 |
1355 // We need pending layouts to be done in order to compute auto-margins p roperly. | |
Manuel Rego
2015/09/24 11:38:26
Probably we could add an ASSERT in the methods
to
jfernandez
2015/09/25 13:47:02
Acknowledged.
| |
1356 updateAutoMarginsInColumnAxisIfNeeded(*child); | |
1357 updateAutoMarginsInRowAxisIfNeeded(*child); | |
1358 | |
1355 #if ENABLE(ASSERT) | 1359 #if ENABLE(ASSERT) |
1356 const GridCoordinate& coordinate = cachedGridCoordinate(*child); | 1360 const GridCoordinate& coordinate = cachedGridCoordinate(*child); |
1357 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); | 1361 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); |
1358 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); | 1362 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); |
1359 #endif | 1363 #endif |
1360 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 1364 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
1361 | 1365 |
1362 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is | 1366 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is |
1363 // not visible | 1367 // not visible |
1364 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 1368 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1601 LayoutUnit marginAfter; | 1605 LayoutUnit marginAfter; |
1602 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, | 1606 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, |
1603 child.style()->marginBeforeUsing(style()), | 1607 child.style()->marginBeforeUsing(style()), |
1604 child.style()->marginAfterUsing(style())); | 1608 child.style()->marginAfterUsing(style())); |
1605 | 1609 |
1606 return marginBefore + marginAfter; | 1610 return marginBefore + marginAfter; |
1607 } | 1611 } |
1608 | 1612 |
1609 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const | 1613 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const |
1610 { | 1614 { |
1611 LayoutUnit childMarginLogicalHeight = marginLogicalHeightForChild(child); | |
1612 | |
1613 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before | 1615 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before |
1614 // children are laid out, so we can't use the child cached values. Hence, we need to | 1616 // children are laid out, so we can't use the child cached values. Hence, we need to |
1615 // compute margins in order to determine the available height before stretch ing. | 1617 // compute margins in order to determine the available height before stretch ing. |
1616 if (childMarginLogicalHeight == 0) | 1618 return gridAreaBreadthForChild - (child.needsLayout() ? computeMarginLogical HeightForChild(child) : marginLogicalHeightForChild(child)); |
1617 childMarginLogicalHeight = computeMarginLogicalHeightForChild(child); | |
1618 | |
1619 return gridAreaBreadthForChild - childMarginLogicalHeight; | |
1620 } | 1619 } |
1621 | 1620 |
1622 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox. | 1621 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox. |
1623 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) | 1622 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) |
1624 { | 1623 { |
1625 // We clear both width and height override values because we will decide now whether they | 1624 // We clear both width and height override values because we will decide now whether they |
1626 // are allowed or not, evaluating the conditions which might have changed si nce the old | 1625 // are allowed or not, evaluating the conditions which might have changed si nce the old |
1627 // values were set. | 1626 // values were set. |
1628 child.clearOverrideSize(); | 1627 child.clearOverrideSize(); |
1629 | 1628 |
(...skipping 26 matching lines...) Expand all Loading... | |
1656 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); | 1655 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); |
1657 if (desiredLogicalHeight != child.logicalHeight()) { | 1656 if (desiredLogicalHeight != child.logicalHeight()) { |
1658 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905. | 1657 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905. |
1659 child.setLogicalHeight(0); | 1658 child.setLogicalHeight(0); |
1660 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1659 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
1661 } | 1660 } |
1662 } | 1661 } |
1663 } | 1662 } |
1664 } | 1663 } |
1665 | 1664 |
1665 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
1666 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const | |
1667 { | |
1668 if (isHorizontalWritingMode()) | |
1669 return child.style()->marginTop().isAuto() || child.style()->marginBotto m().isAuto(); | |
1670 return child.style()->marginLeft().isAuto() || child.style()->marginRight(). isAuto(); | |
1671 } | |
1672 | |
1673 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
1674 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const | |
1675 { | |
1676 if (isHorizontalWritingMode()) | |
1677 return child.style()->marginLeft().isAuto() || child.style()->marginRigh t().isAuto(); | |
1678 return child.style()->marginTop().isAuto() || child.style()->marginBottom(). isAuto(); | |
1679 } | |
1680 | |
1681 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
1682 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) | |
1683 { | |
1684 ASSERT(!child.isOutOfFlowPositioned()); | |
1685 | |
1686 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalWidth() - child.logicalWidth(); | |
1687 if (availableAlignmentSpace <= 0) | |
1688 return; | |
1689 | |
1690 bool isHorizontal = isHorizontalWritingMode(); | |
1691 Length topOrLeft = isHorizontal ? child.style()->marginLeft() : child.style( )->marginTop(); | |
Manuel Rego
2015/09/24 11:38:26
To simplify the code and all the checks related to
jfernandez
2015/09/25 13:47:02
I think it wouldn't be an equivalent logic. Be awa
Manuel Rego
2015/09/25 16:00:58
BTW, I was thinking in style()->marginStart()
whic
| |
1692 Length bottomOrRight = isHorizontal ? child.style()->marginRight() : child.s tyle()->marginBottom(); | |
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
1693 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) { | |
1694 if (isHorizontal) { | |
1695 child.setMarginLeft(availableAlignmentSpace / 2); | |
1696 child.setMarginRight(availableAlignmentSpace / 2); | |
1697 } else { | |
1698 child.setMarginTop(availableAlignmentSpace / 2); | |
1699 child.setMarginBottom(availableAlignmentSpace / 2); | |
1700 } | |
Manuel Rego
2015/09/24 11:38:27
Probably here you could use setMarginStart().
jfernandez
2015/09/25 13:47:02
This could be true, but I'm not sure whether it'd
| |
1701 } else if (topOrLeft.isAuto()) { | |
1702 if (isHorizontal) | |
1703 child.setMarginLeft(availableAlignmentSpace); | |
1704 else | |
1705 child.setMarginTop(availableAlignmentSpace); | |
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
1706 } else if (bottomOrRight.isAuto()) { | |
1707 if (isHorizontal) | |
1708 child.setMarginRight(availableAlignmentSpace); | |
1709 else | |
1710 child.setMarginBottom(availableAlignmentSpace); | |
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
1711 } | |
1712 } | |
1713 | |
1714 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
1715 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) | |
1716 { | |
1717 ASSERT(!child.isOutOfFlowPositioned()); | |
1718 | |
1719 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalHeight() - child.logicalHeight(); | |
1720 if (availableAlignmentSpace <= 0) | |
1721 return; | |
1722 | |
1723 bool isHorizontal = isHorizontalWritingMode(); | |
1724 Length topOrLeft = isHorizontal ? child.style()->marginTop() : child.style() ->marginLeft(); | |
Manuel Rego
2015/09/24 11:38:26
The same than in the row axis method.
jfernandez
2015/09/25 13:47:02
Replied.
| |
1725 Length bottomOrRight = isHorizontal ? child.style()->marginBottom() : child. style()->marginRight(); | |
1726 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) { | |
1727 if (isHorizontal) { | |
1728 child.setMarginTop(availableAlignmentSpace / 2); | |
1729 child.setMarginBottom(availableAlignmentSpace / 2); | |
1730 } else { | |
1731 child.setMarginLeft(availableAlignmentSpace / 2); | |
1732 child.setMarginRight(availableAlignmentSpace / 2); | |
1733 } | |
1734 } else if (topOrLeft.isAuto()) { | |
1735 if (isHorizontal) | |
1736 child.setMarginTop(availableAlignmentSpace); | |
1737 else | |
1738 child.setMarginLeft(availableAlignmentSpace); | |
1739 } else if (bottomOrRight.isAuto()) { | |
1740 if (isHorizontal) | |
1741 child.setMarginBottom(availableAlignmentSpace); | |
1742 else | |
1743 child.setMarginRight(availableAlignmentSpace); | |
1744 } | |
1745 } | |
1746 | |
1666 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const | 1747 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const |
1667 { | 1748 { |
1668 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); | 1749 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); |
1669 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); | 1750 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); |
1670 | 1751 |
1671 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { | 1752 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { |
1672 case ItemPositionSelfStart: | 1753 case ItemPositionSelfStart: |
1673 // If orthogonal writing-modes, this computes to 'start'. | 1754 // If orthogonal writing-modes, this computes to 'start'. |
1674 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. | 1755 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. |
1675 // 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. | 1756 // 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 Loading... | |
1753 | 1834 |
1754 ASSERT_NOT_REACHED(); | 1835 ASSERT_NOT_REACHED(); |
1755 return GridAxisStart; | 1836 return GridAxisStart; |
1756 } | 1837 } |
1757 | 1838 |
1758 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const | 1839 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const |
1759 { | 1840 { |
1760 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1841 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1761 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; | 1842 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; |
1762 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); | 1843 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); |
1844 if (hasAutoMarginsInColumnAxis(child)) | |
1845 return startPosition; | |
1763 GridAxisPosition axisPosition = columnAxisPositionForChild(child); | 1846 GridAxisPosition axisPosition = columnAxisPositionForChild(child); |
1764 switch (axisPosition) { | 1847 switch (axisPosition) { |
1765 case GridAxisStart: | 1848 case GridAxisStart: |
1766 return startPosition; | 1849 return startPosition; |
1767 case GridAxisEnd: | 1850 case GridAxisEnd: |
1768 case GridAxisCenter: { | 1851 case GridAxisCenter: { |
1769 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; | 1852 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; |
1770 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); | 1853 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); |
1771 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); | 1854 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); |
1772 } | 1855 } |
1773 } | 1856 } |
1774 | 1857 |
1775 ASSERT_NOT_REACHED(); | 1858 ASSERT_NOT_REACHED(); |
1776 return 0; | 1859 return 0; |
1777 } | 1860 } |
1778 | 1861 |
1779 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const | 1862 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const |
1780 { | 1863 { |
1781 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1864 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1782 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; | 1865 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; |
1783 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); | 1866 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); |
1867 if (hasAutoMarginsInRowAxis(child)) | |
1868 return startPosition; | |
1784 GridAxisPosition axisPosition = rowAxisPositionForChild(child); | 1869 GridAxisPosition axisPosition = rowAxisPositionForChild(child); |
1785 switch (axisPosition) { | 1870 switch (axisPosition) { |
1786 case GridAxisStart: | 1871 case GridAxisStart: |
1787 return startPosition; | 1872 return startPosition; |
1788 case GridAxisEnd: | 1873 case GridAxisEnd: |
1789 case GridAxisCenter: { | 1874 case GridAxisCenter: { |
1790 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; | 1875 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; |
1791 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); | 1876 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); |
1792 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); | 1877 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); |
1793 } | 1878 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1923 | 2008 |
1924 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 2009 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
1925 } | 2010 } |
1926 | 2011 |
1927 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) | 2012 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) |
1928 { | 2013 { |
1929 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 2014 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
1930 } | 2015 } |
1931 | 2016 |
1932 } // namespace blink | 2017 } // namespace blink |
OLD | NEW |