15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/webview/webview.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessibility_types.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/accessibility/native_view_accessibility.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/native/native_view_host.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/focus_manager.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/views_delegate.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char WebView::kViewClassName[] = "WebView";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebView, public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebView::WebView(content::BrowserContext* browser_context)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : wcv_holder_(new NativeViewHost),
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_(NULL),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context_(browser_context),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      allow_accelerators_(false) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(wcv_holder_);
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NativeViewAccessibility::RegisterWebView(this);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebView::~WebView() {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NativeViewAccessibility::UnregisterWebView(this);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::WebContents* WebView::GetWebContents() {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateWebContentsWithSiteInstance(NULL);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_contents_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::CreateWebContentsWithSiteInstance(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::SiteInstance* site_instance) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_contents_) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wc_owner_.reset(CreateWebContents(browser_context_, site_instance));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_ = wc_owner_.get();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_->SetDelegate(this);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttachWebContents();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::SetWebContents(content::WebContents* web_contents) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents == web_contents_)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DetachWebContents();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wc_owner_.reset();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_ = web_contents;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AttachWebContents();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::LoadInitialURL(const GURL& url) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWebContents()->GetController().LoadURL(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::SetFastResize(bool fast_resize) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wcv_holder_->set_fast_resize(fast_resize);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::OnWebContentsFocused(content::WebContents* web_contents) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FocusManager* focus_manager = GetFocusManager();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focus_manager)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    focus_manager->SetFocusedView(this);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::SetPreferredSize(const gfx::Size& preferred_size) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  preferred_size_ = preferred_size;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PreferredSizeChanged();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebView, View overrides:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* WebView::GetClassName() const {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kViewClassName;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wcv_holder_->SetSize(bounds().size());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void WebView::ViewHierarchyChanged(
104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (details.is_add)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttachWebContents();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allow_accelerators_)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FocusManager::IsTabTraversalKeyEvent(event);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't look-up accelerators or tab-traversal if we are showing a non-crashed
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TabContents.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We'll first give the page a chance to process the key events.  If it does
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not process them, they'll be returned to us and we'll treat them as
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // accelerators then.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_contents_ && !web_contents_->IsCrashed();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebView::IsFocusable() const {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to be focusable when our contents is not a view hierarchy, as
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clicking on the contents needs to focus us.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!web_contents_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::OnFocus() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents_->GetView()->Focus();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_->FocusThroughTabTraversal(reverse);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::GetAccessibleState(ui::AccessibleViewState* state) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state->role = ui::AccessibilityTypes::ROLE_GROUPING;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeViewAccessible WebView::GetNativeViewAccessible() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderWidgetHostView* host_view =
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        web_contents_->GetRenderWidgetHostView();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (host_view)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return host_view->GetNativeViewAccessible();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return View::GetNativeViewAccessible();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size WebView::GetPreferredSize() {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (preferred_size_ == gfx::Size())
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return View::GetPreferredSize();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return preferred_size_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebView, content::NotificationObserver implementation:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::Observe(int type,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const content::NotificationSource& source,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const content::NotificationDetails& details) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::pair<content::RenderViewHost*, content::RenderViewHost*>*
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switched_details =
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::Details<std::pair<content::RenderViewHost*,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       content::RenderViewHost*> >(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                details).ptr();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHostChanged(switched_details->first,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          switched_details->second);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContentsDestroyed(content::Source<content::WebContents>(source).ptr());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebView, content::WebContentsDelegate implementation:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::WebContentsFocused(content::WebContents* web_contents) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(wc_owner_.get());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The WebView is only the delegate of WebContentses it creates itself.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnWebContentsFocused(web_contents_);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// WebView, AccessibleWebView implementation:
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::NativeViewAccessible WebView::AccessibleObjectFromChildId(long child_id) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN) && defined(USE_AURA)
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!web_contents_)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::RenderWidgetHostView* host_view =
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      web_contents_->GetRenderWidgetHostView();
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (host_view)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return host_view->AccessibleObjectFromChildId(child_id);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTIMPLEMENTED();
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)View* WebView::AsView() {
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return this;
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebView, private:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::AttachWebContents() {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevents attachment if the WebView isn't already in a Widget, or it's
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already attached.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWidget() || !web_contents_ ||
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      wcv_holder_->native_view() == web_contents_->GetView()->GetNativeView()) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wcv_holder_->Attach(web_contents_->GetView()->GetNativeView());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The WebContentsView will not be focused automatically when it is
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // attached, so we need to pass on focus to it if the FocusManager thinks
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the WebView is focused. Note that not every Widget has a focus manager.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FocusManager* focus_manager = GetFocusManager();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (focus_manager && focus_manager->GetFocusedView() == this)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_->GetView()->Focus();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<content::NavigationController>(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &web_contents_->GetController()));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<content::WebContents>(web_contents_));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) && defined(USE_AURA)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_contents_->SetParentNativeViewAccessible(
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parent()->GetNativeViewAccessible());
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::DetachWebContents() {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wcv_holder_->Detach();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(beng): This should either not be necessary, or be done implicitly by
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NativeViewHostWin on Detach(). As it stands, this is needed so that the
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // view of the detached contents knows to tell the renderer it's been
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // hidden.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Moving this out of here would also mean we wouldn't be potentially
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // calling member functions on a half-destroyed WebContents.
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN) && defined(USE_AURA)
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    web_contents_->SetParentNativeViewAccessible(NULL);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.RemoveAll();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    content::RenderViewHost* new_host) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetFocusManager()->GetFocusedView() == this)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents_->GetView()->Focus();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebView::WebContentsDestroyed(content::WebContents* web_contents) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_contents == web_contents_);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetWebContents(NULL);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::WebContents* WebView::CreateWebContents(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserContext* browser_context,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::SiteInstance* site_instance) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* contents = NULL;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ViewsDelegate::views_delegate) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contents = ViewsDelegate::views_delegate->CreateWebContents(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_context, site_instance);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!contents) {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents::CreateParams create_params(
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser_context, site_instance);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return content::WebContents::Create(create_params);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return contents;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
297