Chromium Code Reviews| 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* WebContentsImpl::WebContentsTreeNode::find_contents_at_node( | |
|
alexmos
2017/02/23 20:07:04
Name this FindContentsAtNode, since it's not a sim
avallee
2017/02/28 20:13:00
Done.
| |
| 428 int frame_tree_node_id) { | |
| 429 auto iter = inner_web_contents_tree_nodes_.find(frame_tree_node_id); | |
| 430 if (iter == inner_web_contents_tree_nodes_.end()) | |
| 431 return nullptr; | |
| 432 return iter->second; | |
| 433 } | |
| 434 | |
| 423 // WebContentsImpl ------------------------------------------------------------- | 435 // WebContentsImpl ------------------------------------------------------------- |
| 424 | 436 |
| 425 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 437 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| 426 : delegate_(NULL), | 438 : delegate_(NULL), |
| 427 controller_(this, browser_context), | 439 controller_(this, browser_context), |
| 428 render_view_host_delegate_view_(NULL), | 440 render_view_host_delegate_view_(NULL), |
| 429 created_with_opener_(false), | 441 created_with_opener_(false), |
| 430 frame_tree_(new NavigatorImpl(&controller_, this), | 442 frame_tree_(new NavigatorImpl(&controller_, this), |
| 431 this, | 443 this, |
| 432 this, | 444 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 | 1445 // before attaching. If the browser side is already initialized, the calls |
| 1434 // below will just early return. | 1446 // below will just early return. |
| 1435 render_manager->InitRenderView(GetRenderViewHost(), nullptr); | 1447 render_manager->InitRenderView(GetRenderViewHost(), nullptr); |
| 1436 GetMainFrame()->Init(); | 1448 GetMainFrame()->Init(); |
| 1437 if (!render_manager->GetRenderWidgetHostView()) | 1449 if (!render_manager->GetRenderWidgetHostView()) |
| 1438 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); | 1450 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); |
| 1439 | 1451 |
| 1440 // Create a link to our outer WebContents. | 1452 // Create a link to our outer WebContents. |
| 1441 node_.reset(new WebContentsTreeNode()); | 1453 node_.reset(new WebContentsTreeNode()); |
| 1442 node_->ConnectToOuterWebContents( | 1454 node_->ConnectToOuterWebContents( |
| 1443 static_cast<WebContentsImpl*>(outer_web_contents), | 1455 this, static_cast<WebContentsImpl*>(outer_web_contents), |
|
alexmos
2017/02/23 20:07:04
Maybe it would help if WebContentsTreeNode just kn
avallee
2017/02/28 20:13:01
My original iteration of the downward link did jus
| |
| 1444 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1456 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| 1445 | 1457 |
| 1446 DCHECK(outer_contents_frame); | 1458 DCHECK(outer_contents_frame); |
| 1447 | 1459 |
| 1448 // Create a proxy in top-level RenderFrameHostManager, pointing to the | 1460 // Create a proxy in top-level RenderFrameHostManager, pointing to the |
| 1449 // SiteInstance of the outer WebContents. The proxy will be used to send | 1461 // SiteInstance of the outer WebContents. The proxy will be used to send |
| 1450 // postMessage to the inner WebContents. | 1462 // postMessage to the inner WebContents. |
| 1451 render_manager->CreateOuterDelegateProxy( | 1463 render_manager->CreateOuterDelegateProxy( |
| 1452 outer_contents_frame->GetSiteInstance(), | 1464 outer_contents_frame->GetSiteInstance(), |
| 1453 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1465 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| 1454 | 1466 |
| 1455 render_manager->SetRWHViewForInnerContents( | 1467 render_manager->SetRWHViewForInnerContents( |
| 1456 render_manager->GetRenderWidgetHostView()); | 1468 render_manager->GetRenderWidgetHostView()); |
| 1457 | 1469 |
| 1458 static_cast<RenderWidgetHostViewChildFrame*>( | 1470 static_cast<RenderWidgetHostViewChildFrame*>( |
| 1459 render_manager->GetRenderWidgetHostView()) | 1471 render_manager->GetRenderWidgetHostView()) |
| 1460 ->RegisterFrameSinkId(); | 1472 ->RegisterFrameSinkId(); |
| 1461 | 1473 |
| 1474 // Set up the the guest's AX tree to point back at the embedder's AX tree. | |
| 1475 auto* parent_frame = outer_contents_frame->GetParent(); | |
| 1476 GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( | |
| 1477 parent_frame->GetAXTreeID()); | |
| 1478 GetMainFrame()->UpdateAXTreeData(); | |
| 1479 | |
| 1462 // At this point, we should destroy the TextInputManager which will notify all | 1480 // 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 | 1481 // the RWHV in this WebContents. The RWHV in this WebContents should use the |
| 1464 // TextInputManager owned by the outer WebContents. | 1482 // TextInputManager owned by the outer WebContents. |
| 1465 // TODO(ekaramad): Is it possible to have TextInputState before attaching to | 1483 // 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 | 1484 // 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 | 1485 // state tracking from inner WebContents's TextInputManager to that of the |
| 1468 // outer WebContent (crbug.com/609846)? | 1486 // outer WebContent (crbug.com/609846)? |
| 1469 text_input_manager_.reset(nullptr); | 1487 text_input_manager_.reset(nullptr); |
| 1470 } | 1488 } |
| 1471 | 1489 |
| (...skipping 2850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4322 return false; | 4340 return false; |
| 4323 } | 4341 } |
| 4324 | 4342 |
| 4325 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | 4343 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
| 4326 WebContentsImpl* root = this; | 4344 WebContentsImpl* root = this; |
| 4327 while (root->GetOuterWebContents()) | 4345 while (root->GetOuterWebContents()) |
| 4328 root = root->GetOuterWebContents(); | 4346 root = root->GetOuterWebContents(); |
| 4329 return root; | 4347 return root; |
| 4330 } | 4348 } |
| 4331 | 4349 |
| 4350 void WebContentsImpl::FocusOuterAttachmentFrameChain() { | |
| 4351 WebContentsImpl* outer_contents = GetOuterWebContents(); | |
| 4352 if (!outer_contents) | |
| 4353 return; | |
| 4354 | |
| 4355 FrameTreeNode* outer_node = | |
| 4356 FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); | |
| 4357 outer_contents->frame_tree_.SetFocusedFrame(outer_node, nullptr); | |
|
alexmos
2017/02/23 20:07:04
Can you please explain why this is now necessary?
avallee
2017/02/28 20:13:01
Maybe the site instance still needs to be passed a
alexmos
2017/03/03 20:07:57
Acknowledged.
Thinking about the source SiteIns
| |
| 4358 if (GetRenderManager()->GetProxyToOuterDelegate()) | |
| 4359 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
| 4360 | |
| 4361 outer_contents->FocusOuterAttachmentFrameChain(); | |
| 4362 } | |
| 4363 | |
| 4332 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4364 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
| 4333 // Don't send notifications if we are just creating a swapped-out RVH for | 4365 // Don't send notifications if we are just creating a swapped-out RVH for |
| 4334 // the opener chain. These won't be used for view-source or WebUI, so it's | 4366 // the opener chain. These won't be used for view-source or WebUI, so it's |
| 4335 // ok to return early. | 4367 // ok to return early. |
| 4336 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4368 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
| 4337 return; | 4369 return; |
| 4338 | 4370 |
| 4339 if (delegate_) | 4371 if (delegate_) |
| 4340 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4372 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4341 | 4373 |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4726 return; | 4758 return; |
| 4727 | 4759 |
| 4728 // Send a page level blur to the old contents so that it displays inactive UI | 4760 // Send a page level blur to the old contents so that it displays inactive UI |
| 4729 // and focus this contents to activate it. | 4761 // and focus this contents to activate it. |
| 4730 if (old_contents) | 4762 if (old_contents) |
| 4731 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); | 4763 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); |
| 4732 | 4764 |
| 4733 // Make sure the outer web contents knows our frame is focused. Otherwise, the | 4765 // Make sure the outer web contents knows our frame is focused. Otherwise, the |
| 4734 // outer renderer could have the element before or after the frame element | 4766 // outer renderer could have the element before or after the frame element |
| 4735 // focused which would return early without actually advancing focus. | 4767 // focused which would return early without actually advancing focus. |
| 4736 if (GetRenderManager()->GetProxyToOuterDelegate()) | 4768 FocusOuterAttachmentFrameChain(); |
| 4737 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
| 4738 | 4769 |
| 4739 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); | 4770 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
| 4740 GetOutermostWebContents()->node_->SetFocusedWebContents(this); | 4771 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| 4741 } | 4772 } |
| 4742 | 4773 |
| 4743 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, | 4774 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| 4744 SiteInstance* source) { | 4775 SiteInstance* source) { |
| 4745 // The PDF plugin still runs as a BrowserPlugin and must go through the | 4776 // The PDF plugin still runs as a BrowserPlugin and must go through the |
| 4746 // input redirection mechanism. It must not become focused direcly. | 4777 // input redirection mechanism. It must not become focused direcly. |
| 4747 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { | 4778 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { |
| 4748 frame_tree_.SetFocusedFrame(node, source); | 4779 frame_tree_.SetFocusedFrame(node, source); |
| 4749 return; | 4780 return; |
| 4750 } | 4781 } |
| 4751 | 4782 |
| 4752 SetAsFocusedWebContentsIfNecessary(); | 4783 frame_tree_.SetFocusedFrame(node, source); |
| 4753 | 4784 |
| 4754 frame_tree_.SetFocusedFrame(node, source); | 4785 WebContentsImpl* inner_contents = nullptr; |
| 4786 if (node_) | |
| 4787 inner_contents = node_->find_contents_at_node(node->frame_tree_node_id()); | |
| 4788 | |
| 4789 WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; | |
|
alexmos
2017/02/23 20:07:04
I'm a bit confused about this change also. See my
avallee
2017/02/28 20:13:00
If you clicked the webview before routing the inpu
alexmos
2017/03/03 20:07:57
Ack. I was confused that FocusOuterAttachmentFram
| |
| 4790 contents_to_focus->SetAsFocusedWebContentsIfNecessary(); | |
| 4791 } | |
| 4792 | |
| 4793 RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { | |
| 4794 if (!node_) | |
| 4795 return GetFocusedFrame(); | |
| 4796 | |
| 4797 auto* contents = this; | |
| 4798 auto* focused_node = contents->frame_tree_.GetFocusedFrame(); | |
|
alexmos
2017/02/23 20:07:04
nit: at least for me, an explicit type here instea
avallee
2017/02/28 20:13:00
Done.
| |
| 4799 | |
| 4800 // If there is no focused frame in the outer WebContents, we need to return | |
| 4801 // null. | |
| 4802 if (!focused_node) | |
| 4803 return nullptr; | |
| 4804 | |
| 4805 // We cannot return the frame where an inner WebContents is attached, if the | |
| 4806 // inner WebContents does not have a focused frame, return its main frame. | |
| 4807 while (true) { | |
| 4808 contents = contents->node_->find_contents_at_node( | |
| 4809 focused_node->frame_tree_node_id()); | |
|
alexmos
2017/02/23 20:07:04
Why not just pass in the FTN* and retrieve the FTN
avallee
2017/02/28 20:13:01
Done.
| |
| 4810 if (!contents) | |
| 4811 return focused_node->current_frame_host(); | |
| 4812 | |
| 4813 focused_node = contents->frame_tree_.GetFocusedFrame(); | |
| 4814 if (!focused_node) | |
| 4815 return contents->GetMainFrame(); | |
|
alexmos
2017/02/23 20:07:04
What makes this necessary? How can we get here in
avallee
2017/02/28 20:13:00
On attach or after reaching the end of content, th
alexmos
2017/03/03 20:07:57
Not quite sure what you meant by "after reaching t
avallee
2017/06/21 02:25:35
I think this will get called on attach, but as a r
| |
| 4816 } | |
| 4755 } | 4817 } |
| 4756 | 4818 |
| 4757 void WebContentsImpl::OnFocusedElementChangedInFrame( | 4819 void WebContentsImpl::OnFocusedElementChangedInFrame( |
| 4758 RenderFrameHostImpl* frame, | 4820 RenderFrameHostImpl* frame, |
| 4759 const gfx::Rect& bounds_in_root_view) { | 4821 const gfx::Rect& bounds_in_root_view) { |
| 4760 RenderWidgetHostViewBase* root_view = | 4822 RenderWidgetHostViewBase* root_view = |
| 4761 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); | 4823 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); |
| 4762 if (!root_view || !frame->GetView()) | 4824 if (!root_view || !frame->GetView()) |
| 4763 return; | 4825 return; |
| 4764 | 4826 |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5429 RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); | 5491 RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); |
| 5430 if (!render_view_host) | 5492 if (!render_view_host) |
| 5431 continue; | 5493 continue; |
| 5432 render_view_host_set.insert(render_view_host); | 5494 render_view_host_set.insert(render_view_host); |
| 5433 } | 5495 } |
| 5434 for (RenderViewHost* render_view_host : render_view_host_set) | 5496 for (RenderViewHost* render_view_host : render_view_host_set) |
| 5435 render_view_host->OnWebkitPreferencesChanged(); | 5497 render_view_host->OnWebkitPreferencesChanged(); |
| 5436 } | 5498 } |
| 5437 | 5499 |
| 5438 } // namespace content | 5500 } // namespace content |
| OLD | NEW |