Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: components/app_modal/javascript_dialog_manager.cc

Issue 1714573002: Remove the ability of webpages to specify strings for the onbeforeunload dialog. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase again Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/app_modal/javascript_dialog_manager.h ('k') | components/app_modal_strings.grdp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/app_modal/javascript_dialog_manager.h" 5 #include "components/app_modal/javascript_dialog_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } 50 }
51 51
52 DISALLOW_COPY_AND_ASSIGN(DefaultExtensionsClient); 52 DISALLOW_COPY_AND_ASSIGN(DefaultExtensionsClient);
53 }; 53 };
54 54
55 bool ShouldDisplaySuppressCheckbox( 55 bool ShouldDisplaySuppressCheckbox(
56 ChromeJavaScriptDialogExtraData* extra_data) { 56 ChromeJavaScriptDialogExtraData* extra_data) {
57 return extra_data->has_already_shown_a_dialog_; 57 return extra_data->has_already_shown_a_dialog_;
58 } 58 }
59 59
60 enum class DialogType { 60 void LogUMAMessageLengthStats(const base::string16& message) {
61 JAVASCRIPT, 61 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfJSDialogMessageCharacters",
62 ON_BEFORE_UNLOAD, 62 static_cast<int32_t>(message.length()));
63 };
64
65 void LogUMAMessageLengthStats(const base::string16& message, DialogType type) {
66 if (type == DialogType::JAVASCRIPT) {
67 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfJSDialogMessageCharacters",
68 static_cast<int32_t>(message.length()));
69 } else {
70 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfOnBeforeUnloadMessageCharacters",
71 static_cast<int32_t>(message.length()));
72 }
73 63
74 int32_t newline_count = 64 int32_t newline_count =
75 std::count_if(message.begin(), message.end(), 65 std::count_if(message.begin(), message.end(),
76 [](const base::char16& c) { return c == '\n'; }); 66 [](const base::char16& c) { return c == '\n'; });
77 if (type == DialogType::JAVASCRIPT) { 67 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfJSDialogMessageNewlines",
78 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfJSDialogMessageNewlines", 68 newline_count);
79 newline_count);
80 } else {
81 UMA_HISTOGRAM_COUNTS("JSDialogs.CountOfOnBeforeUnloadMessageNewlines",
82 newline_count);
83 }
84 } 69 }
85 70
86 } // namespace 71 } // namespace
87 72
88 //////////////////////////////////////////////////////////////////////////////// 73 ////////////////////////////////////////////////////////////////////////////////
89 // JavaScriptDialogManager, public: 74 // JavaScriptDialogManager, public:
90 75
91 // static 76 // static
92 JavaScriptDialogManager* JavaScriptDialogManager::GetInstance() { 77 JavaScriptDialogManager* JavaScriptDialogManager::GetInstance() {
93 return base::Singleton<JavaScriptDialogManager>::get(); 78 return base::Singleton<JavaScriptDialogManager>::get();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 now - last_close_time_); 150 now - last_close_time_);
166 last_close_time_ = base::TimeTicks(); 151 last_close_time_ = base::TimeTicks();
167 } 152 }
168 153
169 bool is_alert = message_type == content::JAVASCRIPT_MESSAGE_TYPE_ALERT; 154 bool is_alert = message_type == content::JAVASCRIPT_MESSAGE_TYPE_ALERT;
170 base::string16 dialog_title = 155 base::string16 dialog_title =
171 GetTitle(web_contents, origin_url, accept_lang, is_alert); 156 GetTitle(web_contents, origin_url, accept_lang, is_alert);
172 157
173 extensions_client_->OnDialogOpened(web_contents); 158 extensions_client_->OnDialogOpened(web_contents);
174 159
175 LogUMAMessageLengthStats(message_text, DialogType::JAVASCRIPT); 160 LogUMAMessageLengthStats(message_text);
176 AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog( 161 AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
177 web_contents, 162 web_contents,
178 &javascript_dialog_extra_data_, 163 &javascript_dialog_extra_data_,
179 dialog_title, 164 dialog_title,
180 message_type, 165 message_type,
181 message_text, 166 message_text,
182 default_prompt_text, 167 default_prompt_text,
183 ShouldDisplaySuppressCheckbox(extra_data), 168 ShouldDisplaySuppressCheckbox(extra_data),
184 false, // is_before_unload_dialog 169 false, // is_before_unload_dialog
185 false, // is_reload 170 false, // is_reload
186 base::Bind(&JavaScriptDialogManager::OnDialogClosed, 171 base::Bind(&JavaScriptDialogManager::OnDialogClosed,
187 base::Unretained(this), web_contents, callback))); 172 base::Unretained(this), web_contents, callback)));
188 } 173 }
189 174
190 void JavaScriptDialogManager::RunBeforeUnloadDialog( 175 void JavaScriptDialogManager::RunBeforeUnloadDialog(
191 content::WebContents* web_contents, 176 content::WebContents* web_contents,
192 const base::string16& message_text,
193 bool is_reload, 177 bool is_reload,
194 const DialogClosedCallback& callback) { 178 const DialogClosedCallback& callback) {
195 ChromeJavaScriptDialogExtraData* extra_data = 179 ChromeJavaScriptDialogExtraData* extra_data =
196 &javascript_dialog_extra_data_[web_contents]; 180 &javascript_dialog_extra_data_[web_contents];
197 181
198 if (extra_data->suppress_javascript_messages_) { 182 if (extra_data->suppress_javascript_messages_) {
199 // If a site harassed the user enough for them to put it on mute, then it 183 // If a site harassed the user enough for them to put it on mute, then it
200 // lost its privilege to deny unloading. 184 // lost its privilege to deny unloading.
201 callback.Run(true, base::string16()); 185 callback.Run(true, base::string16());
202 return; 186 return;
203 } 187 }
204 188
189 // Build the dialog message. We explicitly do _not_ allow the webpage to
190 // specify the contents of this dialog, because most of the time nowadays it's
191 // used for scams.
192 //
193 // This does not violate the spec. Per
194 // https://html.spec.whatwg.org/#prompt-to-unload-a-document, step 7:
195 //
196 // "The prompt shown by the user agent may include the string of the
197 // returnValue attribute, or some leading subset thereof."
198 //
199 // The prompt MAY include the string. It doesn't any more. Scam web page
200 // authors have abused this, so we're taking away the toys from everyone. This
201 // is why we can't have nice things.
202
205 const base::string16 title = l10n_util::GetStringUTF16(is_reload ? 203 const base::string16 title = l10n_util::GetStringUTF16(is_reload ?
206 IDS_BEFORERELOAD_MESSAGEBOX_TITLE : IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE); 204 IDS_BEFORERELOAD_MESSAGEBOX_TITLE : IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE);
207 const base::string16 footer = l10n_util::GetStringUTF16(is_reload ? 205 const base::string16 message =
208 IDS_BEFORERELOAD_MESSAGEBOX_FOOTER : IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER); 206 l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_MESSAGE);
209
210 base::string16 full_message =
211 message_text + base::ASCIIToUTF16("\n\n") + footer;
212 207
213 extensions_client_->OnDialogOpened(web_contents); 208 extensions_client_->OnDialogOpened(web_contents);
214 209
215 LogUMAMessageLengthStats(message_text, DialogType::ON_BEFORE_UNLOAD);
216 AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog( 210 AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
217 web_contents, 211 web_contents,
218 &javascript_dialog_extra_data_, 212 &javascript_dialog_extra_data_,
219 title, 213 title,
220 content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM, 214 content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
221 full_message, 215 message,
222 base::string16(), // default_prompt_text 216 base::string16(), // default_prompt_text
223 ShouldDisplaySuppressCheckbox(extra_data), 217 ShouldDisplaySuppressCheckbox(extra_data),
224 true, // is_before_unload_dialog 218 true, // is_before_unload_dialog
225 is_reload, 219 is_reload,
226 base::Bind(&JavaScriptDialogManager::OnBeforeUnloadDialogClosed, 220 base::Bind(&JavaScriptDialogManager::OnBeforeUnloadDialogClosed,
227 base::Unretained(this), web_contents, callback))); 221 base::Unretained(this), web_contents, callback)));
228 } 222 }
229 223
230 bool JavaScriptDialogManager::HandleJavaScriptDialog( 224 bool JavaScriptDialogManager::HandleJavaScriptDialog(
231 content::WebContents* web_contents, 225 content::WebContents* web_contents,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // lazy background page after the dialog closes. (Dialogs are closed before 329 // lazy background page after the dialog closes. (Dialogs are closed before
336 // their WebContents is destroyed so |web_contents| is still valid here.) 330 // their WebContents is destroyed so |web_contents| is still valid here.)
337 extensions_client_->OnDialogClosed(web_contents); 331 extensions_client_->OnDialogClosed(web_contents);
338 332
339 last_close_time_ = base::TimeTicks::Now(); 333 last_close_time_ = base::TimeTicks::Now();
340 334
341 callback.Run(success, user_input); 335 callback.Run(success, user_input);
342 } 336 }
343 337
344 } // namespace app_modal 338 } // namespace app_modal
OLDNEW
« no previous file with comments | « components/app_modal/javascript_dialog_manager.h ('k') | components/app_modal_strings.grdp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698