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 |