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..51a125d6729a0841994e3358d29c57150de8083b 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; |
| @@ -270,7 +284,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 = |
| @@ -445,6 +460,18 @@ void IntersectionObserver::deliver() { |
| m_callback->handleEvent(entries, *this); |
| } |
| +void IntersectionObserver::intersectWithRemoteAncestorsIfNeeded( |
|
szager1
2016/11/16 22:11:22
I agree with Ojan's point that this should be hand
kenrb
2016/11/21 19:37:35
In the most recent PS I have modified mapToVisualR
ojan
2016/11/23 19:14:00
Can we always pass nullptr to mapToVisualRectInAnc
kenrb
2016/11/23 20:07:28
We still need a boolean in the IntersectionObserve
|
| + 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); |