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

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

Issue 1164723004: Remove block continuation support. (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 | « Source/core/layout/LayoutBlock.h ('k') | Source/core/layout/LayoutObject.h » ('j') | 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) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com) 4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 318
319 void LayoutBlock::styleDidChange(StyleDifference diff, const ComputedStyle* oldS tyle) 319 void LayoutBlock::styleDidChange(StyleDifference diff, const ComputedStyle* oldS tyle)
320 { 320 {
321 LayoutBox::styleDidChange(diff, oldStyle); 321 LayoutBox::styleDidChange(diff, oldStyle);
322 322
323 if (isFloatingOrOutOfFlowPositioned() && oldStyle && !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && parent() && parent()->isLayoutBlockFlow ()) 323 if (isFloatingOrOutOfFlowPositioned() && oldStyle && !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && parent() && parent()->isLayoutBlockFlow ())
324 toLayoutBlock(parent())->removeAnonymousWrappersIfRequired(); 324 toLayoutBlock(parent())->removeAnonymousWrappersIfRequired();
325 325
326 const ComputedStyle& newStyle = styleRef(); 326 const ComputedStyle& newStyle = styleRef();
327 327
328 if (!isAnonymousBlock()) {
329 // Ensure that all of our continuation blocks pick up the new style.
330 for (LayoutBlock* currCont = blockElementContinuation(); currCont; currC ont = currCont->blockElementContinuation()) {
331 LayoutBoxModelObject* nextCont = currCont->continuation();
332 currCont->setContinuation(0);
333 currCont->setStyle(mutableStyle());
334 currCont->setContinuation(nextCont);
335 }
336 }
337
338 if (TextAutosizer* textAutosizer = document().textAutosizer()) 328 if (TextAutosizer* textAutosizer = document().textAutosizer())
339 textAutosizer->record(this); 329 textAutosizer->record(this);
340 330
341 propagateStyleToAnonymousChildren(true); 331 propagateStyleToAnonymousChildren(true);
342 332
343 // It's possible for our border/padding to change, but for the overall logic al width of the block to 333 // It's possible for our border/padding to change, but for the overall logic al width of the block to
344 // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true. 334 // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
345 m_widthAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && n eedsLayout() && borderOrPaddingLogicalWidthChanged(*oldStyle, newStyle); 335 m_widthAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && n eedsLayout() && borderOrPaddingLogicalWidthChanged(*oldStyle, newStyle);
346 336
347 // If the style has unloaded images, want to notify the ResourceLoadPriority Optimizer so that 337 // If the style has unloaded images, want to notify the ResourceLoadPriority Optimizer so that
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 box->invalidateTreeIfNeeded(disabledPaintInvalidationState); 380 box->invalidateTreeIfNeeded(disabledPaintInvalidationState);
391 continue; 381 continue;
392 } 382 }
393 } 383 }
394 384
395 box->invalidateTreeIfNeeded(childPaintInvalidationState); 385 box->invalidateTreeIfNeeded(childPaintInvalidationState);
396 } 386 }
397 } 387 }
398 } 388 }
399 389
400 LayoutBlock* LayoutBlock::continuationBefore(LayoutObject* beforeChild) 390 void LayoutBlock::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObj ect* beforeChild)
401 {
402 if (beforeChild && beforeChild->parent() == this)
403 return this;
404
405 LayoutBlock* curr = toLayoutBlock(continuation());
406 LayoutBlock* nextToLast = this;
407 LayoutBlock* last = this;
408 while (curr) {
409 if (beforeChild && beforeChild->parent() == curr) {
410 if (curr->firstChild() == beforeChild)
411 return last;
412 return curr;
413 }
414
415 nextToLast = last;
416 last = curr;
417 curr = toLayoutBlock(curr->continuation());
418 }
419
420 if (!beforeChild && !last->firstChild())
421 return nextToLast;
422 return last;
423 }
424
425 void LayoutBlock::addChildToContinuation(LayoutObject* newChild, LayoutObject* b eforeChild)
426 {
427 LayoutBlock* flow = continuationBefore(beforeChild);
428 LayoutBoxModelObject* beforeChildParent = 0;
429 if (beforeChild) {
430 beforeChildParent = toLayoutBoxModelObject(beforeChild->parent());
431 // Don't attempt to insert into something that isn't a LayoutBlockFlow ( block
432 // container). While the DOM nodes of |beforeChild| and |newChild| are s iblings, there may
433 // be anonymous table wrapper objects around |beforeChild| on the layout side. Therefore,
434 // find the nearest LayoutBlockFlow. If it turns out that the new layout Object doesn't belong
435 // inside the anonymous table, this will make sure that it's really put on the outside. If
436 // it turns out that it does belong inside it, the normal child insertio n machinery will
437 // make sure it ends up there, and at the right place too. We cannot jus t guess that it's
438 // going to be right under the parent of |beforeChild|.
439 while (beforeChildParent && !beforeChildParent->isLayoutBlockFlow()) {
440 ASSERT(!beforeChildParent->virtualContinuation());
441 ASSERT(beforeChildParent->isAnonymous());
442 RELEASE_ASSERT(beforeChildParent != this);
443 beforeChildParent = toLayoutBoxModelObject(beforeChildParent->parent ());
444 }
445 ASSERT(beforeChildParent);
446 } else {
447 LayoutBoxModelObject* cont = flow->continuation();
448 if (cont)
449 beforeChildParent = cont;
450 else
451 beforeChildParent = flow;
452 }
453
454 if (newChild->isFloatingOrOutOfFlowPositioned()) {
455 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
456 return;
457 }
458
459 // A continuation always consists of two potential candidates: a block or an anonymous
460 // column span box holding column span children.
461 bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan( );
462 bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->styl e()->columnSpan();
463 bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
464
465 if (flow == beforeChildParent) {
466 flow->addChildIgnoringContinuation(newChild, beforeChild);
467 return;
468 }
469
470 // The goal here is to match up if we can, so that we can coalesce and creat e the
471 // minimal # of continuations needed for the inline.
472 if (childIsNormal == bcpIsNormal) {
473 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
474 return;
475 }
476 if (flowIsNormal == childIsNormal) {
477 flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an a ppend.
478 return;
479 }
480 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
481 }
482
483
484 void LayoutBlock::addChildToAnonymousColumnBlocks(LayoutObject* newChild, Layout Object* beforeChild)
485 {
486 ASSERT(!continuation()); // We don't yet support column spans that aren't im mediate children of the multi-column block.
487
488 // The goal is to locate a suitable box in which to place our child.
489 LayoutBlock* beforeChildParent = 0;
490 if (beforeChild) {
491 LayoutObject* curr = beforeChild;
492 while (curr && curr->parent() != this)
493 curr = curr->parent();
494 beforeChildParent = toLayoutBlock(curr);
495 ASSERT(beforeChildParent);
496 ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent ->isAnonymousColumnSpanBlock());
497 } else {
498 beforeChildParent = toLayoutBlock(lastChild());
499 }
500
501 // If the new child is floating or positioned it can just go in that block.
502 if (newChild->isFloatingOrOutOfFlowPositioned()) {
503 beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, befor eChild);
504 return;
505 }
506
507 // See if the child can be placed in the box.
508 bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->i sInline();
509 bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColum nSpanBlock();
510
511 if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
512 beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, befor eChild);
513 return;
514 }
515
516 if (!beforeChild) {
517 // Create a new block of the correct type.
518 LayoutBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanB lock() : createAnonymousColumnsBlock();
519 children()->appendChildNode(this, newBox);
520 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
521 return;
522 }
523
524 LayoutObject* immediateChild = beforeChild;
525 bool isPreviousBlockViable = true;
526 while (immediateChild->parent() != this) {
527 if (isPreviousBlockViable)
528 isPreviousBlockViable = !immediateChild->previousSibling();
529 immediateChild = immediateChild->parent();
530 }
531 if (isPreviousBlockViable && immediateChild->previousSibling()) {
532 toLayoutBlock(immediateChild->previousSibling())->addChildIgnoringAnonym ousColumnBlocks(newChild, 0); // Treat like an append.
533 return;
534 }
535
536 // Split our anonymous blocks.
537 LayoutObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
538
539
540 // Create a new anonymous box of the appropriate type.
541 LayoutBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock () : createAnonymousColumnsBlock();
542 children()->insertChildNode(this, newBox, newBeforeChild);
543 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
544 return;
545 }
546
547 LayoutBlockFlow* LayoutBlock::containingColumnsBlock(bool allowAnonymousColumnBl ock)
548 {
549 LayoutBlock* firstChildIgnoringAnonymousWrappers = 0;
550 for (LayoutObject* curr = this; curr; curr = curr->parent()) {
551 if (!curr->isLayoutBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isDocumentElement() || curr->isLayoutView() || cur r->hasOverflowClip()
552 || curr->isInlineBlockOrInlineTable())
553 return 0;
554
555 // FIXME: LayoutObjects that do special management of their children (ta bles, buttons,
556 // lists, flexboxes, etc.) breaks when the flow is split through them. D isabling
557 // multi-column for them to avoid this problem.)
558 if (!curr->isLayoutBlockFlow() || curr->isListItem())
559 return 0;
560
561 LayoutBlockFlow* currBlock = toLayoutBlockFlow(curr);
562 if (!currBlock->createsAnonymousWrapper())
563 firstChildIgnoringAnonymousWrappers = currBlock;
564
565 if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
566 return toLayoutBlockFlow(firstChildIgnoringAnonymousWrappers);
567
568 if (currBlock->isAnonymousColumnSpanBlock())
569 return 0;
570 }
571 return 0;
572 }
573
574 LayoutBlock* LayoutBlock::clone() const
575 {
576 LayoutBlock* cloneBlock;
577 if (isAnonymousBlock()) {
578 cloneBlock = createAnonymousBlock();
579 cloneBlock->setChildrenInline(childrenInline());
580 } else {
581 LayoutObject* cloneLayoutObject = toElement(node())->createLayoutObject( styleRef());
582 cloneBlock = toLayoutBlock(cloneLayoutObject);
583 cloneBlock->setStyle(mutableStyle());
584
585 // This takes care of setting the right value of childrenInline in case
586 // generated content is added to cloneBlock and 'this' does not have
587 // generated content added yet.
588 cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->fir stChild()->isInline() : childrenInline());
589 }
590 cloneBlock->setIsInsideFlowThread(isInsideFlowThread());
591 return cloneBlock;
592 }
593
594 void LayoutBlock::splitBlocks(LayoutBlock* fromBlock, LayoutBlock* toBlock,
595 LayoutBlock* middleBlock,
596 LayoutObject* beforeChild, LayoutBoxModelObject* oldCont)
597 {
598 ASSERT(isDescendantOf(fromBlock));
599
600 if (!beforeChild && isAfterContent(lastChild()))
601 beforeChild = lastChild();
602
603 Vector<LayoutBlock*> blocksToClone;
604 for (LayoutObject* o = this; o != fromBlock; o = o->parent())
605 blocksToClone.append(toLayoutBlock(o));
606
607 // Create a new clone of the top-most block.
608 LayoutBlock* topMostBlockToClone = blocksToClone.last();
609 LayoutBlock* cloneBlock = topMostBlockToClone->clone();
610
611 // Put |cloneBlock| as a child of |toBlock|.
612 toBlock->children()->appendChildNode(toBlock, cloneBlock);
613
614 // Now take all the children after |topMostBlockToClone| and remove them fro m the |fromBlock|
615 // and put them in the |toBlock|.
616 fromBlock->moveChildrenTo(toBlock, topMostBlockToClone->nextSibling(), nullp tr, true);
617
618 LayoutBlock* currentBlockParent = topMostBlockToClone;
619 LayoutBlock* cloneBlockParent = cloneBlock;
620
621 // Clone the blocks from top to down to ensure any new object will be added into a rooted tree.
622 // Note that we have already cloned the top-most one, so the loop begins fro m size - 2.
623 for (int i = static_cast<int>(blocksToClone.size()) - 2; i >= 0; --i) {
624 // Hook the clone up as a continuation of |currentBlockParent|. Note we do encounter
625 // anonymous blocks possibly as we walk down the block chain. When we s plit an
626 // anonymous block, there's no need to do any continuation hookup, since we haven't
627 // actually split a real element.
628 if (!currentBlockParent->isAnonymousBlock()) {
629 LayoutBoxModelObject* oldCont = currentBlockParent->continuation();
630 currentBlockParent->setContinuation(cloneBlock);
631 cloneBlock->setContinuation(oldCont);
632 }
633
634 // Create a new clone.
635 LayoutBlock* currentBlock = blocksToClone[i];
636 cloneBlock = currentBlock->clone();
637
638 // Insert the |cloneBlock| as the first child of |cloneBlockParent|.
639 cloneBlockParent->addChildIgnoringContinuation(cloneBlock, nullptr);
640
641 // Take all the children after |currentBlock| and remove them from the | currentBlockParent|
642 // and put them to the end of the |cloneParent|.
643 currentBlockParent->moveChildrenTo(cloneBlockParent, currentBlock->nextS ibling(), nullptr, true);
644
645 cloneBlockParent = cloneBlock;
646 currentBlockParent = currentBlock;
647 }
648
649 // The last block to clone is |this|, and the current |cloneBlock| is cloned from |this|.
650 ASSERT(this == blocksToClone.first());
651
652 // Hook |cloneBlock| up as the continuation of the |middleBlock|.
653 if (!isAnonymousBlock()) {
654 cloneBlock->setContinuation(oldCont);
655 middleBlock->setContinuation(cloneBlock);
656 }
657
658 // Now take all of the children from |beforeChild| to the end and remove
659 // them from |this| and place them in the |cloneBlock|.
660 moveChildrenTo(cloneBlock, beforeChild, nullptr, true);
661 }
662
663 void LayoutBlock::splitFlow(LayoutObject* beforeChild, LayoutBlock* newBlockBox,
664 LayoutObject* newChild, LayoutBoxModelObject* oldCont)
665 {
666 LayoutBlock* pre = 0;
667 LayoutBlock* block = containingColumnsBlock();
668
669 // Delete our line boxes before we do the inline split into continuations.
670 block->deleteLineBoxTree();
671
672 bool madeNewBeforeBlock = false;
673 if (block->isAnonymousColumnsBlock()) {
674 // We can reuse this block and make it the preBlock of the next continua tion.
675 pre = block;
676 pre->removePositionedObjects(0);
677 if (block->isLayoutBlockFlow())
678 toLayoutBlockFlow(pre)->removeFloatingObjects();
679 block = toLayoutBlock(block->parent());
680 } else {
681 // No anonymous block available for use. Make one.
682 pre = block->createAnonymousColumnsBlock();
683 pre->setChildrenInline(false);
684 madeNewBeforeBlock = true;
685 }
686
687 LayoutBlock* post = block->createAnonymousColumnsBlock();
688 post->setChildrenInline(false);
689
690 LayoutObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nex tSibling();
691 if (madeNewBeforeBlock)
692 block->children()->insertChildNode(block, pre, boxFirst);
693 block->children()->insertChildNode(block, newBlockBox, boxFirst);
694 block->children()->insertChildNode(block, post, boxFirst);
695 block->setChildrenInline(false);
696
697 if (madeNewBeforeBlock)
698 block->moveChildrenTo(pre, boxFirst, 0, true);
699
700 splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
701
702 // We already know the newBlockBox isn't going to contain inline kids, so av oid wasting
703 // time in makeChildrenNonInline by just setting this explicitly up front.
704 newBlockBox->setChildrenInline(false);
705
706 newBlockBox->addChild(newChild);
707
708 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images)
709 // get deleted properly. Because objects moves from the pre block into the post block, we want to
710 // make new line boxes instead of leaving the old line boxes around.
711 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvalid ationReason::ColumnsChanged);
712 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInval idationReason::ColumnsChanged);
713 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvali dationReason::ColumnsChanged);
714 }
715
716 void LayoutBlock::makeChildrenAnonymousColumnBlocks(LayoutObject* beforeChild, L ayoutBlockFlow* newBlockBox, LayoutObject* newChild)
717 {
718 LayoutBlockFlow* pre = 0;
719 LayoutBlockFlow* post = 0;
720 LayoutBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|. Assign to a variable
721 // so that we don't have to patch all of the rest of the code later on.
722
723 // Delete the block's line boxes before we do the split.
724 block->deleteLineBoxTree();
725
726 if (beforeChild && beforeChild->parent() != this)
727 beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
728
729 if (beforeChild != firstChild()) {
730 pre = block->createAnonymousColumnsBlock();
731 pre->setChildrenInline(block->childrenInline());
732 }
733
734 if (beforeChild) {
735 post = block->createAnonymousColumnsBlock();
736 post->setChildrenInline(block->childrenInline());
737 }
738
739 LayoutObject* boxFirst = block->firstChild();
740 if (pre)
741 block->children()->insertChildNode(block, pre, boxFirst);
742 block->children()->insertChildNode(block, newBlockBox, boxFirst);
743 if (post)
744 block->children()->insertChildNode(block, post, boxFirst);
745 block->setChildrenInline(false);
746
747 // The pre/post blocks always have layers, so we know to always do a full in sert/remove (so we pass true as the last argument).
748 block->moveChildrenTo(pre, boxFirst, beforeChild, true);
749 block->moveChildrenTo(post, beforeChild, 0, true);
750
751 // We already know the newBlockBox isn't going to contain inline kids, so av oid wasting
752 // time in makeChildrenNonInline by just setting this explicitly up front.
753 newBlockBox->setChildrenInline(false);
754
755 newBlockBox->addChild(newChild);
756
757 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images)
758 // get deleted properly. Because objects moved from the pre block into the post block, we want to
759 // make new line boxes instead of leaving the old line boxes around.
760 if (pre)
761 pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInv alidationReason::ColumnsChanged);
762 block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInval idationReason::ColumnsChanged);
763 if (post)
764 post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutIn validationReason::ColumnsChanged);
765 }
766
767 LayoutBlockFlow* LayoutBlock::columnsBlockForSpanningElement(LayoutObject* newCh ild)
768 {
769 // FIXME: This function is the gateway for the addition of column-span suppo rt. It will
770 // be added to in three stages:
771 // (1) Immediate children of a multi-column block can span.
772 // (2) Nested block-level children with only block-level ancestors between t hem and the multi-column block can span.
773 // (3) Nested children with block or inline ancestors between them and the m ulti-column block can span (this is when we
774 // cross the streams and have to cope with both types of continuations mixed together).
775 // This function currently supports (1) and (2).
776 LayoutBlockFlow* columnsBlockAncestor = 0;
777 if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isB eforeOrAfterContent()
778 && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !newChild->isTablePart()
779 && !isAnonymousColumnSpanBlock()) {
780 columnsBlockAncestor = containingColumnsBlock(false);
781 if (columnsBlockAncestor) {
782 // Make sure that none of the parent ancestors have a continuation.
783 // If yes, we do not want split the block into continuations.
784 LayoutObject* curr = this;
785 while (curr && curr != columnsBlockAncestor) {
786 if (curr->isLayoutBlock() && toLayoutBlock(curr)->continuation() ) {
787 columnsBlockAncestor = 0;
788 break;
789 }
790 curr = curr->parent();
791 }
792 }
793 }
794 return columnsBlockAncestor;
795 }
796
797 void LayoutBlock::addChildIgnoringAnonymousColumnBlocks(LayoutObject* newChild, LayoutObject* beforeChild)
798 { 391 {
799 if (beforeChild && beforeChild->parent() != this) { 392 if (beforeChild && beforeChild->parent() != this) {
800 LayoutObject* beforeChildContainer = beforeChild->parent(); 393 LayoutObject* beforeChildContainer = beforeChild->parent();
801 while (beforeChildContainer->parent() != this) 394 while (beforeChildContainer->parent() != this)
802 beforeChildContainer = beforeChildContainer->parent(); 395 beforeChildContainer = beforeChildContainer->parent();
803 ASSERT(beforeChildContainer); 396 ASSERT(beforeChildContainer);
804 397
805 if (beforeChildContainer->isAnonymous()) { 398 if (beforeChildContainer->isAnonymous()) {
806 // If the requested beforeChild is not one of our children, then thi s is because 399 // If the requested beforeChild is not one of our children, then thi s is because
807 // there is an anonymous container within this object that contains the beforeChild. 400 // there is an anonymous container within this object that contains the beforeChild.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 467
875 LayoutBox::addChild(newChild, beforeChild); 468 LayoutBox::addChild(newChild, beforeChild);
876 469
877 if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isLayo utBlock()) 470 if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isLayo utBlock())
878 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this); 471 toLayoutBlock(parent())->removeLeftoverAnonymousBlock(this);
879 // this object may be dead here 472 // this object may be dead here
880 } 473 }
881 474
882 void LayoutBlock::addChild(LayoutObject* newChild, LayoutObject* beforeChild) 475 void LayoutBlock::addChild(LayoutObject* newChild, LayoutObject* beforeChild)
883 { 476 {
884 if (continuation() && !isAnonymousBlock()) 477 addChildIgnoringContinuation(newChild, beforeChild);
885 addChildToContinuation(newChild, beforeChild);
886 else
887 addChildIgnoringContinuation(newChild, beforeChild);
888 }
889
890 void LayoutBlock::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObj ect* beforeChild)
891 {
892 if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumns Block() || firstChild()->isAnonymousColumnSpanBlock()))
893 addChildToAnonymousColumnBlocks(newChild, beforeChild);
894 else
895 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
896 } 478 }
897 479
898 static void getInlineRun(LayoutObject* start, LayoutObject* boundary, 480 static void getInlineRun(LayoutObject* start, LayoutObject* boundary,
899 LayoutObject*& inlineRunStart, 481 LayoutObject*& inlineRunStart,
900 LayoutObject*& inlineRunEnd) 482 LayoutObject*& inlineRunEnd)
901 { 483 {
902 // Beginning at |start| we find the largest contiguous run of inlines that 484 // Beginning at |start| we find the largest contiguous run of inlines that
903 // we can. We denote the run with start and end points, |inlineRunStart| 485 // we can. We denote the run with start and end points, |inlineRunStart|
904 // and |inlineRunEnd|. Note that these two values may be the same if 486 // and |inlineRunEnd|. Note that these two values may be the same if
905 // we encounter only one inline. 487 // we encounter only one inline.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 if (parent->children()->lastChild() == this) 585 if (parent->children()->lastChild() == this)
1004 parent->children()->setLastChild(lastPromotee); 586 parent->children()->setLastChild(lastPromotee);
1005 } 587 }
1006 588
1007 void LayoutBlock::removeLeftoverAnonymousBlock(LayoutBlock* child) 589 void LayoutBlock::removeLeftoverAnonymousBlock(LayoutBlock* child)
1008 { 590 {
1009 ASSERT(child->isAnonymousBlock()); 591 ASSERT(child->isAnonymousBlock());
1010 ASSERT(!child->childrenInline()); 592 ASSERT(!child->childrenInline());
1011 ASSERT(child->parent() == this); 593 ASSERT(child->parent() == this);
1012 594
1013 if (child->continuation() || (child->firstChild() && (child->isAnonymousColu mnSpanBlock() || child->isAnonymousColumnsBlock()))) 595 if (child->continuation())
1014 return; 596 return;
1015 597
1016 // Promote all the leftover anonymous block's children (to become children o f this block 598 // Promote all the leftover anonymous block's children (to become children o f this block
1017 // instead). We still want to keep the leftover block in the tree for a mome nt, for notification 599 // instead). We still want to keep the leftover block in the tree for a mome nt, for notification
1018 // purposes done further below (flow threads and grids). 600 // purposes done further below (flow threads and grids).
1019 child->promoteAllChildrenAndInsertAfter(); 601 child->promoteAllChildrenAndInsertAfter();
1020 602
1021 // Remove all the information in the flow thread associated with the leftove r anonymous block. 603 // Remove all the information in the flow thread associated with the leftove r anonymous block.
1022 child->removeFromLayoutFlowThread(); 604 child->removeFromLayoutFlowThread();
1023 605
(...skipping 14 matching lines...) Expand all
1038 return false; 620 return false;
1039 621
1040 if ((prev && (!prev->isAnonymousBlock() || toLayoutBlock(prev)->continuation () || toLayoutBlock(prev)->beingDestroyed())) 622 if ((prev && (!prev->isAnonymousBlock() || toLayoutBlock(prev)->continuation () || toLayoutBlock(prev)->beingDestroyed()))
1041 || (next && (!next->isAnonymousBlock() || toLayoutBlock(next)->continuat ion() || toLayoutBlock(next)->beingDestroyed()))) 623 || (next && (!next->isAnonymousBlock() || toLayoutBlock(next)->continuat ion() || toLayoutBlock(next)->beingDestroyed())))
1042 return false; 624 return false;
1043 625
1044 if ((prev && (prev->isRubyRun() || prev->isRubyBase())) 626 if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
1045 || (next && (next->isRubyRun() || next->isRubyBase()))) 627 || (next && (next->isRubyRun() || next->isRubyBase())))
1046 return false; 628 return false;
1047 629
1048 if (!prev || !next) 630 return true;
1049 return true;
1050
1051 // Make sure the types of the anonymous blocks match up.
1052 return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1053 && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBloc k();
1054 } 631 }
1055 632
1056 void LayoutBlock::removeAnonymousWrappersIfRequired() 633 void LayoutBlock::removeAnonymousWrappersIfRequired()
1057 { 634 {
1058 ASSERT(isLayoutBlockFlow()); 635 ASSERT(isLayoutBlockFlow());
1059 Vector<LayoutBox*, 16> blocksToRemove; 636 Vector<LayoutBox*, 16> blocksToRemove;
1060 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { 637 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) {
1061 if (child->isFloatingOrOutOfFlowPositioned()) 638 if (child->isFloatingOrOutOfFlowPositioned())
1062 continue; 639 continue;
1063 640
(...skipping 20 matching lines...) Expand all
1084 // It's possible that this block's destruction may have been triggered by th e 661 // It's possible that this block's destruction may have been triggered by th e
1085 // child's removal. Just bail if the anonymous child block is already being 662 // child's removal. Just bail if the anonymous child block is already being
1086 // destroyed. See crbug.com/282088 663 // destroyed. See crbug.com/282088
1087 if (child->beingDestroyed()) 664 if (child->beingDestroyed())
1088 return; 665 return;
1089 parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInva lidationReason::ChildAnonymousBlockChanged); 666 parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInva lidationReason::ChildAnonymousBlockChanged);
1090 parent->setChildrenInline(child->childrenInline()); 667 parent->setChildrenInline(child->childrenInline());
1091 LayoutObject* nextSibling = child->nextSibling(); 668 LayoutObject* nextSibling = child->nextSibling();
1092 669
1093 parent->children()->removeChildNode(parent, child, child->hasLayer()); 670 parent->children()->removeChildNode(parent, child, child->hasLayer());
1094 // FIXME: Get rid of the temporary disabling of continuations. This is neede d by the old
1095 // multicol implementation, because of buggy block continuation handling (wh ich is hard and
1096 // rather pointless to fix at this point). Support for block continuations c an be removed
1097 // together with the old multicol implementation. crbug.com/408123
1098 LayoutBoxModelObject* temporarilyInactiveContinuation = parent->continuation ();
1099 if (temporarilyInactiveContinuation)
1100 parent->setContinuation(0);
1101 child->moveAllChildrenTo(parent, nextSibling, child->hasLayer()); 671 child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
1102 if (temporarilyInactiveContinuation)
1103 parent->setContinuation(temporarilyInactiveContinuation);
1104 // Explicitly delete the child's line box tree, or the special anonymous 672 // Explicitly delete the child's line box tree, or the special anonymous
1105 // block handling in willBeDestroyed will cause problems. 673 // block handling in willBeDestroyed will cause problems.
1106 child->deleteLineBoxTree(); 674 child->deleteLineBoxTree();
1107 child->destroy(); 675 child->destroy();
1108 } 676 }
1109 677
1110 void LayoutBlock::removeChild(LayoutObject* oldChild) 678 void LayoutBlock::removeChild(LayoutObject* oldChild)
1111 { 679 {
1112 // No need to waste time in merging or removing empty anonymous blocks. 680 // No need to waste time in merging or removing empty anonymous blocks.
1113 // We can just bail out if our document is getting destroyed. 681 // We can just bail out if our document is getting destroyed.
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 { 1299 {
1732 BlockPainter(*this).paintObject(paintInfo, paintOffset); 1300 BlockPainter(*this).paintObject(paintInfo, paintOffset);
1733 } 1301 }
1734 1302
1735 LayoutInline* LayoutBlock::inlineElementContinuation() const 1303 LayoutInline* LayoutBlock::inlineElementContinuation() const
1736 { 1304 {
1737 LayoutBoxModelObject* continuation = this->continuation(); 1305 LayoutBoxModelObject* continuation = this->continuation();
1738 return continuation && continuation->isInline() ? toLayoutInline(continuatio n) : 0; 1306 return continuation && continuation->isInline() ? toLayoutInline(continuatio n) : 0;
1739 } 1307 }
1740 1308
1741 LayoutBlock* LayoutBlock::blockElementContinuation() const
1742 {
1743 LayoutBoxModelObject* currentContinuation = continuation();
1744 if (!currentContinuation || currentContinuation->isInline())
1745 return 0;
1746 LayoutBlock* nextContinuation = toLayoutBlock(currentContinuation);
1747 if (nextContinuation->isAnonymousBlock())
1748 return nextContinuation->blockElementContinuation();
1749 return nextContinuation;
1750 }
1751
1752 ContinuationOutlineTableMap* continuationOutlineTable() 1309 ContinuationOutlineTableMap* continuationOutlineTable()
1753 { 1310 {
1754 DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ()); 1311 DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
1755 return &table; 1312 return &table;
1756 } 1313 }
1757 1314
1758 void LayoutBlock::addContinuationWithOutline(LayoutInline* flow) 1315 void LayoutBlock::addContinuationWithOutline(LayoutInline* flow)
1759 { 1316 {
1760 // We can't make this work if the inline is in a layer. We'll just rely on the broken 1317 // We can't make this work if the inline is in a layer. We'll just rely on the broken
1761 // way of painting. 1318 // way of painting.
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top); 2605 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top);
3049 // It's common for this rect to be entirely contained in our box, so exclude that simple case. 2606 // It's common for this rect to be entirely contained in our box, so exclude that simple case.
3050 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)) ) 2607 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)) )
3051 rects.append(rect); 2608 rects.append(rect);
3052 } 2609 }
3053 } 2610 }
3054 } 2611 }
3055 2612
3056 LayoutBox* LayoutBlock::createAnonymousBoxWithSameTypeAs(const LayoutObject* par ent) const 2613 LayoutBox* LayoutBlock::createAnonymousBoxWithSameTypeAs(const LayoutObject* par ent) const
3057 { 2614 {
3058 if (isAnonymousColumnsBlock())
3059 return createAnonymousColumnsWithParent(parent);
3060 if (isAnonymousColumnSpanBlock())
3061 return createAnonymousColumnSpanWithParent(parent);
3062 return createAnonymousWithParentAndDisplay(parent, style()->display()); 2615 return createAnonymousWithParentAndDisplay(parent, style()->display());
3063 } 2616 }
3064 2617
3065 LayoutUnit LayoutBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundar yRule pageBoundaryRule) const 2618 LayoutUnit LayoutBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundar yRule pageBoundaryRule) const
3066 { 2619 {
3067 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 2620 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
3068 if (!pageLogicalHeight) 2621 if (!pageLogicalHeight)
3069 return logicalOffset; 2622 return logicalOffset;
3070 2623
3071 // The logicalOffset is in our coordinate space. We can add in our pushed o ffset. 2624 // The logicalOffset is in our coordinate space. We can add in our pushed o ffset.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3202 newBox = LayoutBlockFlow::createAnonymous(&parent->document()); 2755 newBox = LayoutBlockFlow::createAnonymous(&parent->document());
3203 newDisplay = BLOCK; 2756 newDisplay = BLOCK;
3204 } 2757 }
3205 2758
3206 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp lay(parent->styleRef(), newDisplay); 2759 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp lay(parent->styleRef(), newDisplay);
3207 parent->updateAnonymousChildStyle(*newBox, *newStyle); 2760 parent->updateAnonymousChildStyle(*newBox, *newStyle);
3208 newBox->setStyle(newStyle.release()); 2761 newBox->setStyle(newStyle.release());
3209 return newBox; 2762 return newBox;
3210 } 2763 }
3211 2764
3212 LayoutBlockFlow* LayoutBlock::createAnonymousColumnsWithParent(const LayoutObjec t* parent)
3213 {
3214 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp lay(parent->styleRef(), BLOCK);
3215 newStyle->inheritColumnPropertiesFrom(parent->styleRef());
3216
3217 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&parent->document ());
3218 parent->updateAnonymousChildStyle(*newBox, *newStyle);
3219 newBox->setStyle(newStyle.release());
3220 return newBox;
3221 }
3222
3223 LayoutBlockFlow* LayoutBlock::createAnonymousColumnSpanWithParent(const LayoutOb ject* parent)
3224 {
3225 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp lay(parent->styleRef(), BLOCK);
3226 newStyle->setColumnSpan(ColumnSpanAll);
3227
3228 LayoutBlockFlow* newBox = LayoutBlockFlow::createAnonymous(&parent->document ());
3229 parent->updateAnonymousChildStyle(*newBox, *newStyle);
3230 newBox->setStyle(newStyle.release());
3231 return newBox;
3232 }
3233
3234 static bool recalcNormalFlowChildOverflowIfNeeded(LayoutObject* layoutObject) 2765 static bool recalcNormalFlowChildOverflowIfNeeded(LayoutObject* layoutObject)
3235 { 2766 {
3236 if (layoutObject->isOutOfFlowPositioned() || !layoutObject->needsOverflowRec alcAfterStyleChange()) 2767 if (layoutObject->isOutOfFlowPositioned() || !layoutObject->needsOverflowRec alcAfterStyleChange())
3237 return false; 2768 return false;
3238 2769
3239 ASSERT(layoutObject->isLayoutBlock()); 2770 ASSERT(layoutObject->isLayoutBlock());
3240 return toLayoutBlock(layoutObject)->recalcOverflowAfterStyleChange(); 2771 return toLayoutBlock(layoutObject)->recalcOverflowAfterStyleChange();
3241 } 2772 }
3242 2773
3243 bool LayoutBlock::recalcChildOverflowAfterStyleChange() 2774 bool LayoutBlock::recalcChildOverflowAfterStyleChange()
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const 2913 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const
3383 { 2914 {
3384 showLayoutObject(); 2915 showLayoutObject();
3385 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 2916 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
3386 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 2917 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
3387 } 2918 }
3388 2919
3389 #endif 2920 #endif
3390 2921
3391 } // namespace blink 2922 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutBlock.h ('k') | Source/core/layout/LayoutObject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698