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 "ui/views/controls/webview/webview.h" | 5 #include "ui/views/controls/webview/webview.h" |
| 6 | 6 |
| 7 #include "content/public/browser/browser_accessibility_state.h" | 7 #include "content/public/browser/browser_accessibility_state.h" |
| 8 #include "content/public/browser/browser_context.h" | 8 #include "content/public/browser/browser_context.h" |
| 9 #include "content/public/browser/navigation_controller.h" | 9 #include "content/public/browser/navigation_controller.h" |
| 10 #include "content/public/browser/render_view_host.h" | 10 #include "content/public/browser/render_view_host.h" |
| 11 #include "content/public/browser/render_widget_host_view.h" | 11 #include "content/public/browser/render_widget_host_view.h" |
| 12 #include "content/public/browser/web_contents.h" | 12 #include "content/public/browser/web_contents.h" |
| 13 #include "content/public/browser/web_contents_view.h" | 13 #include "content/public/browser/web_contents_view.h" |
| 14 #include "ipc/ipc_message.h" | 14 #include "ipc/ipc_message.h" |
| 15 #include "ui/accessibility/ax_enums.h" | 15 #include "ui/accessibility/ax_enums.h" |
| 16 #include "ui/accessibility/ax_view_state.h" | 16 #include "ui/accessibility/ax_view_state.h" |
| 17 #include "ui/base/ui_base_switches_util.h" | |
| 17 #include "ui/events/event.h" | 18 #include "ui/events/event.h" |
| 18 #include "ui/views/accessibility/native_view_accessibility.h" | 19 #include "ui/views/accessibility/native_view_accessibility.h" |
| 19 #include "ui/views/controls/native/native_view_host.h" | 20 #include "ui/views/controls/native/native_view_host.h" |
| 20 #include "ui/views/focus/focus_manager.h" | 21 #include "ui/views/focus/focus_manager.h" |
| 21 #include "ui/views/views_delegate.h" | 22 #include "ui/views/views_delegate.h" |
| 22 | 23 |
| 23 namespace views { | 24 namespace views { |
| 24 | 25 |
| 25 // static | 26 // static |
| 26 const char WebView::kViewClassName[] = "WebView"; | 27 const char WebView::kViewClassName[] = "WebView"; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 44 | 45 |
| 45 content::WebContents* WebView::GetWebContents() { | 46 content::WebContents* WebView::GetWebContents() { |
| 46 if (!web_contents()) { | 47 if (!web_contents()) { |
| 47 wc_owner_.reset(CreateWebContents(browser_context_)); | 48 wc_owner_.reset(CreateWebContents(browser_context_)); |
| 48 wc_owner_->SetDelegate(this); | 49 wc_owner_->SetDelegate(this); |
| 49 SetWebContents(wc_owner_.get()); | 50 SetWebContents(wc_owner_.get()); |
| 50 } | 51 } |
| 51 return web_contents(); | 52 return web_contents(); |
| 52 } | 53 } |
| 53 | 54 |
| 54 void WebView::SetWebContents(content::WebContents* replacement) { | 55 void WebView::SetWebContents(content::WebContents* replacement) { |
|
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Very good catch. I added it to {Attach,Detach}Web
| |
| 55 if (replacement == web_contents()) | 56 if (replacement == web_contents()) |
| 56 return; | 57 return; |
| 57 DetachWebContents(); | 58 DetachWebContents(); |
| 58 if (wc_owner_ != replacement) | 59 if (wc_owner_ != replacement) |
| 59 wc_owner_.reset(); | 60 wc_owner_.reset(); |
| 60 WebContentsObserver::Observe(replacement); | 61 WebContentsObserver::Observe(replacement); |
| 61 // web_contents() now returns |replacement| from here onwards. | 62 // web_contents() now returns |replacement| from here onwards. |
| 62 if (embed_fullscreen_widget_mode_enabled_) { | 63 if (embed_fullscreen_widget_mode_enabled_) { |
| 63 is_embedding_fullscreen_widget_ = | 64 is_embedding_fullscreen_widget_ = |
| 64 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); | 65 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 PreferredSizeChanged(); | 104 PreferredSizeChanged(); |
| 104 } | 105 } |
| 105 | 106 |
| 106 //////////////////////////////////////////////////////////////////////////////// | 107 //////////////////////////////////////////////////////////////////////////////// |
| 107 // WebView, View overrides: | 108 // WebView, View overrides: |
| 108 | 109 |
| 109 const char* WebView::GetClassName() const { | 110 const char* WebView::GetClassName() const { |
| 110 return kViewClassName; | 111 return kViewClassName; |
| 111 } | 112 } |
| 112 | 113 |
| 114 ui::TextInputClient* WebView::GetTextInputClient() { | |
| 115 if (switches::IsTextInputFocusManagerEnabled() && | |
| 116 web_contents() && !web_contents()->IsBeingDestroyed()) { | |
| 117 content::RenderWidgetHostView* host_view = | |
| 118 web_contents()->GetRenderWidgetHostView(); | |
|
msw
2014/03/11 23:24:39
Should this ever use web_contents()->GetFullscreen
Yuki
2014/03/12 09:13:15
Very good catch. Updated.
| |
| 119 if (host_view) | |
| 120 return host_view->GetTextInputClient(); | |
| 121 } | |
| 122 return NULL; | |
| 123 } | |
| 124 | |
| 113 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 125 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 114 wcv_holder_->SetSize(bounds().size()); | 126 wcv_holder_->SetSize(bounds().size()); |
| 115 } | 127 } |
| 116 | 128 |
| 117 void WebView::ViewHierarchyChanged( | 129 void WebView::ViewHierarchyChanged( |
| 118 const ViewHierarchyChangedDetails& details) { | 130 const ViewHierarchyChangedDetails& details) { |
| 119 if (details.is_add) | 131 if (details.is_add) |
| 120 AttachWebContents(); | 132 AttachWebContents(); |
| 121 } | 133 } |
| 122 | 134 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 } | 199 } |
| 188 | 200 |
| 189 bool WebView::EmbedsFullscreenWidget() const { | 201 bool WebView::EmbedsFullscreenWidget() const { |
| 190 DCHECK(wc_owner_.get()); | 202 DCHECK(wc_owner_.get()); |
| 191 return embed_fullscreen_widget_mode_enabled_; | 203 return embed_fullscreen_widget_mode_enabled_; |
| 192 } | 204 } |
| 193 | 205 |
| 194 //////////////////////////////////////////////////////////////////////////////// | 206 //////////////////////////////////////////////////////////////////////////////// |
| 195 // WebView, content::WebContentsObserver implementation: | 207 // WebView, content::WebContentsObserver implementation: |
| 196 | 208 |
| 209 void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) { | |
| 210 // WebView::GetTextInputClient() delegates the text input handling to the | |
| 211 // underlying content::RenderWidgetHostView. So when the underlying RWHV is | |
| 212 // destroyed, we have to notify the FocusManager that the focused | |
| 213 // TextInputClient needs to be updated. | |
| 214 FocusManager* const focus_manager = GetFocusManager(); | |
| 215 if (focus_manager) | |
| 216 focus_manager->OnTextInputClientChanged(this); | |
| 217 } | |
| 218 | |
| 197 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, | 219 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, |
| 198 content::RenderViewHost* new_host) { | 220 content::RenderViewHost* new_host) { |
| 199 FocusManager* const focus_manager = GetFocusManager(); | 221 FocusManager* const focus_manager = GetFocusManager(); |
| 200 if (focus_manager && focus_manager->GetFocusedView() == this) | 222 if (focus_manager && focus_manager->GetFocusedView() == this) |
| 201 OnFocus(); | 223 OnFocus(); |
| 202 } | 224 } |
| 203 | 225 |
| 204 void WebView::WebContentsDestroyed(content::WebContents* web_contents) { | 226 void WebView::WebContentsDestroyed(content::WebContents* web_contents) { |
|
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
I think no need here. SetWebContents(NULL) handle
| |
| 205 // We watch for destruction of WebContents that we host but do not own. If we | 227 // We watch for destruction of WebContents that we host but do not own. If we |
| 206 // own a WebContents that is being destroyed, we're doing the destroying, so | 228 // own a WebContents that is being destroyed, we're doing the destroying, so |
| 207 // we don't want to recursively tear it down while it's being torn down. | 229 // we don't want to recursively tear it down while it's being torn down. |
| 208 if (!wc_owner_.get()) | 230 if (!wc_owner_.get()) |
| 209 SetWebContents(NULL); | 231 SetWebContents(NULL); |
| 210 } | 232 } |
| 211 | 233 |
| 212 void WebView::DidShowFullscreenWidget(int routing_id) { | 234 void WebView::DidShowFullscreenWidget(int routing_id) { |
| 213 if (embed_fullscreen_widget_mode_enabled_) | 235 if (embed_fullscreen_widget_mode_enabled_) |
| 214 ReattachForFullscreenChange(true); | 236 ReattachForFullscreenChange(true); |
| 215 } | 237 } |
| 216 | 238 |
| 217 void WebView::DidDestroyFullscreenWidget(int routing_id) { | 239 void WebView::DidDestroyFullscreenWidget(int routing_id) { |
| 218 if (embed_fullscreen_widget_mode_enabled_) | 240 if (embed_fullscreen_widget_mode_enabled_) |
| 219 ReattachForFullscreenChange(false); | 241 ReattachForFullscreenChange(false); |
| 220 } | 242 } |
| 221 | 243 |
| 222 //////////////////////////////////////////////////////////////////////////////// | 244 //////////////////////////////////////////////////////////////////////////////// |
| 223 // WebView, private: | 245 // WebView, private: |
| 224 | 246 |
| 225 void WebView::AttachWebContents() { | 247 void WebView::AttachWebContents() { |
|
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Done.
| |
| 226 // Prevents attachment if the WebView isn't already in a Widget, or it's | 248 // Prevents attachment if the WebView isn't already in a Widget, or it's |
| 227 // already attached. | 249 // already attached. |
| 228 if (!GetWidget() || !web_contents()) | 250 if (!GetWidget() || !web_contents()) |
| 229 return; | 251 return; |
| 230 | 252 |
| 231 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? | 253 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? |
| 232 web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() : | 254 web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() : |
| 233 web_contents()->GetView()->GetNativeView(); | 255 web_contents()->GetView()->GetNativeView(); |
| 234 if (wcv_holder_->native_view() == view_to_attach) | 256 if (wcv_holder_->native_view() == view_to_attach) |
| 235 return; | 257 return; |
| 236 wcv_holder_->Attach(view_to_attach); | 258 wcv_holder_->Attach(view_to_attach); |
| 237 | 259 |
| 238 // The view will not be focused automatically when it is attached, so we need | 260 // The view will not be focused automatically when it is attached, so we need |
| 239 // to pass on focus to it if the FocusManager thinks the view is focused. Note | 261 // to pass on focus to it if the FocusManager thinks the view is focused. Note |
| 240 // that not every Widget has a focus manager. | 262 // that not every Widget has a focus manager. |
| 241 FocusManager* const focus_manager = GetFocusManager(); | 263 FocusManager* const focus_manager = GetFocusManager(); |
| 242 if (focus_manager && focus_manager->GetFocusedView() == this) | 264 if (focus_manager && focus_manager->GetFocusedView() == this) |
| 243 OnFocus(); | 265 OnFocus(); |
| 244 | 266 |
| 245 #if defined(OS_WIN) | 267 #if defined(OS_WIN) |
| 246 if (!is_embedding_fullscreen_widget_) { | 268 if (!is_embedding_fullscreen_widget_) { |
| 247 web_contents()->SetParentNativeViewAccessible( | 269 web_contents()->SetParentNativeViewAccessible( |
| 248 parent()->GetNativeViewAccessible()); | 270 parent()->GetNativeViewAccessible()); |
| 249 } | 271 } |
| 250 #endif | 272 #endif |
| 251 } | 273 } |
| 252 | 274 |
| 253 void WebView::DetachWebContents() { | 275 void WebView::DetachWebContents() { |
|
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Done.
| |
| 254 if (web_contents()) { | 276 if (web_contents()) { |
| 255 wcv_holder_->Detach(); | 277 wcv_holder_->Detach(); |
| 256 #if defined(OS_WIN) | 278 #if defined(OS_WIN) |
| 257 if (!is_embedding_fullscreen_widget_) { | 279 if (!is_embedding_fullscreen_widget_) { |
| 258 #if !defined(USE_AURA) | 280 #if !defined(USE_AURA) |
| 259 // TODO(beng): This should either not be necessary, or be done implicitly | 281 // TODO(beng): This should either not be necessary, or be done implicitly |
| 260 // by NativeViewHostWin on Detach(). As it stands, this is needed so that | 282 // by NativeViewHostWin on Detach(). As it stands, this is needed so that |
| 261 // the of the detached contents knows to tell the renderer it's been | 283 // the of the detached contents knows to tell the renderer it's been |
| 262 // hidden. | 284 // hidden. |
| 263 // | 285 // |
| 264 // Moving this out of here would also mean we wouldn't be potentially | 286 // Moving this out of here would also mean we wouldn't be potentially |
| 265 // calling member functions on a half-destroyed WebContents. | 287 // calling member functions on a half-destroyed WebContents. |
| 266 ShowWindow(web_contents()->GetView()->GetNativeView(), SW_HIDE); | 288 ShowWindow(web_contents()->GetView()->GetNativeView(), SW_HIDE); |
| 267 #else | 289 #else |
| 268 web_contents()->SetParentNativeViewAccessible(NULL); | 290 web_contents()->SetParentNativeViewAccessible(NULL); |
| 269 #endif | 291 #endif |
| 270 } | 292 } |
| 271 #endif | 293 #endif |
| 272 } | 294 } |
| 273 } | 295 } |
| 274 | 296 |
| 275 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { | 297 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { |
|
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
This method calls DetachWebContents() and then Att
| |
| 276 DetachWebContents(); | 298 DetachWebContents(); |
| 277 is_embedding_fullscreen_widget_ = enter_fullscreen && | 299 is_embedding_fullscreen_widget_ = enter_fullscreen && |
| 278 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); | 300 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
| 279 AttachWebContents(); | 301 AttachWebContents(); |
| 280 } | 302 } |
| 281 | 303 |
| 282 content::WebContents* WebView::CreateWebContents( | 304 content::WebContents* WebView::CreateWebContents( |
| 283 content::BrowserContext* browser_context) { | 305 content::BrowserContext* browser_context) { |
| 284 content::WebContents* contents = NULL; | 306 content::WebContents* contents = NULL; |
| 285 if (ViewsDelegate::views_delegate) { | 307 if (ViewsDelegate::views_delegate) { |
| 286 contents = ViewsDelegate::views_delegate->CreateWebContents( | 308 contents = ViewsDelegate::views_delegate->CreateWebContents( |
| 287 browser_context, NULL); | 309 browser_context, NULL); |
| 288 } | 310 } |
| 289 | 311 |
| 290 if (!contents) { | 312 if (!contents) { |
| 291 content::WebContents::CreateParams create_params( | 313 content::WebContents::CreateParams create_params( |
| 292 browser_context, NULL); | 314 browser_context, NULL); |
| 293 return content::WebContents::Create(create_params); | 315 return content::WebContents::Create(create_params); |
| 294 } | 316 } |
| 295 | 317 |
| 296 return contents; | 318 return contents; |
| 297 } | 319 } |
| 298 | 320 |
| 299 } // namespace views | 321 } // namespace views |
| OLD | NEW |