| 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
|
| +{
|
| + 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;
|
|
|