| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google 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 are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 if (child->isFloatingOrOutOfFlowPositioned() || child->isColumnSpanAll()) | 384 if (child->isFloatingOrOutOfFlowPositioned() || child->isColumnSpanAll()) |
| 385 continue; | 385 continue; |
| 386 if (!child->isSelfCollapsingBlock()) | 386 if (!child->isSelfCollapsingBlock()) |
| 387 return false; | 387 return false; |
| 388 } | 388 } |
| 389 return true; | 389 return true; |
| 390 } | 390 } |
| 391 return false; | 391 return false; |
| 392 } | 392 } |
| 393 | 393 |
| 394 DISABLE_CFI_PERF |
| 394 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { | 395 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { |
| 395 ASSERT(needsLayout()); | 396 ASSERT(needsLayout()); |
| 396 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 397 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
| 397 | 398 |
| 398 if (!relayoutChildren && simplifiedLayout()) | 399 if (!relayoutChildren && simplifiedLayout()) |
| 399 return; | 400 return; |
| 400 | 401 |
| 401 LayoutAnalyzer::BlockScope analyzer(*this); | 402 LayoutAnalyzer::BlockScope analyzer(*this); |
| 402 SubtreeLayoutScope layoutScope(*this); | 403 SubtreeLayoutScope layoutScope(*this); |
| 403 | 404 |
| 405 LayoutUnit previousHeight = logicalHeight(); |
| 406 LayoutUnit oldLeft = logicalLeft(); |
| 407 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
| 408 relayoutChildren |= logicalWidthChanged; |
| 409 |
| 410 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); |
| 411 LayoutState state(*this, logicalWidthChanged); |
| 412 |
| 413 if (m_paginationStateChanged) { |
| 414 // We now need a deep layout to clean up struts after pagination, if we |
| 415 // just ceased to be paginated, or, if we just became paginated on the |
| 416 // other hand, we now need the deep layout, to insert pagination struts. |
| 417 m_paginationStateChanged = false; |
| 418 state.setPaginationStateChanged(); |
| 419 } |
| 420 |
| 421 bool preferredLogicalWidthsWereDirty = preferredLogicalWidthsDirty(); |
| 422 |
| 404 // Multiple passes might be required for column based layout. | 423 // Multiple passes might be required for column based layout. |
| 405 // The number of passes could be as high as the number of columns. | 424 // The number of passes could be as high as the number of columns. |
| 406 LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); | 425 LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); |
| 407 do { | 426 do { |
| 408 layoutBlockFlow(relayoutChildren, layoutScope); | 427 layoutChildren(relayoutChildren, layoutScope); |
| 428 |
| 429 if (!preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty()) { |
| 430 // The only thing that should dirty preferred widths at this point is the |
| 431 // addition of overflow:auto scrollbars in a descendant. To avoid a |
| 432 // potential infinite loop, run layout again with auto scrollbars frozen |
| 433 // in their current state. |
| 434 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; |
| 435 relayoutChildren |= updateLogicalWidthAndColumnWidth(); |
| 436 layoutChildren(relayoutChildren, layoutScope); |
| 437 } |
| 409 | 438 |
| 410 if (flowThread && flowThread->columnHeightsChanged()) { | 439 if (flowThread && flowThread->columnHeightsChanged()) { |
| 411 setChildNeedsLayout(MarkOnlyThis); | 440 setChildNeedsLayout(MarkOnlyThis); |
| 412 continue; | 441 continue; |
| 413 } | 442 } |
| 414 | 443 |
| 415 if (shouldBreakAtLineToAvoidWidow()) { | 444 if (shouldBreakAtLineToAvoidWidow()) { |
| 416 setEverHadLayout(); | 445 setEverHadLayout(); |
| 417 continue; | 446 continue; |
| 418 } | 447 } |
| 419 break; | 448 break; |
| 420 } while (true); | 449 } while (true); |
| 421 | 450 |
| 451 // Remember the automatic logical height we got from laying out the children. |
| 452 LayoutUnit unconstrainedHeight = logicalHeight(); |
| 453 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); |
| 454 |
| 455 // Adjust logical height to satisfy whatever computed style requires. |
| 456 updateLogicalHeight(); |
| 457 |
| 458 if (!childrenInline()) |
| 459 addOverhangingFloatsFromChildren(unconstrainedHeight); |
| 460 |
| 461 if (logicalHeight() != previousHeight || isDocumentElement()) |
| 462 relayoutChildren = true; |
| 463 |
| 464 PositionedLayoutBehavior behavior = DefaultLayout; |
| 465 if (oldLeft != logicalLeft()) |
| 466 behavior = ForcedLayoutAfterContainingBlockMoved; |
| 467 layoutPositionedObjects(relayoutChildren, behavior); |
| 468 |
| 469 // Add overflow from children. |
| 470 computeOverflow(unconstrainedClientAfterEdge); |
| 471 |
| 472 m_descendantsWithFloatsMarkedForLayout = false; |
| 473 |
| 422 updateLayerTransformAfterLayout(); | 474 updateLayerTransformAfterLayout(); |
| 423 | 475 |
| 424 updateAfterLayout(); | 476 updateAfterLayout(); |
| 425 | 477 |
| 426 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) | 478 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) |
| 427 positionDialog(); | 479 positionDialog(); |
| 428 | 480 |
| 429 clearNeedsLayout(); | 481 clearNeedsLayout(); |
| 430 updateIsSelfCollapsing(); | 482 updateIsSelfCollapsing(); |
| 431 } | 483 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 // exists *between* in-flow siblings (i.e. not before the first child and | 519 // exists *between* in-flow siblings (i.e. not before the first child and |
| 468 // not after the last child). | 520 // not after the last child). |
| 469 // | 521 // |
| 470 // [1] https://drafts.csswg.org/css-break/#possible-breaks | 522 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
| 471 setBreakBefore(LayoutBlock::breakBefore()); | 523 setBreakBefore(LayoutBlock::breakBefore()); |
| 472 setBreakAfter(LayoutBlock::breakAfter()); | 524 setBreakAfter(LayoutBlock::breakAfter()); |
| 473 } | 525 } |
| 474 } | 526 } |
| 475 | 527 |
| 476 DISABLE_CFI_PERF | 528 DISABLE_CFI_PERF |
| 477 inline void LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, | 529 void LayoutBlockFlow::layoutChildren(bool relayoutChildren, |
| 478 SubtreeLayoutScope& layoutScope) { | 530 SubtreeLayoutScope& layoutScope) { |
| 479 LayoutUnit oldLeft = logicalLeft(); | |
| 480 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | |
| 481 relayoutChildren |= logicalWidthChanged; | |
| 482 | |
| 483 LayoutState state(*this, logicalWidthChanged); | |
| 484 | |
| 485 if (m_paginationStateChanged) { | |
| 486 // We now need a deep layout to clean up struts after pagination, if we | |
| 487 // just ceased to be paginated, or, if we just became paginated on the | |
| 488 // other hand, we now need the deep layout, to insert pagination struts. | |
| 489 m_paginationStateChanged = false; | |
| 490 state.setPaginationStateChanged(); | |
| 491 } | |
| 492 | |
| 493 LayoutUnit previousHeight = logicalHeight(); | |
| 494 resetLayout(); | 531 resetLayout(); |
| 495 | 532 |
| 496 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 533 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
| 497 LayoutUnit afterEdge = | 534 LayoutUnit afterEdge = |
| 498 borderAfter() + paddingAfter() + scrollbarLogicalHeight(); | 535 borderAfter() + paddingAfter() + scrollbarLogicalHeight(); |
| 499 setLogicalHeight(beforeEdge); | 536 setLogicalHeight(beforeEdge); |
| 500 | 537 |
| 501 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); | |
| 502 | |
| 503 bool preferredLogicalWidthsWereDirty = preferredLogicalWidthsDirty(); | |
| 504 | |
| 505 if (childrenInline()) | 538 if (childrenInline()) |
| 506 layoutInlineChildren(relayoutChildren, afterEdge); | 539 layoutInlineChildren(relayoutChildren, afterEdge); |
| 507 else | 540 else |
| 508 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); | 541 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); |
| 509 | 542 |
| 510 bool preferredLogicalWidthsBecameDirty = | |
| 511 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); | |
| 512 if (preferredLogicalWidthsBecameDirty) { | |
| 513 // The only thing that should dirty preferred widths at this point is the | |
| 514 // addition of overflow:auto scrollbars in a descendant. To avoid a | |
| 515 // potential infinite loop, run layout again with auto scrollbars frozen in | |
| 516 // their current state. | |
| 517 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; | |
| 518 layoutBlockFlow(relayoutChildren, layoutScope); | |
| 519 return; | |
| 520 } | |
| 521 | |
| 522 // Expand our intrinsic height to encompass floats. | 543 // Expand our intrinsic height to encompass floats. |
| 523 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && | 544 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && |
| 524 createsNewFormattingContext()) | 545 createsNewFormattingContext()) |
| 525 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 546 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
| 526 | |
| 527 // Remember the automatic logical height we got from laying out the children. | |
| 528 LayoutUnit unconstrainedHeight = logicalHeight(); | |
| 529 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); | |
| 530 | |
| 531 // Adjust logical height to satisfy whatever computed style requires. | |
| 532 updateLogicalHeight(); | |
| 533 | |
| 534 if (!childrenInline()) | |
| 535 addOverhangingFloatsFromChildren(unconstrainedHeight); | |
| 536 | |
| 537 if (previousHeight != logicalHeight() || isDocumentElement()) | |
| 538 relayoutChildren = true; | |
| 539 | |
| 540 PositionedLayoutBehavior behavior = DefaultLayout; | |
| 541 if (oldLeft != logicalLeft()) | |
| 542 behavior = ForcedLayoutAfterContainingBlockMoved; | |
| 543 layoutPositionedObjects(relayoutChildren, behavior); | |
| 544 | |
| 545 // Add overflow from children (unless we're multi-column, since in that case | |
| 546 // all our child overflow is clipped anyway). | |
| 547 computeOverflow(unconstrainedClientAfterEdge); | |
| 548 | |
| 549 m_descendantsWithFloatsMarkedForLayout = false; | |
| 550 } | 547 } |
| 551 | 548 |
| 552 void LayoutBlockFlow::addOverhangingFloatsFromChildren( | 549 void LayoutBlockFlow::addOverhangingFloatsFromChildren( |
| 553 LayoutUnit unconstrainedHeight) { | 550 LayoutUnit unconstrainedHeight) { |
| 554 LayoutBlockFlow* lowestBlock = nullptr; | 551 LayoutBlockFlow* lowestBlock = nullptr; |
| 555 bool addedOverhangingFloats = false; | 552 bool addedOverhangingFloats = false; |
| 556 // One of our children's floats may have become an overhanging float for us. | 553 // One of our children's floats may have become an overhanging float for us. |
| 557 for (LayoutObject* child = lastChild(); child; | 554 for (LayoutObject* child = lastChild(); child; |
| 558 child = child->previousSibling()) { | 555 child = child->previousSibling()) { |
| 559 // TODO(robhogan): We should exclude blocks that create formatting | 556 // TODO(robhogan): We should exclude blocks that create formatting |
| (...skipping 4004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4564 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4561 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
| 4565 } | 4562 } |
| 4566 | 4563 |
| 4567 void LayoutBlockFlow::invalidateDisplayItemClients( | 4564 void LayoutBlockFlow::invalidateDisplayItemClients( |
| 4568 PaintInvalidationReason invalidationReason) const { | 4565 PaintInvalidationReason invalidationReason) const { |
| 4569 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4566 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
| 4570 invalidationReason); | 4567 invalidationReason); |
| 4571 } | 4568 } |
| 4572 | 4569 |
| 4573 } // namespace blink | 4570 } // namespace blink |
| OLD | NEW |