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. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. |
7 * All rights reserved. | 7 * All rights reserved. |
8 * Copyright (C) 2009 Google Inc. All rights reserved. | 8 * Copyright (C) 2009 Google Inc. All rights reserved. |
9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. | 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. |
10 * (http://www.torchmobile.com/) | 10 * (http://www.torchmobile.com/) |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 if (current->hasLayer()) | 605 if (current->hasLayer()) |
606 return toLayoutBoxModelObject(current)->layer(); | 606 return toLayoutBoxModelObject(current)->layer(); |
607 } | 607 } |
608 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at | 608 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at |
609 // which point this code should not be reached. | 609 // which point this code should not be reached. |
610 return nullptr; | 610 return nullptr; |
611 } | 611 } |
612 | 612 |
613 PaintLayer* LayoutObject::paintingLayer() const { | 613 PaintLayer* LayoutObject::paintingLayer() const { |
614 for (const LayoutObject* current = this; current; | 614 for (const LayoutObject* current = this; current; |
615 current = current->paintInvalidationParent()) { | 615 // Use containingBlock instead of paintInvalidationParent for floating |
616 // object to omit any self-painting layers of inline objects that don't | |
617 // paint the floating object. | |
618 current = current->isFloating() ? current->containingBlock() | |
619 : current->paintInvalidationParent()) { | |
616 if (current->hasLayer() && | 620 if (current->hasLayer() && |
617 toLayoutBoxModelObject(current)->layer()->isSelfPaintingLayer()) | 621 toLayoutBoxModelObject(current)->layer()->isSelfPaintingLayer()) |
618 return toLayoutBoxModelObject(current)->layer(); | 622 return toLayoutBoxModelObject(current)->layer(); |
619 } | 623 } |
620 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at | 624 // TODO(crbug.com/365897): we should get rid of detached layout subtrees, at |
621 // which point this code should not be reached. | 625 // which point this code should not be reached. |
622 return nullptr; | 626 return nullptr; |
623 } | 627 } |
624 | 628 |
625 bool LayoutObject::scrollRectToVisible(const LayoutRect& rect, | 629 bool LayoutObject::scrollRectToVisible(const LayoutRect& rect, |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
880 *ancestorSkipped = true; | 884 *ancestorSkipped = true; |
881 | 885 |
882 if (filterSkipped && object->hasFilterInducingProperty()) | 886 if (filterSkipped && object->hasFilterInducingProperty()) |
883 *filterSkipped = true; | 887 *filterSkipped = true; |
884 } | 888 } |
885 | 889 |
886 ASSERT(!object || !object->isAnonymousBlock()); | 890 ASSERT(!object || !object->isAnonymousBlock()); |
887 return toLayoutBlock(object); | 891 return toLayoutBlock(object); |
888 } | 892 } |
889 | 893 |
890 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const { | 894 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition( |
891 LayoutObject* o = containerForAbsolutePosition(); | 895 const LayoutBoxModelObject* ancestor, |
896 bool* ancestorSkipped, | |
897 bool* filterSkipped) const { | |
898 LayoutObject* object = | |
899 containerForAbsolutePosition(ancestor, ancestorSkipped, filterSkipped); | |
892 | 900 |
893 // For relpositioned inlines, we return the nearest non-anonymous enclosing | 901 // For relpositioned inlines, we return the nearest non-anonymous enclosing |
894 // block. We don't try to return the inline itself. This allows us to avoid | 902 // block. We don't try to return the inline itself. This allows us to avoid |
895 // having a positioned objects list in all LayoutInlines and lets us return a | 903 // having a positioned objects list in all LayoutInlines and lets us return a |
896 // strongly-typed LayoutBlock* result from this method. The container() method | 904 // strongly-typed LayoutBlock* result from this method. The container() method |
897 // can actually be used to obtain the inline directly. | 905 // can actually be used to obtain the inline directly. |
898 if (o && o->isInline() && !o->isAtomicInlineLevel()) { | 906 if (object && object->isInline() && !object->isAtomicInlineLevel()) { |
899 ASSERT(o->style()->hasInFlowPosition()); | 907 DCHECK(object->style()->hasInFlowPosition()); |
900 o = o->containingBlock(); | 908 object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
901 } | 909 } |
902 | 910 |
903 if (o && !o->isLayoutBlock()) | 911 if (object && !object->isLayoutBlock()) |
904 o = o->containingBlock(); | 912 object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
905 | 913 |
906 while (o && o->isAnonymousBlock()) | 914 while (object && object->isAnonymousBlock()) |
907 o = o->containingBlock(); | 915 object = object->containingBlock(ancestor, ancestorSkipped, filterSkipped); |
908 | 916 |
909 if (!o || !o->isLayoutBlock()) | 917 if (!object || !object->isLayoutBlock()) |
910 return nullptr; // This can still happen in case of an orphaned tree | 918 return nullptr; // This can still happen in case of an orphaned tree |
911 | 919 |
912 return toLayoutBlock(o); | 920 return toLayoutBlock(object); |
913 } | 921 } |
914 | 922 |
915 LayoutBlock* LayoutObject::containingBlock() const { | 923 LayoutBlock* LayoutObject::containingBlock(const LayoutBoxModelObject* ancestor, |
916 LayoutObject* o = parent(); | 924 bool* ancestorSkipped, |
917 if (!o && isLayoutScrollbarPart()) | 925 bool* filterSkipped) const { |
918 o = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); | 926 LayoutObject* object = parent(); |
927 if (!object && isLayoutScrollbarPart()) | |
928 object = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); | |
919 if (!isTextOrSVGChild()) { | 929 if (!isTextOrSVGChild()) { |
920 if (m_style->position() == FixedPosition) | 930 if (m_style->position() == FixedPosition) { |
921 return containerForFixedPosition(); | 931 return containerForFixedPosition(ancestor, ancestorSkipped, |
922 if (m_style->position() == AbsolutePosition) | 932 filterSkipped); |
923 return containingBlockForAbsolutePosition(); | 933 } |
934 if (m_style->position() == AbsolutePosition) { | |
935 return containingBlockForAbsolutePosition(ancestor, ancestorSkipped, | |
936 filterSkipped); | |
937 } | |
924 } | 938 } |
925 if (isColumnSpanAll()) { | 939 if (isColumnSpanAll()) { |
926 o = spannerPlaceholder()->containingBlock(); | 940 object = spannerPlaceholder()->containingBlock(); |
927 } else { | 941 } else { |
928 while (o && ((o->isInline() && !o->isAtomicInlineLevel()) || | 942 while (object && ((object->isInline() && !object->isAtomicInlineLevel()) || |
929 !o->isLayoutBlock())) | 943 !object->isLayoutBlock())) { |
930 o = o->parent(); | 944 if (ancestorSkipped && object == ancestor) |
945 *ancestorSkipped = true; | |
946 | |
947 if (filterSkipped && object->hasFilterInducingProperty()) | |
948 *filterSkipped = true; | |
949 object = object->parent(); | |
950 } | |
931 } | 951 } |
932 | 952 |
933 if (!o || !o->isLayoutBlock()) | 953 if (!object || !object->isLayoutBlock()) |
934 return nullptr; // This can still happen in case of an orphaned tree | 954 return nullptr; // This can still happen in case of an orphaned tree |
935 | 955 |
936 return toLayoutBlock(o); | 956 return toLayoutBlock(object); |
937 } | 957 } |
938 | 958 |
939 FloatRect LayoutObject::absoluteBoundingBoxFloatRect() const { | 959 FloatRect LayoutObject::absoluteBoundingBoxFloatRect() const { |
940 Vector<FloatQuad> quads; | 960 Vector<FloatQuad> quads; |
941 absoluteQuads(quads); | 961 absoluteQuads(quads); |
942 | 962 |
943 size_t n = quads.size(); | 963 size_t n = quads.size(); |
944 if (n == 0) | 964 if (n == 0) |
945 return FloatRect(); | 965 return FloatRect(); |
946 | 966 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1017 for (LayoutObject* current = slowFirstChild(); current; | 1037 for (LayoutObject* current = slowFirstChild(); current; |
1018 current = current->nextSibling()) | 1038 current = current->nextSibling()) |
1019 current->addAbsoluteRectForLayer(result); | 1039 current->addAbsoluteRectForLayer(result); |
1020 return result; | 1040 return result; |
1021 } | 1041 } |
1022 | 1042 |
1023 void LayoutObject::paint(const PaintInfo&, const LayoutPoint&) const {} | 1043 void LayoutObject::paint(const PaintInfo&, const LayoutPoint&) const {} |
1024 | 1044 |
1025 const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() | 1045 const LayoutBoxModelObject& LayoutObject::containerForPaintInvalidation() |
1026 const { | 1046 const { |
1027 RELEASE_ASSERT(isRooted()); | 1047 CHECK(isRooted()); |
1028 | 1048 |
1029 if (const LayoutBoxModelObject* paintInvalidationContainer = | 1049 if (const LayoutBoxModelObject* paintInvalidationContainer = |
1030 enclosingCompositedContainer()) | 1050 enclosingCompositedContainer()) |
1031 return *paintInvalidationContainer; | 1051 return *paintInvalidationContainer; |
1032 | 1052 |
1033 // If the current frame is not composited, we send just return the main | 1053 // If the current frame is not composited, we send just return the main |
1034 // frame's LayoutView so that we generate invalidations on the window. | 1054 // frame's LayoutView so that we generate invalidations on the window. |
1035 const LayoutView* layoutView = view(); | 1055 const LayoutView* layoutView = view(); |
1036 while ( | 1056 while (const LayoutObject* ownerObject = LayoutAPIShim::constLayoutObjectFrom( |
1037 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem())) | 1057 layoutView->frame()->ownerLayoutItem())) |
1038 layoutView = | 1058 layoutView = ownerObject->view(); |
1039 LayoutAPIShim::layoutObjectFrom(layoutView->frame()->ownerLayoutItem()) | 1059 |
1040 ->view(); | 1060 DCHECK(layoutView); |
1041 ASSERT(layoutView); | |
1042 return *layoutView; | 1061 return *layoutView; |
1043 } | 1062 } |
1044 | 1063 |
1045 const LayoutBoxModelObject* LayoutObject::enclosingCompositedContainer() const { | 1064 const LayoutBoxModelObject* LayoutObject::enclosingCompositedContainer() const { |
1046 LayoutBoxModelObject* container = nullptr; | 1065 LayoutBoxModelObject* container = nullptr; |
1047 // FIXME: CompositingState is not necessarily up to date for many callers of | 1066 // FIXME: CompositingState is not necessarily up to date for many callers of |
1048 // this function. | 1067 // this function. |
1049 DisableCompositingQueryAsserts disabler; | 1068 DisableCompositingQueryAsserts disabler; |
1050 | 1069 |
1051 if (PaintLayer* paintingLayer = this->paintingLayer()) { | 1070 if (PaintLayer* paintingLayer = this->paintingLayer()) { |
(...skipping 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2515 walker && walker != multicolContainer; walker = walker->parent()) { | 2534 walker && walker != multicolContainer; walker = walker->parent()) { |
2516 if (ancestorSkipped && walker == ancestor) | 2535 if (ancestorSkipped && walker == ancestor) |
2517 *ancestorSkipped = true; | 2536 *ancestorSkipped = true; |
2518 if (filterSkipped && walker->hasFilterInducingProperty()) | 2537 if (filterSkipped && walker->hasFilterInducingProperty()) |
2519 *filterSkipped = true; | 2538 *filterSkipped = true; |
2520 } | 2539 } |
2521 } | 2540 } |
2522 return multicolContainer; | 2541 return multicolContainer; |
2523 } | 2542 } |
2524 | 2543 |
2544 if (isFloating()) | |
chrishtr
2016/12/16 18:50:20
I'm concerned about side-effects of modifying cont
Xianzhu
2016/12/16 19:08:49
Paint invalidation of float-under-inline was broke
wkorman
2016/12/16 19:40:31
Are there any ramifications to using containingBlo
Xianzhu
2016/12/16 20:06:42
According to https://www.w3.org/TR/CSS2/visuren.ht
wkorman
2016/12/16 21:50:40
I was thinking the same as the tests you've alread
| |
2545 return containingBlock(ancestor, ancestorSkipped, filterSkipped); | |
2546 | |
2525 return o; | 2547 return o; |
2526 } | 2548 } |
2527 | 2549 |
2528 inline LayoutObject* LayoutObject::paintInvalidationParent() const { | 2550 inline LayoutObject* LayoutObject::paintInvalidationParent() const { |
2529 if (isLayoutView()) | 2551 if (isLayoutView()) |
2530 return LayoutAPIShim::layoutObjectFrom(frame()->ownerLayoutItem()); | 2552 return LayoutAPIShim::layoutObjectFrom(frame()->ownerLayoutItem()); |
2531 if (isColumnSpanAll()) | 2553 if (isColumnSpanAll()) |
2532 return spannerPlaceholder(); | 2554 return spannerPlaceholder(); |
2533 return parent(); | 2555 return parent(); |
2534 } | 2556 } |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3514 const blink::LayoutObject* root = object1; | 3536 const blink::LayoutObject* root = object1; |
3515 while (root->parent()) | 3537 while (root->parent()) |
3516 root = root->parent(); | 3538 root = root->parent(); |
3517 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3539 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
3518 } else { | 3540 } else { |
3519 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3541 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
3520 } | 3542 } |
3521 } | 3543 } |
3522 | 3544 |
3523 #endif | 3545 #endif |
OLD | NEW |