| OLD | NEW |
| 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) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. |
| 7 * All rights reserved. |
| 7 * Copyright (C) 2009 Google Inc. All rights reserved. | 8 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. |
| 10 * (http://www.torchmobile.com/) |
| 9 * | 11 * |
| 10 * This library is free software; you can redistribute it and/or | 12 * This library is free software; you can redistribute it and/or |
| 11 * modify it under the terms of the GNU Library General Public | 13 * modify it under the terms of the GNU Library General Public |
| 12 * License as published by the Free Software Foundation; either | 14 * License as published by the Free Software Foundation; either |
| 13 * version 2 of the License, or (at your option) any later version. | 15 * version 2 of the License, or (at your option) any later version. |
| 14 * | 16 * |
| 15 * This library is distributed in the hope that it will be useful, | 17 * This library is distributed in the hope that it will be useful, |
| 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 18 * Library General Public License for more details. | 20 * Library General Public License for more details. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 119 |
| 118 struct SameSizeAsLayoutObject : DisplayItemClient { | 120 struct SameSizeAsLayoutObject : DisplayItemClient { |
| 119 virtual ~SameSizeAsLayoutObject() {} // Allocate vtable pointer. | 121 virtual ~SameSizeAsLayoutObject() {} // Allocate vtable pointer. |
| 120 void* pointers[5]; | 122 void* pointers[5]; |
| 121 Member<void*> members[1]; | 123 Member<void*> members[1]; |
| 122 #if ENABLE(ASSERT) | 124 #if ENABLE(ASSERT) |
| 123 unsigned m_debugBitfields : 2; | 125 unsigned m_debugBitfields : 2; |
| 124 #endif | 126 #endif |
| 125 unsigned m_bitfields; | 127 unsigned m_bitfields; |
| 126 unsigned m_bitfields2; | 128 unsigned m_bitfields2; |
| 127 LayoutRect rect; // Stores the previous paint invalidation rect. | 129 LayoutRect rect; // Stores the previous paint invalidation rect. |
| 128 LayoutPoint | 130 LayoutPoint position; // Stores the previous position from the paint |
| 129 position; // Stores the previous position from the paint invalidation con
tainer. | 131 // invalidation container. |
| 130 }; | 132 }; |
| 131 | 133 |
| 132 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), | 134 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), |
| 133 "LayoutObject should stay small"); | 135 "LayoutObject should stay small"); |
| 134 | 136 |
| 135 bool LayoutObject::s_affectsParentBlock = false; | 137 bool LayoutObject::s_affectsParentBlock = false; |
| 136 | 138 |
| 137 // The pointer to paint properties is implemented as a global hash map temporari
ly, | 139 // The pointer to paint properties is implemented as a global hash map |
| 140 // temporarily, |
| 138 // to avoid memory regression during the transition towards SPv2. | 141 // to avoid memory regression during the transition towards SPv2. |
| 139 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> | 142 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> |
| 140 ObjectPaintPropertiesMap; | 143 ObjectPaintPropertiesMap; |
| 141 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() { | 144 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() { |
| 142 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap, | 145 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap, |
| 143 ()); | 146 ()); |
| 144 return staticObjectPaintPropertiesMap; | 147 return staticObjectPaintPropertiesMap; |
| 145 } | 148 } |
| 146 | 149 |
| 147 void* LayoutObject::operator new(size_t sz) { | 150 void* LayoutObject::operator new(size_t sz) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 159 const ComputedStyle& style) { | 162 const ComputedStyle& style) { |
| 160 ASSERT(isAllowedToModifyLayoutTreeStructure(element->document())); | 163 ASSERT(isAllowedToModifyLayoutTreeStructure(element->document())); |
| 161 | 164 |
| 162 // Minimal support for content properties replacing an entire element. | 165 // Minimal support for content properties replacing an entire element. |
| 163 // Works only if we have exactly one piece of content and it's a URL. | 166 // Works only if we have exactly one piece of content and it's a URL. |
| 164 // Otherwise acts as if we didn't support this feature. | 167 // Otherwise acts as if we didn't support this feature. |
| 165 const ContentData* contentData = style.contentData(); | 168 const ContentData* contentData = style.contentData(); |
| 166 if (contentData && !contentData->next() && contentData->isImage() && | 169 if (contentData && !contentData->next() && contentData->isImage() && |
| 167 !element->isPseudoElement()) { | 170 !element->isPseudoElement()) { |
| 168 LayoutImage* image = new LayoutImage(element); | 171 LayoutImage* image = new LayoutImage(element); |
| 169 // LayoutImageResourceStyleImage requires a style being present on the image
but we don't want to | 172 // LayoutImageResourceStyleImage requires a style being present on the image |
| 170 // trigger a style change now as the node is not fully attached. Moving this
code to style change | 173 // but we don't want to trigger a style change now as the node is not fully |
| 171 // doesn't make sense as it should be run once at layoutObject creation. | 174 // attached. Moving this code to style change doesn't make sense as it |
| 175 // should be run once at layoutObject creation. |
| 172 image->setStyleInternal(const_cast<ComputedStyle*>(&style)); | 176 image->setStyleInternal(const_cast<ComputedStyle*>(&style)); |
| 173 if (const StyleImage* styleImage = | 177 if (const StyleImage* styleImage = |
| 174 toImageContentData(contentData)->image()) { | 178 toImageContentData(contentData)->image()) { |
| 175 image->setImageResource(LayoutImageResourceStyleImage::create( | 179 image->setImageResource(LayoutImageResourceStyleImage::create( |
| 176 const_cast<StyleImage*>(styleImage))); | 180 const_cast<StyleImage*>(styleImage))); |
| 177 image->setIsGeneratedContent(); | 181 image->setIsGeneratedContent(); |
| 178 } else { | 182 } else { |
| 179 image->setImageResource(LayoutImageResource::create()); | 183 image->setImageResource(LayoutImageResource::create()); |
| 180 } | 184 } |
| 181 image->setStyleInternal(nullptr); | 185 image->setStyleInternal(nullptr); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 } | 263 } |
| 260 | 264 |
| 261 bool LayoutObject::isLegend() const { | 265 bool LayoutObject::isLegend() const { |
| 262 return isHTMLLegendElement(node()); | 266 return isHTMLLegendElement(node()); |
| 263 } | 267 } |
| 264 | 268 |
| 265 void LayoutObject::setIsInsideFlowThreadIncludingDescendants( | 269 void LayoutObject::setIsInsideFlowThreadIncludingDescendants( |
| 266 bool insideFlowThread) { | 270 bool insideFlowThread) { |
| 267 LayoutObject* next; | 271 LayoutObject* next; |
| 268 for (LayoutObject* object = this; object; object = next) { | 272 for (LayoutObject* object = this; object; object = next) { |
| 269 // If object is a fragmentation context it already updated the descendants f
lag accordingly. | 273 // If object is a fragmentation context it already updated the descendants |
| 274 // flag accordingly. |
| 270 if (object->isLayoutFlowThread()) { | 275 if (object->isLayoutFlowThread()) { |
| 271 next = object->nextInPreOrderAfterChildren(this); | 276 next = object->nextInPreOrderAfterChildren(this); |
| 272 continue; | 277 continue; |
| 273 } | 278 } |
| 274 next = object->nextInPreOrder(this); | 279 next = object->nextInPreOrder(this); |
| 275 ASSERT(insideFlowThread != object->isInsideFlowThread()); | 280 ASSERT(insideFlowThread != object->isInsideFlowThread()); |
| 276 object->setIsInsideFlowThread(insideFlowThread); | 281 object->setIsInsideFlowThread(insideFlowThread); |
| 277 } | 282 } |
| 278 } | 283 } |
| 279 | 284 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 children->insertChildNode(this, table, beforeChild); | 328 children->insertChildNode(this, table, beforeChild); |
| 324 } | 329 } |
| 325 table->addChild(newChild); | 330 table->addChild(newChild); |
| 326 } else { | 331 } else { |
| 327 children->insertChildNode(this, newChild, beforeChild); | 332 children->insertChildNode(this, newChild, beforeChild); |
| 328 } | 333 } |
| 329 | 334 |
| 330 if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) | 335 if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) |
| 331 toLayoutText(newChild)->transformText(); | 336 toLayoutText(newChild)->transformText(); |
| 332 | 337 |
| 333 // SVG creates layoutObjects for <g display="none">, as SVG requires children
of hidden | 338 // SVG creates layoutObjects for <g display="none">, as SVG requires children |
| 334 // <g>s to have layoutObjects - at least that's how our implementation works.
Consider: | 339 // of hidden <g>s to have layoutObjects - at least that's how our |
| 340 // implementation works. |
| 341 // Consider: |
| 335 // <g display="none"><foreignObject><body style="position: relative">FOO... | 342 // <g display="none"><foreignObject><body style="position: relative">FOO... |
| 336 // - layerTypeRequired() would return true for the <body>, creating a new Laye
r | 343 // - layerTypeRequired() would return true for the <body>, creating a new |
| 337 // - when the document is painted, both layers are painted. The <body> layer d
oesn't | 344 // Layer |
| 338 // know that it's inside a "hidden SVG subtree", and thus paints, even if it
shouldn't. | 345 // - when the document is painted, both layers are painted. The <body> layer |
| 339 // To avoid the problem altogether, detect early if we're inside a hidden SVG
subtree | 346 // doesn't know that it's inside a "hidden SVG subtree", and thus paints, |
| 340 // and stop creating layers at all for these cases - they're not used anyways. | 347 // even if it shouldn't. |
| 348 // To avoid the problem altogether, detect early if we're inside a hidden SVG |
| 349 // subtree and stop creating layers at all for these cases - they're not used |
| 350 // anyways. |
| 341 if (newChild->hasLayer() && !layerCreationAllowedForSubtree()) | 351 if (newChild->hasLayer() && !layerCreationAllowedForSubtree()) |
| 342 toLayoutBoxModelObject(newChild) | 352 toLayoutBoxModelObject(newChild) |
| 343 ->layer() | 353 ->layer() |
| 344 ->removeOnlyThisLayerAfterStyleChange(); | 354 ->removeOnlyThisLayerAfterStyleChange(); |
| 345 } | 355 } |
| 346 | 356 |
| 347 void LayoutObject::removeChild(LayoutObject* oldChild) { | 357 void LayoutObject::removeChild(LayoutObject* oldChild) { |
| 348 ASSERT(isAllowedToModifyLayoutTreeStructure(document())); | 358 ASSERT(isAllowedToModifyLayoutTreeStructure(document())); |
| 349 | 359 |
| 350 LayoutObjectChildList* children = virtualChildren(); | 360 LayoutObjectChildList* children = virtualChildren(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 return; | 561 return; |
| 552 } | 562 } |
| 553 | 563 |
| 554 for (LayoutObject* curr = slowFirstChild(); curr; curr = curr->nextSibling()) | 564 for (LayoutObject* curr = slowFirstChild(); curr; curr = curr->nextSibling()) |
| 555 curr->moveLayers(oldParent, newParent); | 565 curr->moveLayers(oldParent, newParent); |
| 556 } | 566 } |
| 557 | 567 |
| 558 PaintLayer* LayoutObject::findNextLayer(PaintLayer* parentLayer, | 568 PaintLayer* LayoutObject::findNextLayer(PaintLayer* parentLayer, |
| 559 LayoutObject* startPoint, | 569 LayoutObject* startPoint, |
| 560 bool checkParent) { | 570 bool checkParent) { |
| 561 // Error check the parent layer passed in. If it's null, we can't find anythin
g. | 571 // Error check the parent layer passed in. If it's null, we can't find |
| 572 // anything. |
| 562 if (!parentLayer) | 573 if (!parentLayer) |
| 563 return 0; | 574 return 0; |
| 564 | 575 |
| 565 // Step 1: If our layer is a child of the desired parent, then return our laye
r. | 576 // Step 1: If our layer is a child of the desired parent, then return our |
| 577 // layer. |
| 566 PaintLayer* ourLayer = | 578 PaintLayer* ourLayer = |
| 567 hasLayer() ? toLayoutBoxModelObject(this)->layer() : nullptr; | 579 hasLayer() ? toLayoutBoxModelObject(this)->layer() : nullptr; |
| 568 if (ourLayer && ourLayer->parent() == parentLayer) | 580 if (ourLayer && ourLayer->parent() == parentLayer) |
| 569 return ourLayer; | 581 return ourLayer; |
| 570 | 582 |
| 571 // Step 2: If we don't have a layer, or our layer is the desired parent, then
descend | 583 // Step 2: If we don't have a layer, or our layer is the desired parent, then |
| 572 // into our siblings trying to find the next layer whose parent is the desired
parent. | 584 // descend into our siblings trying to find the next layer whose parent is the |
| 585 // desired parent. |
| 573 if (!ourLayer || ourLayer == parentLayer) { | 586 if (!ourLayer || ourLayer == parentLayer) { |
| 574 for (LayoutObject* curr = startPoint ? startPoint->nextSibling() | 587 for (LayoutObject* curr = startPoint ? startPoint->nextSibling() |
| 575 : slowFirstChild(); | 588 : slowFirstChild(); |
| 576 curr; curr = curr->nextSibling()) { | 589 curr; curr = curr->nextSibling()) { |
| 577 PaintLayer* nextLayer = curr->findNextLayer(parentLayer, nullptr, false); | 590 PaintLayer* nextLayer = curr->findNextLayer(parentLayer, nullptr, false); |
| 578 if (nextLayer) | 591 if (nextLayer) |
| 579 return nextLayer; | 592 return nextLayer; |
| 580 } | 593 } |
| 581 } | 594 } |
| 582 | 595 |
| 583 // Step 3: If our layer is the desired parent layer, then we're finished. We d
idn't | 596 // Step 3: If our layer is the desired parent layer, then we're finished. We |
| 584 // find anything. | 597 // didn't find anything. |
| 585 if (parentLayer == ourLayer) | 598 if (parentLayer == ourLayer) |
| 586 return nullptr; | 599 return nullptr; |
| 587 | 600 |
| 588 // Step 4: If |checkParent| is set, climb up to our parent and check its sibli
ngs that | 601 // Step 4: If |checkParent| is set, climb up to our parent and check its |
| 589 // follow us to see if we can locate a layer. | 602 // siblings that follow us to see if we can locate a layer. |
| 590 if (checkParent && parent()) | 603 if (checkParent && parent()) |
| 591 return parent()->findNextLayer(parentLayer, this, true); | 604 return parent()->findNextLayer(parentLayer, this, true); |
| 592 | 605 |
| 593 return nullptr; | 606 return nullptr; |
| 594 } | 607 } |
| 595 | 608 |
| 596 PaintLayer* LayoutObject::enclosingLayer() const { | 609 PaintLayer* LayoutObject::enclosingLayer() const { |
| 597 for (const LayoutObject* current = this; current; | 610 for (const LayoutObject* current = this; current; |
| 598 current = current->parent()) { | 611 current = current->parent()) { |
| 599 if (current->hasLayer()) | 612 if (current->hasLayer()) |
| 600 return toLayoutBoxModelObject(current)->layer(); | 613 return toLayoutBoxModelObject(current)->layer(); |
| 601 } | 614 } |
| 602 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at w
hich point this code should | 615 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at |
| 603 // not be reached. | 616 // which point this code should not be reached. |
| 604 return nullptr; | 617 return nullptr; |
| 605 } | 618 } |
| 606 | 619 |
| 607 PaintLayer* LayoutObject::paintingLayer() const { | 620 PaintLayer* LayoutObject::paintingLayer() const { |
| 608 for (const LayoutObject* current = this; current; | 621 for (const LayoutObject* current = this; current; |
| 609 current = current->paintInvalidationParent()) { | 622 current = current->paintInvalidationParent()) { |
| 610 if (current->hasLayer() && | 623 if (current->hasLayer() && |
| 611 toLayoutBoxModelObject(current)->layer()->isSelfPaintingLayer()) | 624 toLayoutBoxModelObject(current)->layer()->isSelfPaintingLayer()) |
| 612 return toLayoutBoxModelObject(current)->layer(); | 625 return toLayoutBoxModelObject(current)->layer(); |
| 613 } | 626 } |
| 614 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at w
hich point this code should | 627 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at |
| 615 // not be reached. | 628 // which point this code should not be reached. |
| 616 return nullptr; | 629 return nullptr; |
| 617 } | 630 } |
| 618 | 631 |
| 619 bool LayoutObject::scrollRectToVisible(const LayoutRect& rect, | 632 bool LayoutObject::scrollRectToVisible(const LayoutRect& rect, |
| 620 const ScrollAlignment& alignX, | 633 const ScrollAlignment& alignX, |
| 621 const ScrollAlignment& alignY, | 634 const ScrollAlignment& alignY, |
| 622 ScrollType scrollType, | 635 ScrollType scrollType, |
| 623 bool makeVisibleInVisualViewport) { | 636 bool makeVisibleInVisualViewport) { |
| 624 LayoutBox* enclosingBox = this->enclosingBox(); | 637 LayoutBox* enclosingBox = this->enclosingBox(); |
| 625 if (!enclosingBox) | 638 if (!enclosingBox) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 if (LayoutState* layoutState = view()->layoutState()) { | 688 if (LayoutState* layoutState = view()->layoutState()) { |
| 676 if (LayoutFlowThread* flowThread = layoutState->flowThread()) | 689 if (LayoutFlowThread* flowThread = layoutState->flowThread()) |
| 677 return flowThread; | 690 return flowThread; |
| 678 } | 691 } |
| 679 | 692 |
| 680 // Not in the middle of layout so have to find the thread the slow way. | 693 // Not in the middle of layout so have to find the thread the slow way. |
| 681 return LayoutFlowThread::locateFlowThreadContainingBlockOf(*this); | 694 return LayoutFlowThread::locateFlowThreadContainingBlockOf(*this); |
| 682 } | 695 } |
| 683 | 696 |
| 684 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) { | 697 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) { |
| 685 // FIXME: In future it may be possible to broaden these conditions in order to
improve performance. | 698 // FIXME: In future it may be possible to broaden these conditions in order to |
| 699 // improve performance. |
| 686 if (object->isTextControl()) | 700 if (object->isTextControl()) |
| 687 return true; | 701 return true; |
| 688 | 702 |
| 689 if (object->isSVGRoot()) | 703 if (object->isSVGRoot()) |
| 690 return true; | 704 return true; |
| 691 | 705 |
| 692 // Table parts can't be relayout roots since the table is responsible for layo
uting all the parts. | 706 // Table parts can't be relayout roots since the table is responsible for |
| 707 // layouting all the parts. |
| 693 if (object->isTablePart()) | 708 if (object->isTablePart()) |
| 694 return false; | 709 return false; |
| 695 | 710 |
| 696 if (object->style()->containsLayout() && object->style()->containsSize()) | 711 if (object->style()->containsLayout() && object->style()->containsSize()) |
| 697 return true; | 712 return true; |
| 698 | 713 |
| 699 if (!object->hasOverflowClip()) | 714 if (!object->hasOverflowClip()) |
| 700 return false; | 715 return false; |
| 701 | 716 |
| 702 if (object->style()->width().isIntrinsicOrAuto() || | 717 if (object->style()->width().isIntrinsicOrAuto() || |
| 703 object->style()->height().isIntrinsicOrAuto() || | 718 object->style()->height().isIntrinsicOrAuto() || |
| 704 object->style()->height().isPercentOrCalc()) | 719 object->style()->height().isPercentOrCalc()) |
| 705 return false; | 720 return false; |
| 706 | 721 |
| 707 // Scrollbar parts can be removed during layout. Avoid the complexity of havin
g to deal with that. | 722 // Scrollbar parts can be removed during layout. Avoid the complexity of |
| 723 // having to deal with that. |
| 708 if (object->isLayoutScrollbarPart()) | 724 if (object->isLayoutScrollbarPart()) |
| 709 return false; | 725 return false; |
| 710 | 726 |
| 711 // In general we can't relayout a flex item independently of its container; no
t only is the result | 727 // In general we can't relayout a flex item independently of its container; |
| 712 // incorrect due to the override size that's set, it also messes with the cach
ed main size on the flexbox. | 728 // not only is the result incorrect due to the override size that's set, it |
| 729 // also messes with the cached main size on the flexbox. |
| 713 if (object->isBox() && toLayoutBox(object)->isFlexItem()) | 730 if (object->isBox() && toLayoutBox(object)->isFlexItem()) |
| 714 return false; | 731 return false; |
| 715 | 732 |
| 716 // Inside multicol it's generally problematic to allow relayout roots. The mul
ticol container | 733 // Inside multicol it's generally problematic to allow relayout roots. The |
| 717 // itself may be scheduled for relayout as well (due to other changes that may
have happened | 734 // multicol container itself may be scheduled for relayout as well (due to |
| 718 // since the previous layout pass), which might affect the column heights, whi
ch may affect how | 735 // other changes that may have happened since the previous layout pass), |
| 719 // this object breaks across columns). Spanners may also have been added or re
moved since the | 736 // which might affect the column heights, which may affect how this object |
| 720 // previous layout pass, which is just another way of affecting the column hei
ghts (and the | 737 // breaks across columns). Spanners may also have been added or removed since |
| 721 // number of rows). Instead of identifying cases where it's safe to allow rela
yout roots, just | 738 // the previous layout pass, which is just another way of affecting the column |
| 722 // disallow them inside multicol. | 739 // heights (and the number of rows). Instead of identifying cases where it's |
| 740 // safe to allow relayout roots, just disallow them inside multicol. |
| 723 if (object->isInsideFlowThread()) | 741 if (object->isInsideFlowThread()) |
| 724 return false; | 742 return false; |
| 725 | 743 |
| 726 return true; | 744 return true; |
| 727 } | 745 } |
| 728 | 746 |
| 729 void LayoutObject::markContainerChainForLayout(bool scheduleRelayout, | 747 void LayoutObject::markContainerChainForLayout(bool scheduleRelayout, |
| 730 SubtreeLayoutScope* layouter) { | 748 SubtreeLayoutScope* layouter) { |
| 731 ASSERT(!isSetNeedsLayoutForbidden()); | 749 ASSERT(!isSetNeedsLayoutForbidden()); |
| 732 ASSERT(!layouter || this != layouter->root()); | 750 ASSERT(!layouter || this != layouter->root()); |
| 733 // When we're in layout, we're marking a descendant as needing layout with | 751 // When we're in layout, we're marking a descendant as needing layout with |
| 734 // the intention of visiting it during this layout. We shouldn't be | 752 // the intention of visiting it during this layout. We shouldn't be |
| 735 // scheduling it to be laid out later. | 753 // scheduling it to be laid out later. Also, scheduleRelayout() must not be |
| 736 // Also, scheduleRelayout() must not be called while iterating | 754 // called while iterating FrameView::m_layoutSubtreeRootList. |
| 737 // FrameView::m_layoutSubtreeRootList. | |
| 738 scheduleRelayout &= !frameView()->isInPerformLayout(); | 755 scheduleRelayout &= !frameView()->isInPerformLayout(); |
| 739 | 756 |
| 740 LayoutObject* object = container(); | 757 LayoutObject* object = container(); |
| 741 LayoutObject* last = this; | 758 LayoutObject* last = this; |
| 742 | 759 |
| 743 bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && | 760 bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && |
| 744 !selfNeedsLayout() && | 761 !selfNeedsLayout() && |
| 745 !normalChildNeedsLayout(); | 762 !normalChildNeedsLayout(); |
| 746 | 763 |
| 747 while (object) { | 764 while (object) { |
| 748 if (object->selfNeedsLayout()) | 765 if (object->selfNeedsLayout()) |
| 749 return; | 766 return; |
| 750 | 767 |
| 751 // Don't mark the outermost object of an unrooted subtree. That object will
be | 768 // Don't mark the outermost object of an unrooted subtree. That object will |
| 752 // marked when the subtree is added to the document. | 769 // be marked when the subtree is added to the document. |
| 753 LayoutObject* container = object->container(); | 770 LayoutObject* container = object->container(); |
| 754 if (!container && !object->isLayoutView()) | 771 if (!container && !object->isLayoutView()) |
| 755 return; | 772 return; |
| 756 if (!last->isTextOrSVGChild() && last->style()->hasOutOfFlowPosition()) { | 773 if (!last->isTextOrSVGChild() && last->style()->hasOutOfFlowPosition()) { |
| 757 object = last->containingBlock(); | 774 object = last->containingBlock(); |
| 758 if (object->posChildNeedsLayout()) | 775 if (object->posChildNeedsLayout()) |
| 759 return; | 776 return; |
| 760 container = object->container(); | 777 container = object->container(); |
| 761 object->setPosChildNeedsLayout(true); | 778 object->setPosChildNeedsLayout(true); |
| 762 simplifiedNormalFlowLayout = true; | 779 simplifiedNormalFlowLayout = true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 if (markParents == MarkContainerChain && | 820 if (markParents == MarkContainerChain && |
| 804 (isText() || !style()->hasOutOfFlowPosition())) | 821 (isText() || !style()->hasOutOfFlowPosition())) |
| 805 invalidateContainerPreferredLogicalWidths(); | 822 invalidateContainerPreferredLogicalWidths(); |
| 806 } | 823 } |
| 807 | 824 |
| 808 void LayoutObject::clearPreferredLogicalWidthsDirty() { | 825 void LayoutObject::clearPreferredLogicalWidthsDirty() { |
| 809 m_bitfields.setPreferredLogicalWidthsDirty(false); | 826 m_bitfields.setPreferredLogicalWidthsDirty(false); |
| 810 } | 827 } |
| 811 | 828 |
| 812 inline void LayoutObject::invalidateContainerPreferredLogicalWidths() { | 829 inline void LayoutObject::invalidateContainerPreferredLogicalWidths() { |
| 813 // In order to avoid pathological behavior when inlines are deeply nested, we
do include them | 830 // In order to avoid pathological behavior when inlines are deeply nested, we |
| 814 // in the chain that we mark dirty (even though they're kind of irrelevant). | 831 // do include them in the chain that we mark dirty (even though they're kind |
| 832 // of irrelevant). |
| 815 LayoutObject* o = isTableCell() ? containingBlock() : container(); | 833 LayoutObject* o = isTableCell() ? containingBlock() : container(); |
| 816 while (o && !o->preferredLogicalWidthsDirty()) { | 834 while (o && !o->preferredLogicalWidthsDirty()) { |
| 817 // Don't invalidate the outermost object of an unrooted subtree. That object
will be | 835 // Don't invalidate the outermost object of an unrooted subtree. That object |
| 818 // invalidated when the subtree is added to the document. | 836 // will be invalidated when the subtree is added to the document. |
| 819 LayoutObject* container = | 837 LayoutObject* container = |
| 820 o->isTableCell() ? o->containingBlock() : o->container(); | 838 o->isTableCell() ? o->containingBlock() : o->container(); |
| 821 if (!container && !o->isLayoutView()) | 839 if (!container && !o->isLayoutView()) |
| 822 break; | 840 break; |
| 823 | 841 |
| 824 o->m_bitfields.setPreferredLogicalWidthsDirty(true); | 842 o->m_bitfields.setPreferredLogicalWidthsDirty(true); |
| 825 if (o->style()->hasOutOfFlowPosition()) { | 843 // A positioned object has no effect on the min/max width of its containing |
| 826 // A positioned object has no effect on the min/max width of its containin
g block ever. | 844 // block ever. We can optimize this case and not go up any further. |
| 827 // We can optimize this case and not go up any further. | 845 if (o->style()->hasOutOfFlowPosition()) |
| 828 break; | 846 break; |
| 829 } | |
| 830 o = container; | 847 o = container; |
| 831 } | 848 } |
| 832 } | 849 } |
| 833 | 850 |
| 834 LayoutObject* LayoutObject::containerForAbsolutePosition( | 851 LayoutObject* LayoutObject::containerForAbsolutePosition( |
| 835 const LayoutBoxModelObject* ancestor, | 852 const LayoutBoxModelObject* ancestor, |
| 836 bool* ancestorSkipped, | 853 bool* ancestorSkipped, |
| 837 bool* filterSkipped) const { | 854 bool* filterSkipped) const { |
| 838 DCHECK(!ancestorSkipped || !*ancestorSkipped); | 855 DCHECK(!ancestorSkipped || !*ancestorSkipped); |
| 839 DCHECK(!filterSkipped || !*filterSkipped); | 856 DCHECK(!filterSkipped || !*filterSkipped); |
| 840 | 857 |
| 841 // We technically just want our containing block, but | 858 // We technically just want our containing block, but we may not have one if |
| 842 // we may not have one if we're part of an uninstalled | 859 // we're part of an uninstalled subtree. We'll climb as high as we can though. |
| 843 // subtree. We'll climb as high as we can though. | |
| 844 for (LayoutObject* object = parent(); object; object = object->parent()) { | 860 for (LayoutObject* object = parent(); object; object = object->parent()) { |
| 845 if (object->canContainAbsolutePositionObjects()) | 861 if (object->canContainAbsolutePositionObjects()) |
| 846 return object; | 862 return object; |
| 847 | 863 |
| 848 if (ancestorSkipped && object == ancestor) | 864 if (ancestorSkipped && object == ancestor) |
| 849 *ancestorSkipped = true; | 865 *ancestorSkipped = true; |
| 850 | 866 |
| 851 if (filterSkipped && object->hasFilterInducingProperty()) | 867 if (filterSkipped && object->hasFilterInducingProperty()) |
| 852 *filterSkipped = true; | 868 *filterSkipped = true; |
| 853 } | 869 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 872 *filterSkipped = true; | 888 *filterSkipped = true; |
| 873 } | 889 } |
| 874 | 890 |
| 875 ASSERT(!object || !object->isAnonymousBlock()); | 891 ASSERT(!object || !object->isAnonymousBlock()); |
| 876 return toLayoutBlock(object); | 892 return toLayoutBlock(object); |
| 877 } | 893 } |
| 878 | 894 |
| 879 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const { | 895 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const { |
| 880 LayoutObject* o = containerForAbsolutePosition(); | 896 LayoutObject* o = containerForAbsolutePosition(); |
| 881 | 897 |
| 882 // For relpositioned inlines, we return the nearest non-anonymous enclosing bl
ock. We don't try | 898 // For relpositioned inlines, we return the nearest non-anonymous enclosing |
| 883 // to return the inline itself. This allows us to avoid having a positioned o
bjects | 899 // block. We don't try to return the inline itself. This allows us to avoid |
| 884 // list in all LayoutInlines and lets us return a strongly-typed LayoutBlock*
result | 900 // having a positioned objects list in all LayoutInlines and lets us return a |
| 885 // from this method. The container() method can actually be used to obtain th
e | 901 // strongly-typed LayoutBlock* result from this method. The container() method |
| 886 // inline directly. | 902 // can actually be used to obtain the inline directly. |
| 887 if (o && o->isInline() && !o->isAtomicInlineLevel()) { | 903 if (o && o->isInline() && !o->isAtomicInlineLevel()) { |
| 888 ASSERT(o->style()->hasInFlowPosition()); | 904 ASSERT(o->style()->hasInFlowPosition()); |
| 889 o = o->containingBlock(); | 905 o = o->containingBlock(); |
| 890 } | 906 } |
| 891 | 907 |
| 892 if (o && !o->isLayoutBlock()) | 908 if (o && !o->isLayoutBlock()) |
| 893 o = o->containingBlock(); | 909 o = o->containingBlock(); |
| 894 | 910 |
| 895 while (o && o->isAnonymousBlock()) | 911 while (o && o->isAnonymousBlock()) |
| 896 o = o->containingBlock(); | 912 o = o->containingBlock(); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 void LayoutObject::paint(const PaintInfo&, const LayoutPoint&) const {} | 1028 void LayoutObject::paint(const PaintInfo&, const LayoutPoint&) const {} |
| 1013 | 1029 |
| 1014 const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() | 1030 const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() |
| 1015 const { | 1031 const { |
| 1016 RELEASE_ASSERT(isRooted()); | 1032 RELEASE_ASSERT(isRooted()); |
| 1017 | 1033 |
| 1018 if (const LayoutBoxModelObject* paintInvalidationContainer = | 1034 if (const LayoutBoxModelObject* paintInvalidationContainer = |
| 1019 enclosingCompositedContainer()) | 1035 enclosingCompositedContainer()) |
| 1020 return *paintInvalidationContainer; | 1036 return *paintInvalidationContainer; |
| 1021 | 1037 |
| 1022 // If the current frame is not composited, we send just return | 1038 // If the current frame is not composited, we send just return the main |
| 1023 // the main frame's LayoutView so that we generate invalidations | 1039 // frame's LayoutView so that we generate invalidations on the window. |
| 1024 // on the window. | |
| 1025 const LayoutView* layoutView = view(); | 1040 const LayoutView* layoutView = view(); |
| 1026 while ( | 1041 while ( |
| 1027 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem())) | 1042 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem())) |
| 1028 layoutView = | 1043 layoutView = |
| 1029 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem()) | 1044 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem()) |
| 1030 ->view(); | 1045 ->view(); |
| 1031 ASSERT(layoutView); | 1046 ASSERT(layoutView); |
| 1032 return *layoutView; | 1047 return *layoutView; |
| 1033 } | 1048 } |
| 1034 | 1049 |
| 1035 const LayoutBoxModelObject* LayoutObject::enclosingCompositedContainer() const { | 1050 const LayoutBoxModelObject* LayoutObject::enclosingCompositedContainer() const { |
| 1036 LayoutBoxModelObject* container = nullptr; | 1051 LayoutBoxModelObject* container = nullptr; |
| 1037 // FIXME: CompositingState is not necessarily up to date for many callers of t
his function. | 1052 // FIXME: CompositingState is not necessarily up to date for many callers of |
| 1053 // this function. |
| 1038 DisableCompositingQueryAsserts disabler; | 1054 DisableCompositingQueryAsserts disabler; |
| 1039 | 1055 |
| 1040 if (PaintLayer* paintingLayer = this->paintingLayer()) { | 1056 if (PaintLayer* paintingLayer = this->paintingLayer()) { |
| 1041 if (PaintLayer* compositingLayer = | 1057 if (PaintLayer* compositingLayer = |
| 1042 paintingLayer | 1058 paintingLayer |
| 1043 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()) | 1059 ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries()) |
| 1044 container = compositingLayer->layoutObject(); | 1060 container = compositingLayer->layoutObject(); |
| 1045 } | 1061 } |
| 1046 return container; | 1062 return container; |
| 1047 } | 1063 } |
| 1048 | 1064 |
| 1049 String LayoutObject::decoratedName() const { | 1065 String LayoutObject::decoratedName() const { |
| 1050 StringBuilder name; | 1066 StringBuilder name; |
| 1051 name.append(this->name()); | 1067 name.append(this->name()); |
| 1052 | 1068 |
| 1053 if (isAnonymous()) | 1069 if (isAnonymous()) |
| 1054 name.append(" (anonymous)"); | 1070 name.append(" (anonymous)"); |
| 1055 // FIXME: Remove the special case for LayoutView here (requires rebaseline of
all tests). | 1071 // FIXME: Remove the special case for LayoutView here (requires rebaseline of |
| 1072 // all tests). |
| 1056 if (isOutOfFlowPositioned() && !isLayoutView()) | 1073 if (isOutOfFlowPositioned() && !isLayoutView()) |
| 1057 name.append(" (positioned)"); | 1074 name.append(" (positioned)"); |
| 1058 if (isRelPositioned()) | 1075 if (isRelPositioned()) |
| 1059 name.append(" (relative positioned)"); | 1076 name.append(" (relative positioned)"); |
| 1060 if (isStickyPositioned()) | 1077 if (isStickyPositioned()) |
| 1061 name.append(" (sticky positioned)"); | 1078 name.append(" (sticky positioned)"); |
| 1062 if (isFloating()) | 1079 if (isFloating()) |
| 1063 name.append(" (floating)"); | 1080 name.append(" (floating)"); |
| 1064 if (spannerPlaceholder()) | 1081 if (spannerPlaceholder()) |
| 1065 name.append(" (column spanner)"); | 1082 name.append(" (column spanner)"); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1082 return previousPaintInvalidationRect(); | 1099 return previousPaintInvalidationRect(); |
| 1083 } | 1100 } |
| 1084 | 1101 |
| 1085 bool LayoutObject::isPaintInvalidationContainer() const { | 1102 bool LayoutObject::isPaintInvalidationContainer() const { |
| 1086 return hasLayer() && | 1103 return hasLayer() && |
| 1087 toLayoutBoxModelObject(this)->layer()->isPaintInvalidationContainer(); | 1104 toLayoutBoxModelObject(this)->layer()->isPaintInvalidationContainer(); |
| 1088 } | 1105 } |
| 1089 | 1106 |
| 1090 void LayoutObject::invalidateDisplayItemClients( | 1107 void LayoutObject::invalidateDisplayItemClients( |
| 1091 PaintInvalidationReason reason) const { | 1108 PaintInvalidationReason reason) const { |
| 1092 // This default implementation invalidates only the object itself as a Display
ItemClient. | 1109 // This default implementation invalidates only the object itself as a |
| 1110 // DisplayItemClient. |
| 1093 ObjectPaintInvalidator(*this).invalidateDisplayItemClient(*this, reason); | 1111 ObjectPaintInvalidator(*this).invalidateDisplayItemClient(*this, reason); |
| 1094 } | 1112 } |
| 1095 | 1113 |
| 1096 bool LayoutObject::compositedScrollsWithRespectTo( | 1114 bool LayoutObject::compositedScrollsWithRespectTo( |
| 1097 const LayoutBoxModelObject& paintInvalidationContainer) const { | 1115 const LayoutBoxModelObject& paintInvalidationContainer) const { |
| 1098 return paintInvalidationContainer.usesCompositedScrolling() && | 1116 return paintInvalidationContainer.usesCompositedScrolling() && |
| 1099 this != &paintInvalidationContainer; | 1117 this != &paintInvalidationContainer; |
| 1100 } | 1118 } |
| 1101 | 1119 |
| 1102 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation( | 1120 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation( |
| 1103 const LayoutBoxModelObject& paintInvalidationContainer) const { | 1121 const LayoutBoxModelObject& paintInvalidationContainer) const { |
| 1104 // Non-composited scrolling should be included in the bounds of scrolled items
. Since mapToVisualRectInAncestorSpace does not include | 1122 // Non-composited scrolling should be included in the bounds of scrolleditems. |
| 1105 // scrolling of the ancestor, we need to add it back in after. | 1123 // Since mapToVisualRectInAncestorSpace does not include scrolling of the |
| 1124 // ancestor, we need to add it back in after. |
| 1106 if (paintInvalidationContainer.isBox() && | 1125 if (paintInvalidationContainer.isBox() && |
| 1107 !paintInvalidationContainer.usesCompositedScrolling() && | 1126 !paintInvalidationContainer.usesCompositedScrolling() && |
| 1108 this != &paintInvalidationContainer) { | 1127 this != &paintInvalidationContainer) { |
| 1109 const LayoutBox* box = toLayoutBox(&paintInvalidationContainer); | 1128 const LayoutBox* box = toLayoutBox(&paintInvalidationContainer); |
| 1110 if (box->hasOverflowClip()) | 1129 if (box->hasOverflowClip()) |
| 1111 return -box->scrolledContentOffset(); | 1130 return -box->scrolledContentOffset(); |
| 1112 } | 1131 } |
| 1113 return IntSize(); | 1132 return IntSize(); |
| 1114 } | 1133 } |
| 1115 | 1134 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1145 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); | 1164 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
| 1146 } | 1165 } |
| 1147 | 1166 |
| 1148 DISABLE_CFI_PERF | 1167 DISABLE_CFI_PERF |
| 1149 void LayoutObject::invalidatePaintOfSubtreesIfNeeded( | 1168 void LayoutObject::invalidatePaintOfSubtreesIfNeeded( |
| 1150 const PaintInvalidationState& childPaintInvalidationState) { | 1169 const PaintInvalidationState& childPaintInvalidationState) { |
| 1151 DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); | 1170 DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); |
| 1152 | 1171 |
| 1153 for (LayoutObject* child = slowFirstChild(); child; | 1172 for (LayoutObject* child = slowFirstChild(); child; |
| 1154 child = child->nextSibling()) { | 1173 child = child->nextSibling()) { |
| 1155 // Column spanners are invalidated through their placeholders. | 1174 // Column spanners are invalidated through their placeholders. See |
| 1156 // See LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfNeede
d(). | 1175 // LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfNeeded(). |
| 1157 if (child->isColumnSpanAll()) | 1176 if (child->isColumnSpanAll()) |
| 1158 continue; | 1177 continue; |
| 1159 child->invalidateTreeIfNeeded(childPaintInvalidationState); | 1178 child->invalidateTreeIfNeeded(childPaintInvalidationState); |
| 1160 } | 1179 } |
| 1161 } | 1180 } |
| 1162 | 1181 |
| 1163 LayoutRect LayoutObject::selectionRectInViewCoordinates() const { | 1182 LayoutRect LayoutObject::selectionRectInViewCoordinates() const { |
| 1164 LayoutRect selectionRect = localSelectionRect(); | 1183 LayoutRect selectionRect = localSelectionRect(); |
| 1165 if (!selectionRect.isEmpty()) | 1184 if (!selectionRect.isEmpty()) |
| 1166 mapToVisualRectInAncestorSpace(view(), selectionRect); | 1185 mapToVisualRectInAncestorSpace(view(), selectionRect); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 scrollAdjustmentForPaintInvalidation(paintInvalidationContainer); | 1217 scrollAdjustmentForPaintInvalidation(paintInvalidationContainer); |
| 1199 context.newLocation.move(adjustment); | 1218 context.newLocation.move(adjustment); |
| 1200 context.newBounds.move(adjustment); | 1219 context.newBounds.move(adjustment); |
| 1201 | 1220 |
| 1202 setPreviousPaintInvalidationRect(context.newBounds); | 1221 setPreviousPaintInvalidationRect(context.newBounds); |
| 1203 setPreviousPositionFromPaintInvalidationBacking(context.newLocation); | 1222 setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
| 1204 | 1223 |
| 1205 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && | 1224 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && |
| 1206 paintInvalidationState | 1225 paintInvalidationState |
| 1207 .forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { | 1226 .forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { |
| 1208 // We are done updating the paint invalidation rect. No other paint invalida
tion work to do for this object. | 1227 // We are done updating the paint invalidation rect. No other paint |
| 1228 // invalidation work to do for this object. |
| 1209 return PaintInvalidationNone; | 1229 return PaintInvalidationNone; |
| 1210 } | 1230 } |
| 1211 | 1231 |
| 1212 return invalidatePaintIfNeeded(context); | 1232 return invalidatePaintIfNeeded(context); |
| 1213 } | 1233 } |
| 1214 | 1234 |
| 1215 DISABLE_CFI_PERF | 1235 DISABLE_CFI_PERF |
| 1216 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded( | 1236 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded( |
| 1217 const PaintInvalidatorContext& context) const { | 1237 const PaintInvalidatorContext& context) const { |
| 1218 return ObjectPaintInvalidatorWithContext(*this, context) | 1238 return ObjectPaintInvalidatorWithContext(*this, context) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1240 | 1260 |
| 1241 void LayoutObject::adjustPreviousPaintInvalidationForScrollIfNeeded( | 1261 void LayoutObject::adjustPreviousPaintInvalidationForScrollIfNeeded( |
| 1242 const DoubleSize& scrollDelta) { | 1262 const DoubleSize& scrollDelta) { |
| 1243 if (containerForPaintInvalidation().usesCompositedScrolling()) | 1263 if (containerForPaintInvalidation().usesCompositedScrolling()) |
| 1244 return; | 1264 return; |
| 1245 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); | 1265 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); |
| 1246 } | 1266 } |
| 1247 | 1267 |
| 1248 void LayoutObject::clearPreviousPaintInvalidationRects() { | 1268 void LayoutObject::clearPreviousPaintInvalidationRects() { |
| 1249 setPreviousPaintInvalidationRect(LayoutRect()); | 1269 setPreviousPaintInvalidationRect(LayoutRect()); |
| 1250 // After clearing ("invalidating" the paint invalidation rects, mark this obje
ct as needing to re-compute them. | 1270 // After clearing ("invalidating" the paint invalidation rects, mark this |
| 1271 // object as needing to re-compute them. |
| 1251 setShouldDoFullPaintInvalidation(); | 1272 setShouldDoFullPaintInvalidation(); |
| 1252 } | 1273 } |
| 1253 | 1274 |
| 1254 LayoutRect LayoutObject::absoluteClippedOverflowRect() const { | 1275 LayoutRect LayoutObject::absoluteClippedOverflowRect() const { |
| 1255 LayoutRect rect = localOverflowRectForPaintInvalidation(); | 1276 LayoutRect rect = localOverflowRectForPaintInvalidation(); |
| 1256 mapToVisualRectInAncestorSpace(view(), rect); | 1277 mapToVisualRectInAncestorSpace(view(), rect); |
| 1257 return rect; | 1278 return rect; |
| 1258 } | 1279 } |
| 1259 | 1280 |
| 1260 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const { | 1281 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const { |
| 1261 ASSERT_NOT_REACHED(); | 1282 ASSERT_NOT_REACHED(); |
| 1262 return LayoutRect(); | 1283 return LayoutRect(); |
| 1263 } | 1284 } |
| 1264 | 1285 |
| 1265 bool LayoutObject::mapToVisualRectInAncestorSpace( | 1286 bool LayoutObject::mapToVisualRectInAncestorSpace( |
| 1266 const LayoutBoxModelObject* ancestor, | 1287 const LayoutBoxModelObject* ancestor, |
| 1267 LayoutRect& rect, | 1288 LayoutRect& rect, |
| 1268 VisualRectFlags visualRectFlags) const { | 1289 VisualRectFlags visualRectFlags) const { |
| 1269 // For any layout object that doesn't override this method (the main example i
s LayoutText), | 1290 // For any layout object that doesn't override this method (the main example |
| 1270 // the rect is assumed to be in the parent's coordinate space, except for cont
ainer flip. | 1291 // is LayoutText), the rect is assumed to be in the parent's coordinate space, |
| 1292 // except for container flip. |
| 1271 | 1293 |
| 1272 if (ancestor == this) | 1294 if (ancestor == this) |
| 1273 return true; | 1295 return true; |
| 1274 | 1296 |
| 1275 if (LayoutObject* parent = this->parent()) { | 1297 if (LayoutObject* parent = this->parent()) { |
| 1276 if (parent->isBox()) { | 1298 if (parent->isBox()) { |
| 1277 LayoutBox* parentBox = toLayoutBox(parent); | 1299 LayoutBox* parentBox = toLayoutBox(parent); |
| 1278 | 1300 |
| 1279 // Never flip for SVG as it handles writing modes itself. | 1301 // Never flip for SVG as it handles writing modes itself. |
| 1280 if (!isSVG()) | 1302 if (!isSVG()) |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1408 | 1430 |
| 1409 Color LayoutObject::selectionEmphasisMarkColor( | 1431 Color LayoutObject::selectionEmphasisMarkColor( |
| 1410 const GlobalPaintFlags globalPaintFlags) const { | 1432 const GlobalPaintFlags globalPaintFlags) const { |
| 1411 return selectionColor(CSSPropertyWebkitTextEmphasisColor, globalPaintFlags); | 1433 return selectionColor(CSSPropertyWebkitTextEmphasisColor, globalPaintFlags); |
| 1412 } | 1434 } |
| 1413 | 1435 |
| 1414 void LayoutObject::selectionStartEnd(int& spos, int& epos) const { | 1436 void LayoutObject::selectionStartEnd(int& spos, int& epos) const { |
| 1415 view()->selectionStartEnd(spos, epos); | 1437 view()->selectionStartEnd(spos, epos); |
| 1416 } | 1438 } |
| 1417 | 1439 |
| 1418 // Called when an object that was floating or positioned becomes a normal flow o
bject | 1440 // Called when an object that was floating or positioned becomes a normal flow |
| 1419 // again. We have to make sure the layout tree updates as needed to accommodate
the new | 1441 // object again. We have to make sure the layout tree updates as needed to |
| 1420 // normal flow object. | 1442 // accommodate the new normal flow object. |
| 1421 static inline void handleDynamicFloatPositionChange(LayoutObject* object) { | 1443 static inline void handleDynamicFloatPositionChange(LayoutObject* object) { |
| 1422 // We have gone from not affecting the inline status of the parent flow to sud
denly | 1444 // We have gone from not affecting the inline status of the parent flow to |
| 1423 // having an impact. See if there is a mismatch between the parent flow's | 1445 // suddenly having an impact. See if there is a mismatch between the parent |
| 1424 // childrenInline() state and our state. | 1446 // flow's childrenInline() state and our state. |
| 1425 object->setInline(object->style()->isDisplayInlineType()); | 1447 object->setInline(object->style()->isDisplayInlineType()); |
| 1426 if (object->isInline() != object->parent()->childrenInline()) { | 1448 if (object->isInline() != object->parent()->childrenInline()) { |
| 1427 if (!object->isInline()) { | 1449 if (!object->isInline()) { |
| 1428 toLayoutBoxModelObject(object->parent())->childBecameNonInline(object); | 1450 toLayoutBoxModelObject(object->parent())->childBecameNonInline(object); |
| 1429 } else { | 1451 } else { |
| 1430 // An anonymous block must be made to wrap this inline. | 1452 // An anonymous block must be made to wrap this inline. |
| 1431 LayoutBlock* block = | 1453 LayoutBlock* block = |
| 1432 toLayoutBlock(object->parent())->createAnonymousBlock(); | 1454 toLayoutBlock(object->parent())->createAnonymousBlock(); |
| 1433 LayoutObjectChildList* childlist = object->parent()->virtualChildren(); | 1455 LayoutObjectChildList* childlist = object->parent()->virtualChildren(); |
| 1434 childlist->insertChildNode(object->parent(), block, object); | 1456 childlist->insertChildNode(object->parent(), block, object); |
| 1435 block->children()->appendChildNode( | 1457 block->children()->appendChildNode( |
| 1436 block, childlist->removeChildNode(object->parent(), object)); | 1458 block, childlist->removeChildNode(object->parent(), object)); |
| 1437 } | 1459 } |
| 1438 } | 1460 } |
| 1439 } | 1461 } |
| 1440 | 1462 |
| 1441 StyleDifference LayoutObject::adjustStyleDifference( | 1463 StyleDifference LayoutObject::adjustStyleDifference( |
| 1442 StyleDifference diff) const { | 1464 StyleDifference diff) const { |
| 1443 if (diff.transformChanged() && isSVG()) { | 1465 if (diff.transformChanged() && isSVG()) { |
| 1444 // Skip a full layout for transforms at the html/svg boundary which do not a
ffect sizes inside SVG. | 1466 // Skip a full layout for transforms at the html/svg boundary which do not |
| 1467 // affect sizes inside SVG. |
| 1445 if (!isSVGRoot()) | 1468 if (!isSVGRoot()) |
| 1446 diff.setNeedsFullLayout(); | 1469 diff.setNeedsFullLayout(); |
| 1447 } | 1470 } |
| 1448 | 1471 |
| 1449 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 1472 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 1450 // Text nodes share style with their parents but the checked styles don't ap
ply to them, | 1473 // Text nodes share style with their parents but the checked styles don't |
| 1451 // hence the !isText() check. | 1474 // apply to them, hence the !isText() check. |
| 1452 if (!isText() && (diff.transformChanged() || diff.opacityChanged() || | 1475 if (!isText() && (diff.transformChanged() || diff.opacityChanged() || |
| 1453 diff.zIndexChanged() || diff.filterChanged() || | 1476 diff.zIndexChanged() || diff.filterChanged() || |
| 1454 diff.backdropFilterChanged())) { | 1477 diff.backdropFilterChanged())) { |
| 1455 // We don't need to invalidate paint of objects on SPv2 when only paint pr
operty or | 1478 // We don't need to invalidate paint of objects on SPv2 when only paint |
| 1456 // paint order change. Mark the painting layer needing repaint for changed
paint | 1479 // property or paint order change. Mark the painting layer needing repaint |
| 1457 // property or paint order. Raster invalidation will be issued if needed d
uring paint. | 1480 // for changed paint property or paint order. Raster invalidation will be |
| 1481 // issued if needed during paint. |
| 1458 ObjectPaintInvalidator(*this).slowSetPaintingLayerNeedsRepaint(); | 1482 ObjectPaintInvalidator(*this).slowSetPaintingLayerNeedsRepaint(); |
| 1459 } | 1483 } |
| 1460 } else { | 1484 } else { |
| 1461 // If transform changed, and the layer does not paint into its own separate
backing, then we need to invalidate paints. | 1485 // If transform changed, and the layer does not paint into its own separate |
| 1486 // backing, then we need to invalidate paints. |
| 1462 if (diff.transformChanged()) { | 1487 if (diff.transformChanged()) { |
| 1463 // Text nodes share style with their parents but transforms don't apply to
them, | 1488 // Text nodes share style with their parents but transforms don't apply to |
| 1464 // hence the !isText() check. | 1489 // them, hence the !isText() check. |
| 1465 if (!isText() && (!hasLayer() || | 1490 if (!isText() && (!hasLayer() || |
| 1466 !toLayoutBoxModelObject(this) | 1491 !toLayoutBoxModelObject(this) |
| 1467 ->layer() | 1492 ->layer() |
| 1468 ->hasStyleDeterminedDirectCompositingReasons())) | 1493 ->hasStyleDeterminedDirectCompositingReasons())) |
| 1469 diff.setNeedsPaintInvalidationSubtree(); | 1494 diff.setNeedsPaintInvalidationSubtree(); |
| 1470 } | 1495 } |
| 1471 | 1496 |
| 1472 // If opacity or zIndex changed, and the layer does not paint into its own s
eparate backing, then we need to invalidate paints (also | 1497 // If opacity or zIndex changed, and the layer does not paint into its own |
| 1473 // ignoring text nodes) | 1498 // separate backing, then we need to invalidate paints (also |
| 1499 // ignoring text nodes). |
| 1474 if (diff.opacityChanged() || diff.zIndexChanged()) { | 1500 if (diff.opacityChanged() || diff.zIndexChanged()) { |
| 1475 if (!isText() && (!hasLayer() || | 1501 if (!isText() && (!hasLayer() || |
| 1476 !toLayoutBoxModelObject(this) | 1502 !toLayoutBoxModelObject(this) |
| 1477 ->layer() | 1503 ->layer() |
| 1478 ->hasStyleDeterminedDirectCompositingReasons())) | 1504 ->hasStyleDeterminedDirectCompositingReasons())) |
| 1479 diff.setNeedsPaintInvalidationSubtree(); | 1505 diff.setNeedsPaintInvalidationSubtree(); |
| 1480 } | 1506 } |
| 1481 | 1507 |
| 1482 // If filter changed, and the layer does not paint into its own separate bac
king or it paints with filters, then we need to invalidate paints. | 1508 // If filter changed, and the layer does not paint into its own separate |
| 1509 // backing or it paints with filters, then we need to invalidate paints. |
| 1483 if (diff.filterChanged() && hasLayer()) { | 1510 if (diff.filterChanged() && hasLayer()) { |
| 1484 PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); | 1511 PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); |
| 1485 if (!layer->hasStyleDeterminedDirectCompositingReasons() || | 1512 if (!layer->hasStyleDeterminedDirectCompositingReasons() || |
| 1486 layer->paintsWithFilters()) | 1513 layer->paintsWithFilters()) |
| 1487 diff.setNeedsPaintInvalidationSubtree(); | 1514 diff.setNeedsPaintInvalidationSubtree(); |
| 1488 } | 1515 } |
| 1489 | 1516 |
| 1490 // If backdrop filter changed, and the layer does not paint into its own sep
arate backing or it paints with filters, then we need to invalidate paints. | 1517 // If backdrop filter changed, and the layer does not paint into its own |
| 1518 // separate backing or it paints with filters, then we need to invalidate |
| 1519 // paints. |
| 1491 if (diff.backdropFilterChanged() && hasLayer()) { | 1520 if (diff.backdropFilterChanged() && hasLayer()) { |
| 1492 PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); | 1521 PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); |
| 1493 if (!layer->hasStyleDeterminedDirectCompositingReasons() || | 1522 if (!layer->hasStyleDeterminedDirectCompositingReasons() || |
| 1494 layer->paintsWithBackdropFilters()) | 1523 layer->paintsWithBackdropFilters()) |
| 1495 diff.setNeedsPaintInvalidationSubtree(); | 1524 diff.setNeedsPaintInvalidationSubtree(); |
| 1496 } | 1525 } |
| 1497 } | 1526 } |
| 1498 | 1527 |
| 1499 // Optimization: for decoration/color property changes, invalidation is only n
eeded if we have style or text affected by these properties. | 1528 // Optimization: for decoration/color property changes, invalidation is only |
| 1529 // needed if we have style or text affected by these properties. |
| 1500 if (diff.textDecorationOrColorChanged() && !diff.needsPaintInvalidation()) { | 1530 if (diff.textDecorationOrColorChanged() && !diff.needsPaintInvalidation()) { |
| 1501 if (style()->hasBorder() || style()->hasOutline() || | 1531 if (style()->hasBorder() || style()->hasOutline() || |
| 1502 style()->hasBackgroundRelatedColorReferencingCurrentColor() | 1532 style()->hasBackgroundRelatedColorReferencingCurrentColor() |
| 1503 // Skip any text nodes that do not contain text boxes. Whitespace cannot
be | 1533 // Skip any text nodes that do not contain text boxes. Whitespace cannot |
| 1504 // skipped or we will miss invalidating decorations (e.g., underlines). | 1534 // be skipped or we will miss invalidating decorations (e.g., |
| 1535 // underlines). |
| 1505 || (isText() && !isBR() && toLayoutText(this)->hasTextBoxes()) | 1536 || (isText() && !isBR() && toLayoutText(this)->hasTextBoxes()) |
| 1506 // Caret is painted in text color. | 1537 // Caret is painted in text color. |
| 1507 || (isLayoutBlock() && toLayoutBlock(this)->hasCaret()) || | 1538 || (isLayoutBlock() && toLayoutBlock(this)->hasCaret()) || |
| 1508 (isSVG() && style()->svgStyle().isFillColorCurrentColor()) || | 1539 (isSVG() && style()->svgStyle().isFillColorCurrentColor()) || |
| 1509 (isSVG() && style()->svgStyle().isStrokeColorCurrentColor()) || | 1540 (isSVG() && style()->svgStyle().isStrokeColorCurrentColor()) || |
| 1510 isListMarker()) | 1541 isListMarker()) |
| 1511 diff.setNeedsPaintInvalidationObject(); | 1542 diff.setNeedsPaintInvalidationObject(); |
| 1512 } | 1543 } |
| 1513 | 1544 |
| 1514 // The answer to layerTypeRequired() for plugins, iframes, and canvas can chan
ge without the actual | 1545 // The answer to layerTypeRequired() for plugins, iframes, and canvas can |
| 1515 // style changing, since it depends on whether we decide to composite these el
ements. When the | 1546 // change without the actual style changing, since it depends on whether we |
| 1516 // layer status of one of these elements changes, we need to force a layout. | 1547 // decide to composite these elements. When the/ layer status of one of these |
| 1548 // elements changes, we need to force a layout. |
| 1517 if (!diff.needsFullLayout() && style() && isBoxModelObject()) { | 1549 if (!diff.needsFullLayout() && style() && isBoxModelObject()) { |
| 1518 bool requiresLayer = | 1550 bool requiresLayer = |
| 1519 toLayoutBoxModelObject(this)->layerTypeRequired() != NoPaintLayer; | 1551 toLayoutBoxModelObject(this)->layerTypeRequired() != NoPaintLayer; |
| 1520 if (hasLayer() != requiresLayer) | 1552 if (hasLayer() != requiresLayer) |
| 1521 diff.setNeedsFullLayout(); | 1553 diff.setNeedsFullLayout(); |
| 1522 } | 1554 } |
| 1523 | 1555 |
| 1524 return diff; | 1556 return diff; |
| 1525 } | 1557 } |
| 1526 | 1558 |
| 1527 void LayoutObject::setPseudoStyle(PassRefPtr<ComputedStyle> pseudoStyle) { | 1559 void LayoutObject::setPseudoStyle(PassRefPtr<ComputedStyle> pseudoStyle) { |
| 1528 ASSERT(pseudoStyle->styleType() == PseudoIdBefore || | 1560 ASSERT(pseudoStyle->styleType() == PseudoIdBefore || |
| 1529 pseudoStyle->styleType() == PseudoIdAfter || | 1561 pseudoStyle->styleType() == PseudoIdAfter || |
| 1530 pseudoStyle->styleType() == PseudoIdFirstLetter); | 1562 pseudoStyle->styleType() == PseudoIdFirstLetter); |
| 1531 | 1563 |
| 1532 // FIXME: We should consider just making all pseudo items use an inherited sty
le. | 1564 // FIXME: We should consider just making all pseudo items use an inherited |
| 1565 // style. |
| 1533 | 1566 |
| 1534 // Images are special and must inherit the pseudoStyle so the width and height
of | 1567 // Images are special and must inherit the pseudoStyle so the width and height |
| 1535 // the pseudo element doesn't change the size of the image. In all other cases
we | 1568 // of the pseudo element doesn't change the size of the image. In all other |
| 1536 // can just share the style. | 1569 // cases we can just share the style. |
| 1537 // | 1570 // |
| 1538 // Quotes are also LayoutInline, so we need to create an inherited style to av
oid | 1571 // Quotes are also LayoutInline, so we need to create an inherited style to |
| 1539 // getting an inline with positioning or an invalid display. | 1572 // avoid getting an inline with positioning or an invalid display. |
| 1540 // | 1573 // |
| 1541 if (isImage() || isQuote()) { | 1574 if (isImage() || isQuote()) { |
| 1542 RefPtr<ComputedStyle> style = ComputedStyle::create(); | 1575 RefPtr<ComputedStyle> style = ComputedStyle::create(); |
| 1543 style->inheritFrom(*pseudoStyle); | 1576 style->inheritFrom(*pseudoStyle); |
| 1544 setStyle(style.release()); | 1577 setStyle(style.release()); |
| 1545 return; | 1578 return; |
| 1546 } | 1579 } |
| 1547 | 1580 |
| 1548 setStyle(std::move(pseudoStyle)); | 1581 setStyle(std::move(pseudoStyle)); |
| 1549 } | 1582 } |
| 1550 | 1583 |
| 1551 void LayoutObject::firstLineStyleDidChange(const ComputedStyle& oldStyle, | 1584 void LayoutObject::firstLineStyleDidChange(const ComputedStyle& oldStyle, |
| 1552 const ComputedStyle& newStyle) { | 1585 const ComputedStyle& newStyle) { |
| 1553 StyleDifference diff = oldStyle.visualInvalidationDiff(newStyle); | 1586 StyleDifference diff = oldStyle.visualInvalidationDiff(newStyle); |
| 1554 | 1587 |
| 1555 if (diff.needsPaintInvalidation() || diff.textDecorationOrColorChanged()) { | 1588 if (diff.needsPaintInvalidation() || diff.textDecorationOrColorChanged()) { |
| 1556 // We need to invalidate all inline boxes in the first line, because they ne
ed to be | 1589 // We need to invalidate all inline boxes in the first line, because they |
| 1557 // repainted with the new style, e.g. background, font style, etc. | 1590 // need to be repainted with the new style, e.g. background, font style, |
| 1591 // etc. |
| 1558 LayoutBlockFlow* firstLineContainer = nullptr; | 1592 LayoutBlockFlow* firstLineContainer = nullptr; |
| 1559 if (behavesLikeBlockContainer()) { | 1593 if (behavesLikeBlockContainer()) { |
| 1560 // This object is a LayoutBlock having PseudoIdFirstLine pseudo style chan
ged. | 1594 // This object is a LayoutBlock having PseudoIdFirstLine pseudo style |
| 1595 // changed. |
| 1561 firstLineContainer = | 1596 firstLineContainer = |
| 1562 toLayoutBlock(this)->nearestInnerBlockWithFirstLine(); | 1597 toLayoutBlock(this)->nearestInnerBlockWithFirstLine(); |
| 1563 } else if (isLayoutInline()) { | 1598 } else if (isLayoutInline()) { |
| 1564 // This object is a LayoutInline having FIRST_LINE_INHERITED pesudo style
changed. | 1599 // This object is a LayoutInline having FIRST_LINE_INHERITED pesudo style |
| 1565 // This method can be called even if the LayoutInline doesn't intersect th
e first line, | 1600 // changed. This method can be called even if the LayoutInline doesn't |
| 1566 // but we only need to invalidate if it does. | 1601 // intersect the first line, but we only need to invalidate if it does. |
| 1567 if (InlineBox* firstLineBox = | 1602 if (InlineBox* firstLineBox = |
| 1568 toLayoutInline(this)->firstLineBoxIncludingCulling()) { | 1603 toLayoutInline(this)->firstLineBoxIncludingCulling()) { |
| 1569 if (firstLineBox->isFirstLineStyle()) | 1604 if (firstLineBox->isFirstLineStyle()) |
| 1570 firstLineContainer = toLayoutBlockFlow(containingBlock()); | 1605 firstLineContainer = toLayoutBlockFlow(containingBlock()); |
| 1571 } | 1606 } |
| 1572 } | 1607 } |
| 1573 if (firstLineContainer) | 1608 if (firstLineContainer) |
| 1574 firstLineContainer->setShouldDoFullPaintInvalidationForFirstLine(); | 1609 firstLineContainer->setShouldDoFullPaintInvalidationForFirstLine(); |
| 1575 } | 1610 } |
| 1576 if (diff.needsLayout()) | 1611 if (diff.needsLayout()) |
| 1577 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); | 1612 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); |
| 1578 } | 1613 } |
| 1579 | 1614 |
| 1580 void LayoutObject::markAncestorsForOverflowRecalcIfNeeded() { | 1615 void LayoutObject::markAncestorsForOverflowRecalcIfNeeded() { |
| 1581 LayoutObject* object = this; | 1616 LayoutObject* object = this; |
| 1582 do { | 1617 do { |
| 1583 // Cell and row need to propagate the flag to their containing section and r
ow as their containing block is the table wrapper. | 1618 // Cell and row need to propagate the flag to their containing section and |
| 1619 // row as their containing block is the table wrapper. |
| 1584 // This enables us to only recompute overflow the modified sections / rows. | 1620 // This enables us to only recompute overflow the modified sections / rows. |
| 1585 object = object->isTableCell() || object->isTableRow() | 1621 object = object->isTableCell() || object->isTableRow() |
| 1586 ? object->parent() | 1622 ? object->parent() |
| 1587 : object->containingBlock(); | 1623 : object->containingBlock(); |
| 1588 if (object) | 1624 if (object) |
| 1589 object->setChildNeedsOverflowRecalcAfterStyleChange(); | 1625 object->setChildNeedsOverflowRecalcAfterStyleChange(); |
| 1590 } while (object); | 1626 } while (object); |
| 1591 } | 1627 } |
| 1592 | 1628 |
| 1593 void LayoutObject::setNeedsOverflowRecalcAfterStyleChange() { | 1629 void LayoutObject::setNeedsOverflowRecalcAfterStyleChange() { |
| 1594 bool neededRecalc = needsOverflowRecalcAfterStyleChange(); | 1630 bool neededRecalc = needsOverflowRecalcAfterStyleChange(); |
| 1595 setSelfNeedsOverflowRecalcAfterStyleChange(); | 1631 setSelfNeedsOverflowRecalcAfterStyleChange(); |
| 1596 if (!neededRecalc) | 1632 if (!neededRecalc) |
| 1597 markAncestorsForOverflowRecalcIfNeeded(); | 1633 markAncestorsForOverflowRecalcIfNeeded(); |
| 1598 } | 1634 } |
| 1599 | 1635 |
| 1600 DISABLE_CFI_PERF | 1636 DISABLE_CFI_PERF |
| 1601 void LayoutObject::setStyle(PassRefPtr<ComputedStyle> style) { | 1637 void LayoutObject::setStyle(PassRefPtr<ComputedStyle> style) { |
| 1602 ASSERT(style); | 1638 ASSERT(style); |
| 1603 | 1639 |
| 1604 if (m_style == style) { | 1640 if (m_style == style) { |
| 1605 // We need to run through adjustStyleDifference() for iframes, plugins, and
canvas so | 1641 // We need to run through adjustStyleDifference() for iframes, plugins, and |
| 1606 // style sharing is disabled for them. That should ensure that we never hit
this code path. | 1642 // canvas so style sharing is disabled for them. That should ensure that we |
| 1643 // never hit this code path. |
| 1607 ASSERT(!isLayoutIFrame() && !isEmbeddedObject() && !isCanvas()); | 1644 ASSERT(!isLayoutIFrame() && !isEmbeddedObject() && !isCanvas()); |
| 1608 return; | 1645 return; |
| 1609 } | 1646 } |
| 1610 | 1647 |
| 1611 StyleDifference diff; | 1648 StyleDifference diff; |
| 1612 if (m_style) | 1649 if (m_style) |
| 1613 diff = m_style->visualInvalidationDiff(*style); | 1650 diff = m_style->visualInvalidationDiff(*style); |
| 1614 | 1651 |
| 1615 diff = adjustStyleDifference(diff); | 1652 diff = adjustStyleDifference(diff); |
| 1616 | 1653 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 | 1686 |
| 1650 updateShapeImage(oldStyle ? oldStyle->shapeOutside() : 0, | 1687 updateShapeImage(oldStyle ? oldStyle->shapeOutside() : 0, |
| 1651 m_style->shapeOutside()); | 1688 m_style->shapeOutside()); |
| 1652 updateCursorImages(oldStyle ? oldStyle->cursors() : nullptr, | 1689 updateCursorImages(oldStyle ? oldStyle->cursors() : nullptr, |
| 1653 m_style->cursors()); | 1690 m_style->cursors()); |
| 1654 | 1691 |
| 1655 bool doesNotNeedLayoutOrPaintInvalidation = !m_parent; | 1692 bool doesNotNeedLayoutOrPaintInvalidation = !m_parent; |
| 1656 | 1693 |
| 1657 styleDidChange(diff, oldStyle.get()); | 1694 styleDidChange(diff, oldStyle.get()); |
| 1658 | 1695 |
| 1659 // FIXME: |this| might be destroyed here. This can currently happen for a Layo
utTextFragment when | 1696 // FIXME: |this| might be destroyed here. This can currently happen for a |
| 1660 // its first-letter block gets an update in LayoutTextFragment::styleDidChange
. For LayoutTextFragment(s), | 1697 // LayoutTextFragment when its first-letter block gets an update in |
| 1661 // we will safely bail out with the doesNotNeedLayoutOrPaintInvalidation flag.
We might want to broaden | 1698 // LayoutTextFragment::styleDidChange. For LayoutTextFragment(s), |
| 1662 // this condition in the future as we move layoutObject changes out of layout
and into style changes. | 1699 // we will safely bail out with the doesNotNeedLayoutOrPaintInvalidation flag. |
| 1700 // We might want to broaden this condition in the future as we move |
| 1701 // layoutObject changes out of layout and into style changes. |
| 1663 if (doesNotNeedLayoutOrPaintInvalidation) | 1702 if (doesNotNeedLayoutOrPaintInvalidation) |
| 1664 return; | 1703 return; |
| 1665 | 1704 |
| 1666 // Now that the layer (if any) has been updated, we need to adjust the diff ag
ain, | 1705 // Now that the layer (if any) has been updated, we need to adjust the diff |
| 1667 // check whether we should layout now, and decide if we need to invalidate pai
nts. | 1706 // again, check whether we should layout now, and decide if we need to |
| 1707 // invalidate paints. |
| 1668 StyleDifference updatedDiff = adjustStyleDifference(diff); | 1708 StyleDifference updatedDiff = adjustStyleDifference(diff); |
| 1669 | 1709 |
| 1670 if (!diff.needsFullLayout()) { | 1710 if (!diff.needsFullLayout()) { |
| 1671 if (updatedDiff.needsFullLayout()) | 1711 if (updatedDiff.needsFullLayout()) |
| 1672 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); | 1712 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); |
| 1673 else if (updatedDiff.needsPositionedMovementLayout()) | 1713 else if (updatedDiff.needsPositionedMovementLayout()) |
| 1674 setNeedsPositionedMovementLayout(); | 1714 setNeedsPositionedMovementLayout(); |
| 1675 } | 1715 } |
| 1676 | 1716 |
| 1677 if (diff.transformChanged() && !needsLayout()) { | 1717 if (diff.transformChanged() && !needsLayout()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1705 m_style->zIndex() != newStyle.zIndex() || | 1745 m_style->zIndex() != newStyle.zIndex() || |
| 1706 m_style->isStackingContext() != newStyle.isStackingContext(); | 1746 m_style->isStackingContext() != newStyle.isStackingContext(); |
| 1707 if (visibilityChanged) { | 1747 if (visibilityChanged) { |
| 1708 document().setAnnotatedRegionsDirty(true); | 1748 document().setAnnotatedRegionsDirty(true); |
| 1709 if (AXObjectCache* cache = document().existingAXObjectCache()) | 1749 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 1710 cache->childrenChanged(parent()); | 1750 cache->childrenChanged(parent()); |
| 1711 } | 1751 } |
| 1712 | 1752 |
| 1713 // Keep layer hierarchy visibility bits up to date if visibility changes. | 1753 // Keep layer hierarchy visibility bits up to date if visibility changes. |
| 1714 if (m_style->visibility() != newStyle.visibility()) { | 1754 if (m_style->visibility() != newStyle.visibility()) { |
| 1715 // We might not have an enclosing layer yet because we might not be in the
tree. | 1755 // We might not have an enclosing layer yet because we might not be in the |
| 1756 // tree. |
| 1716 if (PaintLayer* layer = enclosingLayer()) | 1757 if (PaintLayer* layer = enclosingLayer()) |
| 1717 layer->potentiallyDirtyVisibleContentStatus(newStyle.visibility()); | 1758 layer->potentiallyDirtyVisibleContentStatus(newStyle.visibility()); |
| 1718 } | 1759 } |
| 1719 | 1760 |
| 1720 if (isFloating() && (m_style->floating() != newStyle.floating())) { | 1761 if (isFloating() && (m_style->floating() != newStyle.floating())) { |
| 1721 // For changes in float styles, we need to conceivably remove ourselves | 1762 // For changes in float styles, we need to conceivably remove ourselves |
| 1722 // from the floating objects list. | 1763 // from the floating objects list. |
| 1723 toLayoutBox(this)->removeFloatingOrPositionedChildFromBlockLists(); | 1764 toLayoutBox(this)->removeFloatingOrPositionedChildFromBlockLists(); |
| 1724 } else if (isOutOfFlowPositioned() && | 1765 } else if (isOutOfFlowPositioned() && |
| 1725 (m_style->position() != newStyle.position())) { | 1766 (m_style->position() != newStyle.position())) { |
| 1726 // For changes in positioning styles, we need to conceivably remove oursel
ves | 1767 // For changes in positioning styles, we need to conceivably remove |
| 1727 // from the positioned objects list. | 1768 // ourselves from the positioned objects list. |
| 1728 toLayoutBox(this)->removeFloatingOrPositionedChildFromBlockLists(); | 1769 toLayoutBox(this)->removeFloatingOrPositionedChildFromBlockLists(); |
| 1729 } | 1770 } |
| 1730 | 1771 |
| 1731 s_affectsParentBlock = | 1772 s_affectsParentBlock = |
| 1732 isFloatingOrOutOfFlowPositioned() && | 1773 isFloatingOrOutOfFlowPositioned() && |
| 1733 (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition()) && | 1774 (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition()) && |
| 1734 parent() && | 1775 parent() && |
| 1735 (parent()->isLayoutBlockFlow() || parent()->isLayoutInline()); | 1776 (parent()->isLayoutBlockFlow() || parent()->isLayoutInline()); |
| 1736 | 1777 |
| 1737 // Clearing these bits is required to avoid leaving stale layoutObjects. | 1778 // Clearing these bits is required to avoid leaving stale layoutObjects. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 markAncestorsForOverflowRecalcIfNeeded(); | 1877 markAncestorsForOverflowRecalcIfNeeded(); |
| 1837 | 1878 |
| 1838 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); | 1879 setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); |
| 1839 } else if (diff.needsPositionedMovementLayout()) { | 1880 } else if (diff.needsPositionedMovementLayout()) { |
| 1840 setNeedsPositionedMovementLayout(); | 1881 setNeedsPositionedMovementLayout(); |
| 1841 } | 1882 } |
| 1842 | 1883 |
| 1843 if (diff.scrollAnchorDisablingPropertyChanged()) | 1884 if (diff.scrollAnchorDisablingPropertyChanged()) |
| 1844 setScrollAnchorDisablingStyleChanged(true); | 1885 setScrollAnchorDisablingStyleChanged(true); |
| 1845 | 1886 |
| 1846 // Don't check for paint invalidation here; we need to wait until the layer ha
s been | 1887 // Don't check for paint invalidation here; we need to wait until the layer |
| 1847 // updated by subclasses before we know if we have to invalidate paints (in se
tStyle()). | 1888 // has been updated by subclasses before we know if we have to invalidate |
| 1889 // paints (in setStyle()). |
| 1848 | 1890 |
| 1849 if (oldStyle && !areCursorsEqual(oldStyle, style())) { | 1891 if (oldStyle && !areCursorsEqual(oldStyle, style())) { |
| 1850 if (LocalFrame* frame = this->frame()) { | 1892 if (LocalFrame* frame = this->frame()) { |
| 1851 // Cursor update scheduling is done by the local root, which is the main f
rame if there | 1893 // Cursor update scheduling is done by the local root, which is the main |
| 1852 // are no RemoteFrame ancestors in the frame tree. Use of localFrameRoot()
is | 1894 // frame if there are no RemoteFrame ancestors in the frame tree. Use of |
| 1853 // discouraged but will change when cursor update scheduling is moved from
EventHandler | 1895 // localFrameRoot() is discouraged but will change when cursor update |
| 1854 // to PageEventHandler. | 1896 // scheduling is moved from EventHandler to PageEventHandler. |
| 1855 frame->localFrameRoot()->eventHandler().scheduleCursorUpdate(); | 1897 frame->localFrameRoot()->eventHandler().scheduleCursorUpdate(); |
| 1856 } | 1898 } |
| 1857 } | 1899 } |
| 1858 } | 1900 } |
| 1859 | 1901 |
| 1860 void LayoutObject::propagateStyleToAnonymousChildren() { | 1902 void LayoutObject::propagateStyleToAnonymousChildren() { |
| 1861 // FIXME: We could save this call when the change only affected non-inherited
properties. | 1903 // FIXME: We could save this call when the change only affected non-inherited |
| 1904 // properties. |
| 1862 for (LayoutObject* child = slowFirstChild(); child; | 1905 for (LayoutObject* child = slowFirstChild(); child; |
| 1863 child = child->nextSibling()) { | 1906 child = child->nextSibling()) { |
| 1864 if (!child->isAnonymous() || child->style()->styleType() != PseudoIdNone) | 1907 if (!child->isAnonymous() || child->style()->styleType() != PseudoIdNone) |
| 1865 continue; | 1908 continue; |
| 1866 | 1909 |
| 1867 if (child->anonymousHasStylePropagationOverride()) | 1910 if (child->anonymousHasStylePropagationOverride()) |
| 1868 continue; | 1911 continue; |
| 1869 | 1912 |
| 1870 RefPtr<ComputedStyle> newStyle = | 1913 RefPtr<ComputedStyle> newStyle = |
| 1871 ComputedStyle::createAnonymousStyleWithDisplay( | 1914 ComputedStyle::createAnonymousStyleWithDisplay( |
| 1872 styleRef(), child->style()->display()); | 1915 styleRef(), child->style()->display()); |
| 1873 | 1916 |
| 1874 // Preserve the position style of anonymous block continuations as they can
have relative position when | 1917 // Preserve the position style of anonymous block continuations as they can |
| 1875 // they contain block descendants of relative positioned inlines. | 1918 // have relative position when they contain block descendants of relative |
| 1919 // positioned inlines. |
| 1876 if (child->isInFlowPositioned() && child->isLayoutBlockFlow() && | 1920 if (child->isInFlowPositioned() && child->isLayoutBlockFlow() && |
| 1877 toLayoutBlockFlow(child)->isAnonymousBlockContinuation()) | 1921 toLayoutBlockFlow(child)->isAnonymousBlockContinuation()) |
| 1878 newStyle->setPosition(child->style()->position()); | 1922 newStyle->setPosition(child->style()->position()); |
| 1879 | 1923 |
| 1880 updateAnonymousChildStyle(*child, *newStyle); | 1924 updateAnonymousChildStyle(*child, *newStyle); |
| 1881 | 1925 |
| 1882 child->setStyle(newStyle.release()); | 1926 child->setStyle(newStyle.release()); |
| 1883 } | 1927 } |
| 1884 } | 1928 } |
| 1885 | 1929 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1903 } | 1947 } |
| 1904 addChild(newChild, beforeChild); | 1948 addChild(newChild, beforeChild); |
| 1905 } | 1949 } |
| 1906 | 1950 |
| 1907 void LayoutObject::updateFillImages(const FillLayer* oldLayers, | 1951 void LayoutObject::updateFillImages(const FillLayer* oldLayers, |
| 1908 const FillLayer& newLayers) { | 1952 const FillLayer& newLayers) { |
| 1909 // Optimize the common case | 1953 // Optimize the common case |
| 1910 if (FillLayer::imagesIdentical(oldLayers, &newLayers)) | 1954 if (FillLayer::imagesIdentical(oldLayers, &newLayers)) |
| 1911 return; | 1955 return; |
| 1912 | 1956 |
| 1913 // Go through the new layers and addClients first, to avoid removing all clien
ts of an image. | 1957 // Go through the new layers and addClients first, to avoid removing all |
| 1958 // clients of an image. |
| 1914 for (const FillLayer* currNew = &newLayers; currNew; | 1959 for (const FillLayer* currNew = &newLayers; currNew; |
| 1915 currNew = currNew->next()) { | 1960 currNew = currNew->next()) { |
| 1916 if (currNew->image()) | 1961 if (currNew->image()) |
| 1917 currNew->image()->addClient(this); | 1962 currNew->image()->addClient(this); |
| 1918 } | 1963 } |
| 1919 | 1964 |
| 1920 for (const FillLayer* currOld = oldLayers; currOld; | 1965 for (const FillLayer* currOld = oldLayers; currOld; |
| 1921 currOld = currOld->next()) { | 1966 currOld = currOld->next()) { |
| 1922 if (currOld->image()) | 1967 if (currOld->image()) |
| 1923 currOld->image()->removeClient(this); | 1968 currOld->image()->removeClient(this); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 transformState.move( | 2055 transformState.move( |
| 2011 toLayoutBox(o)->flipForWritingMode(LayoutPoint(centerPoint)) - | 2056 toLayoutBox(o)->flipForWritingMode(LayoutPoint(centerPoint)) - |
| 2012 centerPoint); | 2057 centerPoint); |
| 2013 } | 2058 } |
| 2014 mode &= ~ApplyContainerFlip; | 2059 mode &= ~ApplyContainerFlip; |
| 2015 } | 2060 } |
| 2016 } | 2061 } |
| 2017 | 2062 |
| 2018 LayoutSize containerOffset = offsetFromContainer(o); | 2063 LayoutSize containerOffset = offsetFromContainer(o); |
| 2019 if (isLayoutFlowThread()) { | 2064 if (isLayoutFlowThread()) { |
| 2020 // So far the point has been in flow thread coordinates (i.e. as if everythi
ng in | 2065 // So far the point has been in flow thread coordinates (i.e. as if |
| 2021 // the fragmentation context lived in one tall single column). Convert it to
a | 2066 // everything in the fragmentation context lived in one tall single column). |
| 2022 // visual point now, since we're about to escape the flow thread. | 2067 // Convert it to a visual point now, since we're about to escape the flow |
| 2068 // thread. |
| 2023 containerOffset += | 2069 containerOffset += |
| 2024 columnOffset(roundedLayoutPoint(transformState.mappedPoint())); | 2070 columnOffset(roundedLayoutPoint(transformState.mappedPoint())); |
| 2025 } | 2071 } |
| 2026 | 2072 |
| 2027 // Text objects just copy their parent's computed style, so we need to ignore
them. | 2073 // Text objects just copy their parent's computed style, so we need to ignore |
| 2074 // them. |
| 2028 bool preserve3D = | 2075 bool preserve3D = |
| 2029 mode & UseTransforms && ((o->style()->preserves3D() && !o->isText()) || | 2076 mode & UseTransforms && ((o->style()->preserves3D() && !o->isText()) || |
| 2030 (style()->preserves3D() && !isText())); | 2077 (style()->preserves3D() && !isText())); |
| 2031 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { | 2078 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { |
| 2032 TransformationMatrix t; | 2079 TransformationMatrix t; |
| 2033 getTransformFromContainer(o, containerOffset, t); | 2080 getTransformFromContainer(o, containerOffset, t); |
| 2034 transformState.applyTransform(t, preserve3D | 2081 transformState.applyTransform(t, preserve3D |
| 2035 ? TransformState::AccumulateTransform | 2082 ? TransformState::AccumulateTransform |
| 2036 : TransformState::FlattenTransform); | 2083 : TransformState::FlattenTransform); |
| 2037 } else { | 2084 } else { |
| 2038 transformState.move(containerOffset.width(), containerOffset.height(), | 2085 transformState.move(containerOffset.width(), containerOffset.height(), |
| 2039 preserve3D ? TransformState::AccumulateTransform | 2086 preserve3D ? TransformState::AccumulateTransform |
| 2040 : TransformState::FlattenTransform); | 2087 : TransformState::FlattenTransform); |
| 2041 } | 2088 } |
| 2042 | 2089 |
| 2043 if (ancestorSkipped) { | 2090 if (ancestorSkipped) { |
| 2044 // There can't be a transform between |ancestor| and |o|, because transforms
create | 2091 // There can't be a transform between |ancestor| and |o|, because transforms |
| 2045 // containers, so it should be safe to just subtract the delta between the a
ncestor and |o|. | 2092 // create containers, so it should be safe to just subtract the delta |
| 2093 // between the ancestor and |o|. |
| 2046 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); | 2094 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); |
| 2047 transformState.move(-containerOffset.width(), -containerOffset.height(), | 2095 transformState.move(-containerOffset.width(), -containerOffset.height(), |
| 2048 preserve3D ? TransformState::AccumulateTransform | 2096 preserve3D ? TransformState::AccumulateTransform |
| 2049 : TransformState::FlattenTransform); | 2097 : TransformState::FlattenTransform); |
| 2050 return; | 2098 return; |
| 2051 } | 2099 } |
| 2052 | 2100 |
| 2053 o->mapLocalToAncestor(ancestor, transformState, mode); | 2101 o->mapLocalToAncestor(ancestor, transformState, mode); |
| 2054 } | 2102 } |
| 2055 | 2103 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2079 applyContainerFlip = o->style()->isFlippedBlocksWritingMode(); | 2127 applyContainerFlip = o->style()->isFlippedBlocksWritingMode(); |
| 2080 mode &= ~ApplyContainerFlip; | 2128 mode &= ~ApplyContainerFlip; |
| 2081 } | 2129 } |
| 2082 } | 2130 } |
| 2083 | 2131 |
| 2084 if (!ancestorSkipped) | 2132 if (!ancestorSkipped) |
| 2085 o->mapAncestorToLocal(ancestor, transformState, mode); | 2133 o->mapAncestorToLocal(ancestor, transformState, mode); |
| 2086 | 2134 |
| 2087 LayoutSize containerOffset = offsetFromContainer(o); | 2135 LayoutSize containerOffset = offsetFromContainer(o); |
| 2088 if (isLayoutFlowThread()) { | 2136 if (isLayoutFlowThread()) { |
| 2089 // Descending into a flow thread. Convert to the local coordinate space, i.e
. flow thread coordinates. | 2137 // Descending into a flow thread. Convert to the local coordinate space, |
| 2138 // i.e. flow thread coordinates. |
| 2090 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint()); | 2139 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint()); |
| 2091 transformState.move( | 2140 transformState.move( |
| 2092 visualPoint - | 2141 visualPoint - |
| 2093 toLayoutFlowThread(this)->visualPointToFlowThreadPoint(visualPoint)); | 2142 toLayoutFlowThread(this)->visualPointToFlowThreadPoint(visualPoint)); |
| 2094 } | 2143 } |
| 2095 | 2144 |
| 2096 bool preserve3D = mode & UseTransforms && | 2145 bool preserve3D = mode & UseTransforms && |
| 2097 (o->style()->preserves3D() || style()->preserves3D()); | 2146 (o->style()->preserves3D() || style()->preserves3D()); |
| 2098 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { | 2147 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { |
| 2099 TransformationMatrix t; | 2148 TransformationMatrix t; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2115 } | 2164 } |
| 2116 | 2165 |
| 2117 if (ancestorSkipped) { | 2166 if (ancestorSkipped) { |
| 2118 containerOffset = ancestor->offsetFromAncestorContainer(o); | 2167 containerOffset = ancestor->offsetFromAncestorContainer(o); |
| 2119 transformState.move(-containerOffset.width(), -containerOffset.height()); | 2168 transformState.move(-containerOffset.width(), -containerOffset.height()); |
| 2120 } | 2169 } |
| 2121 } | 2170 } |
| 2122 | 2171 |
| 2123 bool LayoutObject::shouldUseTransformFromContainer( | 2172 bool LayoutObject::shouldUseTransformFromContainer( |
| 2124 const LayoutObject* containerObject) const { | 2173 const LayoutObject* containerObject) const { |
| 2125 // hasTransform() indicates whether the object has transform, transform-style
or perspective. We just care about transform, | 2174 // hasTransform() indicates whether the object has transform, transform-style |
| 2126 // so check the layer's transform directly. | 2175 // or perspective. We just care about transform, so check the layer's |
| 2176 // transform directly. |
| 2127 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) || | 2177 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) || |
| 2128 (containerObject && containerObject->style()->hasPerspective()); | 2178 (containerObject && containerObject->style()->hasPerspective()); |
| 2129 } | 2179 } |
| 2130 | 2180 |
| 2131 void LayoutObject::getTransformFromContainer( | 2181 void LayoutObject::getTransformFromContainer( |
| 2132 const LayoutObject* containerObject, | 2182 const LayoutObject* containerObject, |
| 2133 const LayoutSize& offsetInContainer, | 2183 const LayoutSize& offsetInContainer, |
| 2134 TransformationMatrix& transform) const { | 2184 TransformationMatrix& transform) const { |
| 2135 transform.makeIdentity(); | 2185 transform.makeIdentity(); |
| 2136 transform.translate(offsetInContainer.width().toFloat(), | 2186 transform.translate(offsetInContainer.width().toFloat(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2153 0); | 2203 0); |
| 2154 transform = perspectiveMatrix * transform; | 2204 transform = perspectiveMatrix * transform; |
| 2155 transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0); | 2205 transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0); |
| 2156 } | 2206 } |
| 2157 } | 2207 } |
| 2158 | 2208 |
| 2159 FloatQuad LayoutObject::localToAncestorQuad( | 2209 FloatQuad LayoutObject::localToAncestorQuad( |
| 2160 const FloatQuad& localQuad, | 2210 const FloatQuad& localQuad, |
| 2161 const LayoutBoxModelObject* ancestor, | 2211 const LayoutBoxModelObject* ancestor, |
| 2162 MapCoordinatesFlags mode) const { | 2212 MapCoordinatesFlags mode) const { |
| 2163 // Track the point at the center of the quad's bounding box. As mapLocalToAnce
stor() calls offsetFromContainer(), | 2213 // Track the point at the center of the quad's bounding box. As |
| 2164 // it will use that point as the reference point to decide which column's tran
sform to apply in multiple-column blocks. | 2214 // mapLocalToAncestor() calls offsetFromContainer(), it will use that point |
| 2215 // as the reference point to decide which column's transform to apply in |
| 2216 // multiple-column blocks. |
| 2165 TransformState transformState(TransformState::ApplyTransformDirection, | 2217 TransformState transformState(TransformState::ApplyTransformDirection, |
| 2166 localQuad.boundingBox().center(), localQuad); | 2218 localQuad.boundingBox().center(), localQuad); |
| 2167 mapLocalToAncestor(ancestor, transformState, | 2219 mapLocalToAncestor(ancestor, transformState, |
| 2168 mode | ApplyContainerFlip | UseTransforms); | 2220 mode | ApplyContainerFlip | UseTransforms); |
| 2169 transformState.flatten(); | 2221 transformState.flatten(); |
| 2170 | 2222 |
| 2171 return transformState.lastPlanarQuad(); | 2223 return transformState.lastPlanarQuad(); |
| 2172 } | 2224 } |
| 2173 | 2225 |
| 2174 FloatPoint LayoutObject::localToAncestorPoint( | 2226 FloatPoint LayoutObject::localToAncestorPoint( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2218 const LayoutBoxModelObject& paintInvalidationContainer = | 2270 const LayoutBoxModelObject& paintInvalidationContainer = |
| 2219 containerForPaintInvalidation(); | 2271 containerForPaintInvalidation(); |
| 2220 ASSERT(paintInvalidationContainer.layer()); | 2272 ASSERT(paintInvalidationContainer.layer()); |
| 2221 | 2273 |
| 2222 if (backingLayer) | 2274 if (backingLayer) |
| 2223 *backingLayer = paintInvalidationContainer.layer(); | 2275 *backingLayer = paintInvalidationContainer.layer(); |
| 2224 FloatPoint containerPoint = | 2276 FloatPoint containerPoint = |
| 2225 localToAncestorPoint(FloatPoint(localPoint), &paintInvalidationContainer, | 2277 localToAncestorPoint(FloatPoint(localPoint), &paintInvalidationContainer, |
| 2226 TraverseDocumentBoundaries); | 2278 TraverseDocumentBoundaries); |
| 2227 | 2279 |
| 2228 // A layoutObject can have no invalidation backing if it is from a detached fr
ame, | 2280 // A layoutObject can have no invalidation backing if it is from a detached |
| 2229 // or when forced compositing is disabled. | 2281 // frame, or when forced compositing is disabled. |
| 2230 if (paintInvalidationContainer.layer()->compositingState() == NotComposited) | 2282 if (paintInvalidationContainer.layer()->compositingState() == NotComposited) |
| 2231 return containerPoint; | 2283 return containerPoint; |
| 2232 | 2284 |
| 2233 PaintLayer::mapPointInPaintInvalidationContainerToBacking( | 2285 PaintLayer::mapPointInPaintInvalidationContainerToBacking( |
| 2234 paintInvalidationContainer, containerPoint); | 2286 paintInvalidationContainer, containerPoint); |
| 2235 return containerPoint; | 2287 return containerPoint; |
| 2236 } | 2288 } |
| 2237 | 2289 |
| 2238 LayoutSize LayoutObject::offsetFromContainer(const LayoutObject* o) const { | 2290 LayoutSize LayoutObject::offsetFromContainer(const LayoutObject* o) const { |
| 2239 ASSERT(o == container()); | 2291 ASSERT(o == container()); |
| 2240 return o->hasOverflowClip() | 2292 return o->hasOverflowClip() |
| 2241 ? LayoutSize(-toLayoutBox(o)->scrolledContentOffset()) | 2293 ? LayoutSize(-toLayoutBox(o)->scrolledContentOffset()) |
| 2242 : LayoutSize(); | 2294 : LayoutSize(); |
| 2243 } | 2295 } |
| 2244 | 2296 |
| 2245 LayoutSize LayoutObject::offsetFromAncestorContainer( | 2297 LayoutSize LayoutObject::offsetFromAncestorContainer( |
| 2246 const LayoutObject* ancestorContainer) const { | 2298 const LayoutObject* ancestorContainer) const { |
| 2247 if (ancestorContainer == this) | 2299 if (ancestorContainer == this) |
| 2248 return LayoutSize(); | 2300 return LayoutSize(); |
| 2249 | 2301 |
| 2250 LayoutSize offset; | 2302 LayoutSize offset; |
| 2251 LayoutPoint referencePoint; | 2303 LayoutPoint referencePoint; |
| 2252 const LayoutObject* currContainer = this; | 2304 const LayoutObject* currContainer = this; |
| 2253 do { | 2305 do { |
| 2254 const LayoutObject* nextContainer = currContainer->container(); | 2306 const LayoutObject* nextContainer = currContainer->container(); |
| 2255 ASSERT( | 2307 // This means we reached the top without finding container. |
| 2256 nextContainer); // This means we reached the top without finding contai
ner. | 2308 DCHECK(nextContainer); |
| 2257 if (!nextContainer) | 2309 if (!nextContainer) |
| 2258 break; | 2310 break; |
| 2259 ASSERT(!currContainer->hasTransformRelatedProperty()); | 2311 ASSERT(!currContainer->hasTransformRelatedProperty()); |
| 2260 LayoutSize currentOffset = | 2312 LayoutSize currentOffset = |
| 2261 currContainer->offsetFromContainer(nextContainer); | 2313 currContainer->offsetFromContainer(nextContainer); |
| 2262 offset += currentOffset; | 2314 offset += currentOffset; |
| 2263 referencePoint.move(currentOffset); | 2315 referencePoint.move(currentOffset); |
| 2264 currContainer = nextContainer; | 2316 currContainer = nextContainer; |
| 2265 } while (currContainer != ancestorContainer); | 2317 } while (currContainer != ancestorContainer); |
| 2266 | 2318 |
| 2267 return offset; | 2319 return offset; |
| 2268 } | 2320 } |
| 2269 | 2321 |
| 2270 LayoutRect LayoutObject::localCaretRect(InlineBox*, | 2322 LayoutRect LayoutObject::localCaretRect(InlineBox*, |
| 2271 int, | 2323 int, |
| 2272 LayoutUnit* extraWidthToEndOfLine) { | 2324 LayoutUnit* extraWidthToEndOfLine) { |
| 2273 if (extraWidthToEndOfLine) | 2325 if (extraWidthToEndOfLine) |
| 2274 *extraWidthToEndOfLine = LayoutUnit(); | 2326 *extraWidthToEndOfLine = LayoutUnit(); |
| 2275 | 2327 |
| 2276 return LayoutRect(); | 2328 return LayoutRect(); |
| 2277 } | 2329 } |
| 2278 | 2330 |
| 2279 void LayoutObject::computeLayerHitTestRects( | 2331 void LayoutObject::computeLayerHitTestRects( |
| 2280 LayerHitTestRects& layerRects) const { | 2332 LayerHitTestRects& layerRects) const { |
| 2281 // Figure out what layer our container is in. Any offset (or new layer) for th
is | 2333 // Figure out what layer our container is in. Any offset (or new layer) for |
| 2282 // layoutObject within it's container will be applied in addLayerHitTestRects. | 2334 // this layoutObject within it's container will be applied in |
| 2335 // addLayerHitTestRects. |
| 2283 LayoutPoint layerOffset; | 2336 LayoutPoint layerOffset; |
| 2284 const PaintLayer* currentLayer = nullptr; | 2337 const PaintLayer* currentLayer = nullptr; |
| 2285 | 2338 |
| 2286 if (!hasLayer()) { | 2339 if (!hasLayer()) { |
| 2287 LayoutObject* container = this->container(); | 2340 LayoutObject* container = this->container(); |
| 2288 currentLayer = container->enclosingLayer(); | 2341 currentLayer = container->enclosingLayer(); |
| 2289 if (container && currentLayer->layoutObject() != container) { | 2342 if (container && currentLayer->layoutObject() != container) { |
| 2290 layerOffset.move( | 2343 layerOffset.move( |
| 2291 container->offsetFromAncestorContainer(currentLayer->layoutObject())); | 2344 container->offsetFromAncestorContainer(currentLayer->layoutObject())); |
| 2292 // If the layer itself is scrolled, we have to undo the subtraction of its
scroll | 2345 // If the layer itself is scrolled, we have to undo the subtraction of its |
| 2293 // offset since we want the offset relative to the scrolling content, not
the | 2346 // scroll offset since we want the offset relative to the scrolling |
| 2294 // element itself. | 2347 // content, not the element itself. |
| 2295 if (currentLayer->layoutObject()->hasOverflowClip()) | 2348 if (currentLayer->layoutObject()->hasOverflowClip()) |
| 2296 layerOffset.move(currentLayer->layoutBox()->scrolledContentOffset()); | 2349 layerOffset.move(currentLayer->layoutBox()->scrolledContentOffset()); |
| 2297 } | 2350 } |
| 2298 } | 2351 } |
| 2299 | 2352 |
| 2300 this->addLayerHitTestRects(layerRects, currentLayer, layerOffset, | 2353 this->addLayerHitTestRects(layerRects, currentLayer, layerOffset, |
| 2301 LayoutRect()); | 2354 LayoutRect()); |
| 2302 } | 2355 } |
| 2303 | 2356 |
| 2304 void LayoutObject::addLayerHitTestRects(LayerHitTestRects& layerRects, | 2357 void LayoutObject::addLayerHitTestRects(LayerHitTestRects& layerRects, |
| 2305 const PaintLayer* currentLayer, | 2358 const PaintLayer* currentLayer, |
| 2306 const LayoutPoint& layerOffset, | 2359 const LayoutPoint& layerOffset, |
| 2307 const LayoutRect& containerRect) const { | 2360 const LayoutRect& containerRect) const { |
| 2308 ASSERT(currentLayer); | 2361 ASSERT(currentLayer); |
| 2309 ASSERT(currentLayer == this->enclosingLayer()); | 2362 ASSERT(currentLayer == this->enclosingLayer()); |
| 2310 | 2363 |
| 2311 // Compute the rects for this layoutObject only and add them to the results. | 2364 // Compute the rects for this layoutObject only and add them to the results. |
| 2312 // Note that we could avoid passing the offset and instead adjust each result,
but this | 2365 // Note that we could avoid passing the offset and instead adjust each result, |
| 2313 // seems slightly simpler. | 2366 // but this seems slightly simpler. |
| 2314 Vector<LayoutRect> ownRects; | 2367 Vector<LayoutRect> ownRects; |
| 2315 LayoutRect newContainerRect; | 2368 LayoutRect newContainerRect; |
| 2316 computeSelfHitTestRects(ownRects, layerOffset); | 2369 computeSelfHitTestRects(ownRects, layerOffset); |
| 2317 | 2370 |
| 2318 // When we get to have a lot of rects on a layer, the performance cost of trac
king those | 2371 // When we get to have a lot of rects on a layer, the performance cost of |
| 2319 // rects outweighs the benefit of doing compositor thread hit testing. | 2372 // tracking those rects outweighs the benefit of doing compositor thread hit |
| 2373 // testing. |
| 2320 // FIXME: This limit needs to be low due to the O(n^2) algorithm in | 2374 // FIXME: This limit needs to be low due to the O(n^2) algorithm in |
| 2321 // WebLayer::setTouchEventHandlerRegion - crbug.com/300282. | 2375 // WebLayer::setTouchEventHandlerRegion - crbug.com/300282. |
| 2322 const size_t maxRectsPerLayer = 100; | 2376 const size_t maxRectsPerLayer = 100; |
| 2323 | 2377 |
| 2324 LayerHitTestRects::iterator iter = layerRects.find(currentLayer); | 2378 LayerHitTestRects::iterator iter = layerRects.find(currentLayer); |
| 2325 Vector<LayoutRect>* iterValue; | 2379 Vector<LayoutRect>* iterValue; |
| 2326 if (iter == layerRects.end()) | 2380 if (iter == layerRects.end()) |
| 2327 iterValue = | 2381 iterValue = |
| 2328 &layerRects.add(currentLayer, Vector<LayoutRect>()).storedValue->value; | 2382 &layerRects.add(currentLayer, Vector<LayoutRect>()).storedValue->value; |
| 2329 else | 2383 else |
| 2330 iterValue = &iter->value; | 2384 iterValue = &iter->value; |
| 2331 for (size_t i = 0; i < ownRects.size(); i++) { | 2385 for (size_t i = 0; i < ownRects.size(); i++) { |
| 2332 if (!containerRect.contains(ownRects[i])) { | 2386 if (!containerRect.contains(ownRects[i])) { |
| 2333 iterValue->append(ownRects[i]); | 2387 iterValue->append(ownRects[i]); |
| 2334 if (iterValue->size() > maxRectsPerLayer) { | 2388 if (iterValue->size() > maxRectsPerLayer) { |
| 2335 // Just mark the entire layer instead, and switch to walking the layer | 2389 // Just mark the entire layer instead, and switch to walking the layer |
| 2336 // tree instead of the layout tree. | 2390 // tree instead of the layout tree. |
| 2337 layerRects.remove(currentLayer); | 2391 layerRects.remove(currentLayer); |
| 2338 currentLayer->addLayerHitTestRects(layerRects); | 2392 currentLayer->addLayerHitTestRects(layerRects); |
| 2339 return; | 2393 return; |
| 2340 } | 2394 } |
| 2341 if (newContainerRect.isEmpty()) | 2395 if (newContainerRect.isEmpty()) |
| 2342 newContainerRect = ownRects[i]; | 2396 newContainerRect = ownRects[i]; |
| 2343 } | 2397 } |
| 2344 } | 2398 } |
| 2345 if (newContainerRect.isEmpty()) | 2399 if (newContainerRect.isEmpty()) |
| 2346 newContainerRect = containerRect; | 2400 newContainerRect = containerRect; |
| 2347 | 2401 |
| 2348 // If it's possible for children to have rects outside our bounds, then we nee
d to descend into | 2402 // If it's possible for children to have rects outside our bounds, then we |
| 2349 // the children and compute them. | 2403 // need to descend into the children and compute them. |
| 2350 // Ideally there would be other cases where we could detect that children coul
dn't have rects | 2404 // Ideally there would be other cases where we could detect that children |
| 2351 // outside our bounds and prune the tree walk. | 2405 // couldn't have rects outside our bounds and prune the tree walk. |
| 2352 // Note that we don't use Region here because Union is O(N) - better to just k
eep a list of | 2406 // Note that we don't use Region here because Union is O(N) - better to just |
| 2353 // partially redundant rectangles. If we find examples where this is expensive
, then we could | 2407 // keep a list of partially redundant rectangles. If we find examples where |
| 2354 // rewrite Region to be more efficient. See https://bugs.webkit.org/show_bug.c
gi?id=100814. | 2408 // this is expensive, then we could rewrite Region to be more efficient. See |
| 2409 // https://bugs.webkit.org/show_bug.cgi?id=100814. |
| 2355 if (!isLayoutView()) { | 2410 if (!isLayoutView()) { |
| 2356 for (LayoutObject* curr = slowFirstChild(); curr; | 2411 for (LayoutObject* curr = slowFirstChild(); curr; |
| 2357 curr = curr->nextSibling()) { | 2412 curr = curr->nextSibling()) { |
| 2358 curr->addLayerHitTestRects(layerRects, currentLayer, layerOffset, | 2413 curr->addLayerHitTestRects(layerRects, currentLayer, layerOffset, |
| 2359 newContainerRect); | 2414 newContainerRect); |
| 2360 } | 2415 } |
| 2361 } | 2416 } |
| 2362 } | 2417 } |
| 2363 | 2418 |
| 2364 bool LayoutObject::isRooted() const { | 2419 bool LayoutObject::isRooted() const { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2413 if (pos == FixedPosition) | 2468 if (pos == FixedPosition) |
| 2414 return containerForFixedPosition(ancestor, ancestorSkipped, filterSkipped); | 2469 return containerForFixedPosition(ancestor, ancestorSkipped, filterSkipped); |
| 2415 | 2470 |
| 2416 if (pos == AbsolutePosition) | 2471 if (pos == AbsolutePosition) |
| 2417 return containerForAbsolutePosition(ancestor, ancestorSkipped, | 2472 return containerForAbsolutePosition(ancestor, ancestorSkipped, |
| 2418 filterSkipped); | 2473 filterSkipped); |
| 2419 | 2474 |
| 2420 if (isColumnSpanAll()) { | 2475 if (isColumnSpanAll()) { |
| 2421 LayoutObject* multicolContainer = spannerPlaceholder()->container(); | 2476 LayoutObject* multicolContainer = spannerPlaceholder()->container(); |
| 2422 if ((ancestorSkipped && ancestor) || filterSkipped) { | 2477 if ((ancestorSkipped && ancestor) || filterSkipped) { |
| 2423 // We jumped directly from the spanner to the multicol container. Need to
check if | 2478 // We jumped directly from the spanner to the multicol container. Need to |
| 2424 // we skipped |ancestor| or filter/reflection on the way. | 2479 // check if we skipped |ancestor| or filter/reflection on the way. |
| 2425 for (LayoutObject* walker = parent(); | 2480 for (LayoutObject* walker = parent(); |
| 2426 walker && walker != multicolContainer; walker = walker->parent()) { | 2481 walker && walker != multicolContainer; walker = walker->parent()) { |
| 2427 if (ancestorSkipped && walker == ancestor) | 2482 if (ancestorSkipped && walker == ancestor) |
| 2428 *ancestorSkipped = true; | 2483 *ancestorSkipped = true; |
| 2429 if (filterSkipped && walker->hasFilterInducingProperty()) | 2484 if (filterSkipped && walker->hasFilterInducingProperty()) |
| 2430 *filterSkipped = true; | 2485 *filterSkipped = true; |
| 2431 } | 2486 } |
| 2432 } | 2487 } |
| 2433 return multicolContainer; | 2488 return multicolContainer; |
| 2434 } | 2489 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2461 LayoutObjectChildList* children = virtualChildren(); | 2516 LayoutObjectChildList* children = virtualChildren(); |
| 2462 if (children) | 2517 if (children) |
| 2463 children->destroyLeftoverChildren(); | 2518 children->destroyLeftoverChildren(); |
| 2464 | 2519 |
| 2465 if (LocalFrame* frame = this->frame()) { | 2520 if (LocalFrame* frame = this->frame()) { |
| 2466 // If this layoutObject is being autoscrolled, stop the autoscrolling. | 2521 // If this layoutObject is being autoscrolled, stop the autoscrolling. |
| 2467 if (frame->page()) | 2522 if (frame->page()) |
| 2468 frame->page()->autoscrollController().stopAutoscrollIfNeeded(this); | 2523 frame->page()->autoscrollController().stopAutoscrollIfNeeded(this); |
| 2469 } | 2524 } |
| 2470 | 2525 |
| 2471 // For accessibility management, notify the parent of the imminent change to i
ts child set. | 2526 // For accessibility management, notify the parent of the imminent change to |
| 2527 // its child set. |
| 2472 // We do it now, before remove(), while the parent pointer is still available. | 2528 // We do it now, before remove(), while the parent pointer is still available. |
| 2473 if (AXObjectCache* cache = document().existingAXObjectCache()) | 2529 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 2474 cache->childrenChanged(this->parent()); | 2530 cache->childrenChanged(this->parent()); |
| 2475 | 2531 |
| 2476 remove(); | 2532 remove(); |
| 2477 | 2533 |
| 2478 // The remove() call above may invoke axObjectCache()->childrenChanged() on th
e parent, which may require the AX layout | 2534 // The remove() call above may invoke axObjectCache()->childrenChanged() on |
| 2479 // object for this layoutObject. So we remove the AX layout object now, after
the layoutObject is removed. | 2535 // the parent, which may require the AX layout object for this layoutObject. |
| 2536 // So we remove the AX layout object now, after the layoutObject is removed. |
| 2480 if (AXObjectCache* cache = document().existingAXObjectCache()) | 2537 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 2481 cache->remove(this); | 2538 cache->remove(this); |
| 2482 | 2539 |
| 2483 // If this layoutObject had a parent, remove should have destroyed any counter
s | 2540 // If this layoutObject had a parent, remove should have destroyed any |
| 2484 // attached to this layoutObject and marked the affected other counters for | 2541 // counters attached to this layoutObject and marked the affected other |
| 2485 // reevaluation. This apparently redundant check is here for the case when | 2542 // counters for reevaluation. This apparently redundant check is here for the |
| 2486 // this layoutObject had no parent at the time remove() was called. | 2543 // case when this layoutObject had no parent at the time remove() was called. |
| 2487 | 2544 |
| 2488 if (hasCounterNodeMap()) | 2545 if (hasCounterNodeMap()) |
| 2489 LayoutCounter::destroyCounterNodes(*this); | 2546 LayoutCounter::destroyCounterNodes(*this); |
| 2490 | 2547 |
| 2491 // Remove the handler if node had touch-action set. Handlers are not added | 2548 // Remove the handler if node had touch-action set. Handlers are not added |
| 2492 // for text nodes so don't try removing for one too. Need to check if | 2549 // for text nodes so don't try removing for one too. Need to check if |
| 2493 // m_style is null in cases of partial construction. Any handler we added | 2550 // m_style is null in cases of partial construction. Any handler we added |
| 2494 // previously may have already been removed by the Document independently. | 2551 // previously may have already been removed by the Document independently. |
| 2495 if (node() && !node()->isTextNode() && m_style && | 2552 if (node() && !node()->isTextNode() && m_style && |
| 2496 m_style->getTouchAction() != TouchActionAuto) { | 2553 m_style->getTouchAction() != TouchActionAuto) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2541 removeShapeImageClient(m_style->shapeOutside()); | 2598 removeShapeImageClient(m_style->shapeOutside()); |
| 2542 removeCursorImageClient(m_style->cursors()); | 2599 removeCursorImageClient(m_style->cursors()); |
| 2543 } | 2600 } |
| 2544 | 2601 |
| 2545 if (frameView()) | 2602 if (frameView()) |
| 2546 setIsBackgroundAttachmentFixedObject(false); | 2603 setIsBackgroundAttachmentFixedObject(false); |
| 2547 } | 2604 } |
| 2548 | 2605 |
| 2549 DISABLE_CFI_PERF | 2606 DISABLE_CFI_PERF |
| 2550 void LayoutObject::insertedIntoTree() { | 2607 void LayoutObject::insertedIntoTree() { |
| 2551 // FIXME: We should ASSERT(isRooted()) here but generated content makes some o
ut-of-order insertion. | 2608 // FIXME: We should ASSERT(isRooted()) here but generated content makes some |
| 2609 // out-of-order insertion. |
| 2552 | 2610 |
| 2553 // Keep our layer hierarchy updated. Optimize for the common case where we don
't have any children | 2611 // Keep our layer hierarchy updated. Optimize for the common case where we |
| 2554 // and don't have a layer attached to ourselves. | 2612 // don't have any children and don't have a layer attached to ourselves. |
| 2555 PaintLayer* layer = nullptr; | 2613 PaintLayer* layer = nullptr; |
| 2556 if (slowFirstChild() || hasLayer()) { | 2614 if (slowFirstChild() || hasLayer()) { |
| 2557 layer = parent()->enclosingLayer(); | 2615 layer = parent()->enclosingLayer(); |
| 2558 addLayers(layer); | 2616 addLayers(layer); |
| 2559 } | 2617 } |
| 2560 | 2618 |
| 2561 // If |this| is visible but this object was not, tell the layer it has some vi
sible content | 2619 // If |this| is visible but this object was not, tell the layer it has some |
| 2562 // that needs to be drawn and layer visibility optimization can't be used | 2620 // visible content that needs to be drawn and layer visibility optimization |
| 2621 // can't be used |
| 2563 if (parent()->style()->visibility() != EVisibility::Visible && | 2622 if (parent()->style()->visibility() != EVisibility::Visible && |
| 2564 style()->visibility() == EVisibility::Visible && !hasLayer()) { | 2623 style()->visibility() == EVisibility::Visible && !hasLayer()) { |
| 2565 if (!layer) | 2624 if (!layer) |
| 2566 layer = parent()->enclosingLayer(); | 2625 layer = parent()->enclosingLayer(); |
| 2567 if (layer) | 2626 if (layer) |
| 2568 layer->dirtyVisibleContentStatus(); | 2627 layer->dirtyVisibleContentStatus(); |
| 2569 } | 2628 } |
| 2570 | 2629 |
| 2571 if (parent()->childrenInline()) | 2630 if (parent()->childrenInline()) |
| 2572 parent()->dirtyLinesFromChangedChild(this); | 2631 parent()->dirtyLinesFromChangedChild(this); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 if (anchor->refersTo(layoutObject)) { | 2665 if (anchor->refersTo(layoutObject)) { |
| 2607 found = true; | 2666 found = true; |
| 2608 if (behavior == Clear) | 2667 if (behavior == Clear) |
| 2609 anchor->notifyRemoved(layoutObject); | 2668 anchor->notifyRemoved(layoutObject); |
| 2610 } | 2669 } |
| 2611 } | 2670 } |
| 2612 return found; | 2671 return found; |
| 2613 } | 2672 } |
| 2614 | 2673 |
| 2615 void LayoutObject::willBeRemovedFromTree() { | 2674 void LayoutObject::willBeRemovedFromTree() { |
| 2616 // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals
which would need to be fixed first. | 2675 // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals |
| 2676 // which would need to be fixed first. |
| 2617 | 2677 |
| 2618 // If we remove a visible child from an invisible parent, we don't know the la
yer visibility any more. | 2678 // If we remove a visible child from an invisible parent, we don't know the |
| 2679 // layer visibility any more. |
| 2619 PaintLayer* layer = nullptr; | 2680 PaintLayer* layer = nullptr; |
| 2620 if (parent()->style()->visibility() != EVisibility::Visible && | 2681 if (parent()->style()->visibility() != EVisibility::Visible && |
| 2621 style()->visibility() == EVisibility::Visible && !hasLayer()) { | 2682 style()->visibility() == EVisibility::Visible && !hasLayer()) { |
| 2622 layer = parent()->enclosingLayer(); | 2683 layer = parent()->enclosingLayer(); |
| 2623 if (layer) | 2684 if (layer) |
| 2624 layer->dirtyVisibleContentStatus(); | 2685 layer->dirtyVisibleContentStatus(); |
| 2625 } | 2686 } |
| 2626 | 2687 |
| 2627 // Keep our layer hierarchy updated. | 2688 // Keep our layer hierarchy updated. |
| 2628 if (slowFirstChild() || hasLayer()) { | 2689 if (slowFirstChild() || hasLayer()) { |
| 2629 if (!layer) | 2690 if (!layer) |
| 2630 layer = parent()->enclosingLayer(); | 2691 layer = parent()->enclosingLayer(); |
| 2631 removeLayers(layer); | 2692 removeLayers(layer); |
| 2632 } | 2693 } |
| 2633 | 2694 |
| 2634 if (isOutOfFlowPositioned() && parent()->childrenInline()) | 2695 if (isOutOfFlowPositioned() && parent()->childrenInline()) |
| 2635 parent()->dirtyLinesFromChangedChild(this); | 2696 parent()->dirtyLinesFromChangedChild(this); |
| 2636 | 2697 |
| 2637 removeFromLayoutFlowThread(); | 2698 removeFromLayoutFlowThread(); |
| 2638 | 2699 |
| 2639 // Update cached boundaries in SVG layoutObjects if a child is removed. | 2700 // Update cached boundaries in SVG layoutObjects if a child is removed. |
| 2640 if (parent()->isSVG()) | 2701 if (parent()->isSVG()) |
| 2641 parent()->setNeedsBoundariesUpdate(); | 2702 parent()->setNeedsBoundariesUpdate(); |
| 2642 | 2703 |
| 2643 if (RuntimeEnabledFeatures::scrollAnchoringEnabled() && | 2704 if (RuntimeEnabledFeatures::scrollAnchoringEnabled() && |
| 2644 m_bitfields.isScrollAnchorObject()) { | 2705 m_bitfields.isScrollAnchorObject()) { |
| 2645 // Clear the bit first so that anchor.clear() doesn't recurse into findRefer
encingScrollAnchors. | 2706 // Clear the bit first so that anchor.clear() doesn't recurse into |
| 2707 // findReferencingScrollAnchors. |
| 2646 m_bitfields.setIsScrollAnchorObject(false); | 2708 m_bitfields.setIsScrollAnchorObject(false); |
| 2647 findReferencingScrollAnchors(this, Clear); | 2709 findReferencingScrollAnchors(this, Clear); |
| 2648 } | 2710 } |
| 2649 } | 2711 } |
| 2650 | 2712 |
| 2651 void LayoutObject::maybeClearIsScrollAnchorObject() { | 2713 void LayoutObject::maybeClearIsScrollAnchorObject() { |
| 2652 if (m_bitfields.isScrollAnchorObject()) | 2714 if (m_bitfields.isScrollAnchorObject()) |
| 2653 m_bitfields.setIsScrollAnchorObject( | 2715 m_bitfields.setIsScrollAnchorObject( |
| 2654 findReferencingScrollAnchors(this, DontClear)); | 2716 findReferencingScrollAnchors(this, DontClear)); |
| 2655 } | 2717 } |
| 2656 | 2718 |
| 2657 void LayoutObject::removeFromLayoutFlowThread() { | 2719 void LayoutObject::removeFromLayoutFlowThread() { |
| 2658 if (!isInsideFlowThread()) | 2720 if (!isInsideFlowThread()) |
| 2659 return; | 2721 return; |
| 2660 | 2722 |
| 2661 // Sometimes we remove the element from the flow, but it's not destroyed at th
at time. | 2723 // Sometimes we remove the element from the flow, but it's not destroyed at |
| 2662 // It's only until later when we actually destroy it and remove all the childr
en from it. | 2724 // that time. |
| 2725 // It's only until later when we actually destroy it and remove all the |
| 2726 // children from it. |
| 2663 // Currently, that happens for firstLetter elements and list markers. | 2727 // Currently, that happens for firstLetter elements and list markers. |
| 2664 // Pass in the flow thread so that we don't have to look it up for all the chi
ldren. | 2728 // Pass in the flow thread so that we don't have to look it up for all the |
| 2665 // If we're a column spanner, we need to use our parent to find the flow threa
d, since a spanner | 2729 // children. |
| 2666 // doesn't have the flow thread in its containing block chain. We still need t
o notify the flow | 2730 // If we're a column spanner, we need to use our parent to find the flow |
| 2667 // thread when the layoutObject removed happens to be a spanner, so that we ge
t rid of the spanner | 2731 // thread, since a spanner doesn't have the flow thread in its containing |
| 2732 // block chain. We still need to notify the flow thread when the layoutObject |
| 2733 // removed happens to be a spanner, so that we get rid of the spanner |
| 2668 // placeholder, and column sets around the placeholder get merged. | 2734 // placeholder, and column sets around the placeholder get merged. |
| 2669 LayoutFlowThread* flowThread = isColumnSpanAll() | 2735 LayoutFlowThread* flowThread = isColumnSpanAll() |
| 2670 ? parent()->flowThreadContainingBlock() | 2736 ? parent()->flowThreadContainingBlock() |
| 2671 : flowThreadContainingBlock(); | 2737 : flowThreadContainingBlock(); |
| 2672 removeFromLayoutFlowThreadRecursive(flowThread); | 2738 removeFromLayoutFlowThreadRecursive(flowThread); |
| 2673 } | 2739 } |
| 2674 | 2740 |
| 2675 void LayoutObject::removeFromLayoutFlowThreadRecursive( | 2741 void LayoutObject::removeFromLayoutFlowThreadRecursive( |
| 2676 LayoutFlowThread* layoutFlowThread) { | 2742 LayoutFlowThread* layoutFlowThread) { |
| 2677 if (const LayoutObjectChildList* children = virtualChildren()) { | 2743 if (const LayoutObjectChildList* children = virtualChildren()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2697 destroy(); | 2763 destroy(); |
| 2698 return; | 2764 return; |
| 2699 } | 2765 } |
| 2700 | 2766 |
| 2701 LayoutObject* destroyRoot = this; | 2767 LayoutObject* destroyRoot = this; |
| 2702 for (LayoutObject *destroyRootParent = destroyRoot->parent(); | 2768 for (LayoutObject *destroyRootParent = destroyRoot->parent(); |
| 2703 destroyRootParent && destroyRootParent->isAnonymous() && | 2769 destroyRootParent && destroyRootParent->isAnonymous() && |
| 2704 !destroyRootParent->parent()->createsAnonymousWrapper(); | 2770 !destroyRootParent->parent()->createsAnonymousWrapper(); |
| 2705 destroyRoot = destroyRootParent, | 2771 destroyRoot = destroyRootParent, |
| 2706 destroyRootParent = destroyRootParent->parent()) { | 2772 destroyRootParent = destroyRootParent->parent()) { |
| 2707 // Anonymous block continuations are tracked and destroyed elsewhere (see th
e bottom of LayoutBlock::removeChild) | 2773 // Anonymous block continuations are tracked and destroyed elsewhere (see |
| 2774 // the bottom of LayoutBlock::removeChild) |
| 2708 if (destroyRootParent->isLayoutBlockFlow() && | 2775 if (destroyRootParent->isLayoutBlockFlow() && |
| 2709 toLayoutBlockFlow(destroyRootParent)->isAnonymousBlockContinuation()) | 2776 toLayoutBlockFlow(destroyRootParent)->isAnonymousBlockContinuation()) |
| 2710 break; | 2777 break; |
| 2711 // A flow thread is tracked by its containing block. Whether its children ar
e removed or not is irrelevant. | 2778 // A flow thread is tracked by its containing block. Whether its children |
| 2779 // are removed or not is irrelevant. |
| 2712 if (destroyRootParent->isLayoutFlowThread()) | 2780 if (destroyRootParent->isLayoutFlowThread()) |
| 2713 break; | 2781 break; |
| 2714 | 2782 |
| 2715 if (destroyRootParent->slowFirstChild() != destroyRoot || | 2783 if (destroyRootParent->slowFirstChild() != destroyRoot || |
| 2716 destroyRootParent->slowLastChild() != destroyRoot) | 2784 destroyRootParent->slowLastChild() != destroyRoot) |
| 2717 break; // Need to keep the anonymous parent, since it won't become empty
by the removal of this layoutObject. | 2785 break; // Need to keep the anonymous parent, since it won't become empty |
| 2786 // by the removal of this layoutObject. |
| 2718 } | 2787 } |
| 2719 | 2788 |
| 2720 destroyRoot->destroy(); | 2789 destroyRoot->destroy(); |
| 2721 | 2790 |
| 2722 // WARNING: |this| is deleted here. | 2791 // WARNING: |this| is deleted here. |
| 2723 } | 2792 } |
| 2724 | 2793 |
| 2725 void LayoutObject::destroy() { | 2794 void LayoutObject::destroy() { |
| 2726 willBeDestroyed(); | 2795 willBeDestroyed(); |
| 2727 delete this; | 2796 delete this; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 if (hitTestFilter != HitTestSelf) { | 2834 if (hitTestFilter != HitTestSelf) { |
| 2766 // First test the foreground layer (lines and inlines). | 2835 // First test the foreground layer (lines and inlines). |
| 2767 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, | 2836 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, |
| 2768 HitTestForeground); | 2837 HitTestForeground); |
| 2769 | 2838 |
| 2770 // Test floats next. | 2839 // Test floats next. |
| 2771 if (!inside) | 2840 if (!inside) |
| 2772 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, | 2841 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, |
| 2773 HitTestFloat); | 2842 HitTestFloat); |
| 2774 | 2843 |
| 2775 // Finally test to see if the mouse is in the background (within a child blo
ck's background). | 2844 // Finally test to see if the mouse is in the background (within a child |
| 2845 // block's background). |
| 2776 if (!inside) | 2846 if (!inside) |
| 2777 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, | 2847 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, |
| 2778 HitTestChildBlockBackgrounds); | 2848 HitTestChildBlockBackgrounds); |
| 2779 } | 2849 } |
| 2780 | 2850 |
| 2781 // See if the mouse is inside us but not any of our descendants | 2851 // See if the mouse is inside us but not any of our descendants |
| 2782 if (hitTestFilter != HitTestDescendants && !inside) | 2852 if (hitTestFilter != HitTestDescendants && !inside) |
| 2783 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, | 2853 inside = nodeAtPoint(result, locationInContainer, accumulatedOffset, |
| 2784 HitTestBlockBackground); | 2854 HitTestBlockBackground); |
| 2785 | 2855 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2826 } | 2896 } |
| 2827 } | 2897 } |
| 2828 } | 2898 } |
| 2829 | 2899 |
| 2830 void LayoutObject::forceLayout() { | 2900 void LayoutObject::forceLayout() { |
| 2831 setSelfNeedsLayout(true); | 2901 setSelfNeedsLayout(true); |
| 2832 setShouldDoFullPaintInvalidation(); | 2902 setShouldDoFullPaintInvalidation(); |
| 2833 layout(); | 2903 layout(); |
| 2834 } | 2904 } |
| 2835 | 2905 |
| 2836 // FIXME: Does this do anything different than forceLayout given that we don't w
alk | 2906 // FIXME: Does this do anything different than forceLayout given that we don't |
| 2837 // the containing block chain. If not, we should change all callers to use force
Layout. | 2907 // walk the containing block chain. If not, we should change all callers to use |
| 2908 // forceLayout. |
| 2838 void LayoutObject::forceChildLayout() { | 2909 void LayoutObject::forceChildLayout() { |
| 2839 setNormalChildNeedsLayout(true); | 2910 setNormalChildNeedsLayout(true); |
| 2840 layout(); | 2911 layout(); |
| 2841 } | 2912 } |
| 2842 | 2913 |
| 2843 enum StyleCacheState { Cached, Uncached }; | 2914 enum StyleCacheState { Cached, Uncached }; |
| 2844 | 2915 |
| 2845 static PassRefPtr<ComputedStyle> firstLineStyleForCachedUncachedType( | 2916 static PassRefPtr<ComputedStyle> firstLineStyleForCachedUncachedType( |
| 2846 StyleCacheState type, | 2917 StyleCacheState type, |
| 2847 const LayoutObject* layoutObject, | 2918 const LayoutObject* layoutObject, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2861 firstLineBlock == layoutObject ? style : 0); | 2932 firstLineBlock == layoutObject ? style : 0); |
| 2862 } | 2933 } |
| 2863 } else if (!layoutObjectForFirstLineStyle->isAnonymous() && | 2934 } else if (!layoutObjectForFirstLineStyle->isAnonymous() && |
| 2864 layoutObjectForFirstLineStyle->isLayoutInline() && | 2935 layoutObjectForFirstLineStyle->isLayoutInline() && |
| 2865 !layoutObjectForFirstLineStyle->node() | 2936 !layoutObjectForFirstLineStyle->node() |
| 2866 ->isFirstLetterPseudoElement()) { | 2937 ->isFirstLetterPseudoElement()) { |
| 2867 const ComputedStyle* parentStyle = | 2938 const ComputedStyle* parentStyle = |
| 2868 layoutObjectForFirstLineStyle->parent()->firstLineStyle(); | 2939 layoutObjectForFirstLineStyle->parent()->firstLineStyle(); |
| 2869 if (parentStyle != layoutObjectForFirstLineStyle->parent()->style()) { | 2940 if (parentStyle != layoutObjectForFirstLineStyle->parent()->style()) { |
| 2870 if (type == Cached) { | 2941 if (type == Cached) { |
| 2871 // A first-line style is in effect. Cache a first-line style for ourselv
es. | 2942 // A first-line style is in effect. Cache a first-line style for |
| 2943 // ourselves. |
| 2872 layoutObjectForFirstLineStyle->mutableStyleRef().setHasPseudoStyle( | 2944 layoutObjectForFirstLineStyle->mutableStyleRef().setHasPseudoStyle( |
| 2873 PseudoIdFirstLineInherited); | 2945 PseudoIdFirstLineInherited); |
| 2874 return layoutObjectForFirstLineStyle->getCachedPseudoStyle( | 2946 return layoutObjectForFirstLineStyle->getCachedPseudoStyle( |
| 2875 PseudoIdFirstLineInherited, parentStyle); | 2947 PseudoIdFirstLineInherited, parentStyle); |
| 2876 } | 2948 } |
| 2877 return layoutObjectForFirstLineStyle->getUncachedPseudoStyle( | 2949 return layoutObjectForFirstLineStyle->getUncachedPseudoStyle( |
| 2878 PseudoStyleRequest(PseudoIdFirstLineInherited), parentStyle, style); | 2950 PseudoStyleRequest(PseudoIdFirstLineInherited), parentStyle, style); |
| 2879 } | 2951 } |
| 2880 } | 2952 } |
| 2881 return nullptr; | 2953 return nullptr; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2978 unsigned currDecs = TextDecorationNone; | 3050 unsigned currDecs = TextDecorationNone; |
| 2979 Color resultColor; | 3051 Color resultColor; |
| 2980 TextDecorationStyle resultStyle; | 3052 TextDecorationStyle resultStyle; |
| 2981 do { | 3053 do { |
| 2982 styleToUse = curr->style(firstlineStyle); | 3054 styleToUse = curr->style(firstlineStyle); |
| 2983 currDecs = styleToUse->getTextDecoration(); | 3055 currDecs = styleToUse->getTextDecoration(); |
| 2984 currDecs &= decorations; | 3056 currDecs &= decorations; |
| 2985 resultColor = | 3057 resultColor = |
| 2986 styleToUse->visitedDependentColor(CSSPropertyTextDecorationColor); | 3058 styleToUse->visitedDependentColor(CSSPropertyTextDecorationColor); |
| 2987 resultStyle = styleToUse->getTextDecorationStyle(); | 3059 resultStyle = styleToUse->getTextDecorationStyle(); |
| 2988 // Parameter 'decorations' is cast as an int to enable the bitwise operation
s below. | 3060 // Parameter 'decorations' is cast as an int to enable the bitwise |
| 3061 // operations below. |
| 2989 if (currDecs) { | 3062 if (currDecs) { |
| 2990 if (currDecs & TextDecorationUnderline) { | 3063 if (currDecs & TextDecorationUnderline) { |
| 2991 decorations &= ~TextDecorationUnderline; | 3064 decorations &= ~TextDecorationUnderline; |
| 2992 underline.color = resultColor; | 3065 underline.color = resultColor; |
| 2993 underline.style = resultStyle; | 3066 underline.style = resultStyle; |
| 2994 } | 3067 } |
| 2995 if (currDecs & TextDecorationOverline) { | 3068 if (currDecs & TextDecorationOverline) { |
| 2996 decorations &= ~TextDecorationOverline; | 3069 decorations &= ~TextDecorationOverline; |
| 2997 overline.color = resultColor; | 3070 overline.color = resultColor; |
| 2998 overline.style = resultStyle; | 3071 overline.style = resultStyle; |
| 2999 } | 3072 } |
| 3000 if (currDecs & TextDecorationLineThrough) { | 3073 if (currDecs & TextDecorationLineThrough) { |
| 3001 decorations &= ~TextDecorationLineThrough; | 3074 decorations &= ~TextDecorationLineThrough; |
| 3002 linethrough.color = resultColor; | 3075 linethrough.color = resultColor; |
| 3003 linethrough.style = resultStyle; | 3076 linethrough.style = resultStyle; |
| 3004 } | 3077 } |
| 3005 } | 3078 } |
| 3006 if (curr->isRubyText()) | 3079 if (curr->isRubyText()) |
| 3007 return; | 3080 return; |
| 3008 curr = curr->parent(); | 3081 curr = curr->parent(); |
| 3009 if (curr && curr->isAnonymousBlock() && curr->isLayoutBlockFlow() && | 3082 if (curr && curr->isAnonymousBlock() && curr->isLayoutBlockFlow() && |
| 3010 toLayoutBlockFlow(curr)->continuation()) | 3083 toLayoutBlockFlow(curr)->continuation()) |
| 3011 curr = toLayoutBlockFlow(curr)->continuation(); | 3084 curr = toLayoutBlockFlow(curr)->continuation(); |
| 3012 } while (curr && decorations && (!quirksMode || !curr->node() || | 3085 } while (curr && decorations && (!quirksMode || !curr->node() || |
| 3013 (!isHTMLAnchorElement(*curr->node()) && | 3086 (!isHTMLAnchorElement(*curr->node()) && |
| 3014 !isHTMLFontElement(*curr->node())))); | 3087 !isHTMLFontElement(*curr->node())))); |
| 3015 | 3088 |
| 3016 // If we bailed out, use the element we bailed out at (typically a <font> or <
a> element). | 3089 // If we bailed out, use the element we bailed out at (typically a <font> or |
| 3090 // <a> element). |
| 3017 if (decorations && curr) { | 3091 if (decorations && curr) { |
| 3018 styleToUse = curr->style(firstlineStyle); | 3092 styleToUse = curr->style(firstlineStyle); |
| 3019 resultColor = | 3093 resultColor = |
| 3020 styleToUse->visitedDependentColor(CSSPropertyTextDecorationColor); | 3094 styleToUse->visitedDependentColor(CSSPropertyTextDecorationColor); |
| 3021 if (decorations & TextDecorationUnderline) { | 3095 if (decorations & TextDecorationUnderline) { |
| 3022 underline.color = resultColor; | 3096 underline.color = resultColor; |
| 3023 underline.style = resultStyle; | 3097 underline.style = resultStyle; |
| 3024 } | 3098 } |
| 3025 if (decorations & TextDecorationOverline) { | 3099 if (decorations & TextDecorationOverline) { |
| 3026 overline.color = resultColor; | 3100 overline.color = resultColor; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3045 FloatRect localBounds(FloatPoint(), FloatSize(box->size())); | 3119 FloatRect localBounds(FloatPoint(), FloatSize(box->size())); |
| 3046 FloatRect absBounds = localToAbsoluteQuad(localBounds).boundingBox(); | 3120 FloatRect absBounds = localToAbsoluteQuad(localBounds).boundingBox(); |
| 3047 | 3121 |
| 3048 AnnotatedRegionValue region; | 3122 AnnotatedRegionValue region; |
| 3049 region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag; | 3123 region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag; |
| 3050 region.bounds = LayoutRect(absBounds); | 3124 region.bounds = LayoutRect(absBounds); |
| 3051 regions.append(region); | 3125 regions.append(region); |
| 3052 } | 3126 } |
| 3053 | 3127 |
| 3054 bool LayoutObject::willRenderImage() { | 3128 bool LayoutObject::willRenderImage() { |
| 3055 // Without visibility we won't render (and therefore don't care about animatio
n). | 3129 // Without visibility we won't render (and therefore don't care about |
| 3130 // animation). |
| 3056 if (style()->visibility() != EVisibility::Visible) | 3131 if (style()->visibility() != EVisibility::Visible) |
| 3057 return false; | 3132 return false; |
| 3058 | 3133 |
| 3059 // We will not render a new image when Active DOM is suspended | 3134 // We will not render a new image when Active DOM is suspended |
| 3060 if (document().activeDOMObjectsAreSuspended()) | 3135 if (document().activeDOMObjectsAreSuspended()) |
| 3061 return false; | 3136 return false; |
| 3062 | 3137 |
| 3063 // If we're not in a window (i.e., we're dormant from being in a background ta
b) | 3138 // If we're not in a window (i.e., we're dormant from being in a background |
| 3064 // then we don't want to render either. | 3139 // tab) then we don't want to render either. |
| 3065 return document().view()->isVisible(); | 3140 return document().view()->isVisible(); |
| 3066 } | 3141 } |
| 3067 | 3142 |
| 3068 bool LayoutObject::getImageAnimationPolicy(ImageAnimationPolicy& policy) { | 3143 bool LayoutObject::getImageAnimationPolicy(ImageAnimationPolicy& policy) { |
| 3069 if (!document().settings()) | 3144 if (!document().settings()) |
| 3070 return false; | 3145 return false; |
| 3071 policy = document().settings()->imageAnimationPolicy(); | 3146 policy = document().settings()->imageAnimationPolicy(); |
| 3072 return true; | 3147 return true; |
| 3073 } | 3148 } |
| 3074 | 3149 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3114 Node* node = nullptr; | 3189 Node* node = nullptr; |
| 3115 for (LayoutObject* ancestor = parent(); ancestor; | 3190 for (LayoutObject* ancestor = parent(); ancestor; |
| 3116 ancestor = ancestor->parent()) { | 3191 ancestor = ancestor->parent()) { |
| 3117 // Spec: http://www.w3.org/TR/cssom-view/#offset-attributes | 3192 // Spec: http://www.w3.org/TR/cssom-view/#offset-attributes |
| 3118 | 3193 |
| 3119 node = ancestor->node(); | 3194 node = ancestor->node(); |
| 3120 | 3195 |
| 3121 if (!node) | 3196 if (!node) |
| 3122 continue; | 3197 continue; |
| 3123 | 3198 |
| 3124 // TODO(kochi): If |base| or |node| is nested deep in shadow roots, this loo
p may | 3199 // TODO(kochi): If |base| or |node| is nested deep in shadow roots, this |
| 3125 // get expensive, as isUnclosedNodeOf() can take up to O(N+M) time (N and M
are depths). | 3200 // loop may get expensive, as isUnclosedNodeOf() can take up to O(N+M) time |
| 3201 // (N and M are depths). |
| 3126 if (base && | 3202 if (base && |
| 3127 (node->isClosedShadowHiddenFrom(*base) || | 3203 (node->isClosedShadowHiddenFrom(*base) || |
| 3128 (node->isInShadowTree() && | 3204 (node->isInShadowTree() && |
| 3129 node->containingShadowRoot()->type() == ShadowRootType::UserAgent))) { | 3205 node->containingShadowRoot()->type() == ShadowRootType::UserAgent))) { |
| 3130 // If 'position: fixed' node is found while traversing up, terminate the l
oop and | 3206 // If 'position: fixed' node is found while traversing up, terminate the |
| 3131 // return null. | 3207 // loop and return null. |
| 3132 if (ancestor->isFixedPositioned()) | 3208 if (ancestor->isFixedPositioned()) |
| 3133 return nullptr; | 3209 return nullptr; |
| 3134 continue; | 3210 continue; |
| 3135 } | 3211 } |
| 3136 | 3212 |
| 3137 if (ancestor->canContainAbsolutePositionObjects()) | 3213 if (ancestor->canContainAbsolutePositionObjects()) |
| 3138 break; | 3214 break; |
| 3139 | 3215 |
| 3140 if (isHTMLBodyElement(*node)) | 3216 if (isHTMLBodyElement(*node)) |
| 3141 break; | 3217 break; |
| 3142 | 3218 |
| 3143 if (!isPositioned() && | 3219 if (!isPositioned() && |
| 3144 (isHTMLTableElement(*node) || isHTMLTableCellElement(*node))) | 3220 (isHTMLTableElement(*node) || isHTMLTableCellElement(*node))) |
| 3145 break; | 3221 break; |
| 3146 | 3222 |
| 3147 // Webkit specific extension where offsetParent stops at zoom level changes. | 3223 // Webkit specific extension where offsetParent stops at zoom level changes. |
| 3148 if (effectiveZoom != ancestor->style()->effectiveZoom()) | 3224 if (effectiveZoom != ancestor->style()->effectiveZoom()) |
| 3149 break; | 3225 break; |
| 3150 } | 3226 } |
| 3151 | 3227 |
| 3152 return node && node->isElementNode() ? toElement(node) : nullptr; | 3228 return node && node->isElementNode() ? toElement(node) : nullptr; |
| 3153 } | 3229 } |
| 3154 | 3230 |
| 3155 PositionWithAffinity LayoutObject::createPositionWithAffinity( | 3231 PositionWithAffinity LayoutObject::createPositionWithAffinity( |
| 3156 int offset, | 3232 int offset, |
| 3157 TextAffinity affinity) { | 3233 TextAffinity affinity) { |
| 3158 // If this is a non-anonymous layoutObject in an editable area, then it's simp
le. | 3234 // If this is a non-anonymous layoutObject in an editable area, then it's |
| 3235 // simple. |
| 3159 if (Node* node = nonPseudoNode()) { | 3236 if (Node* node = nonPseudoNode()) { |
| 3160 if (!hasEditableStyle(*node)) { | 3237 if (!hasEditableStyle(*node)) { |
| 3161 // If it can be found, we prefer a visually equivalent position that is ed
itable. | 3238 // If it can be found, we prefer a visually equivalent position that is |
| 3239 // editable. |
| 3162 const Position position = Position(node, offset); | 3240 const Position position = Position(node, offset); |
| 3163 Position candidate = | 3241 Position candidate = |
| 3164 mostForwardCaretPosition(position, CanCrossEditingBoundary); | 3242 mostForwardCaretPosition(position, CanCrossEditingBoundary); |
| 3165 if (hasEditableStyle(*candidate.anchorNode())) | 3243 if (hasEditableStyle(*candidate.anchorNode())) |
| 3166 return PositionWithAffinity(candidate, affinity); | 3244 return PositionWithAffinity(candidate, affinity); |
| 3167 candidate = mostBackwardCaretPosition(position, CanCrossEditingBoundary); | 3245 candidate = mostBackwardCaretPosition(position, CanCrossEditingBoundary); |
| 3168 if (hasEditableStyle(*candidate.anchorNode())) | 3246 if (hasEditableStyle(*candidate.anchorNode())) |
| 3169 return PositionWithAffinity(candidate, affinity); | 3247 return PositionWithAffinity(candidate, affinity); |
| 3170 } | 3248 } |
| 3171 // FIXME: Eliminate legacy editing positions | 3249 // FIXME: Eliminate legacy editing positions |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3377 DeprecatedDisableModifyLayoutTreeStructureAsserts() | 3455 DeprecatedDisableModifyLayoutTreeStructureAsserts() |
| 3378 : m_disabler(&gModifyLayoutTreeStructureAnyState, true) {} | 3456 : m_disabler(&gModifyLayoutTreeStructureAnyState, true) {} |
| 3379 | 3457 |
| 3380 bool DeprecatedDisableModifyLayoutTreeStructureAsserts:: | 3458 bool DeprecatedDisableModifyLayoutTreeStructureAsserts:: |
| 3381 canModifyLayoutTreeStateInAnyState() { | 3459 canModifyLayoutTreeStateInAnyState() { |
| 3382 return gModifyLayoutTreeStructureAnyState; | 3460 return gModifyLayoutTreeStructureAnyState; |
| 3383 } | 3461 } |
| 3384 | 3462 |
| 3385 void LayoutObject:: | 3463 void LayoutObject:: |
| 3386 setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() { | 3464 setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() { |
| 3387 // Clear first because PaintInvalidationSubtree overrides other full paint inv
alidation reasons. | 3465 // Clear first because PaintInvalidationSubtree overrides other full paint |
| 3466 // invalidation reasons. |
| 3388 clearShouldDoFullPaintInvalidation(); | 3467 clearShouldDoFullPaintInvalidation(); |
| 3389 setShouldDoFullPaintInvalidation(PaintInvalidationSubtree); | 3468 setShouldDoFullPaintInvalidation(PaintInvalidationSubtree); |
| 3390 } | 3469 } |
| 3391 | 3470 |
| 3392 void LayoutObject::setIsBackgroundAttachmentFixedObject( | 3471 void LayoutObject::setIsBackgroundAttachmentFixedObject( |
| 3393 bool isBackgroundAttachmentFixedObject) { | 3472 bool isBackgroundAttachmentFixedObject) { |
| 3394 ASSERT(frameView()); | 3473 ASSERT(frameView()); |
| 3395 if (m_bitfields.isBackgroundAttachmentFixedObject() == | 3474 if (m_bitfields.isBackgroundAttachmentFixedObject() == |
| 3396 isBackgroundAttachmentFixedObject) | 3475 isBackgroundAttachmentFixedObject) |
| 3397 return; | 3476 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3454 const blink::LayoutObject* root = object1; | 3533 const blink::LayoutObject* root = object1; |
| 3455 while (root->parent()) | 3534 while (root->parent()) |
| 3456 root = root->parent(); | 3535 root = root->parent(); |
| 3457 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3536 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3458 } else { | 3537 } else { |
| 3459 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3538 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
| 3460 } | 3539 } |
| 3461 } | 3540 } |
| 3462 | 3541 |
| 3463 #endif | 3542 #endif |
| OLD | NEW |