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); |
} |