Index: third_party/WebKit/Source/web/ChromeClientImpl.cpp |
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp |
index c2bd61290d86b9bbebaa2e65327387f73a93ae27..7cc7f42277c6ee58bb842743c3d225bd5b956dcb 100644 |
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp |
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp |
@@ -928,23 +928,55 @@ bool ChromeClientImpl::shouldOpenModalDialogDuringPageDismissal( |
} |
void ChromeClientImpl::setEventListenerProperties( |
+ LocalFrame* frame, |
WebEventListenerClass eventClass, |
WebEventListenerProperties properties) { |
- if (WebLayerTreeView* treeView = m_webView->layerTreeView()) { |
+ // |frame| might be null if called via TreeScopeAdopter:: |
+ // moveNodeToNewDocument() and the new document has no frame attached. |
+ // Since a document without a frame cannot attach one later, it is safe to |
+ // exit early. |
+ if (!frame) |
+ return; |
+ |
+ WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame); |
+ WebFrameWidgetBase* widget = webFrame->localRoot()->frameWidget(); |
+ // The widget may be nullptr if the frame is provisional. |
+ if (!widget) { |
+ // If we hit a provisional frame, we expect it to be during initialization |
+ // in which case the |properties| should be 'nothing'. |
+ DCHECK(properties == WebEventListenerProperties::Nothing); |
+ return; |
+ } |
+ |
+ // This relies on widget always pointing to a WebFrameWidgetImpl when |
+ // |frame| points to an OOPIF frame, i.e. |frame|'s mainFrame() is |
+ // remote. |
+ setEventListenerProperties(widget, eventClass, properties); |
+} |
+ |
+void ChromeClientImpl::setEventListenerProperties( |
+ WebFrameWidgetBase* widget, |
+ WebEventListenerClass eventClass, |
+ WebEventListenerProperties properties) { |
+ DCHECK(widget); |
dcheng
2017/01/16 11:05:41
In Blink, prefer to pass by mutable reference to i
wjmaclean
2017/01/17 18:23:28
Done.
|
+ WebWidgetClient* client = widget->client(); |
+ if (WebLayerTreeView* treeView = widget->getLayerTreeView()) { |
treeView->setEventListenerProperties(eventClass, properties); |
if (eventClass == WebEventListenerClass::TouchStartOrMove) { |
- m_webView->hasTouchEventHandlers( |
+ client->hasTouchEventHandlers( |
properties != WebEventListenerProperties::Nothing || |
- eventListenerProperties(WebEventListenerClass::TouchEndOrCancel) != |
+ eventListenerProperties(treeView, |
+ WebEventListenerClass::TouchEndOrCancel) != |
WebEventListenerProperties::Nothing); |
} else if (eventClass == WebEventListenerClass::TouchEndOrCancel) { |
- m_webView->hasTouchEventHandlers( |
+ client->hasTouchEventHandlers( |
properties != WebEventListenerProperties::Nothing || |
- eventListenerProperties(WebEventListenerClass::TouchStartOrMove) != |
+ eventListenerProperties(treeView, |
+ WebEventListenerClass::TouchStartOrMove) != |
WebEventListenerProperties::Nothing); |
} |
} else { |
- m_webView->hasTouchEventHandlers(true); |
+ client->hasTouchEventHandlers(true); |
} |
} |
@@ -956,21 +988,43 @@ void ChromeClientImpl::beginLifecycleUpdates() { |
} |
WebEventListenerProperties ChromeClientImpl::eventListenerProperties( |
+ LocalFrame* frame, |
WebEventListenerClass eventClass) const { |
- if (WebLayerTreeView* treeView = m_webView->layerTreeView()) |
+ if (!frame) |
+ return WebEventListenerProperties::Nothing; |
+ |
+ WebFrameWidgetBase* widget = |
+ WebLocalFrameImpl::fromFrame(frame)->localRoot()->frameWidget(); |
+ |
+ if (!widget) |
dcheng
2017/01/16 11:05:41
I guess this can also be called on provisional fra
wjmaclean
2017/01/17 18:23:27
I assume so ... we do see null widgets getting in
|
+ return WebEventListenerProperties::Nothing; |
+ return eventListenerProperties(widget->getLayerTreeView(), eventClass); |
+} |
+ |
+WebEventListenerProperties ChromeClientImpl::eventListenerProperties( |
dcheng
2017/01/16 11:05:40
Would it make sense to fold this into eventListene
wjmaclean
2017/01/17 18:23:28
Done.
|
+ WebLayerTreeView* treeView, |
+ WebEventListenerClass eventClass) const { |
+ if (treeView) |
return treeView->eventListenerProperties(eventClass); |
return WebEventListenerProperties::Nothing; |
} |
-void ChromeClientImpl::setHasScrollEventHandlers(bool hasEventHandlers) { |
- if (WebLayerTreeView* treeView = m_webView->layerTreeView()) |
- treeView->setHaveScrollEventHandlers(hasEventHandlers); |
-} |
+void ChromeClientImpl::setHasScrollEventHandlers(LocalFrame* frame, |
+ bool hasEventHandlers) { |
+ // |frame| might be null if called via TreeScopeAdopter:: |
+ // moveNodeToNewDocument() and the new document has no frame attached. |
+ // Since a document without a frame cannot attach one later, it is safe to |
+ // exit early. |
+ if (!frame) |
+ return; |
-bool ChromeClientImpl::hasScrollEventHandlers() const { |
- if (WebLayerTreeView* treeView = m_webView->layerTreeView()) |
- return treeView->haveScrollEventHandlers(); |
- return false; |
+ WebFrameWidgetBase* widget = |
+ WebLocalFrameImpl::fromFrame(frame)->localRoot()->frameWidget(); |
+ // While a frame is shutting down, we may get called after the layerTreeView |
+ // is gone: in this case we always expect |hasEventHandlers| to be false. |
+ DCHECK(!widget || widget->getLayerTreeView() || !hasEventHandlers); |
+ if (widget && widget->getLayerTreeView()) |
+ widget->getLayerTreeView()->setHaveScrollEventHandlers(hasEventHandlers); |
} |
void ChromeClientImpl::setTouchAction(TouchAction touchAction) { |