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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 : render_process_id(render_process_id), | 321 : render_process_id(render_process_id), |
| 322 render_frame_id(render_frame_id), | 322 render_frame_id(render_frame_id), |
| 323 chooser(chooser), | 323 chooser(chooser), |
| 324 identifier(identifier) { | 324 identifier(identifier) { |
| 325 } | 325 } |
| 326 | 326 |
| 327 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { | 327 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { |
| 328 } | 328 } |
| 329 | 329 |
| 330 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 330 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
| 331 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 331 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode( |
| 332 : outer_web_contents_(nullptr), | 332 WebContentsImpl* inner) |
| 333 : inner_web_contents_(inner), | |
| 334 outer_web_contents_(nullptr), | |
| 333 outer_contents_frame_tree_node_id_( | 335 outer_contents_frame_tree_node_id_( |
| 334 FrameTreeNode::kFrameTreeNodeInvalidId) { | 336 FrameTreeNode::kFrameTreeNodeInvalidId) {} |
| 335 } | |
| 336 | 337 |
| 337 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 338 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| 338 // Remove child pointer from our parent. | 339 // Remove child pointer from our parent. |
| 339 if (outer_web_contents_) { | 340 if (outer_web_contents_) { |
| 340 ChildrenSet& child_ptrs_in_parent = | 341 ChildrenMap& child_ptrs_in_parent = |
| 341 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 342 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
| 342 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 343 ChildrenMap::iterator iter = |
| 344 child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_); | |
| 343 DCHECK(iter != child_ptrs_in_parent.end()); | 345 DCHECK(iter != child_ptrs_in_parent.end()); |
| 344 child_ptrs_in_parent.erase(this); | 346 child_ptrs_in_parent.erase(iter); |
| 345 } | 347 } |
| 346 | 348 |
| 347 // Remove parent pointers from our children. | 349 // Remove parent pointers from our children. |
| 348 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 350 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
| 349 // children do not manage their own lifetime, then we would leak their | 351 // children do not manage their own lifetime, then we would leak their |
| 350 // WebContentses. | 352 // WebContentses. |
| 351 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 353 for (auto children : inner_web_contents_tree_nodes_) |
|
lfg
2016/05/06 21:23:33
Use auto&, so you don't make a copy of the pair to
avallee
2016/05/11 18:26:11
Done.
| |
| 352 child->outer_web_contents_ = nullptr; | 354 children.second->outer_web_contents_ = nullptr; |
| 353 } | 355 } |
| 354 | 356 |
| 355 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 357 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| 356 WebContentsImpl* outer_web_contents, | 358 WebContentsImpl* outer_web_contents, |
| 357 RenderFrameHostImpl* outer_contents_frame) { | 359 RenderFrameHostImpl* outer_contents_frame) { |
| 358 outer_web_contents_ = outer_web_contents; | 360 outer_web_contents_ = outer_web_contents; |
| 359 outer_contents_frame_tree_node_id_ = | 361 outer_contents_frame_tree_node_id_ = |
| 360 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 362 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
| 361 | 363 |
| 362 if (!outer_web_contents_->node_) | 364 if (!outer_web_contents_->node_) |
| 363 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 365 outer_web_contents_->node_.reset( |
| 366 new WebContentsTreeNode(outer_web_contents_)); | |
| 364 | 367 |
| 365 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 368 outer_web_contents_->node_ |
| 369 ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] = | |
| 370 this; | |
| 371 } | |
| 372 | |
| 373 WebContentsImpl* WebContentsImpl::WebContentsTreeNode::find_contents_for_frame( | |
| 374 int frame_id) const { | |
| 375 auto iter = inner_web_contents_tree_nodes_.find(frame_id); | |
| 376 if (iter != inner_web_contents_tree_nodes_.end()) { | |
| 377 return iter->second->inner_web_contents_; | |
| 378 } | |
| 379 return nullptr; | |
| 366 } | 380 } |
| 367 | 381 |
| 368 // WebContentsImpl ------------------------------------------------------------- | 382 // WebContentsImpl ------------------------------------------------------------- |
| 369 | 383 |
| 370 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 384 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| 371 : delegate_(NULL), | 385 : delegate_(NULL), |
| 372 controller_(this, browser_context), | 386 controller_(this, browser_context), |
| 373 render_view_host_delegate_view_(NULL), | 387 render_view_host_delegate_view_(NULL), |
| 374 created_with_opener_(false), | 388 created_with_opener_(false), |
| 375 frame_tree_(new NavigatorImpl(&controller_, this), | 389 frame_tree_(new NavigatorImpl(&controller_, this), |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1386 // created. This is needed because the usual initialization happens during | 1400 // created. This is needed because the usual initialization happens during |
| 1387 // the first navigation, but when attaching a new window we don't navigate | 1401 // the first navigation, but when attaching a new window we don't navigate |
| 1388 // before attaching. If the browser side is already initialized, the calls | 1402 // before attaching. If the browser side is already initialized, the calls |
| 1389 // below will just early return. | 1403 // below will just early return. |
| 1390 render_manager->InitRenderView(GetRenderViewHost(), nullptr); | 1404 render_manager->InitRenderView(GetRenderViewHost(), nullptr); |
| 1391 GetMainFrame()->Init(); | 1405 GetMainFrame()->Init(); |
| 1392 if (!render_manager->GetRenderWidgetHostView()) | 1406 if (!render_manager->GetRenderWidgetHostView()) |
| 1393 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); | 1407 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); |
| 1394 | 1408 |
| 1395 // Create a link to our outer WebContents. | 1409 // Create a link to our outer WebContents. |
| 1396 node_.reset(new WebContentsTreeNode()); | 1410 node_.reset(new WebContentsTreeNode(this)); |
| 1397 node_->ConnectToOuterWebContents( | 1411 node_->ConnectToOuterWebContents( |
| 1398 static_cast<WebContentsImpl*>(outer_web_contents), | 1412 static_cast<WebContentsImpl*>(outer_web_contents), |
| 1399 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1413 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
| 1400 | 1414 |
| 1401 DCHECK(outer_contents_frame); | 1415 DCHECK(outer_contents_frame); |
| 1402 | 1416 |
| 1403 // Create a proxy in top-level RenderFrameHostManager, pointing to the | 1417 // Create a proxy in top-level RenderFrameHostManager, pointing to the |
| 1404 // SiteInstance of the outer WebContents. The proxy will be used to send | 1418 // SiteInstance of the outer WebContents. The proxy will be used to send |
| 1405 // postMessage to the inner WebContents. | 1419 // postMessage to the inner WebContents. |
| 1406 render_manager->CreateOuterDelegateProxy( | 1420 render_manager->CreateOuterDelegateProxy( |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1786 | 1800 |
| 1787 // Events for widgets other than the main frame (e.g., popup menus) should be | 1801 // Events for widgets other than the main frame (e.g., popup menus) should be |
| 1788 // forwarded directly to the widget they arrived on. | 1802 // forwarded directly to the widget they arrived on. |
| 1789 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) | 1803 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) |
| 1790 return receiving_widget; | 1804 return receiving_widget; |
| 1791 | 1805 |
| 1792 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); | 1806 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); |
| 1793 if (!focused_frame) | 1807 if (!focused_frame) |
| 1794 return receiving_widget; | 1808 return receiving_widget; |
| 1795 | 1809 |
| 1810 // If there is an inner web contents (<webview>, <guestview>, ...) with focus, | |
| 1811 // return its RenderWidgetHost. | |
| 1812 WebContentsImpl* inner_contents = | |
| 1813 (node_.get()) | |
| 1814 ? node_->find_contents_for_frame(focused_frame->frame_tree_node_id()) | |
| 1815 : nullptr; | |
| 1816 if (inner_contents) { | |
| 1817 return inner_contents->GetFocusedRenderWidgetHost( | |
| 1818 inner_contents->GetMainFrame()->GetRenderWidgetHost()); | |
| 1819 } | |
| 1796 // The view may be null if a subframe's renderer process has crashed while | 1820 // The view may be null if a subframe's renderer process has crashed while |
| 1797 // the subframe has focus. Drop the event in that case. Do not give | 1821 // the subframe has focus. Drop the event in that case. Do not give |
| 1798 // it to the main frame, so that the user doesn't unexpectedly type into the | 1822 // it to the main frame, so that the user doesn't unexpectedly type into the |
| 1799 // wrong frame if a focused subframe renderer crashes while they type. | 1823 // wrong frame if a focused subframe renderer crashes while they type. |
| 1800 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); | 1824 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); |
| 1801 if (!view) | 1825 if (!view) |
| 1802 return nullptr; | 1826 return nullptr; |
| 1803 | 1827 |
| 1804 return RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); | 1828 return RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); |
| 1805 } | 1829 } |
| (...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4478 GetSiteInstance()); | 4502 GetSiteInstance()); |
| 4479 } else { | 4503 } else { |
| 4480 RenderFrameHostImpl* source_rfhi = | 4504 RenderFrameHostImpl* source_rfhi = |
| 4481 static_cast<RenderFrameHostImpl*>(source_rfh); | 4505 static_cast<RenderFrameHostImpl*>(source_rfh); |
| 4482 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( | 4506 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( |
| 4483 GetSiteInstance(), nullptr); | 4507 GetSiteInstance(), nullptr); |
| 4484 } | 4508 } |
| 4485 } | 4509 } |
| 4486 } | 4510 } |
| 4487 | 4511 |
| 4512 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, | |
| 4513 SiteInstance* source) { | |
| 4514 SetFocusedFrameInternal(node, source, true /* can visit outer contents */); | |
| 4515 | |
| 4516 auto rwh = node->current_frame_host()->GetRenderWidgetHost(); | |
| 4517 if (rwh) { | |
|
lfg
2016/05/06 21:23:33
nit: {}
avallee
2016/05/11 18:26:11
Done.
| |
| 4518 rwh->Focus(); | |
| 4519 } | |
| 4520 } | |
| 4521 | |
| 4522 void WebContentsImpl::SetFocusedFrameInternal(FrameTreeNode* node, | |
| 4523 SiteInstance* source, | |
| 4524 bool can_visit_outer_contents) { | |
| 4525 // Approach: Recursively unfocus any inner web contents. Then set | |
| 4526 // representation of this web contents in the outer contents to be focused, | |
| 4527 // finally focus the node in current frame tree. | |
| 4528 // | |
| 4529 // Usually only one of unfocusing children and focusing self in parent would | |
| 4530 // happen. If unfocusing a child, then we're already focused in our parent, if | |
| 4531 // we have one. | |
| 4532 | |
| 4533 auto old_focus_node = frame_tree_.GetFocusedFrame(); | |
| 4534 | |
| 4535 if (old_focus_node != nullptr && node_.get()) { | |
| 4536 if (!node || old_focus_node != node) { | |
| 4537 WebContentsImpl* inner_contents = | |
| 4538 node_->find_contents_for_frame(old_focus_node->frame_tree_node_id()); | |
| 4539 if (inner_contents) { | |
|
lfg
2016/05/06 21:23:33
nit: {}
avallee
2016/05/11 18:26:11
Done.
| |
| 4540 inner_contents->SetFocusedFrameInternal(nullptr, source, false); | |
| 4541 } | |
| 4542 } | |
| 4543 } | |
| 4544 | |
| 4545 // focus in parent. | |
| 4546 auto outer_contents = GetOuterWebContents(); | |
| 4547 // If we're coming from parent, we don't want to recurse back into the parent. | |
| 4548 if (outer_contents && can_visit_outer_contents) { | |
| 4549 auto outer_node = | |
| 4550 outer_contents->frame_tree_.FindByID(GetOuterDelegateFrameTreeNodeId()); | |
| 4551 if (outer_node == nullptr) { | |
| 4552 // With browser plugin, we will have an outer contents but no node in the | |
| 4553 // outer contents' frame tree. | |
| 4554 // maybe focus outer main frame. | |
|
lfg
2016/05/06 21:23:33
Not sure I follow this. Why are we focusing the ro
avallee
2016/05/11 18:26:11
Comment should answer this. It's not ideal, but it
| |
| 4555 outer_contents->SetFocusedFrameInternal( | |
| 4556 outer_contents->frame_tree_.root(), source, true); | |
| 4557 } else { | |
| 4558 // Notify outer about our focus change. | |
| 4559 auto outer_node_site_instance = | |
| 4560 outer_node->current_frame_host()->GetSiteInstance(); | |
|
lfg
2016/05/06 21:23:33
I think this should be outer_node->parent()->curre
avallee
2016/05/11 18:26:11
Done.
| |
| 4561 auto outer_proxy = | |
| 4562 frame_tree_.root()->render_manager()->GetRenderFrameProxyHost( | |
| 4563 outer_node_site_instance); | |
| 4564 if (outer_proxy) { | |
|
lfg
2016/05/06 21:23:33
nit: {}
avallee
2016/05/11 18:26:11
Done.
| |
| 4565 outer_proxy->SetFocusedFrame(); | |
| 4566 } | |
| 4567 outer_contents->SetFocusedFrameInternal(outer_node, source, true); | |
| 4568 } | |
| 4569 } | |
| 4570 // Set focus for myself. | |
| 4571 frame_tree_.SetFocusedFrame(node, source); | |
| 4572 } | |
| 4573 | |
| 4488 bool WebContentsImpl::AddMessageToConsole(int32_t level, | 4574 bool WebContentsImpl::AddMessageToConsole(int32_t level, |
| 4489 const base::string16& message, | 4575 const base::string16& message, |
| 4490 int32_t line_no, | 4576 int32_t line_no, |
| 4491 const base::string16& source_id) { | 4577 const base::string16& source_id) { |
| 4492 if (!delegate_) | 4578 if (!delegate_) |
| 4493 return false; | 4579 return false; |
| 4494 return delegate_->AddMessageToConsole(this, level, message, line_no, | 4580 return delegate_->AddMessageToConsole(this, level, message, line_no, |
| 4495 source_id); | 4581 source_id); |
| 4496 } | 4582 } |
| 4497 | 4583 |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5015 for (RenderViewHost* render_view_host : render_view_host_set) | 5101 for (RenderViewHost* render_view_host : render_view_host_set) |
| 5016 render_view_host->OnWebkitPreferencesChanged(); | 5102 render_view_host->OnWebkitPreferencesChanged(); |
| 5017 } | 5103 } |
| 5018 | 5104 |
| 5019 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( | 5105 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( |
| 5020 JavaScriptDialogManager* dialog_manager) { | 5106 JavaScriptDialogManager* dialog_manager) { |
| 5021 dialog_manager_ = dialog_manager; | 5107 dialog_manager_ = dialog_manager; |
| 5022 } | 5108 } |
| 5023 | 5109 |
| 5024 } // namespace content | 5110 } // namespace content |
| OLD | NEW |