OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/web_contents/web_contents_impl.h" | 5 #include "content/browser/web_contents/web_contents_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <utility> | 10 #include <utility> |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 373 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
374 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 374 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
375 : outer_web_contents_(nullptr), | 375 : outer_web_contents_(nullptr), |
376 outer_contents_frame_tree_node_id_( | 376 outer_contents_frame_tree_node_id_( |
377 FrameTreeNode::kFrameTreeNodeInvalidId), | 377 FrameTreeNode::kFrameTreeNodeInvalidId), |
378 focused_web_contents_(nullptr) {} | 378 focused_web_contents_(nullptr) {} |
379 | 379 |
380 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 380 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
381 // Remove child pointer from our parent. | 381 // Remove child pointer from our parent. |
382 if (outer_web_contents_) { | 382 if (outer_web_contents_) { |
383 ChildrenSet& child_ptrs_in_parent = | 383 ChildrenMap& child_ptrs_in_parent = |
384 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 384 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
385 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 385 ChildrenMap::iterator iter = |
386 child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_); | |
386 DCHECK(iter != child_ptrs_in_parent.end()); | 387 DCHECK(iter != child_ptrs_in_parent.end()); |
387 child_ptrs_in_parent.erase(iter); | 388 child_ptrs_in_parent.erase(iter); |
388 } | 389 } |
389 | 390 |
390 // Remove parent pointers from our children. | 391 // Remove parent pointers from our children. |
391 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 392 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
392 // children do not manage their own lifetime, then we would leak their | 393 // children do not manage their own lifetime, then we would leak their |
393 // WebContentses. | 394 // WebContentses. |
394 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 395 for (auto child : inner_web_contents_tree_nodes_) |
395 child->outer_web_contents_ = nullptr; | 396 child.second->node_->outer_web_contents_ = nullptr; |
396 } | 397 } |
397 | 398 |
398 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 399 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
400 WebContentsImpl* web_contents, | |
399 WebContentsImpl* outer_web_contents, | 401 WebContentsImpl* outer_web_contents, |
400 RenderFrameHostImpl* outer_contents_frame) { | 402 RenderFrameHostImpl* outer_contents_frame) { |
401 DCHECK(!focused_web_contents_) << "Should not attach a root node."; | 403 DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
402 outer_web_contents_ = outer_web_contents; | 404 outer_web_contents_ = outer_web_contents; |
403 outer_contents_frame_tree_node_id_ = | 405 outer_contents_frame_tree_node_id_ = |
404 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 406 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
405 | 407 |
406 if (!outer_web_contents_->node_) { | 408 if (!outer_web_contents_->node_) { |
407 // This will only be reached when creating a new WebContents tree. | 409 // This will only be reached when creating a new WebContents tree. |
408 // Initialize the root of this tree and set it as focused. | 410 // Initialize the root of this tree and set it as focused. |
409 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 411 outer_web_contents_->node_.reset(new WebContentsTreeNode()); |
410 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); | 412 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
411 } | 413 } |
412 | 414 |
413 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 415 outer_web_contents_->node_ |
416 ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] = | |
417 web_contents; | |
414 } | 418 } |
415 | 419 |
416 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( | 420 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
417 WebContentsImpl* web_contents) { | 421 WebContentsImpl* web_contents) { |
418 DCHECK(!outer_web_contents()) | 422 DCHECK(!outer_web_contents()) |
419 << "Only the outermost WebContents tracks focus."; | 423 << "Only the outermost WebContents tracks focus."; |
420 focused_web_contents_ = web_contents; | 424 focused_web_contents_ = web_contents; |
421 } | 425 } |
422 | 426 |
427 WebContentsImpl* | |
428 WebContentsImpl::WebContentsTreeNode::FindInnerWebContentsAtNode( | |
429 FrameTreeNode* node) { | |
430 int frame_tree_node_id = node->frame_tree_node_id(); | |
431 auto iter = inner_web_contents_tree_nodes_.find(frame_tree_node_id); | |
alexmos
2017/03/03 20:07:57
nit: might as well just use "node->frame_tree_node
avallee
2017/06/21 02:25:35
This is gone after rebase.
| |
432 if (iter == inner_web_contents_tree_nodes_.end()) | |
433 return nullptr; | |
434 return iter->second; | |
435 } | |
436 | |
423 // WebContentsImpl ------------------------------------------------------------- | 437 // WebContentsImpl ------------------------------------------------------------- |
424 | 438 |
425 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 439 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
426 : delegate_(NULL), | 440 : delegate_(NULL), |
427 controller_(this, browser_context), | 441 controller_(this, browser_context), |
428 render_view_host_delegate_view_(NULL), | 442 render_view_host_delegate_view_(NULL), |
429 created_with_opener_(false), | 443 created_with_opener_(false), |
430 frame_tree_(new NavigatorImpl(&controller_, this), | 444 frame_tree_(new NavigatorImpl(&controller_, this), |
431 this, | 445 this, |
432 this, | 446 this, |
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1433 // before attaching. If the browser side is already initialized, the calls | 1447 // before attaching. If the browser side is already initialized, the calls |
1434 // below will just early return. | 1448 // below will just early return. |
1435 render_manager->InitRenderView(GetRenderViewHost(), nullptr); | 1449 render_manager->InitRenderView(GetRenderViewHost(), nullptr); |
1436 GetMainFrame()->Init(); | 1450 GetMainFrame()->Init(); |
1437 if (!render_manager->GetRenderWidgetHostView()) | 1451 if (!render_manager->GetRenderWidgetHostView()) |
1438 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); | 1452 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); |
1439 | 1453 |
1440 // Create a link to our outer WebContents. | 1454 // Create a link to our outer WebContents. |
1441 node_.reset(new WebContentsTreeNode()); | 1455 node_.reset(new WebContentsTreeNode()); |
1442 node_->ConnectToOuterWebContents( | 1456 node_->ConnectToOuterWebContents( |
1443 static_cast<WebContentsImpl*>(outer_web_contents), | 1457 this, static_cast<WebContentsImpl*>(outer_web_contents), |
1444 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1458 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
1445 | 1459 |
1446 DCHECK(outer_contents_frame); | 1460 DCHECK(outer_contents_frame); |
1447 | 1461 |
1448 // Create a proxy in top-level RenderFrameHostManager, pointing to the | 1462 // Create a proxy in top-level RenderFrameHostManager, pointing to the |
1449 // SiteInstance of the outer WebContents. The proxy will be used to send | 1463 // SiteInstance of the outer WebContents. The proxy will be used to send |
1450 // postMessage to the inner WebContents. | 1464 // postMessage to the inner WebContents. |
1451 render_manager->CreateOuterDelegateProxy( | 1465 render_manager->CreateOuterDelegateProxy( |
1452 outer_contents_frame->GetSiteInstance(), | 1466 outer_contents_frame->GetSiteInstance(), |
1453 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1467 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
1454 | 1468 |
1455 render_manager->SetRWHViewForInnerContents( | 1469 render_manager->SetRWHViewForInnerContents( |
1456 render_manager->GetRenderWidgetHostView()); | 1470 render_manager->GetRenderWidgetHostView()); |
1457 | 1471 |
1458 static_cast<RenderWidgetHostViewChildFrame*>( | 1472 static_cast<RenderWidgetHostViewChildFrame*>( |
1459 render_manager->GetRenderWidgetHostView()) | 1473 render_manager->GetRenderWidgetHostView()) |
1460 ->RegisterFrameSinkId(); | 1474 ->RegisterFrameSinkId(); |
1461 | 1475 |
1476 // Set up the the guest's AX tree to point back at the embedder's AX tree. | |
1477 auto* parent_frame = outer_contents_frame->GetParent(); | |
1478 GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( | |
1479 parent_frame->GetAXTreeID()); | |
1480 GetMainFrame()->UpdateAXTreeData(); | |
1481 | |
1462 // At this point, we should destroy the TextInputManager which will notify all | 1482 // At this point, we should destroy the TextInputManager which will notify all |
1463 // the RWHV in this WebContents. The RWHV in this WebContents should use the | 1483 // the RWHV in this WebContents. The RWHV in this WebContents should use the |
1464 // TextInputManager owned by the outer WebContents. | 1484 // TextInputManager owned by the outer WebContents. |
1465 // TODO(ekaramad): Is it possible to have TextInputState before attaching to | 1485 // TODO(ekaramad): Is it possible to have TextInputState before attaching to |
1466 // outer WebContents? In such a case, is this still the right way to hand off | 1486 // outer WebContents? In such a case, is this still the right way to hand off |
1467 // state tracking from inner WebContents's TextInputManager to that of the | 1487 // state tracking from inner WebContents's TextInputManager to that of the |
1468 // outer WebContent (crbug.com/609846)? | 1488 // outer WebContent (crbug.com/609846)? |
1469 text_input_manager_.reset(nullptr); | 1489 text_input_manager_.reset(nullptr); |
1470 } | 1490 } |
1471 | 1491 |
(...skipping 2849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4321 return false; | 4341 return false; |
4322 } | 4342 } |
4323 | 4343 |
4324 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | 4344 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
4325 WebContentsImpl* root = this; | 4345 WebContentsImpl* root = this; |
4326 while (root->GetOuterWebContents()) | 4346 while (root->GetOuterWebContents()) |
4327 root = root->GetOuterWebContents(); | 4347 root = root->GetOuterWebContents(); |
4328 return root; | 4348 return root; |
4329 } | 4349 } |
4330 | 4350 |
4351 void WebContentsImpl::FocusOuterAttachmentFrameChain() { | |
4352 WebContentsImpl* outer_contents = GetOuterWebContents(); | |
4353 if (!outer_contents) | |
4354 return; | |
4355 | |
4356 FrameTreeNode* outer_node = | |
4357 FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); | |
4358 outer_contents->frame_tree_.SetFocusedFrame(outer_node, nullptr); | |
4359 | |
4360 // For browser initiated focus change, let embedding renderer know of the | |
4361 // change. In tab navigation can become trapped in the inner contents without | |
alexmos
2017/03/03 20:07:57
By "In tab navigation" do you just mean "Tab navig
avallee
2017/06/21 02:25:35
Clarified comment.
| |
4362 // this. | |
4363 if (GetRenderManager()->GetProxyToOuterDelegate()) | |
4364 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
4365 | |
4366 outer_contents->FocusOuterAttachmentFrameChain(); | |
4367 } | |
4368 | |
4331 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4369 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
4332 // Don't send notifications if we are just creating a swapped-out RVH for | 4370 // Don't send notifications if we are just creating a swapped-out RVH for |
4333 // the opener chain. These won't be used for view-source or WebUI, so it's | 4371 // the opener chain. These won't be used for view-source or WebUI, so it's |
4334 // ok to return early. | 4372 // ok to return early. |
4335 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4373 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
4336 return; | 4374 return; |
4337 | 4375 |
4338 if (delegate_) | 4376 if (delegate_) |
4339 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4377 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
4340 | 4378 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4725 return; | 4763 return; |
4726 | 4764 |
4727 // Send a page level blur to the old contents so that it displays inactive UI | 4765 // Send a page level blur to the old contents so that it displays inactive UI |
4728 // and focus this contents to activate it. | 4766 // and focus this contents to activate it. |
4729 if (old_contents) | 4767 if (old_contents) |
4730 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); | 4768 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); |
4731 | 4769 |
4732 // Make sure the outer web contents knows our frame is focused. Otherwise, the | 4770 // Make sure the outer web contents knows our frame is focused. Otherwise, the |
4733 // outer renderer could have the element before or after the frame element | 4771 // outer renderer could have the element before or after the frame element |
4734 // focused which would return early without actually advancing focus. | 4772 // focused which would return early without actually advancing focus. |
4735 if (GetRenderManager()->GetProxyToOuterDelegate()) | 4773 FocusOuterAttachmentFrameChain(); |
4736 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
4737 | 4774 |
4738 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); | 4775 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
4739 GetOutermostWebContents()->node_->SetFocusedWebContents(this); | 4776 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
4740 } | 4777 } |
4741 | 4778 |
4742 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, | 4779 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
4743 SiteInstance* source) { | 4780 SiteInstance* source) { |
4744 // The PDF plugin still runs as a BrowserPlugin and must go through the | 4781 // The PDF plugin still runs as a BrowserPlugin and must go through the |
4745 // input redirection mechanism. It must not become focused direcly. | 4782 // input redirection mechanism. It must not become focused direcly. |
4746 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { | 4783 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { |
4747 frame_tree_.SetFocusedFrame(node, source); | 4784 frame_tree_.SetFocusedFrame(node, source); |
4748 return; | 4785 return; |
4749 } | 4786 } |
4750 | 4787 |
4751 SetAsFocusedWebContentsIfNecessary(); | 4788 frame_tree_.SetFocusedFrame(node, source); |
4752 | 4789 |
4753 frame_tree_.SetFocusedFrame(node, source); | 4790 WebContentsImpl* inner_contents = nullptr; |
4791 if (node_) | |
4792 inner_contents = node_->FindInnerWebContentsAtNode(node); | |
4793 | |
4794 WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; | |
4795 contents_to_focus->SetAsFocusedWebContentsIfNecessary(); | |
4796 } | |
4797 | |
4798 RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { | |
4799 if (!node_) | |
4800 return GetFocusedFrame(); | |
4801 | |
4802 WebContentsImpl* contents = this; | |
4803 FrameTreeNode* focused_node = contents->frame_tree_.GetFocusedFrame(); | |
4804 | |
4805 // If there is no focused frame in the outer WebContents, we need to return | |
4806 // null. | |
4807 if (!focused_node) | |
4808 return nullptr; | |
4809 | |
4810 // We cannot return the frame where an inner WebContents is attached, if the | |
alexmos
2017/03/03 20:07:57
I think this is talking about two different things
avallee
2017/06/21 02:25:35
rephrased.
| |
4811 // inner WebContents does not have a focused frame, return its main frame. | |
4812 while (true) { | |
4813 contents = contents->node_->FindInnerWebContentsAtNode(focused_node); | |
4814 if (!contents) | |
4815 return focused_node->current_frame_host(); | |
4816 | |
4817 focused_node = contents->frame_tree_.GetFocusedFrame(); | |
4818 if (!focused_node) | |
4819 return contents->GetMainFrame(); | |
4820 } | |
4754 } | 4821 } |
4755 | 4822 |
4756 void WebContentsImpl::OnFocusedElementChangedInFrame( | 4823 void WebContentsImpl::OnFocusedElementChangedInFrame( |
4757 RenderFrameHostImpl* frame, | 4824 RenderFrameHostImpl* frame, |
4758 const gfx::Rect& bounds_in_root_view) { | 4825 const gfx::Rect& bounds_in_root_view) { |
4759 RenderWidgetHostViewBase* root_view = | 4826 RenderWidgetHostViewBase* root_view = |
4760 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); | 4827 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); |
4761 if (!root_view || !frame->GetView()) | 4828 if (!root_view || !frame->GetView()) |
4762 return; | 4829 return; |
4763 | 4830 |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5428 RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); | 5495 RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); |
5429 if (!render_view_host) | 5496 if (!render_view_host) |
5430 continue; | 5497 continue; |
5431 render_view_host_set.insert(render_view_host); | 5498 render_view_host_set.insert(render_view_host); |
5432 } | 5499 } |
5433 for (RenderViewHost* render_view_host : render_view_host_set) | 5500 for (RenderViewHost* render_view_host : render_view_host_set) |
5434 render_view_host->OnWebkitPreferencesChanged(); | 5501 render_view_host->OnWebkitPreferencesChanged(); |
5435 } | 5502 } |
5436 | 5503 |
5437 } // namespace content | 5504 } // namespace content |
OLD | NEW |