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 40429d51814846c69671b3bce27a1af955e1452b..ae0aea05948f8aeb8951f9dc32fed5aae33d696f 100644 |
--- a/content/browser/web_contents/web_contents_impl.cc |
+++ b/content/browser/web_contents/web_contents_impl.cc |
@@ -1574,6 +1574,12 @@ void WebContentsImpl::AttachToOuterWebContentsFrame( |
SetFocusedFrame(frame_tree_.root(), nullptr); |
} |
+ // 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. |
@@ -4604,6 +4610,26 @@ WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
return root; |
} |
+void WebContentsImpl::FocusOuterAttachmentFrameChain() { |
+ WebContentsImpl* outer_contents = GetOuterWebContents(); |
+ if (!outer_contents) |
+ return; |
+ |
+ FrameTreeNode* outer_node = |
+ FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); |
+ outer_contents->frame_tree_.SetFocusedFrame(outer_node, nullptr); |
+ |
+ // For a browser initiated focus change, let embedding renderer know of the |
+ // change. Otherwise, if the currently focused element is just across a |
+ // process boundry in focus order, it will not be possible to move across that |
alexmos
2017/06/21 20:29:26
nit: s/boundry/boundary/
|
+ // boundary. This is because the target element will already be focused (that |
+ // renderer was not notified) and drop the event. |
+ if (GetRenderManager()->GetProxyToOuterDelegate()) |
+ GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); |
+ |
+ outer_contents->FocusOuterAttachmentFrameChain(); |
+} |
+ |
void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
// Don't send notifications if we are just creating a swapped-out RVH for |
// the opener chain. These won't be used for view-source or WebUI, so it's |
@@ -5014,8 +5040,7 @@ 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(); |
+ FocusOuterAttachmentFrameChain(); |
if (ShowingInterstitialPage()) { |
static_cast<RenderFrameHostImpl*>( |
@@ -5030,7 +5055,37 @@ void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() { |
void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
SiteInstance* source) { |
SetAsFocusedWebContentsIfNecessary(); |
+ |
frame_tree_.SetFocusedFrame(node, source); |
+ |
+ WebContentsImpl* inner_contents = node_.GetInnerWebContentsInFrame(node); |
+ |
+ WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; |
+ contents_to_focus->SetAsFocusedWebContentsIfNecessary(); |
+} |
+ |
+RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { |
+ WebContentsImpl* contents = this; |
+ FrameTreeNode* focused_node = contents->frame_tree_.GetFocusedFrame(); |
+ |
+ // If there is no focused frame in the outer WebContents, we need to return |
+ // null. |
+ if (!focused_node) |
+ return nullptr; |
+ |
+ // If the focused frame is embedding an inner WebContents, we must descend |
+ // into that contents. If the current WebContents does not have a focused |
+ // frame, return the main frame of this contents instead of the focused empty |
+ // frmae embedding this contents. |
alexmos
2017/06/21 20:29:26
nit: s/frmae/frame/
|
+ while (true) { |
+ contents = contents->node_.GetInnerWebContentsInFrame(focused_node); |
+ if (!contents) |
+ return focused_node->current_frame_host(); |
+ |
+ focused_node = contents->frame_tree_.GetFocusedFrame(); |
+ if (!focused_node) |
+ return contents->GetMainFrame(); |
+ } |
} |
void WebContentsImpl::OnFocusedElementChangedInFrame( |