Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: third_party/WebKit/Source/core/dom/IntersectionObservation.cpp

Issue 1672273002: Enforce containing block requirement for IntersectionObserver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: nits Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..07364afadca65fdc6f581cff3c30b59b85b55292 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,15 +88,44 @@ 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;
+
+ 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)
return false;
if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText())
return false;
+ if (!rootLayoutObject || !rootLayoutObject->isBoxModelObject())
+ return false;
+ if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject))
+ return false;
// Initialize targetRect and intersectionRect to bounds of target, in target's coordinate space.
initializeGeometry(geometry);
@@ -126,19 +155,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 +173,7 @@ void IntersectionObservation::computeIntersectionObservations(DOMHighResTimeStam
pixelSnappedIntRect(geometry.targetRect),
rootBoundsPointer,
pixelSnappedIntRect(geometry.intersectionRect),
- targetElement);
+ target());
observer().enqueueIntersectionObserverEntry(*newEntry);
}
setLastThresholdIndex(newThresholdIndex);

Powered by Google App Engine
This is Rietveld 408576698