Chromium Code Reviews| Index: ui/views/controls/webview/webview.cc |
| =================================================================== |
| --- ui/views/controls/webview/webview.cc (revision 132062) |
| +++ ui/views/controls/webview/webview.cc (working copy) |
| @@ -5,8 +5,17 @@ |
| #include "ui/views/controls/webview/webview.h" |
| #include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_registrar.h" |
| +#include "content/public/browser/notification_source.h" |
| +#include "content/public/browser/notification_types.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/render_widget_host_view.h" |
| #include "ipc/ipc_message.h" |
| +#include "ui/base/accessibility/accessible_view_state.h" |
| +#include "ui/base/accessibility/accessibility_types.h" |
| #include "ui/views/controls/native/native_view_host.h" |
| +#include "ui/views/focus/focus_manager.h" |
| namespace views { |
| @@ -15,23 +24,49 @@ |
| WebView::WebView(content::BrowserContext* browser_context) |
| : wcv_holder_(new NativeViewHost), |
| + web_contents_(NULL), |
| browser_context_(browser_context) { |
| - Init(); |
| + AddChildView(wcv_holder_); |
| } |
| WebView::~WebView() { |
| } |
| -//////////////////////////////////////////////////////////////////////////////// |
| -// WebView, private: |
| +content::WebContents* WebView::GetWebContents() { |
| + if (!web_contents_) { |
|
sky
2012/04/13 19:19:08
I don't think this works quite right if invoked af
|
| + wc_owner_.reset(content::WebContents::Create(browser_context_, |
| + NULL, |
| + MSG_ROUTING_NONE, |
| + NULL, |
| + NULL)); |
| + web_contents_ = wc_owner_.get(); |
| + web_contents_->SetDelegate(this); |
| + } |
| + return web_contents_; |
| +} |
| -void WebView::Init() { |
| - AddChildView(wcv_holder_); |
| - web_contents_.reset( |
| - content::WebContents::Create(browser_context_, NULL, MSG_ROUTING_NONE, |
| - NULL, NULL)); |
| +void WebView::SetWebContents(content::WebContents* web_contents) { |
| + DetachWebContents(web_contents_); |
| + if (wc_owner_.get()) |
|
sky
2012/04/13 19:19:08
nit: no need to test, can always do wc_owner_.rese
|
| + wc_owner_.reset(); |
| + web_contents_ = web_contents; |
| + AttachWebContents(web_contents_); |
| } |
| +void WebView::SetFastResize(bool fast_resize) { |
| + wcv_holder_->set_fast_resize(fast_resize); |
| +} |
| + |
| +void WebView::OnWebContentsFocused(content::WebContents* web_contents) { |
| + DCHECK(web_contents == web_contents_); |
| + FocusManager* focus_manager = GetFocusManager(); |
| + if (!focus_manager) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + focus_manager->SetFocusedView(this); |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // WebView, View overrides: |
| @@ -40,8 +75,118 @@ |
| } |
| void WebView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { |
| - if (is_add && child == this) |
| - wcv_holder_->Attach(web_contents_->GetNativeView()); |
| + if (is_add && GetWidget()) |
| + AttachWebContents(web_contents_); |
|
sky
2012/04/13 19:19:08
Won't this lead to potentially invoking Attach mor
|
| } |
| +bool WebView::SkipDefaultKeyEventProcessing(const views::KeyEvent& event) { |
| + // Don't look-up accelerators or tab-traversal if we are showing a non-crashed |
| + // TabContents. |
| + // We'll first give the page a chance to process the key events. If it does |
| + // not process them, they'll be returned to us and we'll treat them as |
| + // accelerators then. |
| + return web_contents_ && !web_contents_->IsCrashed(); |
| +} |
| + |
| +bool WebView::IsFocusable() const { |
| + // We need to be focusable when our contents is not a view hierarchy, as |
| + // clicking on the contents needs to focus us. |
| + return !!web_contents_; |
| +} |
| + |
| +void WebView::OnFocus() { |
| + if (web_contents_) |
| + web_contents_->Focus(); |
| +} |
| + |
| +void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) { |
| + if (web_contents_) |
| + web_contents_->FocusThroughTabTraversal(reverse); |
| +} |
| + |
| +void WebView::RequestFocus() { |
| + // TODO(beng): determine if code in NTCCWin is really necessary. |
| + View::RequestFocus(); |
| +} |
| + |
| +void WebView::GetAccessibleState(ui::AccessibleViewState* state) { |
| + state->role = ui::AccessibilityTypes::ROLE_GROUPING; |
| +} |
| + |
| +gfx::NativeViewAccessible WebView::GetNativeViewAccessible() { |
| + if (web_contents_) { |
| + content::RenderWidgetHostView* host_view = |
| + web_contents_->GetRenderWidgetHostView(); |
| + if (host_view) |
| + return host_view->GetNativeViewAccessible(); |
| + } |
| + return View::GetNativeViewAccessible(); |
| +} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// WebView, content::NotificationObserver implementation: |
| + |
| +void WebView::Observe(int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) { |
| + std::pair<content::RenderViewHost*, content::RenderViewHost*>* |
| + switched_details = |
| + content::Details<std::pair<content::RenderViewHost*, |
| + content::RenderViewHost*> >( |
| + details).ptr(); |
| + RenderViewHostChanged(switched_details->first, |
| + switched_details->second); |
| + } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { |
| + WebContentsDestroyed(content::Source<content::WebContents>(source).ptr()); |
| + } else { |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// WebView, content::WebContentsDelegate implementation: |
| + |
| +void WebView::WebContentsFocused(content::WebContents* web_contents) { |
| + DCHECK(wc_owner_.get()); |
| + // The WebView is only the delegate of WebContentses it creates itself. |
| + WebContentsFocused(web_contents_); |
| +} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// WebView, private: |
| + |
| +void WebView::AttachWebContents(content::WebContents* web_contents) { |
| + if (web_contents) { |
| + wcv_holder_->Attach(web_contents->GetNativeView()); |
| + |
| + registrar_.Add( |
| + this, |
| + content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| + content::Source<content::NavigationController>( |
| + &web_contents_->GetController())); |
| + registrar_.Add( |
| + this, |
| + content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| + content::Source<content::WebContents>(web_contents_)); |
| + } |
| +} |
| + |
| +void WebView::DetachWebContents(content::WebContents* web_contents) { |
| + if (web_contents) |
| + wcv_holder_->Detach(); |
| + registrar_.RemoveAll(); |
| +} |
| + |
| +void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, |
| + content::RenderViewHost* new_host) { |
| + if (GetFocusManager()->GetFocusedView() == this) |
| + web_contents_->Focus(); |
| +} |
| + |
| +void WebView::WebContentsDestroyed(content::WebContents* web_contents) { |
| + DCHECK(web_contents == web_contents_); |
| + SetWebContents(NULL); |
| +} |
| + |
| } // namespace views |