blob: 1452bd37a3f663b0686c57a1b012cb2c92ed683b [file] [log] [blame]
[email protected]fedec012012-01-28 03:09:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]12f74a92010-02-05 22:32:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
oshimaf65398422014-11-18 23:30:425#include "components/app_modal/javascript_app_modal_dialog.h"
[email protected]12f74a92010-02-05 22:32:146
oshima0929be2a2014-11-19 22:21:037#include "components/app_modal/javascript_dialog_manager.h"
oshimaf65398422014-11-18 23:30:428#include "components/app_modal/javascript_native_dialog_factory.h"
palmerd8b2ff02015-08-18 00:24:599#include "content/public/browser/web_contents.h"
[email protected]dbb97ba2013-09-09 22:15:2510#include "ui/gfx/text_elider.h"
palmerd8b2ff02015-08-18 00:24:5911#include "url/origin.h"
[email protected]51da7e32012-01-30 19:24:5212
oshima0929be2a2014-11-19 22:21:0313namespace app_modal {
[email protected]999adfd62010-06-02 19:42:4214namespace {
15
[email protected]416126c52011-03-29 16:28:5716// Control maximum sizes of various texts passed to us from javascript.
[email protected]7be64502011-05-03 17:51:4717#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]416126c52011-03-29 16:28:5718// Two-dimensional eliding. Reformat the text of the message dialog
19// inserting line breaks because otherwise a single long line can overflow
20// the message dialog (and crash/hang the GTK, depending on the version).
[email protected]af4b9df2010-12-22 21:19:0221const int kMessageTextMaxRows = 32;
22const int kMessageTextMaxCols = 132;
[email protected]416126c52011-03-29 16:28:5723const int kDefaultPromptMaxRows = 24;
24const int kDefaultPromptMaxCols = 132;
[email protected]dcd0249872013-12-06 23:58:4525void EnforceMaxTextSize(const base::string16& in_string,
26 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2527 gfx::ElideRectangleString(in_string, kMessageTextMaxRows,
[email protected]416126c52011-03-29 16:28:5728 kMessageTextMaxCols, false, out_string);
29}
[email protected]dcd0249872013-12-06 23:58:4530void EnforceMaxPromptSize(const base::string16& in_string,
31 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2532 gfx::ElideRectangleString(in_string, kDefaultPromptMaxRows,
[email protected]416126c52011-03-29 16:28:5733 kDefaultPromptMaxCols, false, out_string);
34}
35#else
36// One-dimensional eliding. Trust the window system to break the string
37// appropriately, but limit its overall length to something reasonable.
38const int kMessageTextMaxSize = 3000;
39const int kDefaultPromptMaxSize = 2000;
[email protected]dcd0249872013-12-06 23:58:4540void EnforceMaxTextSize(const base::string16& in_string,
41 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2542 gfx::ElideString(in_string, kMessageTextMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5743}
[email protected]dcd0249872013-12-06 23:58:4544void EnforceMaxPromptSize(const base::string16& in_string,
45 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2546 gfx::ElideString(in_string, kDefaultPromptMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5747}
48#endif
[email protected]999adfd62010-06-02 19:42:4249
50} // namespace
51
[email protected]3ab9cb82011-06-03 18:02:0752ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
palmerd8b2ff02015-08-18 00:24:5953 : has_already_shown_a_dialog_(false),
54 suppress_javascript_messages_(false) {}
[email protected]3ab9cb82011-06-03 18:02:0755
[email protected]12f74a92010-02-05 22:32:1456JavaScriptAppModalDialog::JavaScriptAppModalDialog(
jochena2afdec2015-01-23 13:09:2257 content::WebContents* web_contents,
[email protected]1f422a7c2013-05-15 17:06:4158 ExtraDataMap* extra_data_map,
[email protected]dcd0249872013-12-06 23:58:4559 const base::string16& title,
[email protected]be2510c02012-05-28 14:52:1460 content::JavaScriptMessageType javascript_message_type,
[email protected]dcd0249872013-12-06 23:58:4561 const base::string16& message_text,
62 const base::string16& default_prompt_text,
[email protected]12f74a92010-02-05 22:32:1463 bool display_suppress_checkbox,
64 bool is_before_unload_dialog,
[email protected]3b3301f62012-02-29 04:32:3265 bool is_reload,
oshima0929be2a2014-11-19 22:21:0366 const content::JavaScriptDialogManager::DialogClosedCallback& callback)
[email protected]51da7e32012-01-30 19:24:5267 : AppModalDialog(web_contents, title),
[email protected]1f422a7c2013-05-15 17:06:4168 extra_data_map_(extra_data_map),
[email protected]269f86d2011-12-07 02:43:4769 javascript_message_type_(javascript_message_type),
[email protected]12f74a92010-02-05 22:32:1470 display_suppress_checkbox_(display_suppress_checkbox),
71 is_before_unload_dialog_(is_before_unload_dialog),
[email protected]3b3301f62012-02-29 04:32:3272 is_reload_(is_reload),
[email protected]51da7e32012-01-30 19:24:5273 callback_(callback),
[email protected]16623742011-05-16 20:04:2674 use_override_prompt_text_(false) {
[email protected]3ab9cb82011-06-03 18:02:0775 EnforceMaxTextSize(message_text, &message_text_);
76 EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
[email protected]12f74a92010-02-05 22:32:1477}
78
79JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
80}
81
[email protected]160ad3d2010-09-28 15:40:2082NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
jochena2afdec2015-01-23 13:09:2283 return JavaScriptDialogManager::GetInstance()
84 ->native_dialog_factory()
85 ->CreateNativeJavaScriptDialog(this);
[email protected]160ad3d2010-09-28 15:40:2086}
87
[email protected]16623742011-05-16 20:04:2688bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() {
89 return true;
90}
91
[email protected]a1e97f02011-06-30 14:04:3492void JavaScriptAppModalDialog::Invalidate() {
[email protected]1f422a7c2013-05-15 17:06:4193 if (!IsValid())
[email protected]12f74a92010-02-05 22:32:1494 return;
95
[email protected]1f422a7c2013-05-15 17:06:4196 AppModalDialog::Invalidate();
[email protected]af905902013-10-01 21:38:5197 if (!callback_.is_null()) {
[email protected]dcd0249872013-12-06 23:58:4598 callback_.Run(false, base::string16());
[email protected]af905902013-10-01 21:38:5199 callback_.Reset();
100 }
[email protected]1f422a7c2013-05-15 17:06:41101 if (native_dialog())
[email protected]66711f6f2010-06-23 01:17:35102 CloseModalDialog();
[email protected]12f74a92010-02-05 22:32:14103}
104
[email protected]ab96d312010-10-14 13:38:51105void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
[email protected]12f74a92010-02-05 22:32:14106 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
107 // will receive its activation messages before this dialog receives
108 // WM_DESTROY. The parent frame would then try to activate any modal dialogs
109 // that were still open in the ModalDialogQueue, which would send activation
110 // back to this one. The framework should be improved to handle this, so this
111 // is a temporary workaround.
112 CompleteDialog();
113
[email protected]dcd0249872013-12-06 23:58:45114 NotifyDelegate(false, base::string16(), suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14115}
116
[email protected]dcd0249872013-12-06 23:58:45117void JavaScriptAppModalDialog::OnAccept(const base::string16& prompt_text,
[email protected]12f74a92010-02-05 22:32:14118 bool suppress_js_messages) {
[email protected]dcd0249872013-12-06 23:58:45119 base::string16 prompt_text_to_use = prompt_text;
[email protected]16623742011-05-16 20:04:26120 // This is only for testing.
121 if (use_override_prompt_text_)
[email protected]3ab9cb82011-06-03 18:02:07122 prompt_text_to_use = override_prompt_text_;
[email protected]16623742011-05-16 20:04:26123
[email protected]12f74a92010-02-05 22:32:14124 CompleteDialog();
[email protected]16623742011-05-16 20:04:26125 NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14126}
[email protected]7d784302010-04-09 21:41:05127
128void JavaScriptAppModalDialog::OnClose() {
[email protected]dcd0249872013-12-06 23:58:45129 NotifyDelegate(false, base::string16(), false);
[email protected]7d784302010-04-09 21:41:05130}
131
[email protected]16623742011-05-16 20:04:26132void JavaScriptAppModalDialog::SetOverridePromptText(
[email protected]dcd0249872013-12-06 23:58:45133 const base::string16& override_prompt_text) {
[email protected]16623742011-05-16 20:04:26134 override_prompt_text_ = override_prompt_text;
135 use_override_prompt_text_ = true;
136}
137
[email protected]594d0622010-12-07 05:33:07138void JavaScriptAppModalDialog::NotifyDelegate(bool success,
[email protected]dcd0249872013-12-06 23:58:45139 const base::string16& user_input,
[email protected]594d0622010-12-07 05:33:07140 bool suppress_js_messages) {
[email protected]1f422a7c2013-05-15 17:06:41141 if (!IsValid())
[email protected]594d0622010-12-07 05:33:07142 return;
143
[email protected]af905902013-10-01 21:38:51144 if (!callback_.is_null()) {
145 callback_.Run(success, user_input);
146 callback_.Reset();
147 }
[email protected]3ab9cb82011-06-03 18:02:07148
[email protected]1f422a7c2013-05-15 17:06:41149 // The callback_ above may delete web_contents_, thus removing the extra
oshima0929be2a2014-11-19 22:21:03150 // data from the map owned by ::JavaScriptDialogManager. Make sure
[email protected]1f422a7c2013-05-15 17:06:41151 // to only use the data if still present. http://crbug.com/236476
palmerd8b2ff02015-08-18 00:24:59152 ExtraDataMap::iterator extra_data =
153 extra_data_map_->find(GetSerializedOriginForWebContents(web_contents()));
[email protected]1f422a7c2013-05-15 17:06:41154 if (extra_data != extra_data_map_->end()) {
palmerd8b2ff02015-08-18 00:24:59155 extra_data->second.has_already_shown_a_dialog_ = true;
[email protected]1f422a7c2013-05-15 17:06:41156 extra_data->second.suppress_javascript_messages_ = suppress_js_messages;
157 }
[email protected]594d0622010-12-07 05:33:07158
159 // On Views, we can end up coming through this code path twice :(.
160 // See crbug.com/63732.
[email protected]1f422a7c2013-05-15 17:06:41161 AppModalDialog::Invalidate();
[email protected]7d784302010-04-09 21:41:05162}
oshima0929be2a2014-11-19 22:21:03163
palmerd8b2ff02015-08-18 00:24:59164// static
165std::string JavaScriptAppModalDialog::GetSerializedOriginForWebContents(
166 content::WebContents* contents) {
167 if (!contents)
168 return url::Origin().Serialize();
169 return url::Origin(contents->GetLastCommittedURL()).Serialize();
170}
171
oshima0929be2a2014-11-19 22:21:03172} // namespace app_modal