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/views/constrained_window_views.h"
11 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
12 #include "content/public/browser/native_web_keyboard_event.h"
13 #include "content/public/browser/web_contents.h"
14 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
15 #include "ui/views/controls/webview/webview.h"
16 #include "ui/views/widget/widget.h"
17 #include "ui/views/window/dialog_delegate.h"
18 #include "ui/web_dialogs/web_dialog_delegate.h"
19 #include "ui/web_dialogs/web_dialog_ui.h"
23 class WebDialogWebContentsDelegateViews
24 : public ui::WebDialogWebContentsDelegate {
26 WebDialogWebContentsDelegateViews(content::BrowserContext* browser_context,
27 content::WebContents* initiator,
28 views::WebView* web_view)
29 : ui::WebDialogWebContentsDelegate(browser_context,
30 new ChromeWebContentsHandler()),
31 initiator_(initiator),
34 virtual ~WebDialogWebContentsDelegateViews() {}
36 // ui::WebDialogWebContentsDelegate:
37 virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE {
38 // Ensure the WebView is focused when its WebContents is focused.
39 web_view_->RequestFocus();
41 virtual void HandleKeyboardEvent(
42 content::WebContents* source,
43 const content::NativeWebKeyboardEvent& event) OVERRIDE {
44 // Forward shortcut keys in dialog to the browser. http://crbug.com/104586
45 // Disabled on Mac due to http://crbug.com/112173
46 #if !defined(OS_MACOSX)
47 Browser* current_browser = chrome::FindBrowserWithWebContents(initiator_);
50 current_browser->window()->HandleKeyboardEvent(event);
55 content::WebContents* initiator_;
56 views::WebView* web_view_;
58 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateViews);
61 class ConstrainedWebDialogDelegateViews
62 : public ConstrainedWebDialogDelegateBase {
64 ConstrainedWebDialogDelegateViews(content::BrowserContext* context,
65 ui::WebDialogDelegate* delegate,
66 content::WebContents* web_contents,
68 : ConstrainedWebDialogDelegateBase(context, delegate,
69 new WebDialogWebContentsDelegateViews(context, web_contents, view)),
72 virtual ~ConstrainedWebDialogDelegateViews() {}
74 // ui::WebDialogWebContentsDelegate:
75 virtual void CloseContents(content::WebContents* source) OVERRIDE {
76 view_->GetWidget()->Close();
79 // contents::WebContentsDelegate:
80 virtual void HandleKeyboardEvent(
81 content::WebContents* source,
82 const content::NativeWebKeyboardEvent& event) OVERRIDE {
83 unhandled_keyboard_event_handler_.HandleKeyboardEvent(
84 event, view_->GetFocusManager());
87 // ConstrainedWebDialogDelegate:
88 virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
89 return view_->GetWidget()->GetNativeView();
93 // Converts keyboard events on the WebContents to accelerators.
94 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
96 views::WebView* view_;
98 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
101 class ConstrainedWebDialogDelegateViewViews
102 : public views::WebView,
103 public ConstrainedWebDialogDelegate,
104 public views::WidgetDelegate {
106 ConstrainedWebDialogDelegateViewViews(
107 content::BrowserContext* browser_context,
108 ui::WebDialogDelegate* delegate,
109 content::WebContents* web_contents)
110 : views::WebView(browser_context),
111 impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate,
112 web_contents, this)) {
113 SetWebContents(GetWebContents());
114 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
116 virtual ~ConstrainedWebDialogDelegateViewViews() {}
118 // ConstrainedWebDialogDelegate:
119 virtual const ui::WebDialogDelegate* GetWebDialogDelegate() const OVERRIDE {
120 return impl_->GetWebDialogDelegate();
122 virtual ui::WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
123 return impl_->GetWebDialogDelegate();
125 virtual void OnDialogCloseFromWebUI() OVERRIDE {
126 return impl_->OnDialogCloseFromWebUI();
128 virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
129 return impl_->ReleaseWebContentsOnDialogClose();
131 virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
132 return impl_->GetNativeDialog();
134 virtual content::WebContents* GetWebContents() OVERRIDE {
135 return impl_->GetWebContents();
138 // views::WidgetDelegate:
139 virtual views::View* GetInitiallyFocusedView() OVERRIDE {
142 virtual void WindowClosing() OVERRIDE {
143 if (!impl_->closed_via_webui())
144 GetWebDialogDelegate()->OnDialogClosed(std::string());
146 virtual views::Widget* GetWidget() OVERRIDE {
147 return View::GetWidget();
149 virtual const views::Widget* GetWidget() const OVERRIDE {
150 return View::GetWidget();
152 virtual base::string16 GetWindowTitle() const OVERRIDE {
153 return impl_->closed_via_webui() ? base::string16() :
154 GetWebDialogDelegate()->GetDialogTitle();
156 virtual views::View* GetContentsView() OVERRIDE {
159 virtual views::NonClientFrameView* CreateNonClientFrameView(
160 views::Widget* widget) OVERRIDE {
161 return views::DialogDelegate::CreateDialogFrameView(widget);
163 virtual bool ShouldShowCloseButton() const OVERRIDE {
164 // No close button if the dialog doesn't want a title bar.
165 return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
167 virtual ui::ModalType GetModalType() const OVERRIDE {
168 return ui::MODAL_TYPE_CHILD;
172 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
173 // Pressing ESC closes the dialog.
174 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
175 GetWidget()->Close();
178 virtual gfx::Size GetPreferredSize() const OVERRIDE {
180 if (!impl_->closed_via_webui())
181 GetWebDialogDelegate()->GetDialogSize(&size);
184 virtual gfx::Size GetMinimumSize() const OVERRIDE {
185 // Return an empty size so that we can be made smaller.
190 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
192 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
197 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
198 content::BrowserContext* browser_context,
199 ui::WebDialogDelegate* delegate,
200 content::WebContents* web_contents) {
201 ConstrainedWebDialogDelegateViewViews* dialog =
202 new ConstrainedWebDialogDelegateViewViews(
203 browser_context, delegate, web_contents);
204 ShowWebModalDialogViews(dialog, web_contents);