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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 private: | 143 private: |
144 const Vector<Vector<Vector<RenderBox*, 1> > >& m_grid; | 144 const Vector<Vector<Vector<RenderBox*, 1> > >& m_grid; |
145 TrackSizingDirection m_direction; | 145 TrackSizingDirection m_direction; |
146 size_t m_rowIndex; | 146 size_t m_rowIndex; |
147 size_t m_columnIndex; | 147 size_t m_columnIndex; |
148 size_t m_childIndex; | 148 size_t m_childIndex; |
149 }; | 149 }; |
150 | 150 |
151 RenderGrid::RenderGrid(Element* element) | 151 RenderGrid::RenderGrid(Element* element) |
152 : RenderBlock(element) | 152 : RenderBlock(element) |
| 153 , m_gridIsDirty(true) |
153 , m_orderIterator(this) | 154 , m_orderIterator(this) |
154 { | 155 { |
155 // All of our children must be block level. | 156 // All of our children must be block level. |
156 setChildrenInline(false); | 157 setChildrenInline(false); |
157 } | 158 } |
158 | 159 |
159 RenderGrid::~RenderGrid() | 160 RenderGrid::~RenderGrid() |
160 { | 161 { |
161 } | 162 } |
162 | 163 |
| 164 void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild) |
| 165 { |
| 166 RenderBlock::addChild(newChild, beforeChild); |
| 167 |
| 168 if (gridIsDirty()) |
| 169 return; |
| 170 |
| 171 RenderBox* newChildBox = toRenderBox(newChild); |
| 172 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, F
orRows); |
| 173 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox
, ForColumns); |
| 174 if (!rowPositions || !columnPositions) { |
| 175 // The new child requires the auto-placement algorithm to run so we need
to recompute the grid fully. |
| 176 dirtyGrid(); |
| 177 } else { |
| 178 if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCoun
t() <= columnPositions->finalPositionIndex) { |
| 179 // FIXME: We could just insert the new child provided we had a primi
tive to arbitrarily grow the grid. |
| 180 dirtyGrid(); |
| 181 } else { |
| 182 insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *colum
nPositions)); |
| 183 } |
| 184 } |
| 185 } |
| 186 |
| 187 void RenderGrid::removeChild(RenderObject* child) |
| 188 { |
| 189 RenderBlock::removeChild(child); |
| 190 |
| 191 if (gridIsDirty()) |
| 192 return; |
| 193 |
| 194 ASSERT(child->isBox()); |
| 195 // FIXME: We could avoid dirtying the grid in some cases (e.g. if it's an ex
plicitly positioned element). |
| 196 dirtyGrid(); |
| 197 } |
| 198 |
| 199 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
e) |
| 200 { |
| 201 RenderBlock::styleDidChange(diff, oldStyle); |
| 202 if (!oldStyle) |
| 203 return; |
| 204 |
| 205 // FIXME: The following checks could be narrowed down if we kept track of wh
ich type of grid items we have: |
| 206 // - explicit grid size changes impact negative explicitely positioned and a
uto-placed grid items. |
| 207 // - named grid lines only impact grid items with named grid lines. |
| 208 // - auto-flow changes only impacts auto-placed children. |
| 209 |
| 210 if (explicitGridDidResize(oldStyle) |
| 211 || namedGridLinesDefinitionDidChange(oldStyle) |
| 212 || oldStyle->gridAutoFlow() != style()->gridAutoFlow()) |
| 213 dirtyGrid(); |
| 214 } |
| 215 |
| 216 bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const |
| 217 { |
| 218 return oldStyle->gridDefinitionColumns().size() != style()->gridDefinitionCo
lumns().size() |
| 219 || oldStyle->gridDefinitionRows().size() != style()->gridDefinitionRows(
).size(); |
| 220 } |
| 221 |
| 222 bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle)
const |
| 223 { |
| 224 return oldStyle->namedGridRowLines() != style()->namedGridRowLines() |
| 225 || oldStyle->namedGridColumnLines() != style()->namedGridColumnLines(); |
| 226 } |
| 227 |
163 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) | 228 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) |
164 { | 229 { |
165 ASSERT(needsLayout()); | 230 ASSERT(needsLayout()); |
166 | 231 |
167 if (!relayoutChildren && simplifiedLayout()) | 232 if (!relayoutChildren && simplifiedLayout()) |
168 return; | 233 return; |
169 | 234 |
170 // FIXME: Much of this method is boiler plate that matches RenderBox::layout
Block and Render*FlexibleBox::layoutBlock. | 235 // FIXME: Much of this method is boiler plate that matches RenderBox::layout
Block and Render*FlexibleBox::layoutBlock. |
171 // It would be nice to refactor some of the duplicate code. | 236 // It would be nice to refactor some of the duplicate code. |
172 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); | 237 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 const GridTrackSize& trackSize = gridTrackSize(ForColumns, i); | 287 const GridTrackSize& trackSize = gridTrackSize(ForColumns, i); |
223 LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackSize.minTra
ckBreadth(), i); | 288 LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackSize.minTra
ckBreadth(), i); |
224 LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackSize.maxTra
ckBreadth(), i); | 289 LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackSize.maxTra
ckBreadth(), i); |
225 maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth); | 290 maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth); |
226 | 291 |
227 minLogicalWidth += minTrackBreadth; | 292 minLogicalWidth += minTrackBreadth; |
228 maxLogicalWidth += maxTrackBreadth; | 293 maxLogicalWidth += maxTrackBreadth; |
229 | 294 |
230 // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexible
Box). | 295 // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexible
Box). |
231 } | 296 } |
232 | |
233 const_cast<RenderGrid*>(this)->clearGrid(); | |
234 } | 297 } |
235 | 298 |
236 void RenderGrid::computePreferredLogicalWidths() | 299 void RenderGrid::computePreferredLogicalWidths() |
237 { | 300 { |
238 ASSERT(preferredLogicalWidthsDirty()); | 301 ASSERT(preferredLogicalWidthsDirty()); |
239 | 302 |
240 m_minPreferredLogicalWidth = 0; | 303 m_minPreferredLogicalWidth = 0; |
241 m_maxPreferredLogicalWidth = 0; | 304 m_maxPreferredLogicalWidth = 0; |
242 | 305 |
243 // FIXME: We don't take our own logical width into account. Once we do, we n
eed to make sure | 306 // FIXME: We don't take our own logical width into account. Once we do, we n
eed to make sure |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 | 677 |
615 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t co
lumnTrack) | 678 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t co
lumnTrack) |
616 { | 679 { |
617 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil
d, ForRows, rowTrack); | 680 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil
d, ForRows, rowTrack); |
618 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c
hild, ForColumns, columnTrack); | 681 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c
hild, ForColumns, columnTrack); |
619 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); | 682 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); |
620 } | 683 } |
621 | 684 |
622 void RenderGrid::placeItemsOnGrid() | 685 void RenderGrid::placeItemsOnGrid() |
623 { | 686 { |
624 ASSERT(!gridWasPopulated()); | 687 if (!gridIsDirty()) |
| 688 return; |
| 689 |
625 ASSERT(m_gridItemCoordinate.isEmpty()); | 690 ASSERT(m_gridItemCoordinate.isEmpty()); |
626 | 691 |
627 populateExplicitGridAndOrderIterator(); | 692 populateExplicitGridAndOrderIterator(); |
628 | 693 |
| 694 // We clear the dirty bit here as the grid sizes have been updated, this mea
ns |
| 695 // that we can safely call gridRowCount() / gridColumnCount(). |
| 696 m_gridIsDirty = false; |
| 697 |
629 Vector<RenderBox*> autoMajorAxisAutoGridItems; | 698 Vector<RenderBox*> autoMajorAxisAutoGridItems; |
630 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; | 699 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; |
631 GridAutoFlow autoFlow = style()->gridAutoFlow(); | 700 GridAutoFlow autoFlow = style()->gridAutoFlow(); |
632 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { | 701 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { |
633 // FIXME: We never re-resolve positions if the grid is grown during auto
-placement which may lead auto / <integer> | 702 // FIXME: We never re-resolve positions if the grid is grown during auto
-placement which may lead auto / <integer> |
634 // positions to not match the author's intent. The specification is uncl
ear on what should be done in this case. | 703 // positions to not match the author's intent. The specification is uncl
ear on what should be done in this case. |
635 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For
Rows); | 704 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For
Rows); |
636 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child,
ForColumns); | 705 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child,
ForColumns); |
637 if (!rowPositions || !columnPositions) { | 706 if (!rowPositions || !columnPositions) { |
638 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? columnPositions.get() : rowPositions.get(); | 707 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? columnPositions.get() : rowPositions.get(); |
(...skipping 11 matching lines...) Expand all Loading... |
650 | 719 |
651 if (autoFlow == AutoFlowNone) { | 720 if (autoFlow == AutoFlowNone) { |
652 // If we did collect some grid items, they won't be placed thus never la
id out. | 721 // If we did collect some grid items, they won't be placed thus never la
id out. |
653 ASSERT(!autoMajorAxisAutoGridItems.size()); | 722 ASSERT(!autoMajorAxisAutoGridItems.size()); |
654 ASSERT(!specifiedMajorAxisAutoGridItems.size()); | 723 ASSERT(!specifiedMajorAxisAutoGridItems.size()); |
655 return; | 724 return; |
656 } | 725 } |
657 | 726 |
658 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); | 727 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); |
659 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); | 728 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); |
| 729 |
| 730 m_grid.shrinkToFit(); |
660 } | 731 } |
661 | 732 |
662 void RenderGrid::populateExplicitGridAndOrderIterator() | 733 void RenderGrid::populateExplicitGridAndOrderIterator() |
663 { | 734 { |
664 OrderIteratorPopulator populator(m_orderIterator); | 735 OrderIteratorPopulator populator(m_orderIterator); |
665 | 736 |
666 size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount()); | 737 size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount()); |
667 size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount()); | 738 size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount()); |
668 | 739 |
669 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { | 740 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 return (flow == AutoFlowColumn) ? ForColumns : ForRows; | 817 return (flow == AutoFlowColumn) ? ForColumns : ForRows; |
747 } | 818 } |
748 | 819 |
749 RenderGrid::TrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() c
onst | 820 RenderGrid::TrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() c
onst |
750 { | 821 { |
751 GridAutoFlow flow = style()->gridAutoFlow(); | 822 GridAutoFlow flow = style()->gridAutoFlow(); |
752 ASSERT(flow != AutoFlowNone); | 823 ASSERT(flow != AutoFlowNone); |
753 return (flow == AutoFlowColumn) ? ForRows : ForColumns; | 824 return (flow == AutoFlowColumn) ? ForRows : ForColumns; |
754 } | 825 } |
755 | 826 |
756 void RenderGrid::clearGrid() | 827 void RenderGrid::dirtyGrid() |
757 { | 828 { |
758 m_grid.clear(); | 829 m_grid.resize(0); |
759 m_gridItemCoordinate.clear(); | 830 m_gridItemCoordinate.clear(); |
| 831 m_gridIsDirty = true; |
760 } | 832 } |
761 | 833 |
762 void RenderGrid::layoutGridItems() | 834 void RenderGrid::layoutGridItems() |
763 { | 835 { |
764 placeItemsOnGrid(); | 836 placeItemsOnGrid(); |
765 | 837 |
766 Vector<GridTrack> columnTracks(gridColumnCount()); | 838 Vector<GridTrack> columnTracks(gridColumnCount()); |
767 Vector<GridTrack> rowTracks(gridRowCount()); | 839 Vector<GridTrack> rowTracks(gridRowCount()); |
768 computedUsedBreadthOfGridTracks(ForColumns, columnTracks, rowTracks); | 840 computedUsedBreadthOfGridTracks(ForColumns, columnTracks, rowTracks); |
769 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, columnTracks)); | 841 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, columnTracks)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) | 876 if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) |
805 child->repaintDuringLayoutIfMoved(oldChildRect); | 877 child->repaintDuringLayoutIfMoved(oldChildRect); |
806 } | 878 } |
807 | 879 |
808 for (size_t i = 0; i < rowTracks.size(); ++i) | 880 for (size_t i = 0; i < rowTracks.size(); ++i) |
809 setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth); | 881 setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth); |
810 | 882 |
811 // FIXME: We should handle min / max logical height. | 883 // FIXME: We should handle min / max logical height. |
812 | 884 |
813 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); | 885 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); |
814 clearGrid(); | |
815 } | 886 } |
816 | 887 |
817 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const | 888 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const |
818 { | 889 { |
819 ASSERT(m_gridItemCoordinate.contains(gridItem)); | 890 ASSERT(m_gridItemCoordinate.contains(gridItem)); |
820 return m_gridItemCoordinate.get(gridItem); | 891 return m_gridItemCoordinate.get(gridItem); |
821 } | 892 } |
822 | 893 |
823 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB
ox*, TrackSizingDirection, size_t initialPosition) const | 894 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB
ox*, TrackSizingDirection, size_t initialPosition) const |
824 { | 895 { |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 if (isOutOfFlowPositioned()) | 1121 if (isOutOfFlowPositioned()) |
1051 return "RenderGrid (positioned)"; | 1122 return "RenderGrid (positioned)"; |
1052 if (isAnonymous()) | 1123 if (isAnonymous()) |
1053 return "RenderGrid (generated)"; | 1124 return "RenderGrid (generated)"; |
1054 if (isRelPositioned()) | 1125 if (isRelPositioned()) |
1055 return "RenderGrid (relative positioned)"; | 1126 return "RenderGrid (relative positioned)"; |
1056 return "RenderGrid"; | 1127 return "RenderGrid"; |
1057 } | 1128 } |
1058 | 1129 |
1059 } // namespace WebCore | 1130 } // namespace WebCore |
OLD | NEW |