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

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

Issue 2511143006: Detect change on the intersection of video and viewport. (Closed)
Patch Set: Rebase again. Created 4 years 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 55d610af229a5ec1111ca814843f748ae86ae57e..2ae1556fc10ddca7a031867902c3f74dde19c9c3 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
@@ -6,199 +6,35 @@
#include "core/dom/ElementRareData.h"
#include "core/dom/IntersectionObserver.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/LocalFrame.h"
-#include "core/layout/LayoutBox.h"
-#include "core/layout/LayoutView.h"
-#include "core/paint/PaintLayer.h"
namespace blink {
-IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
- Element& target,
- bool shouldReportRootBounds)
+IntersectionObservation::IntersectionObservation(
+ IntersectionObserver& observer,
+ Element& target,
+ IntersectionGeometry::ReportRootBounds shouldReportRootBounds)
: m_observer(observer),
m_target(&target),
- m_shouldReportRootBounds(shouldReportRootBounds),
+ m_shouldReportRootBounds(
+ shouldReportRootBounds ==
+ IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds),
m_lastThresholdIndex(0) {}
-void IntersectionObservation::applyRootMargin(LayoutRect& rect) const {
- if (m_shouldReportRootBounds)
- 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 {
- DCHECK(m_target);
- LayoutObject* targetLayoutObject = target()->layoutObject();
- DCHECK(targetLayoutObject && targetLayoutObject->isBoxModelObject());
- rect = LayoutRect(
- toLayoutBoxModelObject(targetLayoutObject)->borderBoundingBox());
-}
-
-void IntersectionObservation::initializeRootRect(LayoutRect& rect) const {
- LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
- if (rootLayoutObject->isLayoutView())
- rect = LayoutRect(
- toLayoutView(rootLayoutObject)->frameView()->visibleContentRect());
- else if (rootLayoutObject->isBox() && rootLayoutObject->hasOverflowClip())
- rect = LayoutRect(toLayoutBox(rootLayoutObject)->contentBoxRect());
- else
- rect = LayoutRect(
- toLayoutBoxModelObject(rootLayoutObject)->borderBoundingBox());
- applyRootMargin(rect);
-}
-
-void IntersectionObservation::clipToRoot(IntersectionGeometry& geometry) const {
- // Map and clip rect into root element coordinates.
- // TODO(szager): the writing mode flipping needs a test.
- DCHECK(m_target);
- LayoutBox* rootLayoutObject = toLayoutBox(m_observer->rootLayoutObject());
- LayoutObject* targetLayoutObject = target()->layoutObject();
-
- geometry.doesIntersect = targetLayoutObject->mapToVisualRectInAncestorSpace(
- rootLayoutObject, geometry.intersectionRect, EdgeInclusive);
- if (rootLayoutObject->hasOverflowClip())
- geometry.intersectionRect.move(-rootLayoutObject->scrolledContentOffset());
-
- if (!geometry.doesIntersect)
- return;
- LayoutRect rootClipRect(geometry.rootRect);
- rootLayoutObject->flipForWritingMode(rootClipRect);
- geometry.doesIntersect &=
- geometry.intersectionRect.inclusiveIntersect(rootClipRect);
-}
-
-static void mapRectUpToDocument(LayoutRect& rect,
- const LayoutObject& layoutObject,
- const Document& document) {
- FloatQuad mappedQuad = layoutObject.localToAbsoluteQuad(
- FloatQuad(FloatRect(rect)), UseTransforms | ApplyContainerFlip);
- rect = LayoutRect(mappedQuad.boundingBox());
-}
-
-static void mapRectDownToDocument(LayoutRect& rect,
- LayoutBoxModelObject& layoutObject,
- const Document& document) {
- FloatQuad mappedQuad = document.layoutView()->ancestorToLocalQuad(
- &layoutObject, FloatQuad(FloatRect(rect)),
- UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries);
- rect = LayoutRect(mappedQuad.boundingBox());
-}
-
-void IntersectionObservation::mapTargetRectToTargetFrameCoordinates(
- LayoutRect& rect) const {
- LayoutObject& targetLayoutObject = *target()->layoutObject();
- Document& targetDocument = target()->document();
- LayoutSize scrollPosition =
- LayoutSize(targetDocument.view()->getScrollOffset());
- mapRectUpToDocument(rect, targetLayoutObject, targetDocument);
- rect.move(-scrollPosition);
-}
-
-void IntersectionObservation::mapRootRectToRootFrameCoordinates(
- LayoutRect& rect) const {
- LayoutObject& rootLayoutObject = *m_observer->rootLayoutObject();
- Document& rootDocument = rootLayoutObject.document();
- LayoutSize scrollPosition =
- LayoutSize(rootDocument.view()->getScrollOffset());
- mapRectUpToDocument(rect, rootLayoutObject, rootLayoutObject.document());
- rect.move(-scrollPosition);
-}
-
-void IntersectionObservation::mapRootRectToTargetFrameCoordinates(
- LayoutRect& rect) const {
- LayoutObject& rootLayoutObject = *m_observer->rootLayoutObject();
- Document& targetDocument = target()->document();
- LayoutSize scrollPosition =
- LayoutSize(targetDocument.view()->getScrollOffset());
-
- if (&targetDocument == &rootLayoutObject.document())
- mapRectUpToDocument(rect, rootLayoutObject, targetDocument);
- else
- mapRectDownToDocument(rect, toLayoutBoxModelObject(rootLayoutObject),
- targetDocument);
-
- rect.move(-scrollPosition);
-}
-
-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) const {
- // In the first few lines here, before initializeGeometry is called, "return
- // true" effectively means "if the previous observed state was that root and
- // target were intersecting, then generate a notification indicating that they
- // are no longer intersecting." This happens, for example, when root or
- // target is removed from the DOM tree and not reinserted before the next
- // frame is generated, or display:none is set on the root or target.
- Element* targetElement = target();
- if (!targetElement)
- return false;
- if (!targetElement->isConnected())
- return true;
- DCHECK(m_observer);
- Element* rootElement = m_observer->root();
- if (rootElement && !rootElement->isConnected())
- return true;
-
- LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
- if (!rootLayoutObject || !rootLayoutObject->isBoxModelObject())
- return true;
- // TODO(szager): Support SVG
- LayoutObject* targetLayoutObject = targetElement->layoutObject();
- if (!targetLayoutObject)
- return true;
- if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText())
- return true;
- if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject))
- return true;
-
- initializeGeometry(geometry);
-
- clipToRoot(geometry);
-
- mapTargetRectToTargetFrameCoordinates(geometry.targetRect);
-
- if (geometry.doesIntersect)
- mapRootRectToTargetFrameCoordinates(geometry.intersectionRect);
- else
- geometry.intersectionRect = LayoutRect();
-
- // Small optimization: if we're not going to report root bounds, don't bother
- // transforming them to the frame.
- if (m_shouldReportRootBounds)
- mapRootRectToRootFrameCoordinates(geometry.rootRect);
-
- return true;
-}
-
void IntersectionObservation::computeIntersectionObservations(
DOMHighResTimeStamp timestamp) {
- IntersectionGeometry geometry;
- if (!computeGeometry(geometry))
+ if (!m_target)
return;
+ Vector<Length> rootMargin(4);
+ rootMargin[0] = m_observer->topMargin();
+ rootMargin[1] = m_observer->rightMargin();
+ rootMargin[2] = m_observer->bottomMargin();
+ rootMargin[3] = m_observer->leftMargin();
+ IntersectionGeometry geometry(
+ m_observer->rootNode(), target(), rootMargin,
+ m_shouldReportRootBounds
+ ? IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds
+ : IntersectionGeometry::ReportRootBounds::kShouldNotReportRootBounds);
+ geometry.computeGeometry();
// Some corner cases for threshold index:
// - If target rect is zero area, because it has zero width and/or zero
@@ -215,27 +51,26 @@ void IntersectionObservation::computeIntersectionObservations(
// any non-zero threshold.
unsigned newThresholdIndex;
float newVisibleRatio = 0;
- if (geometry.targetRect.isEmpty()) {
- newThresholdIndex = geometry.doesIntersect ? 1 : 0;
- } else if (!geometry.doesIntersect) {
+ if (geometry.targetRect().isEmpty()) {
+ newThresholdIndex = geometry.doesIntersect() ? 1 : 0;
+ } else if (!geometry.doesIntersect()) {
newThresholdIndex = 0;
} else {
float intersectionArea =
- geometry.intersectionRect.size().width().toFloat() *
- geometry.intersectionRect.size().height().toFloat();
- float targetArea = geometry.targetRect.size().width().toFloat() *
- geometry.targetRect.size().height().toFloat();
+ geometry.intersectionRect().size().width().toFloat() *
+ geometry.intersectionRect().size().height().toFloat();
+ float targetArea = geometry.targetRect().size().width().toFloat() *
+ geometry.targetRect().size().height().toFloat();
newVisibleRatio = intersectionArea / targetArea;
newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio);
}
if (m_lastThresholdIndex != newThresholdIndex) {
- IntRect snappedRootBounds = pixelSnappedIntRect(geometry.rootRect);
+ IntRect snappedRootBounds = geometry.rootIntRect();
IntRect* rootBoundsPointer =
m_shouldReportRootBounds ? &snappedRootBounds : nullptr;
IntersectionObserverEntry* newEntry = new IntersectionObserverEntry(
- timestamp, newVisibleRatio, pixelSnappedIntRect(geometry.targetRect),
- rootBoundsPointer, pixelSnappedIntRect(geometry.intersectionRect),
- target());
+ timestamp, newVisibleRatio, geometry.targetIntRect(), rootBoundsPointer,
+ geometry.intersectionIntRect(), target());
observer().enqueueIntersectionObserverEntry(*newEntry);
setLastThresholdIndex(newThresholdIndex);
}

Powered by Google App Engine
This is Rietveld 408576698