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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 369 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
| 370 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 370 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
| 371 : outer_web_contents_(nullptr), | 371 : outer_web_contents_(nullptr), |
| 372 outer_contents_frame_tree_node_id_( | 372 outer_contents_frame_tree_node_id_( |
| 373 FrameTreeNode::kFrameTreeNodeInvalidId), | 373 FrameTreeNode::kFrameTreeNodeInvalidId), |
| 374 focused_web_contents_(nullptr) {} | 374 focused_web_contents_(nullptr) {} |
| 375 | 375 |
| 376 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 376 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| 377 // Remove child pointer from our parent. | 377 // Remove child pointer from our parent. |
| 378 if (outer_web_contents_) { | 378 if (outer_web_contents_) { |
| 379 ChildrenSet& child_ptrs_in_parent = | 379 ChildrenMap& child_ptrs_in_parent = |
| 380 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 380 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
| 381 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 381 ChildrenMap::iterator iter = |
| 382 child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_); | |
| 382 DCHECK(iter != child_ptrs_in_parent.end()); | 383 DCHECK(iter != child_ptrs_in_parent.end()); |
| 383 child_ptrs_in_parent.erase(iter); | 384 child_ptrs_in_parent.erase(iter); |
| 384 } | 385 } |
| 385 | 386 |
| 386 // Remove parent pointers from our children. | 387 // Remove parent pointers from our children. |
| 387 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 388 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
| 388 // children do not manage their own lifetime, then we would leak their | 389 // children do not manage their own lifetime, then we would leak their |
| 389 // WebContentses. | 390 // WebContentses. |
| 390 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 391 for (auto child : inner_web_contents_tree_nodes_) |
| 391 child->outer_web_contents_ = nullptr; | 392 child.second->node_->outer_web_contents_ = nullptr; |
| 392 } | 393 } |
| 393 | 394 |
| 394 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 395 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| 396 WebContentsImpl* web_contents, | |
| 395 WebContentsImpl* outer_web_contents, | 397 WebContentsImpl* outer_web_contents, |
| 396 RenderFrameHostImpl* outer_contents_frame) { | 398 RenderFrameHostImpl* outer_contents_frame) { |
| 397 DCHECK(!focused_web_contents_) << "Should not attach a root node."; | 399 DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
| 398 outer_web_contents_ = outer_web_contents; | 400 outer_web_contents_ = outer_web_contents; |
| 399 outer_contents_frame_tree_node_id_ = | 401 outer_contents_frame_tree_node_id_ = |
| 400 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 402 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
| 401 | 403 |
| 402 if (!outer_web_contents_->node_) { | 404 if (!outer_web_contents_->node_) { |
| 403 // This will only be reached when creating a new WebContents tree. | 405 // This will only be reached when creating a new WebContents tree. |
| 404 // Initialize the root of this tree and set it as focused. | 406 // Initialize the root of this tree and set it as focused. |
| 405 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 407 outer_web_contents_->node_.reset(new WebContentsTreeNode()); |
| 406 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); | 408 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
| 407 } | 409 } |
| 408 | 410 |
| 409 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 411 outer_web_contents_->node_ |
| 412 ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] = | |
| 413 web_contents; | |
| 410 } | 414 } |
| 411 | 415 |
| 412 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( | 416 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
| 413 WebContentsImpl* web_contents) { | 417 WebContentsImpl* web_contents) { |
| 414 DCHECK(!outer_web_contents()) | 418 DCHECK(!outer_web_contents()) |
| 415 << "Only the outermost WebContents tracks focus."; | 419 << "Only the outermost WebContents tracks focus."; |
| 416 focused_web_contents_ = web_contents; | 420 focused_web_contents_ = web_contents; |
| 417 } | 421 } |
| 418 | 422 |
| 423 WebContentsImpl* WebContentsImpl::WebContentsTreeNode::find_contents_at_node( | |
| 424 int frame_tree_node_id) { | |
| 425 auto iter = inner_web_contents_tree_nodes_.find(frame_tree_node_id); | |
| 426 if (iter == inner_web_contents_tree_nodes_.end()) | |
| 427 return nullptr; | |
| 428 return iter->second; | |
| 429 } | |
| 430 | |
| 419 // WebContentsImpl ------------------------------------------------------------- | 431 // WebContentsImpl ------------------------------------------------------------- |
| 420 | 432 |
| 421 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 433 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| 422 : delegate_(NULL), | 434 : delegate_(NULL), |
| 423 controller_(this, browser_context), | 435 controller_(this, browser_context), |
| 424 render_view_host_delegate_view_(NULL), | 436 render_view_host_delegate_view_(NULL), |
| 425 created_with_opener_(false), | 437 created_with_opener_(false), |
| 426 frame_tree_(new NavigatorImpl(&controller_, this), | 438 frame_tree_(new NavigatorImpl(&controller_, this), |
| 427 this, | 439 this, |
| 428 this, | 440 this, |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1416 // before attaching. If the browser side is already initialized, the calls | 1428 // before attaching. If the browser side is already initialized, the calls |
| 1417 // below will just early return. | 1429 // below will just early return. |
| 1418 render_manager->InitRenderView(GetRenderViewHost(), nullptr); | 1430 render_manager->InitRenderView(GetRenderViewHost(), nullptr); |
| 1419 GetMainFrame()->Init(); | 1431 GetMainFrame()->Init(); |
| 1420 if (!render_manager->GetRenderWidgetHostView()) | 1432 if (!render_manager->GetRenderWidgetHostView()) |
| 1421 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); | 1433 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); |
| 1422 | 1434 |
| 1423 // Create a link to our outer WebContents. | 1435 // Create a link to our outer WebContents. |
| 1424 node_.reset(new WebContentsTreeNode()); | 1436 node_.reset(new WebContentsTreeNode()); |
| 1425 node_->ConnectToOuterWebContents( | 1437 node_->ConnectToOuterWebContents( |
| 1426 static_cast<WebContentsImpl*>(outer_web_contents), | 1438 this, static_cast<WebContentsImpl*>(outer_web_contents), |
| 1427 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1439 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| 1428 | 1440 |
| 1429 DCHECK(outer_contents_frame); | 1441 DCHECK(outer_contents_frame); |
| 1430 | 1442 |
| 1431 // Create a proxy in top-level RenderFrameHostManager, pointing to the | 1443 // Create a proxy in top-level RenderFrameHostManager, pointing to the |
| 1432 // SiteInstance of the outer WebContents. The proxy will be used to send | 1444 // SiteInstance of the outer WebContents. The proxy will be used to send |
| 1433 // postMessage to the inner WebContents. | 1445 // postMessage to the inner WebContents. |
| 1434 render_manager->CreateOuterDelegateProxy( | 1446 render_manager->CreateOuterDelegateProxy( |
| 1435 outer_contents_frame->GetSiteInstance(), | 1447 outer_contents_frame->GetSiteInstance(), |
| 1436 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1448 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| 1437 | 1449 |
| 1438 render_manager->SetRWHViewForInnerContents( | 1450 render_manager->SetRWHViewForInnerContents( |
| 1439 render_manager->GetRenderWidgetHostView()); | 1451 render_manager->GetRenderWidgetHostView()); |
| 1440 | 1452 |
| 1441 static_cast<RenderWidgetHostViewChildFrame*>( | 1453 static_cast<RenderWidgetHostViewChildFrame*>( |
| 1442 render_manager->GetRenderWidgetHostView()) | 1454 render_manager->GetRenderWidgetHostView()) |
| 1443 ->RegisterFrameSinkId(); | 1455 ->RegisterFrameSinkId(); |
| 1444 | 1456 |
| 1457 // Set up the the guest's AX tree to point back at the embedder's AX tree. | |
| 1458 auto* parent_frame = outer_contents_frame->GetParent(); | |
| 1459 GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( | |
| 1460 parent_frame->GetAXTreeID()); | |
| 1461 GetMainFrame()->UpdateAXTreeData(); | |
| 1462 | |
| 1445 // At this point, we should destroy the TextInputManager which will notify all | 1463 // At this point, we should destroy the TextInputManager which will notify all |
| 1446 // the RWHV in this WebContents. The RWHV in this WebContents should use the | 1464 // the RWHV in this WebContents. The RWHV in this WebContents should use the |
| 1447 // TextInputManager owned by the outer WebContents. | 1465 // TextInputManager owned by the outer WebContents. |
| 1448 // TODO(ekaramad): Is it possible to have TextInputState before attaching to | 1466 // TODO(ekaramad): Is it possible to have TextInputState before attaching to |
| 1449 // outer WebContents? In such a case, is this still the right way to hand off | 1467 // outer WebContents? In such a case, is this still the right way to hand off |
| 1450 // state tracking from inner WebContents's TextInputManager to that of the | 1468 // state tracking from inner WebContents's TextInputManager to that of the |
| 1451 // outer WebContent (crbug.com/609846)? | 1469 // outer WebContent (crbug.com/609846)? |
| 1452 text_input_manager_.reset(nullptr); | 1470 text_input_manager_.reset(nullptr); |
| 1453 } | 1471 } |
| 1454 | 1472 |
| (...skipping 2850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4305 return false; | 4323 return false; |
| 4306 } | 4324 } |
| 4307 | 4325 |
| 4308 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | 4326 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
| 4309 WebContentsImpl* root = this; | 4327 WebContentsImpl* root = this; |
| 4310 while (root->GetOuterWebContents()) | 4328 while (root->GetOuterWebContents()) |
| 4311 root = root->GetOuterWebContents(); | 4329 root = root->GetOuterWebContents(); |
| 4312 return root; | 4330 return root; |
| 4313 } | 4331 } |
| 4314 | 4332 |
| 4333 void WebContentsImpl::FocusOuterAttachmentFrameChain() { | |
| 4334 WebContentsImpl* outer_contents = GetOuterWebContents(); | |
| 4335 if (!outer_contents) | |
| 4336 return; | |
| 4337 | |
| 4338 FrameTreeNode* outer_node = | |
| 4339 FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); | |
| 4340 outer_contents->frame_tree_.SetFocusedFrame(outer_node, nullptr); | |
| 4341 if(GetRenderManager()->GetProxyToOuterDelegate()) | |
|
dmazzoni
2017/02/22 08:46:41
nit: space before first (
avallee
2017/02/22 16:58:49
Done.
| |
| 4342 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
| 4343 | |
| 4344 outer_contents->FocusOuterAttachmentFrameChain(); | |
| 4345 } | |
| 4346 | |
| 4315 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4347 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
| 4316 // Don't send notifications if we are just creating a swapped-out RVH for | 4348 // Don't send notifications if we are just creating a swapped-out RVH for |
| 4317 // the opener chain. These won't be used for view-source or WebUI, so it's | 4349 // the opener chain. These won't be used for view-source or WebUI, so it's |
| 4318 // ok to return early. | 4350 // ok to return early. |
| 4319 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4351 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
| 4320 return; | 4352 return; |
| 4321 | 4353 |
| 4322 if (delegate_) | 4354 if (delegate_) |
| 4323 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4355 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4324 | 4356 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4705 return; | 4737 return; |
| 4706 | 4738 |
| 4707 // Send a page level blur to the old contents so that it displays inactive UI | 4739 // Send a page level blur to the old contents so that it displays inactive UI |
| 4708 // and focus this contents to activate it. | 4740 // and focus this contents to activate it. |
| 4709 if (old_contents) | 4741 if (old_contents) |
| 4710 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); | 4742 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); |
| 4711 | 4743 |
| 4712 // Make sure the outer web contents knows our frame is focused. Otherwise, the | 4744 // Make sure the outer web contents knows our frame is focused. Otherwise, the |
| 4713 // outer renderer could have the element before or after the frame element | 4745 // outer renderer could have the element before or after the frame element |
| 4714 // focused which would return early without actually advancing focus. | 4746 // focused which would return early without actually advancing focus. |
| 4715 if (GetRenderManager()->GetProxyToOuterDelegate()) | 4747 FocusOuterAttachmentFrameChain(); |
| 4716 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
| 4717 | 4748 |
| 4718 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); | 4749 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
| 4719 GetOutermostWebContents()->node_->SetFocusedWebContents(this); | 4750 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| 4720 } | 4751 } |
| 4721 | 4752 |
| 4722 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, | 4753 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| 4723 SiteInstance* source) { | 4754 SiteInstance* source) { |
| 4724 // The PDF plugin still runs as a BrowserPlugin and must go through the | 4755 // The PDF plugin still runs as a BrowserPlugin and must go through the |
| 4725 // input redirection mechanism. It must not become focused direcly. | 4756 // input redirection mechanism. It must not become focused direcly. |
| 4726 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { | 4757 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { |
| 4727 frame_tree_.SetFocusedFrame(node, source); | 4758 frame_tree_.SetFocusedFrame(node, source); |
| 4728 return; | 4759 return; |
| 4729 } | 4760 } |
| 4730 | 4761 |
| 4731 SetAsFocusedWebContentsIfNecessary(); | 4762 frame_tree_.SetFocusedFrame(node, source); |
| 4732 | 4763 |
| 4733 frame_tree_.SetFocusedFrame(node, source); | 4764 WebContentsImpl* inner_contents = nullptr; |
| 4765 if (node_) | |
| 4766 inner_contents = node_->find_contents_at_node(node->frame_tree_node_id()); | |
| 4767 | |
| 4768 WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; | |
| 4769 contents_to_focus->SetAsFocusedWebContentsIfNecessary(); | |
| 4770 } | |
| 4771 | |
| 4772 RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { | |
| 4773 if (!node_) | |
| 4774 return GetFocusedFrame(); | |
| 4775 | |
| 4776 auto* contents = this; | |
| 4777 auto* focused_node = contents->frame_tree_.GetFocusedFrame(); | |
| 4778 | |
| 4779 // If there is no focused frame in the outer WebContents, we need to return | |
| 4780 // null. | |
| 4781 if (!focused_node) | |
| 4782 return nullptr; | |
| 4783 | |
| 4784 // We cannot return the frame where an inner WebContents is attached, if the | |
| 4785 // inner WebContents does not have a focused frame, return its main frame. | |
| 4786 while(true) { | |
|
dmazzoni
2017/02/22 08:46:41
nit: space before (
avallee
2017/02/22 16:58:49
Done.
| |
| 4787 contents = contents->node_->find_contents_at_node( | |
| 4788 focused_node->frame_tree_node_id()); | |
| 4789 if (!contents) | |
| 4790 return focused_node->current_frame_host(); | |
| 4791 | |
| 4792 focused_node = contents->frame_tree_.GetFocusedFrame(); | |
| 4793 if (!focused_node) | |
| 4794 return contents->GetMainFrame(); | |
| 4795 } | |
| 4734 } | 4796 } |
| 4735 | 4797 |
| 4736 void WebContentsImpl::OnFocusedElementChangedInFrame( | 4798 void WebContentsImpl::OnFocusedElementChangedInFrame( |
| 4737 RenderFrameHostImpl* frame, | 4799 RenderFrameHostImpl* frame, |
| 4738 const gfx::Rect& bounds_in_root_view) { | 4800 const gfx::Rect& bounds_in_root_view) { |
| 4739 RenderWidgetHostViewBase* root_view = | 4801 RenderWidgetHostViewBase* root_view = |
| 4740 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); | 4802 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); |
| 4741 if (!root_view || !frame->GetView()) | 4803 if (!root_view || !frame->GetView()) |
| 4742 return; | 4804 return; |
| 4743 | 4805 |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5396 GetMainFrame()->AddMessageToConsole( | 5458 GetMainFrame()->AddMessageToConsole( |
| 5397 content::CONSOLE_MESSAGE_LEVEL_WARNING, | 5459 content::CONSOLE_MESSAGE_LEVEL_WARNING, |
| 5398 base::StringPrintf("This site does not have a valid SSL " | 5460 base::StringPrintf("This site does not have a valid SSL " |
| 5399 "certificate! Without SSL, your site's and " | 5461 "certificate! Without SSL, your site's and " |
| 5400 "visitors' data is vulnerable to theft and " | 5462 "visitors' data is vulnerable to theft and " |
| 5401 "tampering. Get a valid SSL certificate before" | 5463 "tampering. Get a valid SSL certificate before" |
| 5402 " releasing your website to the public.")); | 5464 " releasing your website to the public.")); |
| 5403 } | 5465 } |
| 5404 | 5466 |
| 5405 } // namespace content | 5467 } // namespace content |
| OLD | NEW |