Chromium Code Reviews| 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 = |