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 |