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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |