blob: 27ccd3d3087356dcd6c518eb1236ee317c6468dc [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"
[email protected]51da7e32012-01-30 19:24:529#include "content/public/browser/web_contents.h"
[email protected]dbb97ba2013-09-09 22:15:2510#include "ui/gfx/text_elider.h"
[email protected]12f74a92010-02-05 22:32:1411
[email protected]2a2caa02013-01-22 20:50:3612#if defined(USE_AURA)
[email protected]f7c05b22013-11-12 21:07:2413#include "ui/aura/window.h"
[email protected]fcc51c952014-02-21 21:31:2614#include "ui/aura/window_event_dispatcher.h"
[email protected]2a2caa02013-01-22 20:50:3615#endif
16
[email protected]51da7e32012-01-30 19:24:5217using content::WebContents;
18
oshima0929be2a2014-11-19 22:21:0319namespace app_modal {
[email protected]999adfd62010-06-02 19:42:4220namespace {
21
[email protected]416126c52011-03-29 16:28:5722// Control maximum sizes of various texts passed to us from javascript.
[email protected]7be64502011-05-03 17:51:4723#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]416126c52011-03-29 16:28:5724// Two-dimensional eliding. Reformat the text of the message dialog
25// inserting line breaks because otherwise a single long line can overflow
26// the message dialog (and crash/hang the GTK, depending on the version).
[email protected]af4b9df2010-12-22 21:19:0227const int kMessageTextMaxRows = 32;
28const int kMessageTextMaxCols = 132;
[email protected]416126c52011-03-29 16:28:5729const int kDefaultPromptMaxRows = 24;
30const int kDefaultPromptMaxCols = 132;
[email protected]dcd0249872013-12-06 23:58:4531void EnforceMaxTextSize(const base::string16& in_string,
32 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2533 gfx::ElideRectangleString(in_string, kMessageTextMaxRows,
[email protected]416126c52011-03-29 16:28:5734 kMessageTextMaxCols, false, out_string);
35}
[email protected]dcd0249872013-12-06 23:58:4536void EnforceMaxPromptSize(const base::string16& in_string,
37 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2538 gfx::ElideRectangleString(in_string, kDefaultPromptMaxRows,
[email protected]416126c52011-03-29 16:28:5739 kDefaultPromptMaxCols, false, out_string);
40}
41#else
42// One-dimensional eliding. Trust the window system to break the string
43// appropriately, but limit its overall length to something reasonable.
44const int kMessageTextMaxSize = 3000;
45const int kDefaultPromptMaxSize = 2000;
[email protected]dcd0249872013-12-06 23:58:4546void EnforceMaxTextSize(const base::string16& in_string,
47 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2548 gfx::ElideString(in_string, kMessageTextMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5749}
[email protected]dcd0249872013-12-06 23:58:4550void EnforceMaxPromptSize(const base::string16& in_string,
51 base::string16* out_string) {
[email protected]dbb97ba2013-09-09 22:15:2552 gfx::ElideString(in_string, kDefaultPromptMaxSize, out_string);
[email protected]416126c52011-03-29 16:28:5753}
54#endif
[email protected]999adfd62010-06-02 19:42:4255
56} // namespace
57
[email protected]3ab9cb82011-06-03 18:02:0758ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
59 : suppress_javascript_messages_(false) {
60}
61
[email protected]12f74a92010-02-05 22:32:1462JavaScriptAppModalDialog::JavaScriptAppModalDialog(
[email protected]51da7e32012-01-30 19:24:5263 WebContents* web_contents,
[email protected]1f422a7c2013-05-15 17:06:4164 ExtraDataMap* extra_data_map,
[email protected]dcd0249872013-12-06 23:58:4565 const base::string16& title,
[email protected]be2510c02012-05-28 14:52:1466 content::JavaScriptMessageType javascript_message_type,
[email protected]dcd0249872013-12-06 23:58:4567 const base::string16& message_text,
68 const base::string16& default_prompt_text,
[email protected]12f74a92010-02-05 22:32:1469 bool display_suppress_checkbox,
70 bool is_before_unload_dialog,
[email protected]3b3301f62012-02-29 04:32:3271 bool is_reload,
oshima0929be2a2014-11-19 22:21:0372 const content::JavaScriptDialogManager::DialogClosedCallback& callback)
[email protected]51da7e32012-01-30 19:24:5273 : AppModalDialog(web_contents, title),
[email protected]1f422a7c2013-05-15 17:06:4174 extra_data_map_(extra_data_map),
[email protected]269f86d2011-12-07 02:43:4775 javascript_message_type_(javascript_message_type),
[email protected]12f74a92010-02-05 22:32:1476 display_suppress_checkbox_(display_suppress_checkbox),
77 is_before_unload_dialog_(is_before_unload_dialog),
[email protected]3b3301f62012-02-29 04:32:3278 is_reload_(is_reload),
[email protected]51da7e32012-01-30 19:24:5279 callback_(callback),
[email protected]16623742011-05-16 20:04:2680 use_override_prompt_text_(false) {
[email protected]3ab9cb82011-06-03 18:02:0781 EnforceMaxTextSize(message_text, &message_text_);
82 EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
[email protected]12f74a92010-02-05 22:32:1483}
84
85JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
86}
87
[email protected]160ad3d2010-09-28 15:40:2088NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
[email protected]fc2b46b2014-05-03 16:33:4589 gfx::NativeWindow parent_window = web_contents()->GetTopLevelNativeWindow();
[email protected]884401d32013-05-02 18:53:3790
[email protected]2a2caa02013-01-22 20:50:3691#if defined(USE_AURA)
92 if (!parent_window->GetRootWindow()) {
93 // When we are part of a WebContents that isn't actually being displayed on
94 // the screen, we can't actually attach to it.
95 parent_window = NULL;
96 }
[email protected]884401d32013-05-02 18:53:3797#endif // defined(USE_AURA)
oshima0929be2a2014-11-19 22:21:0398 return JavaScriptDialogManager::GetInstance()->native_dialog_factory()->
oshima758abebc2014-11-06 10:55:5099 CreateNativeJavaScriptDialog(this, parent_window);
[email protected]160ad3d2010-09-28 15:40:20100}
101
[email protected]16623742011-05-16 20:04:26102bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() {
103 return true;
104}
105
[email protected]a1e97f02011-06-30 14:04:34106void JavaScriptAppModalDialog::Invalidate() {
[email protected]1f422a7c2013-05-15 17:06:41107 if (!IsValid())
[email protected]12f74a92010-02-05 22:32:14108 return;
109
[email protected]1f422a7c2013-05-15 17:06:41110 AppModalDialog::Invalidate();
[email protected]af905902013-10-01 21:38:51111 if (!callback_.is_null()) {
[email protected]dcd0249872013-12-06 23:58:45112 callback_.Run(false, base::string16());
[email protected]af905902013-10-01 21:38:51113 callback_.Reset();
114 }
[email protected]1f422a7c2013-05-15 17:06:41115 if (native_dialog())
[email protected]66711f6f2010-06-23 01:17:35116 CloseModalDialog();
[email protected]12f74a92010-02-05 22:32:14117}
118
[email protected]ab96d312010-10-14 13:38:51119void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
[email protected]12f74a92010-02-05 22:32:14120 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
121 // will receive its activation messages before this dialog receives
122 // WM_DESTROY. The parent frame would then try to activate any modal dialogs
123 // that were still open in the ModalDialogQueue, which would send activation
124 // back to this one. The framework should be improved to handle this, so this
125 // is a temporary workaround.
126 CompleteDialog();
127
[email protected]dcd0249872013-12-06 23:58:45128 NotifyDelegate(false, base::string16(), suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14129}
130
[email protected]dcd0249872013-12-06 23:58:45131void JavaScriptAppModalDialog::OnAccept(const base::string16& prompt_text,
[email protected]12f74a92010-02-05 22:32:14132 bool suppress_js_messages) {
[email protected]dcd0249872013-12-06 23:58:45133 base::string16 prompt_text_to_use = prompt_text;
[email protected]16623742011-05-16 20:04:26134 // This is only for testing.
135 if (use_override_prompt_text_)
[email protected]3ab9cb82011-06-03 18:02:07136 prompt_text_to_use = override_prompt_text_;
[email protected]16623742011-05-16 20:04:26137
[email protected]12f74a92010-02-05 22:32:14138 CompleteDialog();
[email protected]16623742011-05-16 20:04:26139 NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
[email protected]12f74a92010-02-05 22:32:14140}
[email protected]7d784302010-04-09 21:41:05141
142void JavaScriptAppModalDialog::OnClose() {
[email protected]dcd0249872013-12-06 23:58:45143 NotifyDelegate(false, base::string16(), false);
[email protected]7d784302010-04-09 21:41:05144}
145
[email protected]16623742011-05-16 20:04:26146void JavaScriptAppModalDialog::SetOverridePromptText(
[email protected]dcd0249872013-12-06 23:58:45147 const base::string16& override_prompt_text) {
[email protected]16623742011-05-16 20:04:26148 override_prompt_text_ = override_prompt_text;
149 use_override_prompt_text_ = true;
150}
151
[email protected]594d0622010-12-07 05:33:07152void JavaScriptAppModalDialog::NotifyDelegate(bool success,
[email protected]dcd0249872013-12-06 23:58:45153 const base::string16& user_input,
[email protected]594d0622010-12-07 05:33:07154 bool suppress_js_messages) {
[email protected]1f422a7c2013-05-15 17:06:41155 if (!IsValid())
[email protected]594d0622010-12-07 05:33:07156 return;
157
[email protected]af905902013-10-01 21:38:51158 if (!callback_.is_null()) {
159 callback_.Run(success, user_input);
160 callback_.Reset();
161 }
[email protected]3ab9cb82011-06-03 18:02:07162
[email protected]1f422a7c2013-05-15 17:06:41163 // The callback_ above may delete web_contents_, thus removing the extra
oshima0929be2a2014-11-19 22:21:03164 // data from the map owned by ::JavaScriptDialogManager. Make sure
[email protected]1f422a7c2013-05-15 17:06:41165 // to only use the data if still present. http://crbug.com/236476
166 ExtraDataMap::iterator extra_data = extra_data_map_->find(web_contents());
167 if (extra_data != extra_data_map_->end()) {
168 extra_data->second.last_javascript_message_dismissal_ =
169 base::TimeTicks::Now();
170 extra_data->second.suppress_javascript_messages_ = suppress_js_messages;
171 }
[email protected]594d0622010-12-07 05:33:07172
173 // On Views, we can end up coming through this code path twice :(.
174 // See crbug.com/63732.
[email protected]1f422a7c2013-05-15 17:06:41175 AppModalDialog::Invalidate();
[email protected]7d784302010-04-09 21:41:05176}
oshima0929be2a2014-11-19 22:21:03177
178} // namespace app_modal