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 |