Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3069)

Unified Diff: content/browser/web_contents/web_contents_impl.cc

Issue 2700613003: Enable find-in-page across GuestViews. (Closed)
Patch Set: Small fix. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/web_contents/web_contents_impl.cc
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2139e3b5fb0dba7690fa808139f557736d2082a4..0e6b4dd522240adf6e92b2d4030b1a2f2dc34167 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -257,6 +257,14 @@ class AXTreeSnapshotCombiner : public base::RefCounted<AXTreeSnapshotCombiner> {
AXTreeSnapshotCallback callback_;
};
+// Helper for GetInnerWebContents().
+bool GetInnerWebContentsHelper(
+ std::vector<WebContentsImpl*>* all_guest_contents,
+ WebContents* guest_contents) {
+ all_guest_contents->push_back(static_cast<WebContentsImpl*>(guest_contents));
+ return false;
+}
+
} // namespace
WebContents* WebContents::Create(const WebContents::CreateParams& params) {
@@ -381,6 +389,9 @@ WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode(
WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
if (OuterContentsFrameTreeNode())
OuterContentsFrameTreeNode()->RemoveObserver(this);
+
+ if (outer_web_contents_)
+ outer_web_contents_->node_.DetachInnerWebContents(current_web_contents_);
}
void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
@@ -391,9 +402,25 @@ void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
outer_contents_frame_tree_node_id_ =
outer_contents_frame->frame_tree_node()->frame_tree_node_id();
+ outer_web_contents_->node_.AttachInnerWebContents(current_web_contents_);
outer_contents_frame->frame_tree_node()->AddObserver(this);
}
+void WebContentsImpl::WebContentsTreeNode::AttachInnerWebContents(
+ WebContentsImpl* inner_web_contents) {
+ inner_web_contents_.push_back(inner_web_contents);
+}
+
+void WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents(
+ WebContentsImpl* inner_web_contents) {
+ DCHECK(std::find(inner_web_contents_.begin(), inner_web_contents_.end(),
+ inner_web_contents) != inner_web_contents_.end());
+ inner_web_contents_.erase(
+ std::remove(inner_web_contents_.begin(), inner_web_contents_.end(),
+ inner_web_contents),
+ inner_web_contents_.end());
+}
+
FrameTreeNode*
WebContentsImpl::WebContentsTreeNode::OuterContentsFrameTreeNode() const {
return FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id_);
@@ -414,6 +441,23 @@ void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents(
focused_web_contents_ = web_contents;
}
+WebContentsImpl*
+WebContentsImpl::WebContentsTreeNode::GetInnerWebContentsInFrame(
+ const FrameTreeNode* frame) {
+ auto ftn_id = frame->frame_tree_node_id();
+ for (WebContentsImpl* contents : inner_web_contents_) {
+ if (contents->node_.outer_contents_frame_tree_node_id() == ftn_id) {
+ return contents;
+ }
+ }
+ return nullptr;
+}
+
+const std::vector<WebContentsImpl*>&
+WebContentsImpl::WebContentsTreeNode::inner_web_contents() const {
+ return inner_web_contents_;
+}
+
// WebContentsImpl -------------------------------------------------------------
WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
@@ -664,7 +708,7 @@ std::vector<WebContentsImpl*> WebContentsImpl::GetAllWebContents() {
// static
WebContentsImpl* WebContentsImpl::FromFrameTreeNode(
- FrameTreeNode* frame_tree_node) {
+ const FrameTreeNode* frame_tree_node) {
return static_cast<WebContentsImpl*>(
WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host()));
}
@@ -681,6 +725,13 @@ WebContents* WebContentsImpl::FromRenderFrameHostID(int render_process_host_id,
return WebContents::FromRenderFrameHost(render_frame_host);
}
+// static
+WebContentsImpl* WebContentsImpl::FromOuterFrameTreeNode(
+ const FrameTreeNode* frame_tree_node) {
+ return WebContentsImpl::FromFrameTreeNode(frame_tree_node)
+ ->node_.GetInnerWebContentsInFrame(frame_tree_node);
+}
+
RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
return GetRenderManager();
}
@@ -1038,6 +1089,29 @@ WebContentsBindingSet* WebContentsImpl::GetBindingSet(
return it->second;
}
+std::vector<WebContentsImpl*> WebContentsImpl::GetInnerWebContents() {
+ if (browser_plugin_embedder_) {
+ std::vector<WebContentsImpl*> inner_contents;
+ GetBrowserContext()->GetGuestManager()->ForEachGuest(
+ this, base::Bind(&GetInnerWebContentsHelper, &inner_contents));
+ return inner_contents;
+ }
+
+ return node_.inner_web_contents();
+}
+
+std::vector<WebContentsImpl*> WebContentsImpl::GetWebContentsAndAllInner() {
+ std::vector<WebContentsImpl*> all_contents(1, this);
+
+ for (size_t i = 0; i != all_contents.size(); ++i) {
+ for (auto* inner_contents : all_contents[i]->GetInnerWebContents()) {
+ all_contents.push_back(inner_contents);
+ }
+ }
+
+ return all_contents;
+}
+
void WebContentsImpl::UpdateDeviceScaleFactor(double device_scale_factor) {
SendPageMessage(
new PageMsg_SetDeviceScaleFactor(MSG_ROUTING_NONE, device_scale_factor));
@@ -1851,8 +1925,16 @@ RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
return receiving_widget;
- FrameTreeNode* focused_frame =
- GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
+ // If the focused WebContents is a guest WebContents, then get the focused
+ // frame in the embedder WebContents instead.
+ FrameTreeNode* focused_frame = nullptr;
+ WebContentsImpl* focused_contents = GetFocusedWebContents();
+ if (focused_contents->browser_plugin_guest_ &&
+ !GuestMode::IsCrossProcessFrameGuest(focused_contents)) {
+ focused_frame = frame_tree_.GetFocusedFrame();
+ } else {
+ focused_frame = GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
+ }
if (!focused_frame)
return receiving_widget;
@@ -3278,25 +3360,12 @@ void WebContentsImpl::Find(int request_id,
return;
}
- // See if a top level browser plugin handles the find request first.
- // TODO(paulmeyer): Remove this after find-in-page works across GuestViews.
- if (browser_plugin_embedder_ &&
- browser_plugin_embedder_->Find(request_id, search_text, options)) {
- return;
- }
-
GetOrCreateFindRequestManager()->Find(request_id, search_text, options);
}
void WebContentsImpl::StopFinding(StopFindAction action) {
- // See if a top level browser plugin handles the stop finding request first.
- // TODO(paulmeyer): Remove this after find-in-page works across GuestViews.
- if (browser_plugin_embedder_ &&
- browser_plugin_embedder_->StopFinding(action)) {
- return;
- }
-
- GetOrCreateFindRequestManager()->StopFinding(action);
+ if (FindRequestManager* manager = GetFindRequestManager())
+ manager->StopFinding(action);
}
bool WebContentsImpl::WasRecentlyAudible() {
@@ -4771,6 +4840,8 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
// input redirection mechanism. It must not become focused direcly.
if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) {
frame_tree_.SetFocusedFrame(node, source);
+ if (GetFocusedWebContents() != this)
+ GetOutermostWebContents()->node_.SetFocusedWebContents(this);
return;
}
@@ -5218,12 +5289,34 @@ std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUI(
return nullptr;
}
+FindRequestManager* WebContentsImpl::GetFindRequestManager() {
+ for (WebContentsImpl* contents = this; contents;
+ contents = contents->GetOuterWebContents()) {
+ if (contents->find_request_manager_)
+ return contents->find_request_manager_.get();
+ }
+
+ return nullptr;
+}
+
FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() {
- // TODO(paulmeyer): This method will need to access (or potentially create)
- // the FindRequestManager in the outermost WebContents once find-in-page
- // across GuestViews is implemented.
- if (!find_request_manager_)
- find_request_manager_.reset(new FindRequestManager(this));
+ if (FindRequestManager* manager = GetFindRequestManager())
+ return manager;
+
+ // No existing FindRequestManager found, so one must be created.
+ find_request_manager_.reset(new FindRequestManager(this));
+
+ // Concurrent find sessions must not overlap, so destroy any existing
+ // FindRequestManagers in any inner WebContentses.
+ for (WebContentsImpl* contents : GetWebContentsAndAllInner()) {
+ if (contents == this)
+ continue;
+ if (contents->find_request_manager_) {
+ contents->find_request_manager_->StopFinding(
+ content::STOP_FIND_ACTION_CLEAR_SELECTION);
+ contents->find_request_manager_.release();
+ }
+ }
return find_request_manager_.get();
}
@@ -5275,6 +5368,12 @@ void WebContentsImpl::SetHasPersistentVideo(bool has_persistent_video) {
media_web_contents_observer()->RequestPersistentVideo(has_persistent_video);
}
+void WebContentsImpl::BrowserPluginGuestWillDestroy() {
+ WebContentsImpl* outermost = GetOutermostWebContents();
+ if (this != outermost && ContainsOrIsFocusedWebContents())
+ outermost->SetAsFocusedWebContentsIfNecessary();
+}
+
#if defined(OS_ANDROID)
void WebContentsImpl::NotifyFindMatchRectsReply(
int version,
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/public/browser/browser_plugin_guest_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698