Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: Source/core/layout/LayoutMultiColumnFlowThread.cpp

Issue 1163603002: Out-of-flow objects inside multicol may not establish column sets. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « LayoutTests/fast/multicol/dynamic/remove-column-content-next-to-abspos-between-spanners-expected.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « LayoutTests/fast/multicol/dynamic/remove-column-content-next-to-abspos-between-spanners-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698