Chromium Code Reviews| 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 766f9169211e5dcb66bafc6528ede5c0be923265..5c48b87f70831a904c336745b24ff7990e785c83 100644 |
| --- a/content/browser/web_contents/web_contents_impl.cc |
| +++ b/content/browser/web_contents/web_contents_impl.cc |
| @@ -376,9 +376,10 @@ WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
| WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| // Remove child pointer from our parent. |
| if (outer_web_contents_) { |
| - ChildrenSet& child_ptrs_in_parent = |
| + ChildrenMap& child_ptrs_in_parent = |
| outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
| - ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); |
| + ChildrenMap::iterator iter = |
| + child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_); |
| DCHECK(iter != child_ptrs_in_parent.end()); |
| child_ptrs_in_parent.erase(iter); |
| } |
| @@ -387,11 +388,12 @@ WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| // TODO(lazyboy): We should destroy the children WebContentses too. If the |
| // children do not manage their own lifetime, then we would leak their |
| // WebContentses. |
| - for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) |
| - child->outer_web_contents_ = nullptr; |
| + for (auto child : inner_web_contents_tree_nodes_) |
| + child.second->node_->outer_web_contents_ = nullptr; |
| } |
| void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| + WebContentsImpl* web_contents, |
| WebContentsImpl* outer_web_contents, |
| RenderFrameHostImpl* outer_contents_frame) { |
| DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
| @@ -406,7 +408,9 @@ void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
| } |
| - outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); |
| + outer_web_contents_->node_ |
| + ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] = |
| + web_contents; |
| } |
| void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
| @@ -416,6 +420,14 @@ void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
| focused_web_contents_ = web_contents; |
| } |
| +WebContentsImpl* WebContentsImpl::WebContentsTreeNode::find_contents_at_node( |
| + int frame_tree_node_id) { |
| + auto iter = inner_web_contents_tree_nodes_.find(frame_tree_node_id); |
| + if (iter == inner_web_contents_tree_nodes_.end()) |
| + return nullptr; |
| + return iter->second; |
| +} |
| + |
| // WebContentsImpl ------------------------------------------------------------- |
| WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| @@ -1423,7 +1435,7 @@ void WebContentsImpl::AttachToOuterWebContentsFrame( |
| // Create a link to our outer WebContents. |
| node_.reset(new WebContentsTreeNode()); |
| node_->ConnectToOuterWebContents( |
| - static_cast<WebContentsImpl*>(outer_web_contents), |
| + this, static_cast<WebContentsImpl*>(outer_web_contents), |
| static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| DCHECK(outer_contents_frame); |
| @@ -1442,6 +1454,12 @@ void WebContentsImpl::AttachToOuterWebContentsFrame( |
| render_manager->GetRenderWidgetHostView()) |
| ->RegisterFrameSinkId(); |
| + // Set up the the guest's AX tree to point back at the embedder's AX tree. |
| + auto* parent_frame = outer_contents_frame->GetParent(); |
| + GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( |
| + parent_frame->GetAXTreeID()); |
| + GetMainFrame()->UpdateAXTreeData(); |
| + |
| // At this point, we should destroy the TextInputManager which will notify all |
| // the RWHV in this WebContents. The RWHV in this WebContents should use the |
| // TextInputManager owned by the outer WebContents. |
| @@ -4712,8 +4730,19 @@ void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() { |
| // Make sure the outer web contents knows our frame is focused. Otherwise, the |
| // outer renderer could have the element before or after the frame element |
| // focused which would return early without actually advancing focus. |
| - if (GetRenderManager()->GetProxyToOuterDelegate()) |
| - GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); |
| + WebContentsImpl* contents = this; |
| + while (contents && |
|
dmazzoni
2017/02/16 00:19:02
Maybe this could be a helper function, like
FindOu
avallee
2017/02/21 20:00:32
Done.
|
| + contents->GetOuterDelegateFrameTreeNodeId() != |
| + FrameTreeNode::kFrameTreeNodeInvalidId) { |
| + auto* outer_node = FrameTreeNode::GloballyFindByID( |
| + contents->GetOuterDelegateFrameTreeNodeId()); |
| + outer_node->frame_tree()->SetFocusedFrame(outer_node, nullptr); |
| + if (contents->GetRenderManager()->GetProxyToOuterDelegate()) |
| + contents->GetRenderManager() |
| + ->GetProxyToOuterDelegate() |
| + ->SetFocusedFrame(); |
| + contents = contents->GetOuterWebContents(); |
| + } |
| GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
| GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| @@ -4728,9 +4757,23 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| return; |
| } |
| - SetAsFocusedWebContentsIfNecessary(); |
| - |
| frame_tree_.SetFocusedFrame(node, source); |
| + |
| + WebContentsImpl* inner_contents = nullptr; |
| + if (node_) |
| + inner_contents = node_->find_contents_at_node(node->frame_tree_node_id()); |
| + |
| + WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; |
| + contents_to_focus->SetAsFocusedWebContentsIfNecessary(); |
| +} |
| + |
| +RenderFrameHost* WebContentsImpl::GetFrameAtNode(FrameTreeNode* tree_node) { |
| + if (!node_) |
| + return tree_node->current_frame_host(); |
| + |
| + auto* contents = |
| + node_->find_contents_at_node(tree_node->frame_tree_node_id()); |
| + return contents ? contents->GetMainFrame() : tree_node->current_frame_host(); |
| } |
| void WebContentsImpl::OnFocusedElementChangedInFrame( |