Chromium Code Reviews| Index: third_party/WebKit/Source/core/frame/RemoteFrameView.cpp |
| diff --git a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp |
| index d73ac0a12b1be30a510ebefa50124bbe42f465bd..d02f1999c84e448dd7c68d1b878a15ef40747536 100644 |
| --- a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp |
| +++ b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp |
| @@ -4,9 +4,13 @@ |
| #include "core/frame/RemoteFrameView.h" |
| +#include "core/dom/IntersectionObserverEntry.h" |
| #include "core/frame/FrameView.h" |
| +#include "core/frame/LocalFrame.h" |
| #include "core/frame/RemoteFrame.h" |
| +#include "core/frame/RemoteFrameClient.h" |
| #include "core/html/HTMLFrameOwnerElement.h" |
| +#include "core/layout/LayoutView.h" |
| #include "core/layout/api/LayoutPartItem.h" |
| namespace blink { |
| @@ -21,6 +25,10 @@ RemoteFrameView::~RemoteFrameView() {} |
| void RemoteFrameView::setParent(Widget* parent) { |
| Widget::setParent(parent); |
| frameRectsChanged(); |
| + if (parent && parent->isFrameView()) |
| + startIntersectionObserver(); |
| + else |
| + stopIntersectionObserver(); |
| } |
| RemoteFrameView* RemoteFrameView::create(RemoteFrame* remoteFrame) { |
| @@ -29,6 +37,43 @@ RemoteFrameView* RemoteFrameView::create(RemoteFrame* remoteFrame) { |
| return view; |
| } |
| +void RemoteFrameView::startIntersectionObserver() { |
| + DCHECK(m_remoteFrame->owner()->isLocal()); |
| + if (!m_intersectionObserver) { |
| + m_intersectionObserver = IntersectionObserver::create( |
|
szager1
2016/11/16 22:11:22
This won't work, because the observer will only fi
kenrb
2016/11/21 19:37:35
Thanks, I didn't realize this. I've reworked it to
|
| + Vector<Length>(), Vector<float>({std::numeric_limits<float>::min()}), |
| + &m_remoteFrame->deprecatedLocalOwner()->document(), |
| + WTF::bind(&RemoteFrameView::onViewportIntersectionChanged, |
| + wrapWeakPersistent(this))); |
| + m_intersectionObserver->setInitialState( |
| + IntersectionObserver::InitialState::kAuto); |
| + // startIntersectionObserver() should only be called on a RemoteFrame with |
| + // a local owner, otherwise it doesn't correspond to a frame root in the |
| + // remote process and therefore doesn't need to send intersection rects. |
| + m_intersectionObserver->observe(m_remoteFrame->deprecatedLocalOwner()); |
| + } |
| +} |
| + |
| +void RemoteFrameView::stopIntersectionObserver() { |
| + if (m_intersectionObserver) { |
| + m_intersectionObserver->disconnect(); |
| + m_intersectionObserver = nullptr; |
| + } |
| +} |
| + |
| +void RemoteFrameView::onViewportIntersectionChanged( |
| + const HeapVector<Member<IntersectionObserverEntry>>& entries) { |
| + ClientRect* rect = entries.last()->intersectionRect(); |
| + IntRect viewportIntersection = roundedIntRect( |
| + FloatRect(rect->left(), rect->top(), rect->width(), rect->height())); |
| + viewportIntersection = convertFromContainingWidget(viewportIntersection); |
| + if (viewportIntersection != m_lastViewportIntersection) { |
| + m_remoteFrame->client()->updateRemoteViewportIntersection( |
| + viewportIntersection); |
| + } |
| + m_lastViewportIntersection = viewportIntersection; |
| +} |
| + |
| void RemoteFrameView::dispose() { |
| HTMLFrameOwnerElement* ownerElement = m_remoteFrame->deprecatedLocalOwner(); |
| // ownerElement can be null during frame swaps, because the |
| @@ -68,7 +113,7 @@ void RemoteFrameView::frameRectsChanged() { |
| if (parent() && parent()->isFrameView()) |
| newRect = parent()->convertToRootFrame( |
| toFrameView(parent())->contentsToFrame(newRect)); |
| - m_remoteFrame->frameRectsChanged(newRect); |
| + m_remoteFrame->client()->frameRectsChanged(newRect); |
| } |
| void RemoteFrameView::hide() { |
| @@ -76,7 +121,8 @@ void RemoteFrameView::hide() { |
| Widget::hide(); |
| - m_remoteFrame->visibilityChanged(false); |
| + if (m_remoteFrame->client()) |
| + m_remoteFrame->client()->visibilityChanged(false); |
| } |
| void RemoteFrameView::show() { |
| @@ -84,7 +130,8 @@ void RemoteFrameView::show() { |
| Widget::show(); |
| - m_remoteFrame->visibilityChanged(true); |
| + if (m_remoteFrame->client()) |
| + m_remoteFrame->client()->visibilityChanged(true); |
| } |
| void RemoteFrameView::setParentVisible(bool visible) { |
| @@ -95,11 +142,13 @@ void RemoteFrameView::setParentVisible(bool visible) { |
| if (!isSelfVisible()) |
| return; |
| - m_remoteFrame->visibilityChanged(isVisible()); |
| + if (m_remoteFrame->client()) |
| + m_remoteFrame->client()->visibilityChanged(isVisible()); |
| } |
| DEFINE_TRACE(RemoteFrameView) { |
| visitor->trace(m_remoteFrame); |
| + visitor->trace(m_intersectionObserver); |
| Widget::trace(visitor); |
| } |