OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 2367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2378 } | 2378 } |
2379 } | 2379 } |
2380 | 2380 |
2381 LayoutBlock::removeChild(oldChild); | 2381 LayoutBlock::removeChild(oldChild); |
2382 | 2382 |
2383 LayoutObject* child = prev ? prev : next; | 2383 LayoutObject* child = prev ? prev : next; |
2384 if (mergedAnonymousBlocks && child && !child->previousSibling() && !child->n
extSibling()) { | 2384 if (mergedAnonymousBlocks && child && !child->previousSibling() && !child->n
extSibling()) { |
2385 // The removal has knocked us down to containing only a single anonymous | 2385 // The removal has knocked us down to containing only a single anonymous |
2386 // box. We can go ahead and pull the content right back up into our | 2386 // box. We can go ahead and pull the content right back up into our |
2387 // box. | 2387 // box. |
2388 collapseAnonymousBlockChild(this, toLayoutBlock(child)); | 2388 collapseAnonymousBlockChild(toLayoutBlockFlow(child)); |
2389 } | 2389 } |
2390 | 2390 |
2391 if (!firstChild()) { | 2391 if (!firstChild()) { |
2392 // If this was our last child be sure to clear out our line boxes. | 2392 // If this was our last child be sure to clear out our line boxes. |
2393 if (childrenInline()) | 2393 if (childrenInline()) |
2394 deleteLineBoxTree(); | 2394 deleteLineBoxTree(); |
2395 | 2395 |
2396 // If we are an empty anonymous block in the continuation chain, | 2396 // If we are an empty anonymous block in the continuation chain, |
2397 // we need to remove ourself and fix the continuation chain. | 2397 // we need to remove ourself and fix the continuation chain. |
2398 if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->is
ListMarker()) { | 2398 if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->is
ListMarker()) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2479 newContainer->reparentSubsequentFloatingOrOutOfFlowSiblings(); | 2479 newContainer->reparentSubsequentFloatingOrOutOfFlowSiblings(); |
2480 return; | 2480 return; |
2481 } | 2481 } |
2482 LayoutObject* next = child->nextSibling(); | 2482 LayoutObject* next = child->nextSibling(); |
2483 if (next && next->isAnonymousBlock() && next->isLayoutBlockFlow()) { | 2483 if (next && next->isAnonymousBlock() && next->isLayoutBlockFlow()) { |
2484 LayoutBlockFlow* newContainer = toLayoutBlockFlow(next); | 2484 LayoutBlockFlow* newContainer = toLayoutBlockFlow(next); |
2485 moveChildTo(newContainer, child, newContainer->firstChild(), false); | 2485 moveChildTo(newContainer, child, newContainer->firstChild(), false); |
2486 } | 2486 } |
2487 } | 2487 } |
2488 | 2488 |
| 2489 void LayoutBlockFlow::collapseAnonymousBlockChild(LayoutBlockFlow* child) |
| 2490 { |
| 2491 // It's possible that this block's destruction may have been triggered by th
e |
| 2492 // child's removal. Just bail if the anonymous child block is already being |
| 2493 // destroyed. See crbug.com/282088 |
| 2494 if (child->beingDestroyed()) |
| 2495 return; |
| 2496 if (child->continuation()) |
| 2497 return; |
| 2498 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by desi
gn, so we don't remove them. |
| 2499 if (child->isRubyRun() || child->isRubyBase()) |
| 2500 return; |
| 2501 setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvalidation
Reason::ChildAnonymousBlockChanged); |
| 2502 |
| 2503 child->moveAllChildrenTo(this, child->nextSibling(), child->hasLayer()); |
| 2504 setChildrenInline(child->childrenInline()); |
| 2505 |
| 2506 children()->removeChildNode(this, child, child->hasLayer()); |
| 2507 child->destroy(); |
| 2508 } |
| 2509 |
2489 static bool isMergeableAnonymousBlock(const LayoutBlockFlow* block) | 2510 static bool isMergeableAnonymousBlock(const LayoutBlockFlow* block) |
2490 { | 2511 { |
2491 return block->isAnonymousBlock() && !block->continuation() && !block->beingD
estroyed() && !block->isRubyRun() && !block->isRubyBase(); | 2512 return block->isAnonymousBlock() && !block->continuation() && !block->beingD
estroyed() && !block->isRubyRun() && !block->isRubyBase(); |
2492 } | 2513 } |
2493 | 2514 |
2494 bool LayoutBlockFlow::mergeSiblingContiguousAnonymousBlock(LayoutBlockFlow* sibl
ingThatMayBeDeleted) | 2515 bool LayoutBlockFlow::mergeSiblingContiguousAnonymousBlock(LayoutBlockFlow* sibl
ingThatMayBeDeleted) |
2495 { | 2516 { |
2496 // Note: |this| and |siblingThatMayBeDeleted| may not be adjacent siblings a
t this point. There | 2517 // Note: |this| and |siblingThatMayBeDeleted| may not be adjacent siblings a
t this point. There |
2497 // may be an object between them which is about to be removed. | 2518 // may be an object between them which is about to be removed. |
2498 | 2519 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 child = sibling; | 2568 child = sibling; |
2548 } | 2569 } |
2549 } | 2570 } |
2550 | 2571 |
2551 void LayoutBlockFlow::makeChildrenInlineIfPossible() | 2572 void LayoutBlockFlow::makeChildrenInlineIfPossible() |
2552 { | 2573 { |
2553 // Collapsing away anonymous wrappers isn't relevant for the children of ano
nymous blocks, unless they are ruby bases. | 2574 // Collapsing away anonymous wrappers isn't relevant for the children of ano
nymous blocks, unless they are ruby bases. |
2554 if (isAnonymousBlock() && !isRubyBase()) | 2575 if (isAnonymousBlock() && !isRubyBase()) |
2555 return; | 2576 return; |
2556 | 2577 |
2557 Vector<LayoutBlock*, 3> blocksToRemove; | 2578 Vector<LayoutBlockFlow*, 3> blocksToRemove; |
2558 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { | 2579 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
2559 if (child->isFloating()) | 2580 if (child->isFloating()) |
2560 continue; | 2581 continue; |
2561 if (child->isOutOfFlowPositioned()) | 2582 if (child->isOutOfFlowPositioned()) |
2562 continue; | 2583 continue; |
2563 | 2584 |
2564 // There are still block children in the container, so any anonymous wra
ppers are still needed. | 2585 // There are still block children in the container, so any anonymous wra
ppers are still needed. |
2565 if (!child->isAnonymousBlock()) | 2586 if (!child->isAnonymousBlock() || !child->isLayoutBlockFlow()) |
2566 return; | 2587 return; |
2567 // If one of the children is being destroyed then it is unsafe to clean
up anonymous wrappers as the | 2588 // If one of the children is being destroyed then it is unsafe to clean
up anonymous wrappers as the |
2568 // entire branch may be being destroyed. | 2589 // entire branch may be being destroyed. |
2569 if (toLayoutBlock(child)->beingDestroyed()) | 2590 if (toLayoutBlock(child)->beingDestroyed()) |
2570 return; | 2591 return; |
2571 // We can't remove anonymous wrappers if they contain continuations as t
his means there are block children present. | 2592 // We can't remove anonymous wrappers if they contain continuations as t
his means there are block children present. |
2572 if (toLayoutBlock(child)->continuation()) | 2593 if (toLayoutBlock(child)->continuation()) |
2573 return; | 2594 return; |
2574 // We are only interested in removing anonymous wrappers if there are in
line siblings underneath them. | 2595 // We are only interested in removing anonymous wrappers if there are in
line siblings underneath them. |
2575 if (!child->childrenInline()) | 2596 if (!child->childrenInline()) |
2576 return; | 2597 return; |
2577 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by
design, so we don't remove them. | 2598 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by
design, so we don't remove them. |
2578 if (child->isRubyRun() || child->isRubyBase()) | 2599 if (child->isRubyRun() || child->isRubyBase()) |
2579 return; | 2600 return; |
2580 | 2601 |
2581 blocksToRemove.append(toLayoutBlock(child)); | 2602 blocksToRemove.append(toLayoutBlockFlow(child)); |
2582 } | 2603 } |
2583 | 2604 |
2584 // If we make an object's children inline we are going to frustrate any futu
re attempts to remove | 2605 // If we make an object's children inline we are going to frustrate any futu
re attempts to remove |
2585 // floats from its children's float-lists before the next layout happens so
clear down all the floatlists | 2606 // floats from its children's float-lists before the next layout happens so
clear down all the floatlists |
2586 // now - they will be rebuilt at layout. | 2607 // now - they will be rebuilt at layout. |
2587 removeFloatingObjectsFromDescendants(); | 2608 removeFloatingObjectsFromDescendants(); |
2588 | 2609 |
2589 for (size_t i = 0; i < blocksToRemove.size(); i++) | 2610 for (size_t i = 0; i < blocksToRemove.size(); i++) |
2590 collapseAnonymousBlockChild(this, blocksToRemove[i]); | 2611 collapseAnonymousBlockChild(blocksToRemove[i]); |
2591 setChildrenInline(true); | 2612 setChildrenInline(true); |
2592 } | 2613 } |
2593 | 2614 |
2594 void LayoutBlockFlow::invalidatePaintForOverhangingFloats(bool paintAllDescendan
ts) | 2615 void LayoutBlockFlow::invalidatePaintForOverhangingFloats(bool paintAllDescendan
ts) |
2595 { | 2616 { |
2596 // Invalidate paint of any overhanging floats (if we know we're the one to p
aint them). | 2617 // Invalidate paint of any overhanging floats (if we know we're the one to p
aint them). |
2597 // Otherwise, bail out. | 2618 // Otherwise, bail out. |
2598 if (!hasOverhangingFloats()) | 2619 if (!hasOverhangingFloats()) |
2599 return; | 2620 return; |
2600 | 2621 |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3669 if (!rect.isEmpty()) | 3690 if (!rect.isEmpty()) |
3670 rects.append(rect); | 3691 rects.append(rect); |
3671 } | 3692 } |
3672 } | 3693 } |
3673 | 3694 |
3674 if (inlineElementContinuation) | 3695 if (inlineElementContinuation) |
3675 inlineElementContinuation->addOutlineRects(rects, additionalOffset + (in
lineElementContinuation->containingBlock()->location() - location()), includeBlo
ckOverflows); | 3696 inlineElementContinuation->addOutlineRects(rects, additionalOffset + (in
lineElementContinuation->containingBlock()->location() - location()), includeBlo
ckOverflows); |
3676 } | 3697 } |
3677 | 3698 |
3678 } // namespace blink | 3699 } // namespace blink |
OLD | NEW |