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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 , m_orderIterator(this) | 153 , m_orderIterator(this) |
154 { | 154 { |
155 // All of our children must be block level. | 155 // All of our children must be block level. |
156 setChildrenInline(false); | 156 setChildrenInline(false); |
157 } | 157 } |
158 | 158 |
159 RenderGrid::~RenderGrid() | 159 RenderGrid::~RenderGrid() |
160 { | 160 { |
161 } | 161 } |
162 | 162 |
163 void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild) | |
164 { | |
165 RenderBlock::addChild(newChild, beforeChild); | |
166 | |
167 if (gridIsDirty() || !newChild->isBox()) | |
ojan
2013/07/30 23:18:57
Don't we force the children to be boxes? Can the s
Julien - ping for review
2013/07/30 23:57:42
Good catch, it seems to be the case.
| |
168 return; | |
169 | |
170 RenderBox* newChildBox = toRenderBox(newChild); | |
171 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, F orRows); | |
172 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox , ForColumns); | |
173 if (!rowPositions || !columnPositions) { | |
174 // The new child requires the auto-placement algorithm to run so we need to recompute the grid fully. | |
175 dirtyGrid(); | |
176 } else { | |
177 if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCoun t() <= columnPositions->finalPositionIndex) { | |
178 // FIXME: We could just insert the new child provided we had a primi tive to arbitrarily grow the grid. | |
179 dirtyGrid(); | |
180 } else { | |
181 insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *colum nPositions)); | |
182 } | |
183 } | |
184 } | |
185 | |
186 void RenderGrid::removeChild(RenderObject* child) | |
187 { | |
188 RenderBlock::removeChild(child); | |
189 | |
190 if (gridIsDirty() || !child->isBox()) | |
ojan
2013/07/30 23:18:57
Ditto.
| |
191 return; | |
192 | |
193 // FIXME: We could avoid dirtying the grid in some cases (e.g. if it's an ex plicitly positioned element). | |
194 dirtyGrid(); | |
195 } | |
196 | |
197 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl e) | |
198 { | |
199 RenderBlock::styleDidChange(diff, oldStyle); | |
200 if (!oldStyle) | |
201 return; | |
202 | |
203 // FIXME: The following checks could be narrowed down if we kept track of wh ich type of grid items we have: | |
204 // - explicit grid size changes impact negative explicitely positioned and a uto-placed grid items. | |
205 // - named grid lines only impact grid items with named grid lines. | |
206 // - auto-flow changes only impacts auto-placed children. | |
207 | |
208 if (explicitGridDidResize(oldStyle) | |
209 || namedGridLinesDefinitionDidChange(oldStyle) | |
210 || oldStyle->gridAutoFlow() != style()->gridAutoFlow()) | |
211 dirtyGrid(); | |
212 } | |
213 | |
214 bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const | |
215 { | |
216 return oldStyle->gridDefinitionColumns().size() != style()->gridDefinitionCo lumns().size() | |
217 || oldStyle->gridDefinitionRows().size() != style()->gridDefinitionRows( ).size(); | |
218 } | |
219 | |
220 bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle) const | |
221 { | |
222 return oldStyle->namedGridRowLines() != style()->namedGridRowLines() | |
223 || oldStyle->namedGridColumnLines() != style()->namedGridColumnLines(); | |
224 } | |
225 | |
163 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) | 226 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) |
164 { | 227 { |
165 ASSERT(needsLayout()); | 228 ASSERT(needsLayout()); |
166 | 229 |
167 if (!relayoutChildren && simplifiedLayout()) | 230 if (!relayoutChildren && simplifiedLayout()) |
168 return; | 231 return; |
169 | 232 |
170 // FIXME: Much of this method is boiler plate that matches RenderBox::layout Block and Render*FlexibleBox::layoutBlock. | 233 // 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. | 234 // It would be nice to refactor some of the duplicate code. |
172 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); | 235 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 const GridTrackSize& trackSize = gridTrackSize(ForColumns, i); | 285 const GridTrackSize& trackSize = gridTrackSize(ForColumns, i); |
223 LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackSize.minTra ckBreadth(), i); | 286 LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackSize.minTra ckBreadth(), i); |
224 LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackSize.maxTra ckBreadth(), i); | 287 LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackSize.maxTra ckBreadth(), i); |
225 maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth); | 288 maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth); |
226 | 289 |
227 minLogicalWidth += minTrackBreadth; | 290 minLogicalWidth += minTrackBreadth; |
228 maxLogicalWidth += maxTrackBreadth; | 291 maxLogicalWidth += maxTrackBreadth; |
229 | 292 |
230 // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexible Box). | 293 // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexible Box). |
231 } | 294 } |
232 | |
233 const_cast<RenderGrid*>(this)->clearGrid(); | |
234 } | 295 } |
235 | 296 |
236 void RenderGrid::computePreferredLogicalWidths() | 297 void RenderGrid::computePreferredLogicalWidths() |
237 { | 298 { |
238 ASSERT(preferredLogicalWidthsDirty()); | 299 ASSERT(preferredLogicalWidthsDirty()); |
239 | 300 |
240 m_minPreferredLogicalWidth = 0; | 301 m_minPreferredLogicalWidth = 0; |
241 m_maxPreferredLogicalWidth = 0; | 302 m_maxPreferredLogicalWidth = 0; |
242 | 303 |
243 // FIXME: We don't take our own logical width into account. Once we do, we n eed to make sure | 304 // 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 | 675 |
615 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t co lumnTrack) | 676 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t co lumnTrack) |
616 { | 677 { |
617 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil d, ForRows, rowTrack); | 678 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil d, ForRows, rowTrack); |
618 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c hild, ForColumns, columnTrack); | 679 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c hild, ForColumns, columnTrack); |
619 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); | 680 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); |
620 } | 681 } |
621 | 682 |
622 void RenderGrid::placeItemsOnGrid() | 683 void RenderGrid::placeItemsOnGrid() |
623 { | 684 { |
624 ASSERT(!gridWasPopulated()); | 685 if (!gridIsDirty()) |
686 return; | |
687 | |
625 ASSERT(m_gridItemCoordinate.isEmpty()); | 688 ASSERT(m_gridItemCoordinate.isEmpty()); |
626 | 689 |
627 populateExplicitGridAndOrderIterator(); | 690 populateExplicitGridAndOrderIterator(); |
628 | 691 |
629 Vector<RenderBox*> autoMajorAxisAutoGridItems; | 692 Vector<RenderBox*> autoMajorAxisAutoGridItems; |
630 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; | 693 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; |
631 GridAutoFlow autoFlow = style()->gridAutoFlow(); | 694 GridAutoFlow autoFlow = style()->gridAutoFlow(); |
632 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera tor.next()) { | 695 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> | 696 // 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. | 697 // positions to not match the author's intent. The specification is uncl ear on what should be done in this case. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 return (flow == AutoFlowColumn) ? ForColumns : ForRows; | 809 return (flow == AutoFlowColumn) ? ForColumns : ForRows; |
747 } | 810 } |
748 | 811 |
749 RenderGrid::TrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() c onst | 812 RenderGrid::TrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() c onst |
750 { | 813 { |
751 GridAutoFlow flow = style()->gridAutoFlow(); | 814 GridAutoFlow flow = style()->gridAutoFlow(); |
752 ASSERT(flow != AutoFlowNone); | 815 ASSERT(flow != AutoFlowNone); |
753 return (flow == AutoFlowColumn) ? ForRows : ForColumns; | 816 return (flow == AutoFlowColumn) ? ForRows : ForColumns; |
754 } | 817 } |
755 | 818 |
756 void RenderGrid::clearGrid() | 819 void RenderGrid::dirtyGrid() |
757 { | 820 { |
821 // An empty grid is a dirty grid as we always one item (so that gridColumnCo unt() can return an answer) but we | |
822 // could hold onto the memory to avoid massive free / malloc cycles if we st ored the information differently. | |
ojan
2013/07/30 23:18:57
A simple way to do this would be to resize(0) here
Julien - ping for review
2013/07/30 23:57:42
Yup, I didn't want to piggyback on this change - e
ojan
2013/07/31 00:13:18
Normally I'm violently against premature optimizat
| |
758 m_grid.clear(); | 823 m_grid.clear(); |
759 m_gridItemCoordinate.clear(); | 824 m_gridItemCoordinate.clear(); |
760 } | 825 } |
761 | 826 |
762 void RenderGrid::layoutGridItems() | 827 void RenderGrid::layoutGridItems() |
763 { | 828 { |
764 placeItemsOnGrid(); | 829 placeItemsOnGrid(); |
765 | 830 |
766 Vector<GridTrack> columnTracks(gridColumnCount()); | 831 Vector<GridTrack> columnTracks(gridColumnCount()); |
767 Vector<GridTrack> rowTracks(gridRowCount()); | 832 Vector<GridTrack> rowTracks(gridRowCount()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) | 869 if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) |
805 child->repaintDuringLayoutIfMoved(oldChildRect); | 870 child->repaintDuringLayoutIfMoved(oldChildRect); |
806 } | 871 } |
807 | 872 |
808 for (size_t i = 0; i < rowTracks.size(); ++i) | 873 for (size_t i = 0; i < rowTracks.size(); ++i) |
809 setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth); | 874 setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth); |
810 | 875 |
811 // FIXME: We should handle min / max logical height. | 876 // FIXME: We should handle min / max logical height. |
812 | 877 |
813 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); | 878 setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight()); |
814 clearGrid(); | |
815 } | 879 } |
816 | 880 |
817 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const | 881 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const |
818 { | 882 { |
819 ASSERT(m_gridItemCoordinate.contains(gridItem)); | 883 ASSERT(m_gridItemCoordinate.contains(gridItem)); |
820 return m_gridItemCoordinate.get(gridItem); | 884 return m_gridItemCoordinate.get(gridItem); |
821 } | 885 } |
822 | 886 |
823 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB ox*, TrackSizingDirection, size_t initialPosition) const | 887 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB ox*, TrackSizingDirection, size_t initialPosition) const |
824 { | 888 { |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 if (isOutOfFlowPositioned()) | 1114 if (isOutOfFlowPositioned()) |
1051 return "RenderGrid (positioned)"; | 1115 return "RenderGrid (positioned)"; |
1052 if (isAnonymous()) | 1116 if (isAnonymous()) |
1053 return "RenderGrid (generated)"; | 1117 return "RenderGrid (generated)"; |
1054 if (isRelPositioned()) | 1118 if (isRelPositioned()) |
1055 return "RenderGrid (relative positioned)"; | 1119 return "RenderGrid (relative positioned)"; |
1056 return "RenderGrid"; | 1120 return "RenderGrid"; |
1057 } | 1121 } |
1058 | 1122 |
1059 } // namespace WebCore | 1123 } // namespace WebCore |
OLD | NEW |