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

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

Issue 815833005: [css-grid] Handle min-content/max-content with orthogonal flows (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Comments and assertions to make the code clearer. Created 4 years, 6 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 Vector<size_t> contentSizedTracksIndex; 244 Vector<size_t> contentSizedTracksIndex;
245 245
246 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. 246 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free.
247 Vector<GridTrack*> filteredTracks; 247 Vector<GridTrack*> filteredTracks;
248 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; 248 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
249 Vector<GridTrack*> growBeyondGrowthLimitsTracks; 249 Vector<GridTrack*> growBeyondGrowthLimitsTracks;
250 250
251 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } 251 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; }
252 252
253 SizingOperation sizingOperation { TrackSizing }; 253 SizingOperation sizingOperation { TrackSizing };
254 254 enum SizingState { ColumnSizingFirstIteration, RowSizingFirstIteration, Colu mnSizingSecondIteration, RowSizingSecondIteration};
255 SizingState sizingState { ColumnSizingFirstIteration };
256 void nextState()
257 {
258 switch (sizingState) {
259 case ColumnSizingFirstIteration:
260 sizingState = RowSizingFirstIteration;
261 return;
262 case RowSizingFirstIteration:
263 sizingState = ColumnSizingSecondIteration;
264 return;
265 case ColumnSizingSecondIteration:
266 sizingState = RowSizingSecondIteration;
267 return;
268 case RowSizingSecondIteration:
269 sizingState = ColumnSizingFirstIteration;
270 return;
271 }
272 NOTREACHED();
273 sizingState = ColumnSizingFirstIteration;
274 }
275 bool isValidTransitionForDirection(GridTrackSizingDirection direction)
276 {
277 switch (sizingState) {
278 case ColumnSizingFirstIteration:
279 return direction == ForColumns ? true : false;
280 case RowSizingFirstIteration:
281 return direction == ForRows ? true : false;
282 case ColumnSizingSecondIteration:
283 if (direction == ForRows)
284 sizingState = RowSizingFirstIteration;
285 return true;
286 case RowSizingSecondIteration:
287 return direction == ForRows ? true : false;
288 }
289 NOTREACHED();
290 return false;
291 }
255 private: 292 private:
256 LayoutUnit freeSpaceForColumns { }; 293 LayoutUnit freeSpaceForColumns { };
257 LayoutUnit freeSpaceForRows { }; 294 LayoutUnit freeSpaceForRows { };
258 }; 295 };
259 296
260 struct GridItemsSpanGroupRange { 297 struct GridItemsSpanGroupRange {
261 Vector<GridItemWithSpan>::iterator rangeStart; 298 Vector<GridItemWithSpan>::iterator rangeStart;
262 Vector<GridItemWithSpan>::iterator rangeEnd; 299 Vector<GridItemWithSpan>::iterator rangeEnd;
263 }; 300 };
264 301
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 for (const auto& row : sizingData.rowTracks) 385 for (const auto& row : sizingData.rowTracks)
349 logicalHeight += row.baseSize(); 386 logicalHeight += row.baseSize();
350 387
351 logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size()); 388 logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size());
352 389
353 return logicalHeight; 390 return logicalHeight;
354 } 391 }
355 392
356 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection directio n, GridSizingData& sizingData, LayoutUnit freeSpace) 393 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection directio n, GridSizingData& sizingData, LayoutUnit freeSpace)
357 { 394 {
395 DCHECK(sizingData.isValidTransitionForDirection(direction));
358 sizingData.freeSpaceForDirection(direction) = freeSpace - guttersSize(direct ion, direction == ForRows ? gridRowCount() : gridColumnCount()); 396 sizingData.freeSpaceForDirection(direction) = freeSpace - guttersSize(direct ion, direction == ForRows ? gridRowCount() : gridColumnCount());
359 sizingData.sizingOperation = TrackSizing; 397 sizingData.sizingOperation = TrackSizing;
360 398
361 LayoutUnit baseSizes, growthLimits; 399 LayoutUnit baseSizes, growthLimits;
362 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, growthLimit s); 400 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, growthLimit s);
363 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); 401 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData));
402 sizingData.nextState();
403 }
404
405 void LayoutGrid::repeatTracksSizingIfNeeded(GridSizingData& sizingData, LayoutUn it availableSpaceForColumns, LayoutUnit availableSpaceForRows)
406 {
407 DCHECK(sizingData.sizingState > GridSizingData::RowSizingFirstIteration);
408
409 // In orthogonal flow cases column track's size is determined by using the c omputed
410 // row track's size, which it was estimated during the first cycle of the si zing
411 // algorithm. Hence we need to repeat computeUsedBreadthOfGridTracks for bot h,
412 // columns and rows, to determine the final values.
413 // TODO (lajava): orthogonal flows is just one of the cases which may requir e
414 // a new cycle of the sizing algorithm; there may be more. In addition, not all the
415 // cases with orthogonal flows require this extra cycle; we need a more spec ific
416 // condition to detect whether child's min-content contribution has changed or not.
417 if (m_hasAnyOrthogonalChild) {
418 computeTrackSizesForDirection(ForColumns, sizingData, availableSpaceForC olumns);
419 computeTrackSizesForDirection(ForRows, sizingData, availableSpaceForRows );
420 }
364 } 421 }
365 422
366 void LayoutGrid::layoutBlock(bool relayoutChildren) 423 void LayoutGrid::layoutBlock(bool relayoutChildren)
367 { 424 {
368 ASSERT(needsLayout()); 425 ASSERT(needsLayout());
369 426
370 if (!relayoutChildren && simplifiedLayout()) 427 if (!relayoutChildren && simplifiedLayout())
371 return; 428 return;
372 429
373 SubtreeLayoutScope layoutScope(*this); 430 SubtreeLayoutScope layoutScope(*this);
(...skipping 12 matching lines...) Expand all
386 443
387 placeItemsOnGrid(); 444 placeItemsOnGrid();
388 445
389 GridSizingData sizingData(gridColumnCount(), gridRowCount()); 446 GridSizingData sizingData(gridColumnCount(), gridRowCount());
390 447
391 // 1- First, the track sizing algorithm is used to resolve the sizes of the grid columns. 448 // 1- First, the track sizing algorithm is used to resolve the sizes of the grid columns.
392 // At this point the logical width is always definite as the above call to updateLogicalWidth() 449 // At this point the logical width is always definite as the above call to updateLogicalWidth()
393 // properly resolves intrinsic sizes. We cannot do the same for heights though because many code 450 // properly resolves intrinsic sizes. We cannot do the same for heights though because many code
394 // paths inside updateLogicalHeight() require a previous call to setLogi calHeight() to resolve 451 // paths inside updateLogicalHeight() require a previous call to setLogi calHeight() to resolve
395 // heights properly (like for positioned items for example). 452 // heights properly (like for positioned items for example).
396 computeTrackSizesForDirection(ForColumns, sizingData, availableLogicalWi dth()); 453 LayoutUnit availableSpaceForColumns = availableLogicalWidth();
454 computeTrackSizesForDirection(ForColumns, sizingData, availableSpaceForC olumns);
397 455
398 // 2- Next, the track sizing algorithm resolves the sizes of the grid ro ws, using the 456 // 2- Next, the track sizing algorithm resolves the sizes of the grid ro ws, using the
399 // grid column sizes calculated in the previous step. 457 // grid column sizes calculated in the previous step.
400 if (logicalHeightWasIndefinite) 458 if (logicalHeightWasIndefinite)
401 computeIntrinsicLogicalHeight(sizingData); 459 computeIntrinsicLogicalHeight(sizingData);
402 else 460 else
403 computeTrackSizesForDirection(ForRows, sizingData, availableLogicalH eight(ExcludeMarginBorderPadding)); 461 computeTrackSizesForDirection(ForRows, sizingData, availableLogicalH eight(ExcludeMarginBorderPadding));
404 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData) + borderAndP addingLogicalHeight() + scrollbarLogicalHeight()); 462 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData) + borderAndP addingLogicalHeight() + scrollbarLogicalHeight());
405 463
406 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 464 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
407 updateLogicalHeight(); 465 updateLogicalHeight();
408 466
409 // The above call might have changed the grid's logical height depending on min|max height restrictions. 467 // The above call might have changed the grid's logical height depending on min|max height restrictions.
410 // Update the sizes of the rows whose size depends on the logical height (also on definite|indefinite sizes). 468 // Update the sizes of the rows whose size depends on the logical height (also on definite|indefinite sizes).
469 LayoutUnit availableSpaceForRows = contentLogicalHeight();
411 if (logicalHeightWasIndefinite) 470 if (logicalHeightWasIndefinite)
412 computeTrackSizesForDirection(ForRows, sizingData, contentLogicalHei ght()); 471 computeTrackSizesForDirection(ForRows, sizingData, availableSpaceFor Rows);
472
473 // 3- If the min-content contribution of any grid items have changed bas ed on the row
474 // sizes calculated in step 2, steps 1 and 2 are repeated with the new m in-content
475 // contribution (once only).
476 repeatTracksSizingIfNeeded(sizingData, availableSpaceForColumns, availab leSpaceForRows);
413 477
414 // Grid container should have the minimum height of a line if it's edita ble. That doesn't affect track sizing though. 478 // Grid container should have the minimum height of a line if it's edita ble. That doesn't affect track sizing though.
415 if (hasLineIfEmpty()) 479 if (hasLineIfEmpty())
416 setLogicalHeight(std::max(logicalHeight(), minimumLogicalHeightForEm ptyLine())); 480 setLogicalHeight(std::max(logicalHeight(), minimumLogicalHeightForEm ptyLine()));
417 481
418 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); 482 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData);
419 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); 483 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData);
420 484
421 layoutGridItems(sizingData); 485 layoutGridItems(sizingData);
422 486
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 } 744 }
681 745
682 // The function is not called if we don't have <flex> grid tracks 746 // The function is not called if we don't have <flex> grid tracks
683 ASSERT(!flexibleTracksIndexes.isEmpty()); 747 ASSERT(!flexibleTracksIndexes.isEmpty());
684 748
685 return computeFlexFactorUnitSize(tracks, direction, flexFactorSum, leftOverS pace, flexibleTracksIndexes); 749 return computeFlexFactorUnitSize(tracks, direction, flexFactorSum, leftOverS pace, flexibleTracksIndexes);
686 } 750 }
687 751
688 static bool hasOverrideContainingBlockContentSizeForChild(const LayoutBox& child , GridTrackSizingDirection direction) 752 static bool hasOverrideContainingBlockContentSizeForChild(const LayoutBox& child , GridTrackSizingDirection direction)
689 { 753 {
690 return direction == ForColumns ? child.hasOverrideContainingBlockLogicalWidt h() : child.overrideContainingBlockContentLogicalHeight(); 754 return direction == ForColumns ? child.hasOverrideContainingBlockLogicalWidt h() : child.hasOverrideContainingBlockLogicalHeight();
691 } 755 }
692 756
693 static LayoutUnit overrideContainingBlockContentSizeForChild(const LayoutBox& ch ild, GridTrackSizingDirection direction) 757 static LayoutUnit overrideContainingBlockContentSizeForChild(const LayoutBox& ch ild, GridTrackSizingDirection direction)
694 { 758 {
695 return direction == ForColumns ? child.overrideContainingBlockContentLogical Width() : child.overrideContainingBlockContentLogicalHeight(); 759 return direction == ForColumns ? child.overrideContainingBlockContentLogical Width() : child.overrideContainingBlockContentLogicalHeight();
696 } 760 }
697 761
698 static void setOverrideContainingBlockContentSizeForChild(LayoutBox& child, Grid TrackSizingDirection direction, LayoutUnit size) 762 static void setOverrideContainingBlockContentSizeForChild(LayoutBox& child, Grid TrackSizingDirection direction, LayoutUnit size)
699 { 763 {
700 if (direction == ForColumns) 764 if (direction == ForColumns)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 { 809 {
746 const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex ); 810 const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex );
747 811
748 GridLength minTrackBreadth = trackSize.minTrackBreadth(); 812 GridLength minTrackBreadth = trackSize.minTrackBreadth();
749 GridLength maxTrackBreadth = trackSize.maxTrackBreadth(); 813 GridLength maxTrackBreadth = trackSize.maxTrackBreadth();
750 814
751 // If the logical width/height of the grid container is indefinite, percenta ge values are treated as <auto>. 815 // If the logical width/height of the grid container is indefinite, percenta ge values are treated as <auto>.
752 if (minTrackBreadth.hasPercentage() || maxTrackBreadth.hasPercentage()) { 816 if (minTrackBreadth.hasPercentage() || maxTrackBreadth.hasPercentage()) {
753 // For the inline axis this only happens when we're computing the intrin sic sizes (AvailableSpaceIndefinite). 817 // For the inline axis this only happens when we're computing the intrin sic sizes (AvailableSpaceIndefinite).
754 // For the block axis we check that the percentage height is resolvable on the first in-flow child. 818 // For the block axis we check that the percentage height is resolvable on the first in-flow child.
819 // TODO (lajava) This condition for determining whether a size is indefi nite or not is not working correctly for orthogonal flows.
755 if ((sizingOperation == IntrinsicSizeComputation) || (direction == ForRo ws && firstInFlowChildBox() && !firstInFlowChildBox()->percentageLogicalHeightIs Resolvable())) { 820 if ((sizingOperation == IntrinsicSizeComputation) || (direction == ForRo ws && firstInFlowChildBox() && !firstInFlowChildBox()->percentageLogicalHeightIs Resolvable())) {
756 if (minTrackBreadth.hasPercentage()) 821 if (minTrackBreadth.hasPercentage())
757 minTrackBreadth = Length(Auto); 822 minTrackBreadth = Length(Auto);
758 if (maxTrackBreadth.hasPercentage()) 823 if (maxTrackBreadth.hasPercentage())
759 maxTrackBreadth = Length(Auto); 824 maxTrackBreadth = Length(Auto);
760 } 825 }
761 } 826 }
762 827
763 // Flex sizes are invalid as a min sizing function. However we still can hav e a flexible |minTrackBreadth| 828 // Flex sizes are invalid as a min sizing function. However we still can hav e a flexible |minTrackBreadth|
764 // if the track had a flex size directly (e.g. "1fr"), the spec says that in this case it implies an automatic minimum. 829 // if the track had a flex size directly (e.g. "1fr"), the spec says that in this case it implies an automatic minimum.
(...skipping 27 matching lines...) Expand all
792 return child.logicalHeight() + child.marginLogicalHeight(); 857 return child.logicalHeight() + child.marginLogicalHeight();
793 } 858 }
794 859
795 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild(const LayoutBox& child, GridTrackSizingDirection direction) const 860 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild(const LayoutBox& child, GridTrackSizingDirection direction) const
796 { 861 {
797 return !isOrthogonalChild(child) ? direction : (direction == ForColumns ? Fo rRows : ForColumns); 862 return !isOrthogonalChild(child) ? direction : (direction == ForColumns ? Fo rRows : ForColumns);
798 } 863 }
799 864
800 LayoutUnit LayoutGrid::minSizeForChild(LayoutBox& child, GridTrackSizingDirectio n direction, GridSizingData& sizingData) 865 LayoutUnit LayoutGrid::minSizeForChild(LayoutBox& child, GridTrackSizingDirectio n direction, GridSizingData& sizingData)
801 { 866 {
802 // TODO(svillar): Properly support orthogonal writing mode.
803 if (isOrthogonalChild(child))
804 return LayoutUnit();
805 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns); 867 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns);
806 bool isRowAxis = direction == childInlineDirection; 868 bool isRowAxis = direction == childInlineDirection;
807 const Length& childSize = isRowAxis ? child.styleRef().logicalWidth() : chil d.styleRef().logicalHeight(); 869 const Length& childSize = isRowAxis ? child.styleRef().logicalWidth() : chil d.styleRef().logicalHeight();
808 const Length& childMinSize = isRowAxis ? child.styleRef().logicalMinWidth() : child.styleRef().logicalMinHeight(); 870 const Length& childMinSize = isRowAxis ? child.styleRef().logicalMinWidth() : child.styleRef().logicalMinHeight();
809 if (!childSize.isAuto() || childMinSize.isAuto()) 871 if (!childSize.isAuto() || childMinSize.isAuto())
810 return minContentForChild(child, direction, sizingData); 872 return minContentForChild(child, direction, sizingData);
811 873
812 bool overrideSizeHasChanged = updateOverrideContainingBlockContentSizeForChi ld(child, childInlineDirection, sizingData); 874 bool overrideSizeHasChanged = updateOverrideContainingBlockContentSizeForChi ld(child, childInlineDirection, sizingData);
813 if (isRowAxis) { 875 if (isRowAxis) {
814 LayoutUnit marginLogicalWidth = sizingData.sizingOperation == TrackSizin g ? computeMarginLogicalSizeForChild(InlineDirection, child) : marginIntrinsicLo gicalWidthForChild(child); 876 LayoutUnit marginLogicalWidth = sizingData.sizingOperation == TrackSizin g ? computeMarginLogicalSizeForChild(InlineDirection, child) : marginIntrinsicLo gicalWidthForChild(child);
815 return child.computeLogicalWidthUsing(MinSize, childMinSize, overrideCon tainingBlockContentSizeForChild(child, childInlineDirection), this) + marginLogi calWidth; 877 return child.computeLogicalWidthUsing(MinSize, childMinSize, overrideCon tainingBlockContentSizeForChild(child, childInlineDirection), this) + marginLogi calWidth;
816 } 878 }
817 879
818 if (overrideSizeHasChanged) 880 if (overrideSizeHasChanged && (direction != ForColumns || sizingData.sizingO peration != IntrinsicSizeComputation))
819 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 881 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
820 child.layoutIfNeeded(); 882 child.layoutIfNeeded();
821 return child.computeLogicalHeightUsing(MinSize, childMinSize, child.intrinsi cLogicalHeight()) + child.marginLogicalHeight() + child.scrollbarLogicalHeight() ; 883 return child.computeLogicalHeightUsing(MinSize, childMinSize, child.intrinsi cLogicalHeight()) + child.marginLogicalHeight() + child.scrollbarLogicalHeight() ;
822 } 884 }
823 885
824 bool LayoutGrid::updateOverrideContainingBlockContentSizeForChild(LayoutBox& chi ld, GridTrackSizingDirection direction, GridSizingData& sizingData) 886 bool LayoutGrid::updateOverrideContainingBlockContentSizeForChild(LayoutBox& chi ld, GridTrackSizingDirection direction, GridSizingData& sizingData)
825 { 887 {
826 LayoutUnit overrideSize = gridAreaBreadthForChild(child, direction, sizingDa ta); 888 LayoutUnit overrideSize = gridAreaBreadthForChild(child, direction, sizingDa ta);
827 if (hasOverrideContainingBlockContentSizeForChild(child, direction) && overr ideContainingBlockContentSizeForChild(child, direction) == overrideSize) 889 if (hasOverrideContainingBlockContentSizeForChild(child, direction) && overr ideContainingBlockContentSizeForChild(child, direction) == overrideSize)
828 return false; 890 return false;
829 891
830 setOverrideContainingBlockContentSizeForChild(child, direction, overrideSize ); 892 setOverrideContainingBlockContentSizeForChild(child, direction, overrideSize );
831 return true; 893 return true;
832 } 894 }
833 895
834 LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, GridTrackSizingDirec tion direction, GridSizingData& sizingData) 896 LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, GridTrackSizingDirec tion direction, GridSizingData& sizingData)
835 { 897 {
836 // FIXME: Properly support orthogonal writing mode.
837 if (isOrthogonalChild(child))
838 return LayoutUnit();
839 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns); 898 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns);
840 if (direction == childInlineDirection) { 899 if (direction == childInlineDirection) {
841 // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is 900 // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
842 // what we are interested in here. Thus we need to set the inline-axis o verride size to -1 (no possible resolution). 901 // what we are interested in here. Thus we need to set the inline-axis o verride size to -1 (no possible resolution).
843 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForColu mns)) 902 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForColu mns))
844 setOverrideContainingBlockContentSizeForChild(child, childInlineDire ction, LayoutUnit(-1)); 903 setOverrideContainingBlockContentSizeForChild(child, childInlineDire ction, LayoutUnit(-1));
845 904
846 // FIXME: It's unclear if we should return the intrinsic width or the pr eferred width. 905 // FIXME: It's unclear if we should return the intrinsic width or the pr eferred width.
847 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html 906 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
848 return child.minPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor Child(child); 907 return child.minPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor Child(child);
849 } 908 }
850 909
910 // All orthogonal flow boxes were already laid out during an early layout ph ase performed in FrameView::performLayout.
911 // It's true that grid track sizing was not completed at that time and it ma y afffect the final height of a
912 // grid item, but since it's forbidden to perform a layout during intrinsic width computation, we have to use
913 // that computed height for now.
914 if (direction == ForColumns && sizingData.sizingOperation == IntrinsicSizeCo mputation) {
915 DCHECK(isOrthogonalChild(child));
916 return child.logicalHeight() + child.marginLogicalHeight();
917 }
918
851 SubtreeLayoutScope layouter(child); 919 SubtreeLayoutScope layouter(child);
852 if (updateOverrideContainingBlockContentSizeForChild(child, childInlineDirec tion, sizingData)) 920 if (updateOverrideContainingBlockContentSizeForChild(child, childInlineDirec tion, sizingData))
853 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 921 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
854 return logicalHeightForChild(child, sizingData); 922 return logicalHeightForChild(child, sizingData);
855 } 923 }
856 924
857 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, GridTrackSizingDirec tion direction, GridSizingData& sizingData) 925 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, GridTrackSizingDirec tion direction, GridSizingData& sizingData)
858 { 926 {
859 if (isOrthogonalChild(child))
860 return LayoutUnit();
861 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns); 927 GridTrackSizingDirection childInlineDirection = flowAwareDirectionForChild(c hild, ForColumns);
862 if (direction == childInlineDirection) { 928 if (direction == childInlineDirection) {
863 // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is 929 // If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
864 // what we are interested in here. Thus we need to set the inline-axis o verride size to -1 (no possible resolution). 930 // what we are interested in here. Thus we need to set the inline-axis o verride size to -1 (no possible resolution).
865 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForColu mns)) 931 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForColu mns))
866 setOverrideContainingBlockContentSizeForChild(child, childInlineDire ction, LayoutUnit(-1)); 932 setOverrideContainingBlockContentSizeForChild(child, childInlineDire ction, LayoutUnit(-1));
867 933
868 // FIXME: It's unclear if we should return the intrinsic width or the pr eferred width. 934 // FIXME: It's unclear if we should return the intrinsic width or the pr eferred width.
869 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html 935 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
870 return child.maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor Child(child); 936 return child.maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor Child(child);
871 } 937 }
872 938
939 // All orthogonal flow boxes were already laid out during an early layout ph ase performed in FrameView::performLayout.
940 // It's true that grid track sizing was not completed at that time and it ma y afffect the final height of a
941 // grid item, but since it's forbidden to perform a layout during intrinsic width computation, we have to use
942 // that computed height for now.
943 if (direction == ForColumns && sizingData.sizingOperation == IntrinsicSizeCo mputation) {
944 DCHECK(isOrthogonalChild(child));
945 return child.logicalHeight() + child.marginLogicalHeight();
946 }
947
873 SubtreeLayoutScope layouter(child); 948 SubtreeLayoutScope layouter(child);
874 if (updateOverrideContainingBlockContentSizeForChild(child, childInlineDirec tion, sizingData)) 949 if (updateOverrideContainingBlockContentSizeForChild(child, childInlineDirec tion, sizingData))
875 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 950 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
876 return logicalHeightForChild(child, sizingData); 951 return logicalHeightForChild(child, sizingData);
877 } 952 }
878 953
879 // We're basically using a class instead of a std::pair because of accessing gri dItem() or getGridSpan() is much more 954 // We're basically using a class instead of a std::pair because of accessing gri dItem() or getGridSpan() is much more
880 // self-explanatory that using .first or .second members in the pair. Having a s td::pair<LayoutBox*, size_t> 955 // self-explanatory that using .first or .second members in the pair. Having a s td::pair<LayoutBox*, size_t>
881 // does not work either because we still need the GridSpan so we'd have to add a n extra hash lookup for each item 956 // does not work either because we still need the GridSpan so we'd have to add a n extra hash lookup for each item
882 // at the beginning of LayoutGrid::resolveContentBasedTrackSizingFunctionsForIte ms(). 957 // at the beginning of LayoutGrid::resolveContentBasedTrackSizingFunctionsForIte ms().
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 m_autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns); 1392 m_autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns);
1318 m_autoRepeatRows = computeAutoRepeatTracksCount(ForRows); 1393 m_autoRepeatRows = computeAutoRepeatTracksCount(ForRows);
1319 1394
1320 populateExplicitGridAndOrderIterator(); 1395 populateExplicitGridAndOrderIterator();
1321 1396
1322 // We clear the dirty bit here as the grid sizes have been updated. 1397 // We clear the dirty bit here as the grid sizes have been updated.
1323 m_gridIsDirty = false; 1398 m_gridIsDirty = false;
1324 1399
1325 Vector<LayoutBox*> autoMajorAxisAutoGridItems; 1400 Vector<LayoutBox*> autoMajorAxisAutoGridItems;
1326 Vector<LayoutBox*> specifiedMajorAxisAutoGridItems; 1401 Vector<LayoutBox*> specifiedMajorAxisAutoGridItems;
1402 m_hasAnyOrthogonalChild = false;
1327 for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderItera tor.next()) { 1403 for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderItera tor.next()) {
1328 if (child->isOutOfFlowPositioned()) 1404 if (child->isOutOfFlowPositioned())
1329 continue; 1405 continue;
1330 1406
1407 m_hasAnyOrthogonalChild = m_hasAnyOrthogonalChild || isOrthogonalChild(* child);
1408
1331 GridArea area = cachedGridArea(*child); 1409 GridArea area = cachedGridArea(*child);
1332 if (!area.rows.isIndefinite()) 1410 if (!area.rows.isIndefinite())
1333 area.rows.translate(abs(m_smallestRowStart)); 1411 area.rows.translate(abs(m_smallestRowStart));
1334 if (!area.columns.isIndefinite()) 1412 if (!area.columns.isIndefinite())
1335 area.columns.translate(abs(m_smallestColumnStart)); 1413 area.columns.translate(abs(m_smallestColumnStart));
1336 m_gridItemArea.set(child, area); 1414 m_gridItemArea.set(child, area);
1337 1415
1338 if (area.rows.isIndefinite() || area.columns.isIndefinite()) { 1416 if (area.rows.isIndefinite() || area.columns.isIndefinite()) {
1339 GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? area.columns : area.rows; 1417 GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? area.columns : area.rows;
1340 if (majorAxisPositions.isIndefinite()) 1418 if (majorAxisPositions.isIndefinite())
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 1682
1605 // Because the grid area cannot be styled, we don't need to adjust 1683 // Because the grid area cannot be styled, we don't need to adjust
1606 // the grid breadth to account for 'box-sizing'. 1684 // the grid breadth to account for 'box-sizing'.
1607 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit(); 1685 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit();
1608 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit(); 1686 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit();
1609 1687
1610 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChildIncludingAlignmentOffsets(*child, ForColumns, sizingData); 1688 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChildIncludingAlignmentOffsets(*child, ForColumns, sizingData);
1611 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChildIncludingAlignmentOffsets(*child, ForRows, sizingData); 1689 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChildIncludingAlignmentOffsets(*child, ForRows, sizingData);
1612 1690
1613 SubtreeLayoutScope layoutScope(*child); 1691 SubtreeLayoutScope layoutScope(*child);
1614 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight())) 1692 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && (child->hasRelativeLogicalHeight() || isOrthogonalChild(*child))))
1615 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged); 1693 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged);
1616 1694
1617 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1695 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1618 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1696 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1619 1697
1620 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded 1698 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded
1621 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly 1699 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly
1622 // determine the available space before stretching, are not set yet. 1700 // determine the available space before stretching, are not set yet.
1623 applyStretchAlignmentToChildIfNeeded(*child); 1701 applyStretchAlignmentToChildIfNeeded(*child);
1624 1702
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 ASSERT(m_gridItemArea.contains(&gridItem)); 1850 ASSERT(m_gridItemArea.contains(&gridItem));
1773 return m_gridItemArea.get(&gridItem); 1851 return m_gridItemArea.get(&gridItem);
1774 } 1852 }
1775 1853
1776 GridSpan LayoutGrid::cachedGridSpan(const LayoutBox& gridItem, GridTrackSizingDi rection direction) const 1854 GridSpan LayoutGrid::cachedGridSpan(const LayoutBox& gridItem, GridTrackSizingDi rection direction) const
1777 { 1855 {
1778 GridArea area = cachedGridArea(gridItem); 1856 GridArea area = cachedGridArea(gridItem);
1779 return direction == ForColumns ? area.columns : area.rows; 1857 return direction == ForColumns ? area.columns : area.rows;
1780 } 1858 }
1781 1859
1860 LayoutUnit LayoutGrid::assumedRowsSizeForOrthogonalChild(const LayoutBox& child, SizingOperation sizingOperation) const
1861 {
1862 DCHECK(isOrthogonalChild(child));
1863 const GridSpan& span = cachedGridSpan(child, ForRows);
1864 LayoutUnit gridAreaSize;
1865 bool gridAreaIsIndefinite = false;
1866 LayoutUnit containingBlockAvailableSize = containingBlockLogicalHeightForCon tent(ExcludeMarginBorderPadding);
1867 for (auto trackPosition : span) {
1868 const GridLength& maxTrackSize = gridTrackSize(ForRows, trackPosition, s izingOperation).maxTrackBreadth();
1869 if (maxTrackSize.isContentSized() || maxTrackSize.isFlex())
1870 gridAreaIsIndefinite = true;
1871 else
1872 gridAreaSize += valueForLength(maxTrackSize.length(), containingBloc kAvailableSize);
1873 }
1874
1875 gridAreaSize += guttersSize(ForRows, span.integerSpan());
1876
1877 return gridAreaIsIndefinite ? std::max(child.maxPreferredLogicalWidth(), gri dAreaSize) : gridAreaSize;
1878 }
1879
1782 LayoutUnit LayoutGrid::gridAreaBreadthForChild(const LayoutBox& child, GridTrack SizingDirection direction, const GridSizingData& sizingData) const 1880 LayoutUnit LayoutGrid::gridAreaBreadthForChild(const LayoutBox& child, GridTrack SizingDirection direction, const GridSizingData& sizingData) const
1783 { 1881 {
1882 // To determine the column track's size based on an orthogonal grid item we need it's logical height, which
1883 // may depend on the row track's size. It's possible that the row tracks siz ing logic has not been performed yet,
1884 // so we will need to do an estimation.
1885 if (direction == ForRows && sizingData.sizingState == GridSizingData::Column SizingFirstIteration)
1886 return assumedRowsSizeForOrthogonalChild(child, sizingData.sizingOperati on);
1887
1784 const Vector<GridTrack>& tracks = direction == ForColumns ? sizingData.colum nTracks : sizingData.rowTracks; 1888 const Vector<GridTrack>& tracks = direction == ForColumns ? sizingData.colum nTracks : sizingData.rowTracks;
1785 const GridSpan& span = cachedGridSpan(child, direction); 1889 const GridSpan& span = cachedGridSpan(child, direction);
1786 LayoutUnit gridAreaBreadth; 1890 LayoutUnit gridAreaBreadth;
1787 for (const auto& trackPosition : span) 1891 for (const auto& trackPosition : span)
1788 gridAreaBreadth += tracks[trackPosition].baseSize(); 1892 gridAreaBreadth += tracks[trackPosition].baseSize();
1789 1893
1790 gridAreaBreadth += guttersSize(direction, span.integerSpan()); 1894 gridAreaBreadth += guttersSize(direction, span.integerSpan());
1791 1895
1792 return gridAreaBreadth; 1896 return gridAreaBreadth;
1793 } 1897 }
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 { 2339 {
2236 ASSERT(!styleRef().isLeftToRightDirection()); 2340 ASSERT(!styleRef().isLeftToRightDirection());
2237 2341
2238 LayoutUnit alignmentOffset = m_columnPositions[0]; 2342 LayoutUnit alignmentOffset = m_columnPositions[0];
2239 LayoutUnit rightGridEdgePosition = m_columnPositions[m_columnPositions.size( ) - 1]; 2343 LayoutUnit rightGridEdgePosition = m_columnPositions[m_columnPositions.size( ) - 1];
2240 return rightGridEdgePosition + alignmentOffset - coordinate; 2344 return rightGridEdgePosition + alignmentOffset - coordinate;
2241 } 2345 }
2242 2346
2243 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSiz ingData& sizingData) const 2347 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSiz ingData& sizingData) const
2244 { 2348 {
2349 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child, sizingData);
2245 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child, sizingData); 2350 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child, sizingData);
2246 // We stored m_columnPosition's data ignoring the direction, hence we might need now 2351 // We stored m_columnPosition's data ignoring the direction, hence we might need now
2247 // to translate positions from RTL to LTR, as it's more convenient for paint ing. 2352 // to translate positions from RTL to LTR, as it's more convenient for paint ing.
2248 if (!style()->isLeftToRightDirection()) 2353 if (!style()->isLeftToRightDirection())
2249 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - child.logicalWid th(); 2354 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - child.logicalWid th();
2250 2355
2251 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child, sizingData )); 2356 // "In the positioning phase [...] calculations are performed according to t he writing mode
2357 // of the containing block of the box establishing the orthogonal flow." How ever, the
2358 // resulting LayoutPoint will be used in 'setLogicalPosition' in order to se t the child's
2359 // logical position, which will only take into account the child's writing-m ode.
2360 LayoutPoint childLocation(rowAxisOffset, columnAxisOffset);
2361 return isOrthogonalChild(child) ? childLocation.transposedPoint() : childLoc ation;
2252 } 2362 }
2253 2363
2254 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const 2364 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const
2255 { 2365 {
2256 if (!m_gridItemArea.isEmpty()) 2366 if (!m_gridItemArea.isEmpty())
2257 GridPainter(*this).paintChildren(paintInfo, paintOffset); 2367 GridPainter(*this).paintChildren(paintInfo, paintOffset);
2258 } 2368 }
2259 2369
2260 } // namespace blink 2370 } // 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