Index: third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
index 7509dcf7051d0c111c615918360c489eed7e098e..e04ca3394f6b48c3eb06b25708f1decc3c23e15c 100644 |
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
@@ -132,11 +132,10 @@ void parseThresholds(const DoubleOrDoubleSequence& thresholdParameter, |
// Returns the root Node of a given Document to use as the IntersectionObserver |
// root when no root is given. |
-// TODO(szager): it doesn't support RemoteFrames, see https://crbug.com/615156 |
Node* getRootNode(Document* document) { |
- Frame* mainFrame = document->frame()->tree().top(); |
- if (mainFrame && mainFrame->isLocalFrame()) |
- return toLocalFrame(mainFrame)->document(); |
+ LocalFrame* rootFrame = document->frame()->localFrameRoot(); |
+ if (rootFrame) |
+ return rootFrame->document(); |
return nullptr; |
} |
@@ -146,11 +145,17 @@ IntersectionObserver* IntersectionObserver::create( |
const IntersectionObserverInit& observerInit, |
IntersectionObserverCallback& callback, |
ExceptionState& exceptionState) { |
+ bool intersectWithRemoteAncestors = false; |
Node* root = observerInit.root(); |
if (!root) { |
ExecutionContext* context = callback.getExecutionContext(); |
DCHECK(context->isDocument()); |
root = getRootNode(toDocument(context)); |
+ if (root && (toDocument(context)->frame()->tree().top()->isRemoteFrame() || |
+ root != |
+ toLocalFrame(toDocument(context)->frame()->tree().top()) |
+ ->document())) |
+ intersectWithRemoteAncestors = true; |
} |
if (!root) { |
exceptionState.throwDOMException( |
@@ -169,7 +174,8 @@ IntersectionObserver* IntersectionObserver::create( |
if (exceptionState.hadException()) |
return nullptr; |
- return new IntersectionObserver(callback, *root, rootMargin, thresholds); |
+ return new IntersectionObserver(callback, *root, rootMargin, thresholds, |
+ intersectWithRemoteAncestors); |
} |
IntersectionObserver* IntersectionObserver::create( |
@@ -179,6 +185,11 @@ IntersectionObserver* IntersectionObserver::create( |
std::unique_ptr<EventCallback> callback, |
ExceptionState& exceptionState) { |
Node* root = getRootNode(document); |
+ bool intersectWithRemoteAncestors = false; |
+ if (root && |
+ (document->frame()->tree().top()->isRemoteFrame() || |
+ root != toLocalFrame(document->frame()->tree().top())->document())) |
+ intersectWithRemoteAncestors = true; |
if (!root) { |
exceptionState.throwDOMException( |
HierarchyRequestError, |
@@ -189,21 +200,24 @@ IntersectionObserver* IntersectionObserver::create( |
IntersectionObserverCallbackImpl* intersectionObserverCallback = |
new IntersectionObserverCallbackImpl(document, std::move(callback)); |
return new IntersectionObserver(*intersectionObserverCallback, *root, |
- rootMargin, thresholds); |
+ rootMargin, thresholds, |
+ intersectWithRemoteAncestors); |
} |
IntersectionObserver::IntersectionObserver( |
IntersectionObserverCallback& callback, |
Node& root, |
const Vector<Length>& rootMargin, |
- const Vector<float>& thresholds) |
+ const Vector<float>& thresholds, |
+ bool intersectWithRemoteAncestors) |
: m_callback(&callback), |
m_root(&root), |
m_thresholds(thresholds), |
m_topMargin(Fixed), |
m_rightMargin(Fixed), |
m_bottomMargin(Fixed), |
- m_leftMargin(Fixed) { |
+ m_leftMargin(Fixed), |
+ m_intersectWithRemoteAncestors(intersectWithRemoteAncestors) { |
switch (rootMargin.size()) { |
case 0: |
break; |
@@ -269,7 +283,8 @@ void IntersectionObserver::observe(Element* target, |
LocalFrame* rootFrame = m_root->document().frame(); |
if (target->document() == rootNode()->document()) { |
- shouldReportRootBounds = true; |
+ if (!m_intersectWithRemoteAncestors) |
+ shouldReportRootBounds = true; |
isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); |
} else if (targetFrame && rootFrame) { |
shouldReportRootBounds = |
@@ -434,6 +449,18 @@ void IntersectionObserver::deliver() { |
m_callback->handleEvent(entries, *this); |
} |
+void IntersectionObserver::intersectWithRemoteAncestorsIfNeeded( |
+ LayoutRect& rect) { |
+ if (m_intersectWithRemoteAncestors) { |
+ Document* root = toDocument(rootNode()); |
+ if (root->view()) { |
+ LayoutRect viewportIntersectionRect( |
+ root->view()->remoteViewportIntersection()); |
+ rect.intersect(viewportIntersectionRect); |
+ } |
+ } |
+} |
+ |
DEFINE_TRACE(IntersectionObserver) { |
visitor->template registerWeakMembers< |
IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); |