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 "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h" | 5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "chrome/browser/ui/browser_finder.h" | 8 #include "chrome/browser/ui/browser_finder.h" |
9 #include "chrome/browser/ui/browser_window.h" | 9 #include "chrome/browser/ui/browser_window.h" |
10 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" | 10 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" |
11 #include "components/constrained_window/constrained_window_views.h" | 11 #include "components/constrained_window/constrained_window_views.h" |
| 12 #include "components/web_modal/popup_manager.h" |
| 13 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
12 #include "content/public/browser/native_web_keyboard_event.h" | 14 #include "content/public/browser/native_web_keyboard_event.h" |
| 15 #include "content/public/browser/render_view_host.h" |
13 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
14 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" | 17 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" |
15 #include "ui/views/controls/webview/webview.h" | 18 #include "ui/views/controls/webview/webview.h" |
| 19 #include "ui/views/view.h" |
16 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
17 #include "ui/views/window/dialog_delegate.h" | 21 #include "ui/views/window/dialog_delegate.h" |
18 #include "ui/web_dialogs/web_dialog_delegate.h" | 22 #include "ui/web_dialogs/web_dialog_delegate.h" |
19 #include "ui/web_dialogs/web_dialog_ui.h" | 23 #include "ui/web_dialogs/web_dialog_ui.h" |
20 | 24 |
21 namespace { | 25 namespace { |
22 | 26 |
| 27 // WebContentsObserver that tracks the lifetime of the WebContents to avoid |
| 28 // potential use after destruction. |
| 29 class InitiatorWebContentsObserver |
| 30 : public content::WebContentsObserver { |
| 31 public: |
| 32 explicit InitiatorWebContentsObserver(content::WebContents* web_contents) |
| 33 : content::WebContentsObserver(web_contents) { |
| 34 } |
| 35 |
| 36 private: |
| 37 DISALLOW_COPY_AND_ASSIGN(InitiatorWebContentsObserver); |
| 38 }; |
| 39 |
23 class WebDialogWebContentsDelegateViews | 40 class WebDialogWebContentsDelegateViews |
24 : public ui::WebDialogWebContentsDelegate { | 41 : public ui::WebDialogWebContentsDelegate { |
25 public: | 42 public: |
26 WebDialogWebContentsDelegateViews(content::BrowserContext* browser_context, | 43 WebDialogWebContentsDelegateViews(content::BrowserContext* browser_context, |
27 content::WebContents* initiator, | 44 InitiatorWebContentsObserver* observer, |
28 views::WebView* web_view) | 45 views::WebView* web_view) |
29 : ui::WebDialogWebContentsDelegate(browser_context, | 46 : ui::WebDialogWebContentsDelegate(browser_context, |
30 new ChromeWebContentsHandler()), | 47 new ChromeWebContentsHandler()), |
31 initiator_(initiator), | 48 initiator_observer_(observer), |
32 web_view_(web_view) { | 49 web_view_(web_view) { |
33 } | 50 } |
34 ~WebDialogWebContentsDelegateViews() override {} | 51 ~WebDialogWebContentsDelegateViews() override {} |
35 | 52 |
36 // ui::WebDialogWebContentsDelegate: | 53 // ui::WebDialogWebContentsDelegate: |
37 void WebContentsFocused(content::WebContents* contents) override { | 54 void WebContentsFocused(content::WebContents* contents) override { |
38 // Ensure the WebView is focused when its WebContents is focused. | 55 // Ensure the WebView is focused when its WebContents is focused. |
39 web_view_->RequestFocus(); | 56 web_view_->RequestFocus(); |
40 } | 57 } |
41 void HandleKeyboardEvent( | 58 void HandleKeyboardEvent( |
42 content::WebContents* source, | 59 content::WebContents* source, |
43 const content::NativeWebKeyboardEvent& event) override { | 60 const content::NativeWebKeyboardEvent& event) override { |
44 // Forward shortcut keys in dialog to our initiator's delegate. | 61 // Forward shortcut keys in dialog to our initiator's delegate. |
45 // http://crbug.com/104586 | 62 // http://crbug.com/104586 |
46 // Disabled on Mac due to http://crbug.com/112173 | 63 // Disabled on Mac due to http://crbug.com/112173 |
47 #if !defined(OS_MACOSX) | 64 #if !defined(OS_MACOSX) |
48 auto delegate = initiator_->GetDelegate(); | 65 if (!initiator_observer_->web_contents()) |
| 66 return; |
| 67 |
| 68 auto delegate = initiator_observer_->web_contents()->GetDelegate(); |
49 if (!delegate) | 69 if (!delegate) |
50 return; | 70 return; |
51 delegate->HandleKeyboardEvent(initiator_, event); | 71 delegate->HandleKeyboardEvent(initiator_observer_->web_contents(), event); |
52 #endif | 72 #endif |
53 } | 73 } |
54 | 74 |
| 75 void ResizeDueToAutoResize(content::WebContents* source, |
| 76 const gfx::Size& preferred_size) override { |
| 77 if (source != web_view_->GetWebContents()) |
| 78 return; |
| 79 |
| 80 if (!initiator_observer_->web_contents()) |
| 81 return; |
| 82 |
| 83 // Sets WebView's preferred size based on auto-resized contents. |
| 84 web_view_->SetPreferredSize(preferred_size); |
| 85 |
| 86 constrained_window::UpdateWebContentsModalDialogPosition( |
| 87 web_view_->GetWidget(), |
| 88 web_modal::WebContentsModalDialogManager::FromWebContents( |
| 89 initiator_observer_->web_contents())->delegate()-> |
| 90 GetWebContentsModalDialogHost()); |
| 91 } |
| 92 |
55 private: | 93 private: |
56 content::WebContents* initiator_; | 94 InitiatorWebContentsObserver* const initiator_observer_; |
57 views::WebView* web_view_; | 95 views::WebView* web_view_; |
58 | 96 |
59 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateViews); | 97 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateViews); |
60 }; | 98 }; |
61 | 99 |
62 class ConstrainedWebDialogDelegateViews | 100 class ConstrainedWebDialogDelegateViews |
63 : public ConstrainedWebDialogDelegateBase { | 101 : public ConstrainedWebDialogDelegateBase { |
64 public: | 102 public: |
65 ConstrainedWebDialogDelegateViews(content::BrowserContext* context, | 103 ConstrainedWebDialogDelegateViews(content::BrowserContext* context, |
66 ui::WebDialogDelegate* delegate, | 104 ui::WebDialogDelegate* delegate, |
67 content::WebContents* web_contents, | 105 InitiatorWebContentsObserver* observer, |
68 views::WebView* view) | 106 views::WebView* view) |
69 : ConstrainedWebDialogDelegateBase(context, delegate, | 107 : ConstrainedWebDialogDelegateBase(context, delegate, |
70 new WebDialogWebContentsDelegateViews(context, web_contents, view)), | 108 new WebDialogWebContentsDelegateViews(context, observer, view)), |
71 view_(view) {} | 109 view_(view) {} |
72 | 110 |
73 ~ConstrainedWebDialogDelegateViews() override {} | 111 ~ConstrainedWebDialogDelegateViews() override {} |
74 | 112 |
75 // ui::WebDialogWebContentsDelegate: | 113 // ui::WebDialogWebContentsDelegate: |
76 void CloseContents(content::WebContents* source) override { | 114 void CloseContents(content::WebContents* source) override { |
77 view_->GetWidget()->Close(); | 115 view_->GetWidget()->Close(); |
78 } | 116 } |
79 | 117 |
80 // contents::WebContentsDelegate: | 118 // contents::WebContentsDelegate: |
(...skipping 19 matching lines...) Expand all Loading... |
100 }; | 138 }; |
101 | 139 |
102 class ConstrainedWebDialogDelegateViewViews | 140 class ConstrainedWebDialogDelegateViewViews |
103 : public views::WebView, | 141 : public views::WebView, |
104 public ConstrainedWebDialogDelegate, | 142 public ConstrainedWebDialogDelegate, |
105 public views::WidgetDelegate { | 143 public views::WidgetDelegate { |
106 public: | 144 public: |
107 ConstrainedWebDialogDelegateViewViews( | 145 ConstrainedWebDialogDelegateViewViews( |
108 content::BrowserContext* browser_context, | 146 content::BrowserContext* browser_context, |
109 ui::WebDialogDelegate* delegate, | 147 ui::WebDialogDelegate* delegate, |
110 content::WebContents* web_contents) | 148 content::WebContents* web_contents, |
| 149 const gfx::Size& min_size, |
| 150 const gfx::Size& max_size) |
111 : views::WebView(browser_context), | 151 : views::WebView(browser_context), |
| 152 initiator_observer_(web_contents), |
112 impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate, | 153 impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate, |
113 web_contents, this)) { | 154 &initiator_observer_, |
| 155 this)), |
| 156 min_size_(min_size), |
| 157 max_size_(max_size) { |
114 SetWebContents(GetWebContents()); | 158 SetWebContents(GetWebContents()); |
115 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 159 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
116 } | 160 } |
117 ~ConstrainedWebDialogDelegateViewViews() override {} | 161 ~ConstrainedWebDialogDelegateViewViews() override {} |
118 | 162 |
119 // ConstrainedWebDialogDelegate: | 163 // ConstrainedWebDialogDelegate: |
120 const ui::WebDialogDelegate* GetWebDialogDelegate() const override { | 164 const ui::WebDialogDelegate* GetWebDialogDelegate() const override { |
121 return impl_->GetWebDialogDelegate(); | 165 return impl_->GetWebDialogDelegate(); |
122 } | 166 } |
123 ui::WebDialogDelegate* GetWebDialogDelegate() override { | 167 ui::WebDialogDelegate* GetWebDialogDelegate() override { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 205 |
162 // views::WebView: | 206 // views::WebView: |
163 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { | 207 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { |
164 // Pressing ESC closes the dialog. | 208 // Pressing ESC closes the dialog. |
165 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code()); | 209 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code()); |
166 GetWidget()->Close(); | 210 GetWidget()->Close(); |
167 return true; | 211 return true; |
168 } | 212 } |
169 gfx::Size GetPreferredSize() const override { | 213 gfx::Size GetPreferredSize() const override { |
170 gfx::Size size; | 214 gfx::Size size; |
171 if (!impl_->closed_via_webui()) | 215 if (!impl_->closed_via_webui()) { |
172 GetWebDialogDelegate()->GetDialogSize(&size); | 216 // The size is set here if the dialog has been auto-resized in |
| 217 // WebDialogWebContentsDelegateViews's ResizeDueToAutoResize. |
| 218 size = WebView::GetPreferredSize(); |
| 219 if (size.IsEmpty()) { |
| 220 // The size set here if the dialog has not been auto-resized or |
| 221 // auto-resizable is not enabled. |
| 222 GetWebDialogDelegate()->GetDialogSize(&size); |
| 223 } |
| 224 } |
173 return size; | 225 return size; |
174 } | 226 } |
175 gfx::Size GetMinimumSize() const override { | 227 gfx::Size GetMinimumSize() const override { |
176 // Return an empty size so that we can be made smaller. | 228 return min_size_; |
177 return gfx::Size(); | 229 } |
| 230 gfx::Size GetMaximumSize() const override { |
| 231 return !max_size_.IsEmpty() ? max_size_ : WebView::GetMaximumSize(); |
| 232 } |
| 233 void RenderViewCreated(content::RenderViewHost* render_view_host) override { |
| 234 if (!max_size_.IsEmpty()) |
| 235 EnableAutoResize(); |
| 236 } |
| 237 void RenderViewHostChanged(content::RenderViewHost* old_host, |
| 238 content::RenderViewHost* new_host) override { |
| 239 if (!max_size_.IsEmpty()) |
| 240 EnableAutoResize(); |
| 241 } |
| 242 void DocumentOnLoadCompletedInMainFrame() override { |
| 243 if (!max_size_.IsEmpty()) { |
| 244 EnableAutoResize(); |
| 245 if (initiator_observer_.web_contents()) { |
| 246 web_modal::PopupManager* popup_manager = |
| 247 web_modal::PopupManager::FromWebContents( |
| 248 initiator_observer_.web_contents()); |
| 249 popup_manager->ShowModalDialog(GetWidget()->GetNativeView(), |
| 250 initiator_observer_.web_contents()); |
| 251 } |
| 252 } |
178 } | 253 } |
179 | 254 |
180 private: | 255 private: |
| 256 void EnableAutoResize() { |
| 257 content::RenderViewHost* render_view_host = |
| 258 GetWebContents()->GetRenderViewHost(); |
| 259 render_view_host->EnableAutoResize(min_size_, max_size_); |
| 260 } |
| 261 |
| 262 InitiatorWebContentsObserver initiator_observer_; |
| 263 |
181 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_; | 264 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_; |
182 | 265 |
| 266 // Minimum and maximum sizes to determine dialog bounds for auto-resizing. |
| 267 const gfx::Size min_size_; |
| 268 const gfx::Size max_size_; |
| 269 |
183 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews); | 270 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews); |
184 }; | 271 }; |
185 | 272 |
186 } // namespace | 273 } // namespace |
187 | 274 |
188 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog( | 275 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog( |
189 content::BrowserContext* browser_context, | 276 content::BrowserContext* browser_context, |
190 ui::WebDialogDelegate* delegate, | 277 ui::WebDialogDelegate* delegate, |
191 content::WebContents* web_contents) { | 278 content::WebContents* web_contents) { |
192 ConstrainedWebDialogDelegateViewViews* dialog = | 279 ConstrainedWebDialogDelegateViewViews* dialog = |
193 new ConstrainedWebDialogDelegateViewViews( | 280 new ConstrainedWebDialogDelegateViewViews( |
194 browser_context, delegate, web_contents); | 281 browser_context, delegate, web_contents, |
| 282 gfx::Size(), gfx::Size()); |
195 constrained_window::ShowWebModalDialogViews(dialog, web_contents); | 283 constrained_window::ShowWebModalDialogViews(dialog, web_contents); |
196 return dialog; | 284 return dialog; |
197 } | 285 } |
| 286 |
| 287 ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize( |
| 288 content::BrowserContext* browser_context, |
| 289 ui::WebDialogDelegate* delegate, |
| 290 content::WebContents* web_contents, |
| 291 const gfx::Size& min_size, |
| 292 const gfx::Size& max_size) { |
| 293 DCHECK(!min_size.IsEmpty()); |
| 294 DCHECK(!max_size.IsEmpty()); |
| 295 ConstrainedWebDialogDelegateViewViews* dialog = |
| 296 new ConstrainedWebDialogDelegateViewViews( |
| 297 browser_context, delegate, web_contents, |
| 298 min_size, max_size); |
| 299 constrained_window::CreateWebModalDialogViews(dialog, web_contents); |
| 300 return dialog; |
| 301 } |
OLD | NEW |