1 // Copyright 2013 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.
4
5 #include "content/shell/browser/shell_javascript_dialog_manager.h"
6
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "build/build_config.h"
11 #include "components/url_formatter/url_formatter.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/shell/browser/shell_javascript_dialog.h"
15 #include "content/shell/common/shell_switches.h"
16
17 namespace content {
18
ShellJavaScriptDialogManager()19 ShellJavaScriptDialogManager::ShellJavaScriptDialogManager()
20 : should_proceed_on_beforeunload_(true), beforeunload_success_(true) {}
21
~ShellJavaScriptDialogManager()22 ShellJavaScriptDialogManager::~ShellJavaScriptDialogManager() {
23 }
24
RunJavaScriptDialog(WebContents * web_contents,RenderFrameHost * render_frame_host,JavaScriptDialogType dialog_type,const base::string16 & message_text,const base::string16 & default_prompt_text,DialogClosedCallback callback,bool * did_suppress_message)25 void ShellJavaScriptDialogManager::RunJavaScriptDialog(
26 WebContents* web_contents,
27 RenderFrameHost* render_frame_host,
28 JavaScriptDialogType dialog_type,
29 const base::string16& message_text,
30 const base::string16& default_prompt_text,
31 DialogClosedCallback callback,
32 bool* did_suppress_message) {
33 if (dialog_request_callback_) {
34 std::move(dialog_request_callback_).Run();
35 std::move(callback).Run(true, base::string16());
36 return;
37 }
38
39 #if defined(OS_MAC) || defined(OS_WIN)
40 *did_suppress_message = false;
41
42 if (dialog_) {
43 // One dialog at a time, please.
44 *did_suppress_message = true;
45 return;
46 }
47
48 base::string16 new_message_text =
49 url_formatter::FormatUrl(render_frame_host->GetLastCommittedURL()) +
50 base::ASCIIToUTF16("\n\n") + message_text;
51 gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow();
52
53 dialog_.reset(new ShellJavaScriptDialog(this, parent_window, dialog_type,
54 new_message_text, default_prompt_text,
55 std::move(callback)));
56 #else
57 // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
58 *did_suppress_message = true;
59 return;
60 #endif
61 }
62
RunBeforeUnloadDialog(WebContents * web_contents,RenderFrameHost * render_frame_host,bool is_reload,DialogClosedCallback callback)63 void ShellJavaScriptDialogManager::RunBeforeUnloadDialog(
64 WebContents* web_contents,
65 RenderFrameHost* render_frame_host,
66 bool is_reload,
67 DialogClosedCallback callback) {
68 // During tests, if the BeforeUnload should not proceed automatically, store
69 // the callback and return.
70 if (dialog_request_callback_) {
71 std::move(dialog_request_callback_).Run();
72
73 if (should_proceed_on_beforeunload_)
74 std::move(callback).Run(beforeunload_success_, base::string16());
75 else
76 before_unload_callback_ = std::move(callback);
77 return;
78 }
79
80 #if defined(OS_MAC) || defined(OS_WIN)
81 if (dialog_) {
82 // Seriously!?
83 std::move(callback).Run(true, base::string16());
84 return;
85 }
86
87 base::string16 message_text =
88 base::ASCIIToUTF16("Is it OK to leave/reload this page?");
89
90 gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow();
91
92 dialog_.reset(new ShellJavaScriptDialog(
93 this, parent_window, JAVASCRIPT_DIALOG_TYPE_CONFIRM, message_text,
94 base::string16(), // default
95 std::move(callback)));
96 #else
97 // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
98 std::move(callback).Run(true, base::string16());
99 return;
100 #endif
101 }
102
CancelDialogs(WebContents * web_contents,bool reset_state)103 void ShellJavaScriptDialogManager::CancelDialogs(WebContents* web_contents,
104 bool reset_state) {
105 #if defined(OS_MAC) || defined(OS_WIN)
106 if (dialog_) {
107 dialog_->Cancel();
108 dialog_.reset();
109 }
110 #else
111 // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
112 #endif
113
114 if (before_unload_callback_.is_null())
115 return;
116
117 if (reset_state)
118 std::move(before_unload_callback_).Run(false, base::string16());
119 }
120
DialogClosed(ShellJavaScriptDialog * dialog)121 void ShellJavaScriptDialogManager::DialogClosed(ShellJavaScriptDialog* dialog) {
122 #if defined(OS_MAC) || defined(OS_WIN)
123 DCHECK_EQ(dialog, dialog_.get());
124 dialog_.reset();
125 #else
126 // TODO: implement ShellJavaScriptDialog for other platforms, drop this #if
127 #endif
128 }
129
130 } // namespace content
131