| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 66 |
| 67 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::lastMultiColumnSet() const | 67 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::lastMultiColumnSet() const |
| 68 { | 68 { |
| 69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { | 69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { |
| 70 if (sibling->isLayoutMultiColumnSet()) | 70 if (sibling->isLayoutMultiColumnSet()) |
| 71 return toLayoutMultiColumnSet(sibling); | 71 return toLayoutMultiColumnSet(sibling); |
| 72 } | 72 } |
| 73 return 0; | 73 return 0; |
| 74 } | 74 } |
| 75 | 75 |
| 76 static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow(LayoutMultiCol
umnFlowThread* flowThread, LayoutObject* descendant) |
| 77 { |
| 78 ASSERT(descendant->isDescendantOf(flowThread)); |
| 79 LayoutObject* object = descendant->nextInPreOrderAfterChildren(flowThread); |
| 80 while (object) { |
| 81 // Walk through the siblings and find the first one which is either in-f
low or has this |
| 82 // flow thread as its containing block flow thread. |
| 83 if (!object->isOutOfFlowPositioned()) |
| 84 break; |
| 85 if (object->containingBlock()->flowThreadContainingBlock() == flowThread
) { |
| 86 // This out-of-flow object is still part of the flow thread, because
its containing |
| 87 // block (probably relatively positioned) is part of the flow thread
. |
| 88 break; |
| 89 } |
| 90 object = object->nextInPreOrderAfterChildren(flowThread); |
| 91 } |
| 92 return object; |
| 93 } |
| 94 |
| 95 static LayoutObject* previousInPreOrderSkippingOutOfFlow(LayoutMultiColumnFlowTh
read* flowThread, LayoutObject* descendant) |
| 96 { |
| 97 ASSERT(descendant->isDescendantOf(flowThread)); |
| 98 LayoutObject* object = descendant->previousInPreOrder(flowThread); |
| 99 while (object && object != flowThread) { |
| 100 // Walk through the siblings and find the first one which is either in-f
low or has this |
| 101 // flow thread as its containing block flow thread. |
| 102 if (!object->isOutOfFlowPositioned()) |
| 103 break; |
| 104 if (object->containingBlock()->flowThreadContainingBlock() == flowThread
) { |
| 105 // This out-of-flow object is still part of the flow thread, because
its containing |
| 106 // block (probably relatively positioned) is part of the flow thread
. |
| 107 break; |
| 108 } |
| 109 object = object->previousInPreOrder(flowThread); |
| 110 } |
| 111 return object && object != flowThread ? object : nullptr; |
| 112 } |
| 113 |
| 76 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) | 114 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) |
| 77 { | 115 { |
| 78 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); | 116 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); |
| 79 if (!sibling) | 117 if (!sibling) |
| 80 return multicolSet->flowThread()->firstChild(); | 118 return multicolSet->flowThread()->firstChild(); |
| 81 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each | 119 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each |
| 82 // of them contains then. | 120 // of them contains then. |
| 83 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); | 121 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); |
| 84 return toLayoutMultiColumnSpannerPlaceholder(sibling)->layoutObjectInFlowThr
ead()->nextInPreOrderAfterChildren(multicolSet->flowThread()); | 122 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling)->layoutO
bjectInFlowThread(); |
| 123 return nextInPreOrderAfterChildrenSkippingOutOfFlow(multicolSet->multiColumn
FlowThread(), spanner); |
| 85 } | 124 } |
| 86 | 125 |
| 87 static LayoutObject* lastLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) | 126 static LayoutObject* lastLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) |
| 88 { | 127 { |
| 89 LayoutBox* sibling = multicolSet->nextSiblingMultiColumnBox(); | 128 LayoutBox* sibling = multicolSet->nextSiblingMultiColumnBox(); |
| 90 if (!sibling) | 129 if (!sibling) |
| 91 return 0; // By right we should return lastLeafChild() here, but the cal
ler doesn't care, so just return 0. | 130 return 0; // By right we should return lastLeafChild() here, but the cal
ler doesn't care, so just return 0. |
| 92 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each | 131 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each |
| 93 // of them contains then. | 132 // of them contains then. |
| 94 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); | 133 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); |
| 95 return toLayoutMultiColumnSpannerPlaceholder(sibling)->layoutObjectInFlowThr
ead()->previousInPreOrder(multicolSet->flowThread()); | 134 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling)->layoutO
bjectInFlowThread(); |
| 135 return previousInPreOrderSkippingOutOfFlow(multicolSet->multiColumnFlowThrea
d(), spanner); |
| 96 } | 136 } |
| 97 | 137 |
| 98 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::mapDescendantToColumnSet(Layo
utObject* layoutObject) const | 138 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::mapDescendantToColumnSet(Layo
utObject* layoutObject) const |
| 99 { | 139 { |
| 100 ASSERT(!containingColumnSpannerPlaceholder(layoutObject)); // should not be
used for spanners or content inside them. | 140 ASSERT(!containingColumnSpannerPlaceholder(layoutObject)); // should not be
used for spanners or content inside them. |
| 101 ASSERT(layoutObject != this); | 141 ASSERT(layoutObject != this); |
| 102 ASSERT(layoutObject->isDescendantOf(this)); | 142 ASSERT(layoutObject->isDescendantOf(this)); |
| 143 ASSERT(layoutObject->containingBlock()->isDescendantOf(this)); // Out-of-flo
w objects don't belong in column sets. |
| 103 LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); | 144 LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); |
| 104 if (!multicolSet) | 145 if (!multicolSet) |
| 105 return 0; | 146 return 0; |
| 106 if (!multicolSet->nextSiblingMultiColumnSet()) | 147 if (!multicolSet->nextSiblingMultiColumnSet()) |
| 107 return multicolSet; | 148 return multicolSet; |
| 108 | 149 |
| 109 // This is potentially SLOW! But luckily very uncommon. You would have to dy
namically insert a | 150 // This is potentially SLOW! But luckily very uncommon. You would have to dy
namically insert a |
| 110 // spanner into the middle of column contents to need this. | 151 // spanner into the middle of column contents to need this. |
| 111 for (; multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet())
{ | 152 for (; multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet())
{ |
| 112 LayoutObject* firstLayoutObject = firstLayoutObjectInSet(multicolSet); | 153 LayoutObject* firstLayoutObject = firstLayoutObjectInSet(multicolSet); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) { | 487 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) { |
| 447 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox); | 488 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox); |
| 448 m_lastSetWorkedOn = nextSet; | 489 m_lastSetWorkedOn = nextSet; |
| 449 nextSet->beginFlow(logicalTopInFlowThread); | 490 nextSet->beginFlow(logicalTopInFlowThread); |
| 450 } | 491 } |
| 451 return adjustment; | 492 return adjustment; |
| 452 } | 493 } |
| 453 | 494 |
| 454 // When processing layout objects to remove or when processing layout objects th
at have just been | 495 // When processing layout objects to remove or when processing layout objects th
at have just been |
| 455 // inserted, certain types of objects should be skipped. | 496 // inserted, certain types of objects should be skipped. |
| 456 static bool shouldSkipInsertedOrRemovedChild(const LayoutObject& child) | 497 static bool shouldSkipInsertedOrRemovedChild(LayoutMultiColumnFlowThread* flowTh
read, const LayoutObject& child) |
| 457 { | 498 { |
| 458 if (child.isSVG() && !child.isSVGRoot()) { | 499 if (child.isSVG() && !child.isSVGRoot()) { |
| 459 // Don't descend into SVG objects. What's in there is of no interest, an
d there might even | 500 // Don't descend into SVG objects. What's in there is of no interest, an
d there might even |
| 460 // be a foreignObject there with column-span:all, which doesn't apply to
us. | 501 // be a foreignObject there with column-span:all, which doesn't apply to
us. |
| 461 return true; | 502 return true; |
| 462 } | 503 } |
| 463 if (child.isLayoutFlowThread()) { | 504 if (child.isLayoutFlowThread()) { |
| 464 // Found an inner flow thread. We need to skip it and its descendants. | 505 // Found an inner flow thread. We need to skip it and its descendants. |
| 465 return true; | 506 return true; |
| 466 } | 507 } |
| 467 if (child.isLayoutMultiColumnSet() || child.isLayoutMultiColumnSpannerPlaceh
older()) { | 508 if (child.isLayoutMultiColumnSet() || child.isLayoutMultiColumnSpannerPlaceh
older()) { |
| 468 // Column sets and spanner placeholders in a child multicol context don'
t affect the parent | 509 // Column sets and spanner placeholders in a child multicol context don'
t affect the parent |
| 469 // flow thread. | 510 // flow thread. |
| 470 return true; | 511 return true; |
| 471 } | 512 } |
| 513 if (child.isOutOfFlowPositioned() && child.containingBlock()->flowThreadCont
ainingBlock() != flowThread) { |
| 514 // Out-of-flow with its containing block on the outside of the multicol
container. |
| 515 return true; |
| 516 } |
| 472 return false; | 517 return false; |
| 473 } | 518 } |
| 474 | 519 |
| 475 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted(LayoutObject*
descendant) | 520 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted(LayoutObject*
descendant) |
| 476 { | 521 { |
| 477 ASSERT(!m_isBeingEvacuated); | 522 ASSERT(!m_isBeingEvacuated); |
| 478 LayoutObject* objectAfterSubtree = descendant->nextInPreOrderAfterChildren(t
his); | |
| 479 // This method ensures that the list of column sets and spanner placeholders
reflects the | 523 // This method ensures that the list of column sets and spanner placeholders
reflects the |
| 480 // multicol content after having inserted a descendant (or descendant subtre
e). See the header | 524 // multicol content after having inserted a descendant (or descendant subtre
e). See the header |
| 481 // file for more information. Go through the subtree that was just inserted
and create column | 525 // file for more information. Go through the subtree that was just inserted
and create column |
| 482 // sets (needed by regular column content) and spanner placeholders (one nee
ded by each spanner) | 526 // sets (needed by regular column content) and spanner placeholders (one nee
ded by each spanner) |
| 483 // where needed. | 527 // where needed. |
| 528 LayoutObject* objectAfterSubtree = nextInPreOrderAfterChildrenSkippingOutOfF
low(this, descendant); |
| 484 LayoutObject* next; | 529 LayoutObject* next; |
| 485 for (LayoutObject* layoutObject = descendant; layoutObject; layoutObject = n
ext) { | 530 for (LayoutObject* layoutObject = descendant; layoutObject; layoutObject = n
ext) { |
| 486 if (shouldSkipInsertedOrRemovedChild(*layoutObject)) { | 531 if (shouldSkipInsertedOrRemovedChild(this, *layoutObject)) { |
| 487 next = layoutObject->nextInPreOrderAfterChildren(descendant); | 532 next = layoutObject->nextInPreOrderAfterChildren(descendant); |
| 488 continue; | 533 continue; |
| 489 } | 534 } |
| 490 next = layoutObject->nextInPreOrder(descendant); | 535 next = layoutObject->nextInPreOrder(descendant); |
| 491 if (containingColumnSpannerPlaceholder(layoutObject)) | 536 if (containingColumnSpannerPlaceholder(layoutObject)) |
| 492 continue; // Inside a column spanner. Nothing to do, then. | 537 continue; // Inside a column spanner. Nothing to do, then. |
| 493 if (descendantIsValidColumnSpanner(layoutObject)) { | 538 if (descendantIsValidColumnSpanner(layoutObject)) { |
| 494 // This layoutObject is a spanner, so it needs to establish a spanne
r placeholder. | 539 // This layoutObject is a spanner, so it needs to establish a spanne
r placeholder. |
| 495 LayoutBox* insertBefore = 0; | 540 LayoutBox* insertBefore = 0; |
| 496 LayoutMultiColumnSet* setToSplit = 0; | 541 LayoutMultiColumnSet* setToSplit = 0; |
| 497 if (objectAfterSubtree) { | 542 if (objectAfterSubtree) { |
| 498 // The spanner is inserted before something. Figure out what thi
s entails. If the | 543 // The spanner is inserted before something. Figure out what thi
s entails. If the |
| 499 // next layoutObject is a spanner too, it means that we can simp
ly insert a new spanner | 544 // next layoutObject is a spanner too, it means that we can simp
ly insert a new spanner |
| 500 // placeholder in front of its placeholder. | 545 // placeholder in front of its placeholder. |
| 501 insertBefore = objectAfterSubtree->spannerPlaceholder(); | 546 insertBefore = objectAfterSubtree->spannerPlaceholder(); |
| 502 if (!insertBefore) { | 547 if (!insertBefore) { |
| 503 // The next layoutObject isn't a spanner; it's regular colum
n content. Examine what | 548 // The next layoutObject isn't a spanner; it's regular colum
n content. Examine what |
| 504 // comes right before us in the flow thread, then. | 549 // comes right before us in the flow thread, then. |
| 505 LayoutObject* previousLayoutObject = layoutObject->previousI
nPreOrder(this); | 550 LayoutObject* previousLayoutObject = previousInPreOrderSkipp
ingOutOfFlow(this, layoutObject); |
| 506 if (!previousLayoutObject || previousLayoutObject == this) { | 551 if (!previousLayoutObject || previousLayoutObject == this) { |
| 507 // The spanner is inserted as the first child of the mul
ticol container, | 552 // The spanner is inserted as the first child of the mul
ticol container, |
| 508 // which means that we simply insert a new spanner place
holder at the | 553 // which means that we simply insert a new spanner place
holder at the |
| 509 // beginning. | 554 // beginning. |
| 510 insertBefore = firstMultiColumnBox(); | 555 insertBefore = firstMultiColumnBox(); |
| 511 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlac
eholder = containingColumnSpannerPlaceholder(previousLayoutObject)) { | 556 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlac
eholder = containingColumnSpannerPlaceholder(previousLayoutObject)) { |
| 512 // Before us is another spanner. We belong right after i
t then. | 557 // Before us is another spanner. We belong right after i
t then. |
| 513 insertBefore = previousPlaceholder->nextSiblingMultiColu
mnBox(); | 558 insertBefore = previousPlaceholder->nextSiblingMultiColu
mnBox(); |
| 514 } else { | 559 } else { |
| 515 // We're inside regular column content with both feet. F
ind out which column | 560 // We're inside regular column content with both feet. F
ind out which column |
| 516 // set this is. It needs to be split it into two sets, s
o that we can insert | 561 // set this is. It needs to be split it into two sets, s
o that we can insert |
| 517 // a new spanner placeholder between them. | 562 // a new spanner placeholder between them. |
| 518 setToSplit = mapDescendantToColumnSet(previousLayoutObje
ct); | 563 setToSplit = mapDescendantToColumnSet(previousLayoutObje
ct); |
| 519 ASSERT(setToSplit == mapDescendantToColumnSet(objectAfte
rSubtree)); | 564 ASSERT(setToSplit == mapDescendantToColumnSet(objectAfte
rSubtree)); |
| 520 setToSplit->setNeedsLayoutAndFullPaintInvalidation(Layou
tInvalidationReason::ColumnsChanged); | 565 setToSplit->setNeedsLayoutAndFullPaintInvalidation(Layou
tInvalidationReason::ColumnsChanged); |
| 521 insertBefore = setToSplit->nextSiblingMultiColumnBox(); | 566 insertBefore = setToSplit->nextSiblingMultiColumnBox(); |
| 522 // We've found out which set that needs to be split. Now
proceed to | 567 // We've found out which set that needs to be split. Now
proceed to |
| 523 // inserting the spanner placeholder, and then insert a
second column set. | 568 // inserting the spanner placeholder, and then insert a
second column set. |
| 524 } | 569 } |
| 525 } | 570 } |
| 526 ASSERT(setToSplit || insertBefore); | 571 ASSERT(setToSplit || insertBefore); |
| 527 } | 572 } |
| 528 createAndInsertSpannerPlaceholder(toLayoutBox(layoutObject), insertB
efore); | 573 createAndInsertSpannerPlaceholder(toLayoutBox(layoutObject), insertB
efore); |
| 529 if (setToSplit) | 574 if (setToSplit) |
| 530 createAndInsertMultiColumnSet(insertBefore); | 575 createAndInsertMultiColumnSet(insertBefore); |
| 531 continue; | 576 continue; |
| 532 } | 577 } |
| 533 // This layoutObject is regular column content (i.e. not a spanner). Cre
ate a set if necessary. | 578 // This layoutObject is regular column content (i.e. not a spanner). Cre
ate a set if necessary. |
| 534 while (objectAfterSubtree) { | |
| 535 // Walk through the siblings and find the first one which is either
in-flow or has this | |
| 536 // flow thread as its containing block flow thread. | |
| 537 if (!objectAfterSubtree->isOutOfFlowPositioned()) { | |
| 538 // In-flow objects are always part of the flow thread (unless it
's a spanner - but | |
| 539 // we'll deal with that further below). | |
| 540 break; | |
| 541 } | |
| 542 if (objectAfterSubtree->containingBlock()->flowThreadContainingBlock
() == this) { | |
| 543 // This out-of-flow object is still part of the flow thread, bec
ause its containing | |
| 544 // block (probably relatively positioned) is part of the flow th
read. | |
| 545 break; | |
| 546 } | |
| 547 objectAfterSubtree = objectAfterSubtree->nextInPreOrderAfterChildren
(this); | |
| 548 } | |
| 549 if (objectAfterSubtree) { | 579 if (objectAfterSubtree) { |
| 550 if (LayoutMultiColumnSpannerPlaceholder* placeholder = objectAfterSu
btree->spannerPlaceholder()) { | 580 if (LayoutMultiColumnSpannerPlaceholder* placeholder = objectAfterSu
btree->spannerPlaceholder()) { |
| 551 // If inserted right before a spanner, we need to make sure that
there's a set for us there. | 581 // If inserted right before a spanner, we need to make sure that
there's a set for us there. |
| 552 LayoutBox* previous = placeholder->previousSiblingMultiColumnBox
(); | 582 LayoutBox* previous = placeholder->previousSiblingMultiColumnBox
(); |
| 553 if (!previous || !previous->isLayoutMultiColumnSet()) | 583 if (!previous || !previous->isLayoutMultiColumnSet()) |
| 554 createAndInsertMultiColumnSet(placeholder); | 584 createAndInsertMultiColumnSet(placeholder); |
| 555 } else { | 585 } else { |
| 556 // Otherwise, since |objectAfterSubtree| isn't a spanner, it has
to mean that there's | 586 // Otherwise, since |objectAfterSubtree| isn't a spanner, it has
to mean that there's |
| 557 // already a set for that content. We can use it for this layout
Object too. | 587 // already a set for that content. We can use it for this layout
Object too. |
| 558 ASSERT(mapDescendantToColumnSet(objectAfterSubtree)); | 588 ASSERT(mapDescendantToColumnSet(objectAfterSubtree)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 573 // multicol content that we'll be left with after removal of a descendant (o
r descendant | 603 // multicol content that we'll be left with after removal of a descendant (o
r descendant |
| 574 // subtree). See the header file for more information. Removing content may
mean that we need to | 604 // subtree). See the header file for more information. Removing content may
mean that we need to |
| 575 // remove column sets and/or spanner placeholders. | 605 // remove column sets and/or spanner placeholders. |
| 576 if (m_isBeingEvacuated) | 606 if (m_isBeingEvacuated) |
| 577 return; | 607 return; |
| 578 bool hadContainingPlaceholder = containingColumnSpannerPlaceholder(descendan
t); | 608 bool hadContainingPlaceholder = containingColumnSpannerPlaceholder(descendan
t); |
| 579 bool processedSomething = false; | 609 bool processedSomething = false; |
| 580 LayoutObject* next; | 610 LayoutObject* next; |
| 581 // Remove spanner placeholders that are no longer needed, and merge column s
ets around them. | 611 // Remove spanner placeholders that are no longer needed, and merge column s
ets around them. |
| 582 for (LayoutObject* layoutObject = descendant; layoutObject; layoutObject = n
ext) { | 612 for (LayoutObject* layoutObject = descendant; layoutObject; layoutObject = n
ext) { |
| 583 if (shouldSkipInsertedOrRemovedChild(*layoutObject)) { | 613 if (shouldSkipInsertedOrRemovedChild(this, *layoutObject)) { |
| 584 next = layoutObject->nextInPreOrderAfterChildren(descendant); | 614 next = layoutObject->nextInPreOrderAfterChildren(descendant); |
| 585 continue; | 615 continue; |
| 586 } | 616 } |
| 587 processedSomething = true; | 617 processedSomething = true; |
| 588 LayoutMultiColumnSpannerPlaceholder* placeholder = layoutObject->spanner
Placeholder(); | 618 LayoutMultiColumnSpannerPlaceholder* placeholder = layoutObject->spanner
Placeholder(); |
| 589 if (!placeholder) { | 619 if (!placeholder) { |
| 590 next = layoutObject->nextInPreOrder(descendant); | 620 next = layoutObject->nextInPreOrder(descendant); |
| 591 continue; | 621 continue; |
| 592 } | 622 } |
| 593 next = layoutObject->nextInPreOrderAfterChildren(descendant); // It's a
spanner. Its children are of no interest to us. | 623 next = layoutObject->nextInPreOrderAfterChildren(descendant); // It's a
spanner. Its children are of no interest to us. |
| 594 if (LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox())
{ | 624 if (LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox())
{ |
| 595 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColu
mnBox(); | 625 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColu
mnBox(); |
| 596 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() | 626 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() |
| 597 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSe
t()) { | 627 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSe
t()) { |
| 598 // Need to merge two column sets. | 628 // Need to merge two column sets. |
| 599 nextColumnBox->destroy(); | 629 nextColumnBox->destroy(); |
| 600 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::Colu
mnsChanged); | 630 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::Colu
mnsChanged); |
| 601 invalidateColumnSets(); | 631 invalidateColumnSets(); |
| 602 } | 632 } |
| 603 } | 633 } |
| 604 placeholder->destroy(); | 634 placeholder->destroy(); |
| 605 } | 635 } |
| 606 if (hadContainingPlaceholder || !processedSomething) | 636 if (hadContainingPlaceholder || !processedSomething) |
| 607 return; // No column content will be removed, so we can stop here. | 637 return; // No column content will be removed, so we can stop here. |
| 608 | 638 |
| 609 // Column content will be removed. Does this mean that we should destroy a c
olumn set? | 639 // Column content will be removed. Does this mean that we should destroy a c
olumn set? |
| 610 LayoutMultiColumnSpannerPlaceholder* adjacentPreviousSpannerPlaceholder = 0; | 640 LayoutMultiColumnSpannerPlaceholder* adjacentPreviousSpannerPlaceholder = 0; |
| 611 LayoutObject* previousLayoutObject = descendant->previousInPreOrder(this); | 641 LayoutObject* previousLayoutObject = previousInPreOrderSkippingOutOfFlow(thi
s, descendant); |
| 612 if (previousLayoutObject && previousLayoutObject != this) { | 642 if (previousLayoutObject && previousLayoutObject != this) { |
| 613 adjacentPreviousSpannerPlaceholder = containingColumnSpannerPlaceholder(
previousLayoutObject); | 643 adjacentPreviousSpannerPlaceholder = containingColumnSpannerPlaceholder(
previousLayoutObject); |
| 614 if (!adjacentPreviousSpannerPlaceholder) | 644 if (!adjacentPreviousSpannerPlaceholder) |
| 615 return; // Preceded by column content. Set still needed. | 645 return; // Preceded by column content. Set still needed. |
| 616 } | 646 } |
| 617 LayoutMultiColumnSpannerPlaceholder* adjacentNextSpannerPlaceholder = 0; | 647 LayoutMultiColumnSpannerPlaceholder* adjacentNextSpannerPlaceholder = 0; |
| 618 LayoutObject* nextLayoutObject = descendant->nextInPreOrderAfterChildren(thi
s); | 648 LayoutObject* nextLayoutObject = nextInPreOrderAfterChildrenSkippingOutOfFlo
w(this, descendant); |
| 619 if (nextLayoutObject) { | 649 if (nextLayoutObject) { |
| 620 adjacentNextSpannerPlaceholder = containingColumnSpannerPlaceholder(next
LayoutObject); | 650 adjacentNextSpannerPlaceholder = containingColumnSpannerPlaceholder(next
LayoutObject); |
| 621 if (!adjacentNextSpannerPlaceholder) | 651 if (!adjacentNextSpannerPlaceholder) |
| 622 return; // Followed by column content. Set still needed. | 652 return; // Followed by column content. Set still needed. |
| 623 } | 653 } |
| 624 // We have now determined that, with the removal of |descendant|, we should
remove a column | 654 // We have now determined that, with the removal of |descendant|, we should
remove a column |
| 625 // set. Locate it and remove it. Do it without involving mapDescendantToColu
mnSet(), as that | 655 // set. Locate it and remove it. Do it without involving mapDescendantToColu
mnSet(), as that |
| 626 // might be very slow. Deduce the right set from the spanner placeholders th
at we've already | 656 // might be very slow. Deduce the right set from the spanner placeholders th
at we've already |
| 627 // found. | 657 // found. |
| 628 LayoutMultiColumnSet* columnSetToRemove; | 658 LayoutMultiColumnSet* columnSetToRemove; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 } | 774 } |
| 745 | 775 |
| 746 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const | 776 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
| 747 { | 777 { |
| 748 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) | 778 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
| 749 return columnSet->pageLogicalHeight(); | 779 return columnSet->pageLogicalHeight(); |
| 750 return false; | 780 return false; |
| 751 } | 781 } |
| 752 | 782 |
| 753 } | 783 } |
| OLD | NEW |