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