blob: d2cc9032871619ef5d3fce671cda02a1f53f7d2a [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
avibc5337b2015-12-25 23:16:337#include "build/build_config.h"
oshima0929be2a2014-11-19 22:21:038#include "components/app_modal/javascript_dialog_manager.h"
oshimaf65398422014-11-18 23:30:429#include "components/app_modal/javascript_native_dialog_factory.h"
palmerd8b2ff02015-08-18 00:24:5910#include "content/public/browser/web_contents.h"
[email protected]dbb97ba2013-09-09 22:15:2511#include "ui/gfx/text_elider.h"
palmerd8b2ff02015-08-18 00:24:5912#include "url/origin.h"
[email protected]51da7e32012-01-30 19:24:5213
oshima0929be2a2014-11-19 22:21:0314namespace app_modal {
[email protected]999adfd62010-06-02 19:42:4215namespace {
16
[email protected]416126c52011-03-29 16:28:5717// Control maximum sizes of various texts passed to us from javascript.
[email protected]7be64502011-05-03 17:51:4718#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]416126c52011-03-29 16:28:5719// Two-dimensional eliding. Reformat the text of the message dialog
20// inserting line breaks because otherwise a single long line can overflow
21// the message dialog (and crash/hang the GTK, depending on the version).
[email protected]af4b9df2010-12-22 21:19:0222const int kMessageTextMaxRows = 32;
23const int kMessageTextMaxCols = 132;
[email protected]416126c52011-03-29 16:28:5724const int kDefaultPromptMaxRows = 24;
25const int kDefaultPromptMaxCols = 132;
[email protected]dcd0249872013-12-06 23:58:4526void EnforceMaxTextSize(const base::string16& in_string,
27 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2528 gfx::ElideRectangleString(in_string, kMessageTextMaxRows,
[email protected]416126c52011-03-29 16:28:5729 kMessageTextMaxCols, false, out_string);
30}
[email protected]dcd0249872013-12-06 23:58:4531void EnforceMaxPromptSize(const base::string16& in_string,
32 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2533 gfx::ElideRectangleString(in_string, kDefaultPromptMaxRows,
[email protected]416126c52011-03-29 16:28:5734 kDefaultPromptMaxCols, false, out_string);
35}
36#else
37// One-dimensional eliding. Trust the window system to break the string
38// appropriately, but limit its overall length to something reasonable.
thestigbbf93ac2016-02-02 00:24:4939const size_t kMessageTextMaxSize = 2000;
40const size_t kDefaultPromptMaxSize = 2000;
[email protected]dcd0249872013-12-06 23:58:4541void EnforceMaxTextSize(const base::string16& in_string,
42 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2543 gfx::ElideString(in_string, kMessageTextMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5744}
[email protected]dcd0249872013-12-06 23:58:4545void EnforceMaxPromptSize(const base::string16& in_string,
46 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2547 gfx::ElideString(in_string, kDefaultPromptMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5748}
49#endif
[email protected]999adfd62010-06-02 19:42:4250
51} // namespace
52
[email protected]3ab9cb82011-06-03 18:02:0753ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
palmerd8b2ff02015-08-18 00:24:5954 : has_already_shown_a_dialog_(false),
55 suppress_javascript_messages_(false) {}
[email protected]3ab9cb82011-06-03 18:02:0756
[email protected]12f74a92010-02-05 22:32:1457JavaScriptAppModalDialog::JavaScriptAppModalDialog(
jochena2afdec2015-01-23 13:09:2258 content::WebContents* web_contents,
[email protected]1f422a7c2013-05-15 17:06:4159 ExtraDataMap* extra_data_map,
[email protected]dcd0249872013-12-06 23:58:4560 const base::string16& title,
[email protected]be2510c02012-05-28 14:52:1461 content::JavaScriptMessageType javascript_message_type,
[email protected]dcd0249872013-12-06 23:58:4562 const base::string16& message_text,
63 const base::string16& default_prompt_text,
[email protected]12f74a92010-02-05 22:32:1464 bool display_suppress_checkbox,
65 bool is_before_unload_dialog,
[email protected]3b3301f62012-02-29 04:32:3266 bool is_reload,
oshima0929be2a2014-11-19 22:21:0367 const content::JavaScriptDialogManager::DialogClosedCallback& callback)
[email protected]51da7e32012-01-30 19:24:5268 : AppModalDialog(web_contents, title),
[email protected]1f422a7c2013-05-15 17:06:4169 extra_data_map_(extra_data_map),
[email protected]269f86d2011-12-07 02:43:4770 javascript_message_type_(javascript_message_type),
[email protected]12f74a92010-02-05 22:32:1471 display_suppress_checkbox_(display_suppress_checkbox),
72 is_before_unload_dialog_(is_before_unload_dialog),
[email protected]3b3301f62012-02-29 04:32:3273 is_reload_(is_reload),
[email protected]51da7e32012-01-30 19:24:5274 callback_(callback),
[email protected]16623742011-05-16 20:04:2675 use_override_prompt_text_(false) {
[email protected]3ab9cb82011-06-03 18:02:0776 EnforceMaxTextSize(message_text, &message_text_);
77 EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
[email protected]12f74a92010-02-05 22:32:1478}
79
80JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
81}
82
[email protected]160ad3d2010-09-28 15:40:2083NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
jochena2afdec2015-01-23 13:09:2284 return JavaScriptDialogManager::GetInstance()
85 ->native_dialog_factory()
86 ->CreateNativeJavaScriptDialog(this);
[email protected]160ad3d2010-09-28 15:40:2087}
88
[email protected]16623742011-05-16 20:04:2689bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() {
90 return true;
91}
92
[email protected]a1e97f02011-06-30 14:04:3493void JavaScriptAppModalDialog::Invalidate() {
[email protected]1f422a7c2013-05-15 17:06:4194 if (!IsValid())
[email protected]12f74a92010-02-05 22:32:1495 return;
96
[email protected]1f422a7c2013-05-15 17:06:4197 AppModalDialog::Invalidate();
[email protected]af905902013-10-01 21:38:5198 if (!callback_.is_null()) {
[email protected]dcd0249872013-12-06 23:58:4599 callback_.Run(false, base::string16());
[email protected]af905902013-10-01 21:38:51100 callback_.Reset();
101 }
[email protected]1f422a7c2013-05-15 17:06:41102 if (native_dialog())
[email protected]66711f6f2010-06-23 01:17:35103 CloseModalDialog();
[email protected]12f74a92010-02-05 22:32:14104}
105
[email protected]ab96d312010-10-14 13:38:51106void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
[email protected]12f74a92010-02-05 22:32:14107 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
108 // will receive its activation messages before this dialog receives
109 // WM_DESTROY. The parent frame would then try to activate any modal dialogs
110 // that were still open in the ModalDialogQueue, which would send activation
111 // back to this one. The framework should be improved to handle this, so this
112 // is a temporary workaround.
113 CompleteDialog();
114
[email protected]dcd0249872013-12-06 23:58:45115 NotifyDelegate(false, base::string16(), suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14116}
117
[email protected]dcd0249872013-12-06 23:58:45118void JavaScriptAppModalDialog::OnAccept(const base::string16& prompt_text,
[email protected]12f74a92010-02-05 22:32:14119 bool suppress_js_messages) {
[email protected]dcd0249872013-12-06 23:58:45120 base::string16 prompt_text_to_use = prompt_text;
[email protected]16623742011-05-16 20:04:26121 // This is only for testing.
122 if (use_override_prompt_text_)
[email protected]3ab9cb82011-06-03 18:02:07123 prompt_text_to_use = override_prompt_text_;
[email protected]16623742011-05-16 20:04:26124
[email protected]12f74a92010-02-05 22:32:14125 CompleteDialog();
[email protected]16623742011-05-16 20:04:26126 NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14127}
[email protected]7d784302010-04-09 21:41:05128
129void JavaScriptAppModalDialog::OnClose() {
[email protected]dcd0249872013-12-06 23:58:45130 NotifyDelegate(false, base::string16(), false);
[email protected]7d784302010-04-09 21:41:05131}
132
[email protected]16623742011-05-16 20:04:26133void JavaScriptAppModalDialog::SetOverridePromptText(
[email protected]dcd0249872013-12-06 23:58:45134 const base::string16& override_prompt_text) {
[email protected]16623742011-05-16 20:04:26135 override_prompt_text_ = override_prompt_text;
136 use_override_prompt_text_ = true;
137}
138
[email protected]594d0622010-12-07 05:33:07139void JavaScriptAppModalDialog::NotifyDelegate(bool success,
[email protected]dcd0249872013-12-06 23:58:45140 const base::string16& user_input,
[email protected]594d0622010-12-07 05:33:07141 bool suppress_js_messages) {
[email protected]1f422a7c2013-05-15 17:06:41142 if (!IsValid())
[email protected]594d0622010-12-07 05:33:07143 return;
144
[email protected]af905902013-10-01 21:38:51145 if (!callback_.is_null()) {
146 callback_.Run(success, user_input);
147 callback_.Reset();
148 }
[email protected]3ab9cb82011-06-03 18:02:07149
[email protected]1f422a7c2013-05-15 17:06:41150 // The callback_ above may delete web_contents_, thus removing the extra
oshima0929be2a2014-11-19 22:21:03151 // data from the map owned by ::JavaScriptDialogManager. Make sure
[email protected]1f422a7c2013-05-15 17:06:41152 // to only use the data if still present. http://crbug.com/236476
palmerd8b2ff02015-08-18 00:24:59153 ExtraDataMap::iterator extra_data =
154 extra_data_map_->find(GetSerializedOriginForWebContents(web_contents()));
[email protected]1f422a7c2013-05-15 17:06:41155 if (extra_data != extra_data_map_->end()) {
palmerd8b2ff02015-08-18 00:24:59156 extra_data->second.has_already_shown_a_dialog_ = true;
[email protected]1f422a7c2013-05-15 17:06:41157 extra_data->second.suppress_javascript_messages_ = suppress_js_messages;
158 }
[email protected]594d0622010-12-07 05:33:07159
160 // On Views, we can end up coming through this code path twice :(.
161 // See crbug.com/63732.
[email protected]1f422a7c2013-05-15 17:06:41162 AppModalDialog::Invalidate();
[email protected]7d784302010-04-09 21:41:05163}
oshima0929be2a2014-11-19 22:21:03164
palmerd8b2ff02015-08-18 00:24:59165// static
166std::string JavaScriptAppModalDialog::GetSerializedOriginForWebContents(
167 content::WebContents* contents) {
168 if (!contents)
169 return url::Origin().Serialize();
170 return url::Origin(contents->GetLastCommittedURL()).Serialize();
171}
172
oshima0929be2a2014-11-19 22:21:03173} // namespace app_modal