Add ICU message format support
[chromium-blink-merge.git] / ui / views / controls / webview / web_dialog_view.cc
blob4b5e8b2ebcd1cd47d0d1ae4afdef9ca3af878336
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 "ui/views/controls/webview/web_dialog_view.h"
7 #include <vector>
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "content/public/browser/notification_details.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "ui/events/event.h"
18 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/views/controls/webview/webview.h"
20 #include "ui/views/layout/fill_layout.h"
21 #include "ui/views/widget/native_widget_private.h"
22 #include "ui/views/widget/root_view.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/web_dialogs/web_dialog_delegate.h"
25 #include "ui/web_dialogs/web_dialog_ui.h"
27 using content::NativeWebKeyboardEvent;
28 using content::WebContents;
29 using content::WebUIMessageHandler;
30 using ui::WebDialogDelegate;
31 using ui::WebDialogUI;
32 using ui::WebDialogWebContentsDelegate;
34 namespace views {
36 ////////////////////////////////////////////////////////////////////////////////
37 // WebDialogView, public:
39 WebDialogView::WebDialogView(
40 content::BrowserContext* context,
41 WebDialogDelegate* delegate,
42 WebContentsHandler* handler)
43 : ClientView(NULL, NULL),
44 WebDialogWebContentsDelegate(context, handler),
45 delegate_(delegate),
46 web_view_(new views::WebView(context)),
47 is_attempting_close_dialog_(false),
48 before_unload_fired_(false),
49 closed_via_webui_(false),
50 close_contents_called_(false) {
51 web_view_->set_allow_accelerators(true);
52 AddChildView(web_view_);
53 set_contents_view(web_view_);
54 SetLayoutManager(new views::FillLayout);
55 // Pressing the ESC key will close the dialog.
56 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
59 WebDialogView::~WebDialogView() {
62 content::WebContents* WebDialogView::web_contents() {
63 return web_view_->web_contents();
66 ////////////////////////////////////////////////////////////////////////////////
67 // WebDialogView, views::View implementation:
69 gfx::Size WebDialogView::GetPreferredSize() const {
70 gfx::Size out;
71 if (delegate_)
72 delegate_->GetDialogSize(&out);
73 return out;
76 gfx::Size WebDialogView::GetMinimumSize() const {
77 gfx::Size out;
78 if (delegate_)
79 delegate_->GetMinimumDialogSize(&out);
80 return out;
83 bool WebDialogView::AcceleratorPressed(const ui::Accelerator& accelerator) {
84 // Pressing ESC closes the dialog.
85 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
86 if (GetWidget())
87 GetWidget()->Close();
88 return true;
91 void WebDialogView::ViewHierarchyChanged(
92 const ViewHierarchyChangedDetails& details) {
93 if (details.is_add && GetWidget())
94 InitDialog();
97 bool WebDialogView::CanClose() {
98 // Don't close UI if |delegate_| does not allow users to close it by
99 // clicking on "x" button or pressing Esc shortcut key on hosting dialog.
100 if (!delegate_->CanCloseDialog() && !close_contents_called_)
101 return false;
103 // If CloseContents() is called before CanClose(), which is called by
104 // RenderViewHostImpl::ClosePageIgnoringUnloadEvents, it indicates
105 // beforeunload event should not be fired during closing.
106 if ((is_attempting_close_dialog_ && before_unload_fired_) ||
107 close_contents_called_) {
108 is_attempting_close_dialog_ = false;
109 before_unload_fired_ = false;
110 return true;
113 if (!is_attempting_close_dialog_) {
114 // Fire beforeunload event when user attempts to close the dialog.
115 is_attempting_close_dialog_ = true;
116 web_view_->web_contents()->DispatchBeforeUnload(false);
118 return false;
121 ////////////////////////////////////////////////////////////////////////////////
122 // WebDialogView, views::WidgetDelegate implementation:
124 bool WebDialogView::CanResize() const {
125 if (delegate_)
126 return delegate_->CanResizeDialog();
127 return true;
130 ui::ModalType WebDialogView::GetModalType() const {
131 return GetDialogModalType();
134 base::string16 WebDialogView::GetWindowTitle() const {
135 if (delegate_)
136 return delegate_->GetDialogTitle();
137 return base::string16();
140 std::string WebDialogView::GetWindowName() const {
141 if (delegate_)
142 return delegate_->GetDialogName();
143 return std::string();
146 void WebDialogView::WindowClosing() {
147 // If we still have a delegate that means we haven't notified it of the
148 // dialog closing. This happens if the user clicks the Close button on the
149 // dialog.
150 if (delegate_)
151 OnDialogClosed("");
154 views::View* WebDialogView::GetContentsView() {
155 return this;
158 views::ClientView* WebDialogView::CreateClientView(views::Widget* widget) {
159 return this;
162 views::View* WebDialogView::GetInitiallyFocusedView() {
163 return web_view_;
166 bool WebDialogView::ShouldShowWindowTitle() const {
167 return ShouldShowDialogTitle();
170 views::Widget* WebDialogView::GetWidget() {
171 return View::GetWidget();
174 const views::Widget* WebDialogView::GetWidget() const {
175 return View::GetWidget();
178 ////////////////////////////////////////////////////////////////////////////////
179 // WebDialogDelegate implementation:
181 ui::ModalType WebDialogView::GetDialogModalType() const {
182 if (delegate_)
183 return delegate_->GetDialogModalType();
184 return ui::MODAL_TYPE_NONE;
187 base::string16 WebDialogView::GetDialogTitle() const {
188 return GetWindowTitle();
191 GURL WebDialogView::GetDialogContentURL() const {
192 if (delegate_)
193 return delegate_->GetDialogContentURL();
194 return GURL();
197 void WebDialogView::GetWebUIMessageHandlers(
198 std::vector<WebUIMessageHandler*>* handlers) const {
199 if (delegate_)
200 delegate_->GetWebUIMessageHandlers(handlers);
203 void WebDialogView::GetDialogSize(gfx::Size* size) const {
204 if (delegate_)
205 delegate_->GetDialogSize(size);
208 void WebDialogView::GetMinimumDialogSize(gfx::Size* size) const {
209 if (delegate_)
210 delegate_->GetMinimumDialogSize(size);
213 std::string WebDialogView::GetDialogArgs() const {
214 if (delegate_)
215 return delegate_->GetDialogArgs();
216 return std::string();
219 void WebDialogView::OnDialogShown(content::WebUI* webui,
220 content::RenderViewHost* render_view_host) {
221 if (delegate_)
222 delegate_->OnDialogShown(webui, render_view_host);
225 void WebDialogView::OnDialogClosed(const std::string& json_retval) {
226 Detach();
227 if (delegate_) {
228 // Store the dialog content area size.
229 delegate_->StoreDialogSize(GetContentsBounds().size());
232 if (GetWidget())
233 GetWidget()->Close();
235 if (delegate_) {
236 delegate_->OnDialogClosed(json_retval);
237 delegate_ = NULL; // We will not communicate further with the delegate.
241 void WebDialogView::OnDialogCloseFromWebUI(const std::string& json_retval) {
242 closed_via_webui_ = true;
243 dialog_close_retval_ = json_retval;
244 if (GetWidget())
245 GetWidget()->Close();
248 void WebDialogView::OnCloseContents(WebContents* source,
249 bool* out_close_dialog) {
250 DCHECK(out_close_dialog);
251 if (delegate_)
252 delegate_->OnCloseContents(source, out_close_dialog);
255 bool WebDialogView::ShouldShowDialogTitle() const {
256 if (delegate_)
257 return delegate_->ShouldShowDialogTitle();
258 return true;
261 bool WebDialogView::HandleContextMenu(
262 const content::ContextMenuParams& params) {
263 if (delegate_)
264 return delegate_->HandleContextMenu(params);
265 return WebDialogWebContentsDelegate::HandleContextMenu(params);
268 ////////////////////////////////////////////////////////////////////////////////
269 // content::WebContentsDelegate implementation:
271 void WebDialogView::MoveContents(WebContents* source, const gfx::Rect& pos) {
272 // The contained web page wishes to resize itself. We let it do this because
273 // if it's a dialog we know about, we trust it not to be mean to the user.
274 GetWidget()->SetBounds(pos);
277 // A simplified version of BrowserView::HandleKeyboardEvent().
278 // We don't handle global keyboard shortcuts here, but that's fine since
279 // they're all browser-specific. (This may change in the future.)
280 void WebDialogView::HandleKeyboardEvent(content::WebContents* source,
281 const NativeWebKeyboardEvent& event) {
282 if (!event.os_event)
283 return;
285 GetWidget()->native_widget_private()->RepostNativeEvent(event.os_event);
288 void WebDialogView::CloseContents(WebContents* source) {
289 close_contents_called_ = true;
290 bool close_dialog = false;
291 OnCloseContents(source, &close_dialog);
292 if (close_dialog)
293 OnDialogClosed(closed_via_webui_ ? dialog_close_retval_ : std::string());
296 content::WebContents* WebDialogView::OpenURLFromTab(
297 content::WebContents* source,
298 const content::OpenURLParams& params) {
299 content::WebContents* new_contents = NULL;
300 if (delegate_ &&
301 delegate_->HandleOpenURLFromTab(source, params, &new_contents)) {
302 return new_contents;
304 return WebDialogWebContentsDelegate::OpenURLFromTab(source, params);
307 void WebDialogView::AddNewContents(content::WebContents* source,
308 content::WebContents* new_contents,
309 WindowOpenDisposition disposition,
310 const gfx::Rect& initial_rect,
311 bool user_gesture,
312 bool* was_blocked) {
313 if (delegate_ && delegate_->HandleAddNewContents(
314 source, new_contents, disposition, initial_rect, user_gesture)) {
315 return;
317 WebDialogWebContentsDelegate::AddNewContents(
318 source, new_contents, disposition, initial_rect, user_gesture,
319 was_blocked);
322 void WebDialogView::LoadingStateChanged(content::WebContents* source,
323 bool to_different_document) {
324 if (delegate_)
325 delegate_->OnLoadingStateChanged(source);
328 void WebDialogView::BeforeUnloadFired(content::WebContents* tab,
329 bool proceed,
330 bool* proceed_to_fire_unload) {
331 before_unload_fired_ = true;
332 *proceed_to_fire_unload = proceed;
335 bool WebDialogView::ShouldCreateWebContents(
336 content::WebContents* web_contents,
337 int route_id,
338 int main_frame_route_id,
339 WindowContainerType window_container_type,
340 const std::string& frame_name,
341 const GURL& target_url,
342 const std::string& partition_id,
343 content::SessionStorageNamespace* session_storage_namespace) {
344 if (delegate_)
345 return delegate_->HandleShouldCreateWebContents();
346 return true;
349 ////////////////////////////////////////////////////////////////////////////////
350 // WebDialogView, private:
352 void WebDialogView::InitDialog() {
353 content::WebContents* web_contents = web_view_->GetWebContents();
354 if (web_contents->GetDelegate() == this)
355 return;
357 web_contents->SetDelegate(this);
359 // Set the delegate. This must be done before loading the page. See
360 // the comment above WebDialogUI in its header file for why.
361 WebDialogUI::SetDelegate(web_contents, this);
363 web_view_->LoadInitialURL(GetDialogContentURL());
366 } // namespace views