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

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

Issue 1817693002: Support edge-inclusive intersections in mapToVisibleRectInAncestorSpace (Closed) Base URL: https://chromium.googlesource.com/chromium/src@intersection-observer-idle-callback
Patch Set: Address comments, add mapToVisibleRectInContainerSpace test Created 4 years, 9 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 8a35d27e6dcdd306ff4eb6c895ac4dc6d1438b10..ead4f184c8fb55cca45bd09d5f0e590a071cf2ef 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
@@ -34,19 +34,20 @@ void IntersectionObservation::applyRootMargin(LayoutRect& rect) const
m_observer->applyRootMargin(rect);
}
+void IntersectionObservation::initializeGeometry(IntersectionGeometry& geometry) const
chrishtr 2016/03/22 19:54:26 Prefer to remove changes to this class from the CL
szager1 2016/03/23 23:26:59 Done.
+{
+ initializeTargetRect(geometry.targetRect);
+ geometry.intersectionRect = geometry.targetRect;
+ initializeRootRect(geometry.rootRect);
+ geometry.doesIntersect = true;
+}
+
void IntersectionObservation::initializeTargetRect(LayoutRect& rect) const
{
ASSERT(m_target);
LayoutObject* targetLayoutObject = target()->layoutObject();
ASSERT(targetLayoutObject && targetLayoutObject->isBoxModelObject());
rect = toLayoutBoxModelObject(targetLayoutObject)->visualOverflowRect();
-
- // TODO(szager): Properly support intersection observations for zero-area targets
- // by using edge-inclusive geometry.
- if (!rect.size().width())
- rect.setWidth(LayoutUnit(1));
- if (!rect.size().height())
- rect.setHeight(LayoutUnit(1));
}
void IntersectionObservation::initializeRootRect(LayoutRect& rect) const
@@ -62,7 +63,7 @@ void IntersectionObservation::initializeRootRect(LayoutRect& rect) const
applyRootMargin(rect);
}
-void IntersectionObservation::clipToRoot(LayoutRect& rect, const LayoutRect& rootRect) const
+void IntersectionObservation::clipToRoot(IntersectionGeometry& geometry) const
{
// Map and clip rect into root element coordinates.
// TODO(szager): the writing mode flipping needs a test.
@@ -70,10 +71,12 @@ void IntersectionObservation::clipToRoot(LayoutRect& rect, const LayoutRect& roo
LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
LayoutObject* targetLayoutObject = target()->layoutObject();
- targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(rootLayoutObject), rect, nullptr);
- LayoutRect rootClipRect(rootRect);
+ geometry.doesIntersect = targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(rootLayoutObject), geometry.intersectionRect, nullptr, EdgeInclusive);
+ if (!geometry.doesIntersect)
+ return;
+ LayoutRect rootClipRect(geometry.rootRect);
toLayoutBox(rootLayoutObject)->flipForWritingMode(rootClipRect);
- rect.intersect(rootClipRect);
+ geometry.doesIntersect &= geometry.intersectionRect.inclusiveIntersect(rootClipRect);
}
static void mapRectUpToDocument(LayoutRect& rect, const LayoutObject& layoutObject, const Document& document)
@@ -164,22 +167,22 @@ bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) co
if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject))
return false;
- initializeTargetRect(geometry.targetRect);
- geometry.intersectionRect = geometry.targetRect;
- initializeRootRect(geometry.rootRect);
+ initializeGeometry(geometry);
- clipToRoot(geometry.intersectionRect, geometry.rootRect);
+ clipToRoot(geometry);
- // TODO(szager): there are some simple optimizations that can be done here:
- // - Don't transform rootRect if it's not going to be reported
- // - Don't transform intersectionRect if it's empty
mapTargetRectToTargetFrameCoordinates(geometry.targetRect);
- mapRootRectToTargetFrameCoordinates(geometry.intersectionRect);
- mapRootRectToRootFrameCoordinates(geometry.rootRect);
- if (geometry.intersectionRect.size().isZero())
+ if (geometry.doesIntersect)
+ mapRootRectToTargetFrameCoordinates(geometry.intersectionRect);
+ else
geometry.intersectionRect = LayoutRect();
+ if (m_shouldReportRootBounds)
+ mapRootRectToRootFrameCoordinates(geometry.rootRect);
+ else
+ geometry.rootRect = LayoutRect();
+
return true;
}
@@ -191,9 +194,11 @@ void IntersectionObservation::computeIntersectionObservations(DOMHighResTimeStam
float intersectionArea = geometry.intersectionRect.size().width().toFloat() * geometry.intersectionRect.size().height().toFloat();
float targetArea = geometry.targetRect.size().width().toFloat() * geometry.targetRect.size().height().toFloat();
- if (!targetArea)
- return;
- float newVisibleRatio = intersectionArea / targetArea;
+ float newVisibleRatio;
+ if (!intersectionArea && geometry.doesIntersect)
+ newVisibleRatio = std::numeric_limits<float>::denorm_min();
+ else
+ newVisibleRatio = intersectionArea / targetArea;
unsigned newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio);
IntRect snappedRootBounds = pixelSnappedIntRect(geometry.rootRect);
IntRect* rootBoundsPointer = m_shouldReportRootBounds ? &snappedRootBounds : nullptr;

Powered by Google App Engine
This is Rietveld 408576698