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 60be0837ef1f6001b6cdf4493d28ebe1097ff8b6..0e20b0906f0d0101e38d6b0954fb73c658f768f2 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,14 +200,16 @@ 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), |
@@ -204,7 +217,8 @@ IntersectionObserver::IntersectionObserver( |
m_rightMargin(Fixed), |
m_bottomMargin(Fixed), |
m_leftMargin(Fixed), |
- m_initialState(InitialState::kHidden) { |
+ m_initialState(InitialState::kHidden), |
+ m_intersectWithRemoteAncestors(intersectWithRemoteAncestors) { |
switch (rootMargin.size()) { |
case 0: |
break; |
@@ -250,6 +264,12 @@ LayoutObject* IntersectionObserver::rootLayoutObject() const { |
return toElement(node)->layoutObject(); |
} |
+LayoutObject* IntersectionObserver::rootLayoutObjectForIntersection() const { |
+ if (m_intersectWithRemoteAncestors) |
+ return nullptr; |
+ return rootLayoutObject(); |
+} |
+ |
void IntersectionObserver::observe(Element* target, |
ExceptionState& exceptionState) { |
if (!m_root) { |
@@ -270,7 +290,8 @@ void IntersectionObserver::observe(Element* target, |
LocalFrame* rootFrame = m_root->document().frame(); |
if (target->document() == rootNode()->document()) { |
- shouldReportRootBounds = true; |
+ if (!m_intersectWithRemoteAncestors) |
ojan
2016/11/23 22:55:54
Isn't this always true if target and root are in t
kenrb
2016/11/23 23:23:25
This is the special case problem I am thinking abo
|
+ shouldReportRootBounds = true; |
isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); |
} else if (targetFrame && rootFrame) { |
shouldReportRootBounds = |