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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 GridTrackSizingDirection m_direction; | 223 GridTrackSizingDirection m_direction; |
224 size_t m_rowIndex; | 224 size_t m_rowIndex; |
225 size_t m_columnIndex; | 225 size_t m_columnIndex; |
226 size_t m_childIndex; | 226 size_t m_childIndex; |
227 }; | 227 }; |
228 | 228 |
229 struct LayoutGrid::GridSizingData { | 229 struct LayoutGrid::GridSizingData { |
230 WTF_MAKE_NONCOPYABLE(GridSizingData); | 230 WTF_MAKE_NONCOPYABLE(GridSizingData); |
231 STACK_ALLOCATED(); | 231 STACK_ALLOCATED(); |
232 public: | 232 public: |
233 GridSizingData(size_t gridColumnCount, size_t gridRowCount, const LayoutUnit
& freeSpaceForColumns, const LayoutUnit& freeSpaceForRows) | 233 GridSizingData(size_t gridColumnCount, size_t gridRowCount) |
234 : columnTracks(gridColumnCount) | 234 : columnTracks(gridColumnCount) |
235 , rowTracks(gridRowCount) | 235 , rowTracks(gridRowCount) |
236 , freeSpaceForColumns(freeSpaceForColumns) | |
237 , freeSpaceForRows(freeSpaceForRows) | |
238 { | 236 { |
239 } | 237 } |
240 | 238 |
241 Vector<GridTrack> columnTracks; | 239 Vector<GridTrack> columnTracks; |
242 Vector<GridTrack> rowTracks; | 240 Vector<GridTrack> rowTracks; |
243 Vector<size_t> contentSizedTracksIndex; | 241 Vector<size_t> contentSizedTracksIndex; |
244 | 242 |
245 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. | 243 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. |
246 Vector<GridTrack*> filteredTracks; | 244 Vector<GridTrack*> filteredTracks; |
247 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; | 245 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
248 Vector<GridTrack*> growBeyondGrowthLimitsTracks; | 246 Vector<GridTrack*> growBeyondGrowthLimitsTracks; |
249 | 247 |
250 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu
rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } | 248 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu
rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } |
251 | 249 |
252 private: | 250 private: |
253 LayoutUnit freeSpaceForColumns; | 251 LayoutUnit freeSpaceForColumns { }; |
254 LayoutUnit freeSpaceForRows; | 252 LayoutUnit freeSpaceForRows { }; |
255 }; | 253 }; |
256 | 254 |
257 struct GridItemsSpanGroupRange { | 255 struct GridItemsSpanGroupRange { |
258 Vector<GridItemWithSpan>::iterator rangeStart; | 256 Vector<GridItemWithSpan>::iterator rangeStart; |
259 Vector<GridItemWithSpan>::iterator rangeEnd; | 257 Vector<GridItemWithSpan>::iterator rangeEnd; |
260 }; | 258 }; |
261 | 259 |
262 LayoutGrid::LayoutGrid(Element* element) | 260 LayoutGrid::LayoutGrid(Element* element) |
263 : LayoutBlock(element) | 261 : LayoutBlock(element) |
264 , m_gridIsDirty(true) | 262 , m_gridIsDirty(true) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum
ns().size() | 307 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum
ns().size() |
310 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s
ize(); | 308 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s
ize(); |
311 } | 309 } |
312 | 310 |
313 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle
) const | 311 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle
) const |
314 { | 312 { |
315 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() | 313 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() |
316 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); | 314 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); |
317 } | 315 } |
318 | 316 |
| 317 LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizi
ngData) const |
| 318 { |
| 319 LayoutUnit logicalHeight = borderAndPaddingLogicalHeight() + scrollbarLogica
lHeight(); |
| 320 |
| 321 for (const auto& row : sizingData.rowTracks) |
| 322 logicalHeight += row.baseSize(); |
| 323 |
| 324 logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size()); |
| 325 |
| 326 return logicalHeight; |
| 327 } |
| 328 |
| 329 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection directio
n, GridSizingData& sizingData, LayoutUnit freeSpace) |
| 330 { |
| 331 if (freeSpace != -1) { |
| 332 LayoutUnit totalGuttersSize = guttersSize(direction, direction == ForRow
s ? gridRowCount() : gridColumnCount()); |
| 333 freeSpace = std::max<LayoutUnit>(0, freeSpace - totalGuttersSize); |
| 334 } |
| 335 sizingData.freeSpaceForDirection(direction) = freeSpace; |
| 336 |
| 337 LayoutUnit baseSizes, growthLimits; |
| 338 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, growthLimit
s); |
| 339 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); |
| 340 } |
| 341 |
319 void LayoutGrid::layoutBlock(bool relayoutChildren) | 342 void LayoutGrid::layoutBlock(bool relayoutChildren) |
320 { | 343 { |
321 ASSERT(needsLayout()); | 344 ASSERT(needsLayout()); |
322 | 345 |
323 if (!relayoutChildren && simplifiedLayout()) | 346 if (!relayoutChildren && simplifiedLayout()) |
324 return; | 347 return; |
325 | 348 |
326 // FIXME: Much of this method is boiler plate that matches LayoutBox::layout
Block and Layout*FlexibleBox::layoutBlock. | |
327 // It would be nice to refactor some of the duplicate code. | |
328 { | 349 { |
329 // LayoutState needs this deliberate scope to pop before updating scroll
information (which | 350 // LayoutState needs this deliberate scope to pop before updating scroll
information (which |
330 // may trigger relayout). | 351 // may trigger relayout). |
331 LayoutState state(*this, locationOffset()); | 352 LayoutState state(*this, locationOffset()); |
332 | 353 |
333 LayoutSize previousSize = size(); | 354 LayoutSize previousSize = size(); |
334 | 355 |
335 setLogicalHeight(0); | |
336 updateLogicalWidth(); | 356 updateLogicalWidth(); |
| 357 bool logicalHeightWasIndefinite = computeContentLogicalHeight(MainOrPref
erredSize, style()->logicalHeight(), -1) == -1; |
337 | 358 |
338 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); | 359 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); |
339 | 360 |
340 layoutGridItems(); | 361 placeItemsOnGrid(); |
| 362 |
| 363 GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
| 364 |
| 365 // At this point the logical width is always definite as the above call
to updateLogicalWidth() |
| 366 // properly resolves intrinsic sizes. We cannot do the same for heights
though because many code |
| 367 // paths inside updateLogicalHeight() require a previous call to setLogi
calHeight() to resolve |
| 368 // heights properly (like for positioned items for example). |
| 369 computeTrackSizesForDirection(ForColumns, sizingData, availableLogicalWi
dth()); |
| 370 |
| 371 if (logicalHeightWasIndefinite) |
| 372 computeIntrinsicLogicalHeight(sizingData, borderAndPaddingLogicalHei
ght()); |
| 373 else |
| 374 computeTrackSizesForDirection(ForRows, sizingData, availableLogicalH
eight(ExcludeMarginBorderPadding)); |
| 375 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData)); |
341 | 376 |
342 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 377 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
343 updateLogicalHeight(); | 378 updateLogicalHeight(); |
344 | 379 |
| 380 // The above call might have changed the grid's logical height depending
on min|max height restrictions. |
| 381 // Update the sizes of the rows whose size depends on the logical height
(also on definite|indefinite sizes). |
| 382 if (logicalHeightWasIndefinite) |
| 383 computeTrackSizesForDirection(ForRows, sizingData, logicalHeight()); |
| 384 |
| 385 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); |
| 386 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); |
| 387 |
| 388 layoutGridItems(sizingData); |
| 389 |
345 if (size() != previousSize) | 390 if (size() != previousSize) |
346 relayoutChildren = true; | 391 relayoutChildren = true; |
347 | 392 |
348 layoutPositionedObjects(relayoutChildren || isDocumentElement()); | 393 layoutPositionedObjects(relayoutChildren || isDocumentElement()); |
349 | 394 |
350 computeOverflow(oldClientAfterEdge); | 395 computeOverflow(oldClientAfterEdge); |
351 } | 396 } |
352 | 397 |
353 updateLayerTransformAfterLayout(); | 398 updateLayerTransformAfterLayout(); |
354 updateScrollInfoAfterLayout(); | 399 updateScrollInfoAfterLayout(); |
355 | 400 |
356 clearNeedsLayout(); | 401 clearNeedsLayout(); |
357 } | 402 } |
358 | 403 |
359 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp
an) const | 404 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp
an) const |
360 { | 405 { |
361 ASSERT(span >= 1); | 406 ASSERT(span >= 1); |
362 | 407 |
363 if (span == 1) | 408 if (span == 1) |
364 return 0; | 409 return 0; |
365 | 410 |
366 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap(
) : styleRef().gridRowGap(); | 411 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap(
) : styleRef().gridRowGap(); |
367 return valueForLength(trackGap, 0) * (span - 1); | 412 return valueForLength(trackGap, 0) * (span - 1); |
368 } | 413 } |
369 | 414 |
370 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
utUnit& maxLogicalWidth) const | 415 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
utUnit& maxLogicalWidth) const |
371 { | 416 { |
372 const_cast<LayoutGrid*>(this)->placeItemsOnGrid(); | 417 const_cast<LayoutGrid*>(this)->placeItemsOnGrid(); |
373 | 418 |
374 GridSizingData sizingData(gridColumnCount(), gridRowCount(), 0, 0); | 419 GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
375 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si
zingData); | 420 sizingData.freeSpaceForDirection(ForColumns) = -1; |
376 | 421 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si
zingData, minLogicalWidth, maxLogicalWidth); |
377 for (const auto& column : sizingData.columnTracks) { | |
378 const LayoutUnit& minTrackBreadth = column.baseSize(); | |
379 const LayoutUnit& maxTrackBreadth = column.growthLimit(); | |
380 | |
381 minLogicalWidth += minTrackBreadth; | |
382 maxLogicalWidth += maxTrackBreadth; | |
383 } | |
384 | 422 |
385 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack
s.size()); | 423 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack
s.size()); |
386 minLogicalWidth += totalGuttersSize; | 424 minLogicalWidth += totalGuttersSize; |
387 maxLogicalWidth += totalGuttersSize; | 425 maxLogicalWidth += totalGuttersSize; |
388 | 426 |
389 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); | 427 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); |
390 minLogicalWidth += scrollbarWidth; | 428 minLogicalWidth += scrollbarWidth; |
391 maxLogicalWidth += scrollbarWidth; | 429 maxLogicalWidth += scrollbarWidth; |
392 } | 430 } |
393 | 431 |
394 bool LayoutGrid::gridElementIsShrinkToFit() | 432 void LayoutGrid::computeIntrinsicLogicalHeight(GridSizingData& sizingData, Layou
tUnit borderAndPadding) |
395 { | 433 { |
396 return isFloatingOrOutOfFlowPositioned(); | 434 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData)); |
| 435 sizingData.freeSpaceForDirection(ForRows) = -1; |
| 436 computeUsedBreadthOfGridTracks(ForRows, sizingData, m_minContentHeight, m_ma
xContentHeight); |
| 437 |
| 438 LayoutUnit totalGuttersSize = guttersSize(ForRows, gridRowCount()); |
| 439 m_minContentHeight += totalGuttersSize; |
| 440 m_maxContentHeight += totalGuttersSize; |
| 441 |
| 442 // Grid container should have the minimum height of a line if it's editable.
That does not affect track sizing though. |
| 443 if (hasLineIfEmpty()) { |
| 444 m_minContentHeight = std::max(m_minContentHeight, minimumLogicalHeightFo
rEmptyLine()); |
| 445 m_maxContentHeight = std::max(m_maxContentHeight, m_minContentHeight); |
| 446 } |
| 447 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData)); |
| 448 } |
| 449 |
| 450 LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing(const Length& l
ogicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPaddi
ng) const |
| 451 { |
| 452 if (logicalHeightLength.isMinContent()) |
| 453 return m_minContentHeight; |
| 454 |
| 455 if (logicalHeightLength.isMaxContent()) |
| 456 return m_maxContentHeight; |
| 457 |
| 458 if (logicalHeightLength.isFitContent()) { |
| 459 LayoutUnit fillAvailableExtent = containingBlock()->availableLogicalHeig
ht(ExcludeMarginBorderPadding); |
| 460 return std::min<LayoutUnit>(m_maxContentHeight, std::max<LayoutUnit>(m_m
inContentHeight, fillAvailableExtent)); |
| 461 } |
| 462 |
| 463 if (logicalHeightLength.isFillAvailable()) |
| 464 return containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadd
ing) - borderAndPadding; |
| 465 ASSERT_NOT_REACHED(); |
| 466 return 0; |
397 } | 467 } |
398 | 468 |
399 static inline double normalizedFlexFraction(const GridTrack& track, double flexF
actor) | 469 static inline double normalizedFlexFraction(const GridTrack& track, double flexF
actor) |
400 { | 470 { |
401 return track.baseSize() / std::max<double>(1, flexFactor); | 471 return track.baseSize() / std::max<double>(1, flexFactor); |
402 } | 472 } |
403 | 473 |
404 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
on, GridSizingData& sizingData) | 474 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
on, GridSizingData& sizingData, LayoutUnit& baseSizesWithoutMaximization, Layout
Unit& growthLimitsWithoutMaximization) |
405 { | 475 { |
406 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction); | 476 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction); |
407 const LayoutUnit initialFreeSpace = freeSpace; | 477 const LayoutUnit initialFreeSpace = freeSpace; |
408 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra
cks : sizingData.rowTracks; | 478 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra
cks : sizingData.rowTracks; |
409 Vector<size_t> flexibleSizedTracksIndex; | 479 Vector<size_t> flexibleSizedTracksIndex; |
410 sizingData.contentSizedTracksIndex.shrink(0); | 480 sizingData.contentSizedTracksIndex.shrink(0); |
411 | 481 |
412 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() :
std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()
->logicalHeight(), -1)); | 482 const LayoutUnit maxSize = std::max(LayoutUnit(), initialFreeSpace); |
413 // 1. Initialize per Grid track variables. | 483 // 1. Initialize per Grid track variables. |
414 for (size_t i = 0; i < tracks.size(); ++i) { | 484 for (size_t i = 0; i < tracks.size(); ++i) { |
415 GridTrack& track = tracks[i]; | 485 GridTrack& track = tracks[i]; |
416 GridTrackSize trackSize = gridTrackSize(direction, i); | 486 GridTrackSize trackSize = gridTrackSize(direction, i); |
417 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); | 487 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
418 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); | 488 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); |
419 | 489 |
420 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize
)); | 490 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize
)); |
421 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac
k.baseSize(), maxSize)); | 491 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac
k.baseSize(), maxSize)); |
422 track.setInfinitelyGrowable(false); | 492 track.setInfinitelyGrowable(false); |
423 | 493 |
424 if (trackSize.isContentSized()) | 494 if (trackSize.isContentSized()) |
425 sizingData.contentSizedTracksIndex.append(i); | 495 sizingData.contentSizedTracksIndex.append(i); |
426 if (trackSize.maxTrackBreadth().isFlex()) | 496 if (trackSize.maxTrackBreadth().isFlex()) |
427 flexibleSizedTracksIndex.append(i); | 497 flexibleSizedTracksIndex.append(i); |
428 } | 498 } |
429 | 499 |
430 // 2. Resolve content-based TrackSizingFunctions. | 500 // 2. Resolve content-based TrackSizingFunctions. |
431 if (!sizingData.contentSizedTracksIndex.isEmpty()) | 501 if (!sizingData.contentSizedTracksIndex.isEmpty()) |
432 resolveContentBasedTrackSizingFunctions(direction, sizingData); | 502 resolveContentBasedTrackSizingFunctions(direction, sizingData); |
433 | 503 |
| 504 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = 0; |
| 505 |
434 for (const auto& track: tracks) { | 506 for (const auto& track: tracks) { |
435 ASSERT(!track.infiniteGrowthPotential()); | 507 ASSERT(!track.infiniteGrowthPotential()); |
436 freeSpace -= track.baseSize(); | 508 baseSizesWithoutMaximization += track.baseSize(); |
| 509 growthLimitsWithoutMaximization += track.growthLimit(); |
437 } | 510 } |
| 511 freeSpace = initialFreeSpace - baseSizesWithoutMaximization; |
438 | 512 |
439 const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->lo
gicalHeight().isAuto() : gridElementIsShrinkToFit(); | 513 const bool hasDefiniteFreeSpace = initialFreeSpace != -1; |
440 | 514 if (hasDefiniteFreeSpace && freeSpace <= 0) |
441 if (!hasUndefinedRemainingSpace && freeSpace <= 0) | |
442 return; | 515 return; |
443 | 516 |
444 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro
wthLimit value until freeSpace is exhausted. | 517 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro
wthLimit value until freeSpace is exhausted. |
445 const size_t tracksSize = tracks.size(); | 518 const size_t tracksSize = tracks.size(); |
446 if (!hasUndefinedRemainingSpace) { | 519 if (hasDefiniteFreeSpace) { |
447 Vector<GridTrack*> tracksForDistribution(tracksSize); | 520 Vector<GridTrack*> tracksForDistribution(tracksSize); |
448 for (size_t i = 0; i < tracksSize; ++i) { | 521 for (size_t i = 0; i < tracksSize; ++i) { |
449 tracksForDistribution[i] = tracks.data() + i; | 522 tracksForDistribution[i] = tracks.data() + i; |
450 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b
aseSize()); | 523 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b
aseSize()); |
451 } | 524 } |
452 | 525 |
453 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr,
sizingData, freeSpace); | 526 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr,
sizingData, freeSpace); |
454 | 527 |
455 for (auto* track : tracksForDistribution) | 528 for (auto* track : tracksForDistribution) |
456 track->setBaseSize(track->plannedSize()); | 529 track->setBaseSize(track->plannedSize()); |
457 } else { | 530 } else { |
458 for (auto& track : tracks) | 531 for (auto& track : tracks) |
459 track.setBaseSize(track.growthLimit()); | 532 track.setBaseSize(track.growthLimit()); |
460 } | 533 } |
461 | 534 |
462 if (flexibleSizedTracksIndex.isEmpty()) | 535 if (flexibleSizedTracksIndex.isEmpty()) |
463 return; | 536 return; |
464 | 537 |
465 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. | 538 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
466 double flexFraction = 0; | 539 double flexFraction = 0; |
467 if (!hasUndefinedRemainingSpace) { | 540 if (hasDefiniteFreeSpace) { |
468 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size()
- 1), direction, initialFreeSpace); | 541 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size()
- 1), direction, initialFreeSpace); |
469 } else { | 542 } else { |
470 for (const auto& trackIndex : flexibleSizedTracksIndex) | 543 for (const auto& trackIndex : flexibleSizedTracksIndex) |
471 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[
trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); | 544 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[
trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); |
472 | 545 |
473 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { | 546 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
474 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]
); | 547 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]
); |
475 while (LayoutBox* gridItem = iterator.nextGridItem()) { | 548 while (LayoutBox* gridItem = iterator.nextGridItem()) { |
476 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem
); | 549 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem
); |
477 const GridSpan span = (direction == ForColumns) ? coordinate.col
umns : coordinate.rows; | 550 const GridSpan span = (direction == ForColumns) ? coordinate.col
umns : coordinate.rows; |
478 | 551 |
479 // Do not include already processed items. | 552 // Do not include already processed items. |
480 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz
edTracksIndex[i - 1]) | 553 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz
edTracksIndex[i - 1]) |
481 continue; | 554 continue; |
482 | 555 |
483 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra
cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column
Tracks))); | 556 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra
cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column
Tracks))); |
484 } | 557 } |
485 } | 558 } |
486 } | 559 } |
487 | 560 |
488 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 561 for (const auto& trackIndex : flexibleSizedTracksIndex) { |
489 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); | 562 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
490 | 563 |
491 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); | 564 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); |
492 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t
rackSize.maxTrackBreadth().flex()); | 565 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t
rackSize.maxTrackBreadth().flex()); |
493 if (LayoutUnit increment = baseSize - oldBaseSize) { | 566 if (LayoutUnit increment = baseSize - oldBaseSize) { |
494 tracks[trackIndex].setBaseSize(baseSize); | 567 tracks[trackIndex].setBaseSize(baseSize); |
495 freeSpace -= increment; | 568 freeSpace -= increment; |
| 569 |
| 570 baseSizesWithoutMaximization += increment; |
| 571 growthLimitsWithoutMaximization += increment; |
496 } | 572 } |
497 } | 573 } |
498 | |
499 // FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 7
39613002). | |
500 } | 574 } |
501 | 575 |
502 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt
h, LayoutUnit maxSize) const | 576 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt
h, LayoutUnit maxSize) const |
503 { | 577 { |
504 if (gridLength.isFlex()) | 578 if (gridLength.isFlex()) |
505 return 0; | 579 return 0; |
506 | 580 |
507 const Length& trackLength = gridLength.length(); | 581 const Length& trackLength = gridLength.length(); |
508 if (trackLength.isSpecified()) | 582 if (trackLength.isSpecified()) |
509 return valueForLength(trackLength, maxSize); | 583 return valueForLength(trackLength, maxSize); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 track->growSizeDuringDistribution(growthShare); | 1086 track->growSizeDuringDistribution(growthShare); |
1013 availableLogicalSpace -= growthShare; | 1087 availableLogicalSpace -= growthShare; |
1014 } | 1088 } |
1015 } | 1089 } |
1016 | 1090 |
1017 for (auto* track : tracks) | 1091 for (auto* track : tracks) |
1018 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri
ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution(
))); | 1092 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri
ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution(
))); |
1019 } | 1093 } |
1020 | 1094 |
1021 #if ENABLE(ASSERT) | 1095 #if ENABLE(ASSERT) |
1022 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
ction, const Vector<GridTrack>& tracks) | 1096 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
ction, GridSizingData& sizingData) |
1023 { | 1097 { |
1024 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() :
std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()
->logicalHeight(), -1)); | 1098 const Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.col
umnTracks : sizingData.rowTracks; |
| 1099 LayoutUnit& maxSize = sizingData.freeSpaceForDirection(direction); |
1025 for (size_t i = 0; i < tracks.size(); ++i) { | 1100 for (size_t i = 0; i < tracks.size(); ++i) { |
1026 GridTrackSize trackSize = gridTrackSize(direction, i); | 1101 GridTrackSize trackSize = gridTrackSize(direction, i); |
1027 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); | 1102 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
1028 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i].
baseSize()) | 1103 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i].
baseSize()) |
1029 return false; | 1104 return false; |
1030 } | 1105 } |
1031 return true; | 1106 return true; |
1032 } | 1107 } |
1033 #endif | 1108 #endif |
1034 | 1109 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 | 1378 |
1304 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; | 1379 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; |
1305 for (const auto& trackIndex : autoSizedTracksIndex) { | 1380 for (const auto& trackIndex : autoSizedTracksIndex) { |
1306 GridTrack* track = tracks.data() + trackIndex; | 1381 GridTrack* track = tracks.data() + trackIndex; |
1307 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; | 1382 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; |
1308 track->setBaseSize(baseSize); | 1383 track->setBaseSize(baseSize); |
1309 } | 1384 } |
1310 availableSpace = 0; | 1385 availableSpace = 0; |
1311 } | 1386 } |
1312 | 1387 |
1313 void LayoutGrid::layoutGridItems() | 1388 void LayoutGrid::layoutGridItems(GridSizingData& sizingData) |
1314 { | 1389 { |
1315 placeItemsOnGrid(); | |
1316 | |
1317 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); | |
1318 LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorde
rPadding); | |
1319 | |
1320 // Remove space consumed by gutters from the available logical space. | |
1321 availableSpaceForColumns -= guttersSize(ForColumns, gridColumnCount()); | |
1322 availableSpaceForRows -= guttersSize(ForRows, gridRowCount()); | |
1323 | |
1324 GridSizingData sizingData(gridColumnCount(), gridRowCount(), availableSpaceF
orColumns, availableSpaceForRows); | |
1325 computeUsedBreadthOfGridTracks(ForColumns, sizingData); | |
1326 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks
)); | |
1327 computeUsedBreadthOfGridTracks(ForRows, sizingData); | |
1328 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); | |
1329 | |
1330 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); | |
1331 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); | |
1332 | |
1333 populateGridPositions(sizingData); | 1390 populateGridPositions(sizingData); |
1334 m_gridItemsOverflowingGridArea.resize(0); | 1391 m_gridItemsOverflowingGridArea.resize(0); |
1335 | 1392 |
1336 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { | 1393 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { |
1337 if (child->isOutOfFlowPositioned()) { | 1394 if (child->isOutOfFlowPositioned()) { |
1338 prepareChildForPositionedLayout(*child); | 1395 prepareChildForPositionedLayout(*child); |
1339 continue; | 1396 continue; |
1340 } | 1397 } |
1341 | 1398 |
1342 // Because the grid area cannot be styled, we don't need to adjust | 1399 // Because the grid area cannot be styled, we don't need to adjust |
(...skipping 28 matching lines...) Expand all Loading... |
1371 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); | 1428 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); |
1372 #endif | 1429 #endif |
1373 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 1430 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
1374 | 1431 |
1375 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is | 1432 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is |
1376 // not visible | 1433 // not visible |
1377 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 1434 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
1378 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt
h) | 1435 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt
h) |
1379 m_gridItemsOverflowingGridArea.append(child); | 1436 m_gridItemsOverflowingGridArea.append(child); |
1380 } | 1437 } |
1381 | |
1382 LayoutUnit height = borderAndPaddingLogicalHeight() + scrollbarLogicalHeight
(); | |
1383 for (const auto& row : sizingData.rowTracks) | |
1384 height += row.baseSize(); | |
1385 | |
1386 height += guttersSize(ForRows, sizingData.rowTracks.size()); | |
1387 | |
1388 if (hasLineIfEmpty()) | |
1389 height = std::max(height, minimumLogicalHeightForEmptyLine()); | |
1390 | |
1391 // Min / max logical height is handled by the call to updateLogicalHeight in
layoutBlock. | |
1392 setLogicalHeight(height); | |
1393 } | 1438 } |
1394 | 1439 |
1395 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) | 1440 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) |
1396 { | 1441 { |
1397 ASSERT(child.isOutOfFlowPositioned()); | 1442 ASSERT(child.isOutOfFlowPositioned()); |
1398 child.containingBlock()->insertPositionedObject(&child); | 1443 child.containingBlock()->insertPositionedObject(&child); |
1399 | 1444 |
1400 PaintLayer* childLayer = child.layer(); | 1445 PaintLayer* childLayer = child.layer(); |
1401 childLayer->setStaticInlinePosition(borderAndPaddingStart()); | 1446 childLayer->setStaticInlinePosition(borderAndPaddingStart()); |
1402 childLayer->setStaticBlockPosition(borderAndPaddingBefore()); | 1447 childLayer->setStaticBlockPosition(borderAndPaddingBefore()); |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 | 2076 |
2032 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 2077 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
2033 } | 2078 } |
2034 | 2079 |
2035 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const | 2080 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const |
2036 { | 2081 { |
2037 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 2082 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
2038 } | 2083 } |
2039 | 2084 |
2040 } // namespace blink | 2085 } // namespace blink |
OLD | NEW |