| 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" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 namespace views { | 23 namespace views { |
| 24 | 24 |
| 25 // static | 25 // static |
| 26 const char WebView::kViewClassName[] = "WebView"; | 26 const char WebView::kViewClassName[] = "WebView"; |
| 27 | 27 |
| 28 //////////////////////////////////////////////////////////////////////////////// | 28 //////////////////////////////////////////////////////////////////////////////// |
| 29 // WebView, public: | 29 // WebView, public: |
| 30 | 30 |
| 31 WebView::WebView(content::BrowserContext* browser_context) | 31 WebView::WebView(content::BrowserContext* browser_context) |
| 32 : wcv_holder_(new NativeViewHost), | 32 : wcv_holder_(new NativeViewHost), |
| 33 web_contents_(NULL), | |
| 34 embed_fullscreen_widget_mode_enabled_(false), | 33 embed_fullscreen_widget_mode_enabled_(false), |
| 35 is_embedding_fullscreen_widget_(false), | 34 is_embedding_fullscreen_widget_(false), |
| 36 browser_context_(browser_context), | 35 browser_context_(browser_context), |
| 37 allow_accelerators_(false) { | 36 allow_accelerators_(false) { |
| 38 AddChildView(wcv_holder_); | 37 AddChildView(wcv_holder_); |
| 39 NativeViewAccessibility::RegisterWebView(this); | 38 NativeViewAccessibility::RegisterWebView(this); |
| 40 } | 39 } |
| 41 | 40 |
| 42 WebView::~WebView() { | 41 WebView::~WebView() { |
| 43 NativeViewAccessibility::UnregisterWebView(this); | 42 NativeViewAccessibility::UnregisterWebView(this); |
| 44 } | 43 } |
| 45 | 44 |
| 46 content::WebContents* WebView::GetWebContents() { | 45 content::WebContents* WebView::GetWebContents() { |
| 47 CreateWebContentsWithSiteInstance(NULL); | 46 if (!web_contents()) { |
| 48 return web_contents_; | 47 wc_owner_.reset(CreateWebContents(browser_context_)); |
| 48 wc_owner_->SetDelegate(this); |
| 49 SetWebContents(wc_owner_.get()); |
| 50 } |
| 51 return web_contents(); |
| 49 } | 52 } |
| 50 | 53 |
| 51 void WebView::CreateWebContentsWithSiteInstance( | 54 void WebView::SetWebContents(content::WebContents* replacement) { |
| 52 content::SiteInstance* site_instance) { | 55 if (replacement == web_contents()) |
| 53 if (!web_contents_) { | |
| 54 wc_owner_.reset(CreateWebContents(browser_context_, site_instance)); | |
| 55 web_contents_ = wc_owner_.get(); | |
| 56 web_contents_->SetDelegate(this); | |
| 57 AttachWebContents(); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 void WebView::SetWebContents(content::WebContents* web_contents) { | |
| 62 if (web_contents == web_contents_) | |
| 63 return; | 56 return; |
| 64 DetachWebContents(); | 57 DetachWebContents(); |
| 65 if (wc_owner_ != web_contents) | 58 if (wc_owner_ != replacement) |
| 66 wc_owner_.reset(); | 59 wc_owner_.reset(); |
| 67 web_contents_ = web_contents; | 60 WebContentsObserver::Observe(replacement); |
| 61 // web_contents() now returns |replacement| from here onwards. |
| 68 if (embed_fullscreen_widget_mode_enabled_) { | 62 if (embed_fullscreen_widget_mode_enabled_) { |
| 69 is_embedding_fullscreen_widget_ = | 63 is_embedding_fullscreen_widget_ = |
| 70 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView(); | 64 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
| 71 } else { | 65 } else { |
| 72 is_embedding_fullscreen_widget_ = false; | 66 is_embedding_fullscreen_widget_ = false; |
| 73 } | 67 } |
| 74 AttachWebContents(); | 68 AttachWebContents(); |
| 75 } | 69 } |
| 76 | 70 |
| 77 void WebView::SetEmbedFullscreenWidgetMode(bool enable) { | 71 void WebView::SetEmbedFullscreenWidgetMode(bool enable) { |
| 78 bool should_be_embedded = enable; | 72 bool should_be_embedded = enable; |
| 79 if (!embed_fullscreen_widget_mode_enabled_ && enable) { | 73 if (!embed_fullscreen_widget_mode_enabled_ && enable) { |
| 80 DCHECK(!is_embedding_fullscreen_widget_); | 74 DCHECK(!is_embedding_fullscreen_widget_); |
| 81 embed_fullscreen_widget_mode_enabled_ = true; | 75 embed_fullscreen_widget_mode_enabled_ = true; |
| 82 should_be_embedded = | 76 should_be_embedded = |
| 83 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView(); | 77 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
| 84 } else if (embed_fullscreen_widget_mode_enabled_ && !enable) { | 78 } else if (embed_fullscreen_widget_mode_enabled_ && !enable) { |
| 85 embed_fullscreen_widget_mode_enabled_ = false; | 79 embed_fullscreen_widget_mode_enabled_ = false; |
| 86 } | 80 } |
| 87 if (should_be_embedded != is_embedding_fullscreen_widget_) | 81 if (should_be_embedded != is_embedding_fullscreen_widget_) |
| 88 ReattachForFullscreenChange(should_be_embedded); | 82 ReattachForFullscreenChange(should_be_embedded); |
| 89 } | 83 } |
| 90 | 84 |
| 91 void WebView::LoadInitialURL(const GURL& url) { | 85 void WebView::LoadInitialURL(const GURL& url) { |
| 92 GetWebContents()->GetController().LoadURL( | 86 GetWebContents()->GetController().LoadURL( |
| 93 url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL, | 87 url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 | 122 |
| 129 bool WebView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { | 123 bool WebView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { |
| 130 if (allow_accelerators_) | 124 if (allow_accelerators_) |
| 131 return FocusManager::IsTabTraversalKeyEvent(event); | 125 return FocusManager::IsTabTraversalKeyEvent(event); |
| 132 | 126 |
| 133 // Don't look-up accelerators or tab-traversal if we are showing a non-crashed | 127 // Don't look-up accelerators or tab-traversal if we are showing a non-crashed |
| 134 // TabContents. | 128 // TabContents. |
| 135 // We'll first give the page a chance to process the key events. If it does | 129 // We'll first give the page a chance to process the key events. If it does |
| 136 // not process them, they'll be returned to us and we'll treat them as | 130 // not process them, they'll be returned to us and we'll treat them as |
| 137 // accelerators then. | 131 // accelerators then. |
| 138 return web_contents_ && !web_contents_->IsCrashed(); | 132 return web_contents() && !web_contents()->IsCrashed(); |
| 139 } | 133 } |
| 140 | 134 |
| 141 bool WebView::IsFocusable() const { | 135 bool WebView::IsFocusable() const { |
| 142 // We need to be focusable when our contents is not a view hierarchy, as | 136 // We need to be focusable when our contents is not a view hierarchy, as |
| 143 // clicking on the contents needs to focus us. | 137 // clicking on the contents needs to focus us. |
| 144 return !!web_contents_; | 138 return !!web_contents(); |
| 145 } | 139 } |
| 146 | 140 |
| 147 void WebView::OnFocus() { | 141 void WebView::OnFocus() { |
| 148 if (!web_contents_) | 142 if (!web_contents()) |
| 149 return; | 143 return; |
| 150 if (is_embedding_fullscreen_widget_) { | 144 if (is_embedding_fullscreen_widget_) { |
| 151 content::RenderWidgetHostView* const current_fs_view = | 145 content::RenderWidgetHostView* const current_fs_view = |
| 152 web_contents_->GetFullscreenRenderWidgetHostView(); | 146 web_contents()->GetFullscreenRenderWidgetHostView(); |
| 153 if (current_fs_view) | 147 if (current_fs_view) |
| 154 current_fs_view->Focus(); | 148 current_fs_view->Focus(); |
| 155 } else { | 149 } else { |
| 156 web_contents_->GetView()->Focus(); | 150 web_contents()->GetView()->Focus(); |
| 157 } | 151 } |
| 158 } | 152 } |
| 159 | 153 |
| 160 void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) { | 154 void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) { |
| 161 if (web_contents_) | 155 if (web_contents()) |
| 162 web_contents_->FocusThroughTabTraversal(reverse); | 156 web_contents()->FocusThroughTabTraversal(reverse); |
| 163 } | 157 } |
| 164 | 158 |
| 165 void WebView::GetAccessibleState(ui::AccessibleViewState* state) { | 159 void WebView::GetAccessibleState(ui::AccessibleViewState* state) { |
| 166 state->role = ui::AccessibilityTypes::ROLE_GROUPING; | 160 state->role = ui::AccessibilityTypes::ROLE_GROUPING; |
| 167 } | 161 } |
| 168 | 162 |
| 169 gfx::NativeViewAccessible WebView::GetNativeViewAccessible() { | 163 gfx::NativeViewAccessible WebView::GetNativeViewAccessible() { |
| 170 if (web_contents_) { | 164 if (web_contents()) { |
| 171 content::RenderWidgetHostView* host_view = | 165 content::RenderWidgetHostView* host_view = |
| 172 web_contents_->GetRenderWidgetHostView(); | 166 web_contents()->GetRenderWidgetHostView(); |
| 173 if (host_view) | 167 if (host_view) |
| 174 return host_view->GetNativeViewAccessible(); | 168 return host_view->GetNativeViewAccessible(); |
| 175 } | 169 } |
| 176 return View::GetNativeViewAccessible(); | 170 return View::GetNativeViewAccessible(); |
| 177 } | 171 } |
| 178 | 172 |
| 179 gfx::Size WebView::GetPreferredSize() { | 173 gfx::Size WebView::GetPreferredSize() { |
| 180 if (preferred_size_ == gfx::Size()) | 174 if (preferred_size_ == gfx::Size()) |
| 181 return View::GetPreferredSize(); | 175 return View::GetPreferredSize(); |
| 182 else | 176 else |
| 183 return preferred_size_; | 177 return preferred_size_; |
| 184 } | 178 } |
| 185 | 179 |
| 186 //////////////////////////////////////////////////////////////////////////////// | 180 //////////////////////////////////////////////////////////////////////////////// |
| 187 // WebView, content::WebContentsDelegate implementation: | 181 // WebView, content::WebContentsDelegate implementation: |
| 188 | 182 |
| 189 void WebView::WebContentsFocused(content::WebContents* web_contents) { | 183 void WebView::WebContentsFocused(content::WebContents* web_contents) { |
| 190 DCHECK(wc_owner_.get()); | 184 DCHECK(wc_owner_.get()); |
| 191 // The WebView is only the delegate of WebContentses it creates itself. | 185 // The WebView is only the delegate of WebContentses it creates itself. |
| 192 OnWebContentsFocused(web_contents_); | 186 OnWebContentsFocused(wc_owner_.get()); |
| 193 } | 187 } |
| 194 | 188 |
| 195 bool WebView::EmbedsFullscreenWidget() const { | 189 bool WebView::EmbedsFullscreenWidget() const { |
| 196 DCHECK(wc_owner_.get()); | 190 DCHECK(wc_owner_.get()); |
| 197 return embed_fullscreen_widget_mode_enabled_; | 191 return embed_fullscreen_widget_mode_enabled_; |
| 198 } | 192 } |
| 199 | 193 |
| 200 //////////////////////////////////////////////////////////////////////////////// | 194 //////////////////////////////////////////////////////////////////////////////// |
| 201 // WebView, content::WebContentsObserver implementation: | 195 // WebView, content::WebContentsObserver implementation: |
| 202 | 196 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 224 if (embed_fullscreen_widget_mode_enabled_) | 218 if (embed_fullscreen_widget_mode_enabled_) |
| 225 ReattachForFullscreenChange(false); | 219 ReattachForFullscreenChange(false); |
| 226 } | 220 } |
| 227 | 221 |
| 228 //////////////////////////////////////////////////////////////////////////////// | 222 //////////////////////////////////////////////////////////////////////////////// |
| 229 // WebView, private: | 223 // WebView, private: |
| 230 | 224 |
| 231 void WebView::AttachWebContents() { | 225 void WebView::AttachWebContents() { |
| 232 // Prevents attachment if the WebView isn't already in a Widget, or it's | 226 // Prevents attachment if the WebView isn't already in a Widget, or it's |
| 233 // already attached. | 227 // already attached. |
| 234 if (!GetWidget() || !web_contents_) | 228 if (!GetWidget() || !web_contents()) |
| 235 return; | 229 return; |
| 236 | 230 |
| 237 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? | 231 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? |
| 238 web_contents_->GetFullscreenRenderWidgetHostView()->GetNativeView() : | 232 web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() : |
| 239 web_contents_->GetView()->GetNativeView(); | 233 web_contents()->GetView()->GetNativeView(); |
| 240 if (wcv_holder_->native_view() == view_to_attach) | 234 if (wcv_holder_->native_view() == view_to_attach) |
| 241 return; | 235 return; |
| 242 wcv_holder_->Attach(view_to_attach); | 236 wcv_holder_->Attach(view_to_attach); |
| 243 | 237 |
| 244 // The view will not be focused automatically when it is attached, so we need | 238 // The view will not be focused automatically when it is attached, so we need |
| 245 // to pass on focus to it if the FocusManager thinks the view is focused. Note | 239 // to pass on focus to it if the FocusManager thinks the view is focused. Note |
| 246 // that not every Widget has a focus manager. | 240 // that not every Widget has a focus manager. |
| 247 FocusManager* const focus_manager = GetFocusManager(); | 241 FocusManager* const focus_manager = GetFocusManager(); |
| 248 if (focus_manager && focus_manager->GetFocusedView() == this) | 242 if (focus_manager && focus_manager->GetFocusedView() == this) |
| 249 OnFocus(); | 243 OnFocus(); |
| 250 | 244 |
| 251 WebContentsObserver::Observe(web_contents_); | |
| 252 | |
| 253 #if defined(OS_WIN) && defined(USE_AURA) | 245 #if defined(OS_WIN) && defined(USE_AURA) |
| 254 if (!is_embedding_fullscreen_widget_) { | 246 if (!is_embedding_fullscreen_widget_) { |
| 255 web_contents_->SetParentNativeViewAccessible( | 247 web_contents()->SetParentNativeViewAccessible( |
| 256 parent()->GetNativeViewAccessible()); | 248 parent()->GetNativeViewAccessible()); |
| 257 } | 249 } |
| 258 #endif | 250 #endif |
| 259 } | 251 } |
| 260 | 252 |
| 261 void WebView::DetachWebContents() { | 253 void WebView::DetachWebContents() { |
| 262 if (web_contents_) { | 254 if (web_contents()) { |
| 263 wcv_holder_->Detach(); | 255 wcv_holder_->Detach(); |
| 264 #if defined(OS_WIN) | 256 #if defined(OS_WIN) |
| 265 if (!is_embedding_fullscreen_widget_) { | 257 if (!is_embedding_fullscreen_widget_) { |
| 266 #if !defined(USE_AURA) | 258 #if !defined(USE_AURA) |
| 267 // TODO(beng): This should either not be necessary, or be done implicitly | 259 // TODO(beng): This should either not be necessary, or be done implicitly |
| 268 // by NativeViewHostWin on Detach(). As it stands, this is needed so that | 260 // by NativeViewHostWin on Detach(). As it stands, this is needed so that |
| 269 // the of the detached contents knows to tell the renderer it's been | 261 // the of the detached contents knows to tell the renderer it's been |
| 270 // hidden. | 262 // hidden. |
| 271 // | 263 // |
| 272 // Moving this out of here would also mean we wouldn't be potentially | 264 // Moving this out of here would also mean we wouldn't be potentially |
| 273 // calling member functions on a half-destroyed WebContents. | 265 // calling member functions on a half-destroyed WebContents. |
| 274 ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE); | 266 ShowWindow(web_contents()->GetView()->GetNativeView(), SW_HIDE); |
| 275 #else | 267 #else |
| 276 web_contents_->SetParentNativeViewAccessible(NULL); | 268 web_contents()->SetParentNativeViewAccessible(NULL); |
| 277 #endif | 269 #endif |
| 278 } | 270 } |
| 279 #endif | 271 #endif |
| 280 } | 272 } |
| 281 WebContentsObserver::Observe(NULL); | |
| 282 } | 273 } |
| 283 | 274 |
| 284 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { | 275 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { |
| 285 DetachWebContents(); | 276 DetachWebContents(); |
| 286 is_embedding_fullscreen_widget_ = enter_fullscreen && | 277 is_embedding_fullscreen_widget_ = enter_fullscreen && |
| 287 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView(); | 278 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
| 288 AttachWebContents(); | 279 AttachWebContents(); |
| 289 } | 280 } |
| 290 | 281 |
| 291 content::WebContents* WebView::CreateWebContents( | 282 content::WebContents* WebView::CreateWebContents( |
| 292 content::BrowserContext* browser_context, | 283 content::BrowserContext* browser_context) { |
| 293 content::SiteInstance* site_instance) { | |
| 294 content::WebContents* contents = NULL; | 284 content::WebContents* contents = NULL; |
| 295 if (ViewsDelegate::views_delegate) { | 285 if (ViewsDelegate::views_delegate) { |
| 296 contents = ViewsDelegate::views_delegate->CreateWebContents( | 286 contents = ViewsDelegate::views_delegate->CreateWebContents( |
| 297 browser_context, site_instance); | 287 browser_context, NULL); |
| 298 } | 288 } |
| 299 | 289 |
| 300 if (!contents) { | 290 if (!contents) { |
| 301 content::WebContents::CreateParams create_params( | 291 content::WebContents::CreateParams create_params( |
| 302 browser_context, site_instance); | 292 browser_context, NULL); |
| 303 return content::WebContents::Create(create_params); | 293 return content::WebContents::Create(create_params); |
| 304 } | 294 } |
| 305 | 295 |
| 306 return contents; | 296 return contents; |
| 307 } | 297 } |
| 308 | 298 |
| 309 } // namespace views | 299 } // namespace views |
| OLD | NEW |