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 |