Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/IntersectionObservation.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp |
| index 152f08dd5ae44179bcee4efd844f2d5f01f9c62b..648714a14a286774c77582facd3963a82bd6c2ce 100644 |
| --- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp |
| +++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp |
| @@ -8,6 +8,7 @@ |
| #include "core/dom/IntersectionObserver.h" |
| #include "core/frame/FrameView.h" |
| #include "core/layout/LayoutBox.h" |
| +#include "core/layout/LayoutPart.h" |
| #include "core/layout/LayoutText.h" |
| #include "core/layout/LayoutView.h" |
| #include "core/paint/PaintLayer.h" |
| @@ -17,7 +18,6 @@ namespace blink { |
| IntersectionObservation::IntersectionObservation(IntersectionObserver& observer, Element& target, bool shouldReportRootBounds) |
| : m_observer(observer) |
| , m_target(target.ensureIntersectionObserverData().createWeakPtr(&target)) |
| - , m_active(true) |
| , m_shouldReportRootBounds(shouldReportRootBounds) |
| , m_lastThresholdIndex(0) |
| { |
| @@ -88,14 +88,41 @@ static void mapRectToDocumentCoordinates(LayoutObject& layoutObject, LayoutRect& |
| rect = LayoutRect(layoutObject.localToAbsoluteQuad(FloatQuad(FloatRect(rect)), UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries).boundingBox()); |
| } |
| +static bool isContainingBlockChainDescendant(LayoutObject* descendant, LayoutObject* ancestor) |
| +{ |
| + LocalFrame* ancestorFrame = ancestor->document().frame(); |
| + LocalFrame* descendantFrame = descendant->document().frame(); |
| + |
| + if (ancestor->isLayoutView()) |
| + return (descendantFrame && descendantFrame->tree().top() == ancestorFrame); |
|
esprehn
2016/02/11 06:15:23
remove parens
szager1
2016/02/11 18:17:24
Done.
|
| + |
| + if (ancestorFrame != descendantFrame) |
| + return false; |
| + |
| + while (descendant && descendant != ancestor) |
| + descendant = descendant->containingBlock(); |
| + return descendant; |
| +} |
| + |
| bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) |
| { |
| - ASSERT(m_target); |
| + // Pre-oilpan, there will be a delay between the time when the target Element gets deleted |
| + // (because its ref count dropped to zero) and when this IntersectionObservation gets |
| + // deleted (during the next gc run, because the target Element is the only thing keeping |
| + // the IntersectionObservation alive). During that interval, we need to check that m_target |
| + // hasn't been cleared. |
| + Element* targetElement = target(); |
| + if (!targetElement || !targetElement->inDocument()) |
| + return false; |
| + LayoutObject* targetLayoutObject = targetElement->layoutObject(); |
| + ASSERT(m_observer); |
| LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); |
| - LayoutObject* targetLayoutObject = target()->layoutObject(); |
| - if (!rootLayoutObject->isBoxModelObject()) |
| + // TODO(szager): Support SVG |
| + if (!targetLayoutObject || !(targetLayoutObject->isBoxModelObject() || targetLayoutObject->isText())) |
|
esprehn
2016/02/11 06:15:23
if (!targetLayoutObject)
return false;
if (!targ
szager1
2016/02/11 18:17:24
Done.
|
| + return false; |
| + if (!rootLayoutObject || !rootLayoutObject->isBoxModelObject()) |
| return false; |
| - if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText()) |
| + if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject)) |
| return false; |
| // Initialize targetRect and intersectionRect to bounds of target, in target's coordinate space. |
| @@ -126,19 +153,6 @@ bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) |
| void IntersectionObservation::computeIntersectionObservations(DOMHighResTimeStamp timestamp) |
| { |
| - // Pre-oilpan, there will be a delay between the time when the target Element gets deleted |
| - // (because its ref count dropped to zero) and when this IntersectionObservation gets |
| - // deleted (during the next gc run, because the target Element is the only thing keeping |
| - // the IntersectionObservation alive). During that interval, we need to check that m_target |
| - // hasn't been cleared. |
| - Element* targetElement = target(); |
| - if (!targetElement || !isActive()) |
| - return; |
| - LayoutObject* targetLayoutObject = targetElement->layoutObject(); |
| - // TODO(szager): Support SVG |
| - if (!targetLayoutObject || (!targetLayoutObject->isBox() && !targetLayoutObject->isInline())) |
| - return; |
| - |
| IntersectionGeometry geometry; |
| if (!computeGeometry(geometry)) |
| return; |
| @@ -157,7 +171,7 @@ void IntersectionObservation::computeIntersectionObservations(DOMHighResTimeStam |
| pixelSnappedIntRect(geometry.targetRect), |
| rootBoundsPointer, |
| pixelSnappedIntRect(geometry.intersectionRect), |
| - targetElement); |
| + target()); |
| observer().enqueueIntersectionObserverEntry(*newEntry); |
| } |
| setLastThresholdIndex(newThresholdIndex); |