Fast user switcher: Distinguish supervised users from child accounts
[chromium-blink-merge.git] / chrome / browser / ui / views / constrained_web_dialog_delegate_views.cc
blob586d47ac60d0658be78dc6284135a5446ee2c54d
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/ui/browser_finder.h"
9 #include "chrome/browser/ui/browser_window.h"
10 #include "chrome/browser/ui/webui/chrome_web_contents_handler.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"
14 #include "content/public/browser/native_web_keyboard_event.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
18 #include "ui/views/controls/webview/webview.h"
19 #include "ui/views/view.h"
20 #include "ui/views/widget/widget.h"
21 #include "ui/views/window/dialog_delegate.h"
22 #include "ui/web_dialogs/web_dialog_delegate.h"
23 #include "ui/web_dialogs/web_dialog_ui.h"
25 namespace {
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) {
36 private:
37 DISALLOW_COPY_AND_ASSIGN(InitiatorWebContentsObserver);
40 class WebDialogWebContentsDelegateViews
41 : public ui::WebDialogWebContentsDelegate {
42 public:
43 WebDialogWebContentsDelegateViews(content::BrowserContext* browser_context,
44 InitiatorWebContentsObserver* observer,
45 views::WebView* web_view)
46 : ui::WebDialogWebContentsDelegate(browser_context,
47 new ChromeWebContentsHandler()),
48 initiator_observer_(observer),
49 web_view_(web_view) {
51 ~WebDialogWebContentsDelegateViews() override {}
53 // ui::WebDialogWebContentsDelegate:
54 void WebContentsFocused(content::WebContents* contents) override {
55 // Ensure the WebView is focused when its WebContents is focused.
56 web_view_->RequestFocus();
58 void HandleKeyboardEvent(
59 content::WebContents* source,
60 const content::NativeWebKeyboardEvent& event) override {
61 // Forward shortcut keys in dialog to our initiator's delegate.
62 // http://crbug.com/104586
63 // Disabled on Mac due to http://crbug.com/112173
64 #if !defined(OS_MACOSX)
65 if (!initiator_observer_->web_contents())
66 return;
68 auto delegate = initiator_observer_->web_contents()->GetDelegate();
69 if (!delegate)
70 return;
71 delegate->HandleKeyboardEvent(initiator_observer_->web_contents(), event);
72 #endif
75 void ResizeDueToAutoResize(content::WebContents* source,
76 const gfx::Size& preferred_size) override {
77 if (source != web_view_->GetWebContents())
78 return;
80 if (!initiator_observer_->web_contents())
81 return;
83 // Sets WebView's preferred size based on auto-resized contents.
84 web_view_->SetPreferredSize(preferred_size);
86 constrained_window::UpdateWebContentsModalDialogPosition(
87 web_view_->GetWidget(),
88 web_modal::WebContentsModalDialogManager::FromWebContents(
89 initiator_observer_->web_contents())->delegate()->
90 GetWebContentsModalDialogHost());
93 private:
94 InitiatorWebContentsObserver* const initiator_observer_;
95 views::WebView* web_view_;
97 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateViews);
100 class ConstrainedWebDialogDelegateViews
101 : public ConstrainedWebDialogDelegateBase {
102 public:
103 ConstrainedWebDialogDelegateViews(content::BrowserContext* context,
104 ui::WebDialogDelegate* delegate,
105 InitiatorWebContentsObserver* observer,
106 views::WebView* view)
107 : ConstrainedWebDialogDelegateBase(context, delegate,
108 new WebDialogWebContentsDelegateViews(context, observer, view)),
109 view_(view) {}
111 ~ConstrainedWebDialogDelegateViews() override {}
113 // ui::WebDialogWebContentsDelegate:
114 void CloseContents(content::WebContents* source) override {
115 view_->GetWidget()->Close();
118 // contents::WebContentsDelegate:
119 void HandleKeyboardEvent(
120 content::WebContents* source,
121 const content::NativeWebKeyboardEvent& event) override {
122 unhandled_keyboard_event_handler_.HandleKeyboardEvent(
123 event, view_->GetFocusManager());
126 // ConstrainedWebDialogDelegate:
127 gfx::NativeWindow GetNativeDialog() override {
128 return view_->GetWidget()->GetNativeWindow();
131 private:
132 // Converts keyboard events on the WebContents to accelerators.
133 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
135 views::WebView* view_;
137 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
140 class ConstrainedWebDialogDelegateViewViews
141 : public views::WebView,
142 public ConstrainedWebDialogDelegate,
143 public views::WidgetDelegate {
144 public:
145 ConstrainedWebDialogDelegateViewViews(
146 content::BrowserContext* browser_context,
147 ui::WebDialogDelegate* delegate,
148 content::WebContents* web_contents,
149 const gfx::Size& min_size,
150 const gfx::Size& max_size)
151 : views::WebView(browser_context),
152 initiator_observer_(web_contents),
153 impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate,
154 &initiator_observer_,
155 this)),
156 min_size_(min_size),
157 max_size_(max_size) {
158 SetWebContents(GetWebContents());
159 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
161 ~ConstrainedWebDialogDelegateViewViews() override {}
163 // ConstrainedWebDialogDelegate:
164 const ui::WebDialogDelegate* GetWebDialogDelegate() const override {
165 return impl_->GetWebDialogDelegate();
167 ui::WebDialogDelegate* GetWebDialogDelegate() override {
168 return impl_->GetWebDialogDelegate();
170 void OnDialogCloseFromWebUI() override {
171 return impl_->OnDialogCloseFromWebUI();
173 void ReleaseWebContentsOnDialogClose() override {
174 return impl_->ReleaseWebContentsOnDialogClose();
176 gfx::NativeWindow GetNativeDialog() override {
177 return impl_->GetNativeDialog();
179 content::WebContents* GetWebContents() override {
180 return impl_->GetWebContents();
183 // views::WidgetDelegate:
184 views::View* GetInitiallyFocusedView() override { return this; }
185 void WindowClosing() override {
186 if (!impl_->closed_via_webui())
187 GetWebDialogDelegate()->OnDialogClosed(std::string());
189 views::Widget* GetWidget() override { return View::GetWidget(); }
190 const views::Widget* GetWidget() const override { return View::GetWidget(); }
191 base::string16 GetWindowTitle() const override {
192 return impl_->closed_via_webui() ? base::string16() :
193 GetWebDialogDelegate()->GetDialogTitle();
195 views::View* GetContentsView() override { return this; }
196 views::NonClientFrameView* CreateNonClientFrameView(
197 views::Widget* widget) override {
198 return views::DialogDelegate::CreateDialogFrameView(widget);
200 bool ShouldShowCloseButton() const override {
201 // No close button if the dialog doesn't want a title bar.
202 return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
204 ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; }
206 // views::WebView:
207 bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
208 // Pressing ESC closes the dialog.
209 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
210 GetWidget()->Close();
211 return true;
213 gfx::Size GetPreferredSize() const override {
214 gfx::Size size;
215 if (!impl_->closed_via_webui()) {
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);
225 return size;
227 gfx::Size GetMinimumSize() const override {
228 return min_size_;
230 gfx::Size GetMaximumSize() const override {
231 return !max_size_.IsEmpty() ? max_size_ : WebView::GetMaximumSize();
233 void RenderViewCreated(content::RenderViewHost* render_view_host) override {
234 if (!max_size_.IsEmpty())
235 EnableAutoResize();
237 void RenderViewHostChanged(content::RenderViewHost* old_host,
238 content::RenderViewHost* new_host) override {
239 if (!max_size_.IsEmpty())
240 EnableAutoResize();
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()->GetNativeWindow(),
250 initiator_observer_.web_contents());
255 private:
256 void EnableAutoResize() {
257 content::RenderViewHost* render_view_host =
258 GetWebContents()->GetRenderViewHost();
259 render_view_host->EnableAutoResize(min_size_, max_size_);
262 InitiatorWebContentsObserver initiator_observer_;
264 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
266 // Minimum and maximum sizes to determine dialog bounds for auto-resizing.
267 const gfx::Size min_size_;
268 const gfx::Size max_size_;
270 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
273 } // namespace
275 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog(
276 content::BrowserContext* browser_context,
277 ui::WebDialogDelegate* delegate,
278 content::WebContents* web_contents) {
279 ConstrainedWebDialogDelegateViewViews* dialog =
280 new ConstrainedWebDialogDelegateViewViews(
281 browser_context, delegate, web_contents,
282 gfx::Size(), gfx::Size());
283 constrained_window::ShowWebModalDialogViews(dialog, web_contents);
284 return dialog;
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;