Roll src/third_party/WebKit 86a890b:30421b4 (svn 193837:193840)
[chromium-blink-merge.git] / components / app_modal / javascript_app_modal_dialog.cc
blob083f17b21143ba1f787a3bb786817c86a9d3c68b
1 // Copyright (c) 2012 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.
5 #include "components/app_modal/javascript_app_modal_dialog.h"
7 #include "components/app_modal/javascript_dialog_manager.h"
8 #include "components/app_modal/javascript_native_dialog_factory.h"
9 #include "ui/gfx/text_elider.h"
12 namespace app_modal {
13 namespace {
15 // Control maximum sizes of various texts passed to us from javascript.
16 #if defined(OS_POSIX) && !defined(OS_MACOSX)
17 // Two-dimensional eliding. Reformat the text of the message dialog
18 // inserting line breaks because otherwise a single long line can overflow
19 // the message dialog (and crash/hang the GTK, depending on the version).
20 const int kMessageTextMaxRows = 32;
21 const int kMessageTextMaxCols = 132;
22 const int kDefaultPromptMaxRows = 24;
23 const int kDefaultPromptMaxCols = 132;
24 void EnforceMaxTextSize(const base::string16& in_string,
25 base::string16* out_string) {
26 gfx::ElideRectangleString(in_string, kMessageTextMaxRows,
27 kMessageTextMaxCols, false, out_string);
29 void EnforceMaxPromptSize(const base::string16& in_string,
30 base::string16* out_string) {
31 gfx::ElideRectangleString(in_string, kDefaultPromptMaxRows,
32 kDefaultPromptMaxCols, false, out_string);
34 #else
35 // One-dimensional eliding. Trust the window system to break the string
36 // appropriately, but limit its overall length to something reasonable.
37 const int kMessageTextMaxSize = 3000;
38 const int kDefaultPromptMaxSize = 2000;
39 void EnforceMaxTextSize(const base::string16& in_string,
40 base::string16* out_string) {
41 gfx::ElideString(in_string, kMessageTextMaxSize, out_string);
43 void EnforceMaxPromptSize(const base::string16& in_string,
44 base::string16* out_string) {
45 gfx::ElideString(in_string, kDefaultPromptMaxSize, out_string);
47 #endif
49 } // namespace
51 ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
52 : suppress_javascript_messages_(false) {
55 JavaScriptAppModalDialog::JavaScriptAppModalDialog(
56 content::WebContents* web_contents,
57 ExtraDataMap* extra_data_map,
58 const base::string16& title,
59 content::JavaScriptMessageType javascript_message_type,
60 const base::string16& message_text,
61 const base::string16& default_prompt_text,
62 bool display_suppress_checkbox,
63 bool is_before_unload_dialog,
64 bool is_reload,
65 const content::JavaScriptDialogManager::DialogClosedCallback& callback)
66 : AppModalDialog(web_contents, title),
67 extra_data_map_(extra_data_map),
68 javascript_message_type_(javascript_message_type),
69 display_suppress_checkbox_(display_suppress_checkbox),
70 is_before_unload_dialog_(is_before_unload_dialog),
71 is_reload_(is_reload),
72 callback_(callback),
73 use_override_prompt_text_(false) {
74 EnforceMaxTextSize(message_text, &message_text_);
75 EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
78 JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
81 NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
82 return JavaScriptDialogManager::GetInstance()
83 ->native_dialog_factory()
84 ->CreateNativeJavaScriptDialog(this);
87 bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() {
88 return true;
91 void JavaScriptAppModalDialog::Invalidate() {
92 if (!IsValid())
93 return;
95 AppModalDialog::Invalidate();
96 if (!callback_.is_null()) {
97 callback_.Run(false, base::string16());
98 callback_.Reset();
100 if (native_dialog())
101 CloseModalDialog();
104 void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
105 // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame
106 // will receive its activation messages before this dialog receives
107 // WM_DESTROY. The parent frame would then try to activate any modal dialogs
108 // that were still open in the ModalDialogQueue, which would send activation
109 // back to this one. The framework should be improved to handle this, so this
110 // is a temporary workaround.
111 CompleteDialog();
113 NotifyDelegate(false, base::string16(), suppress_js_messages);
116 void JavaScriptAppModalDialog::OnAccept(const base::string16& prompt_text,
117 bool suppress_js_messages) {
118 base::string16 prompt_text_to_use = prompt_text;
119 // This is only for testing.
120 if (use_override_prompt_text_)
121 prompt_text_to_use = override_prompt_text_;
123 CompleteDialog();
124 NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
127 void JavaScriptAppModalDialog::OnClose() {
128 NotifyDelegate(false, base::string16(), false);
131 void JavaScriptAppModalDialog::SetOverridePromptText(
132 const base::string16& override_prompt_text) {
133 override_prompt_text_ = override_prompt_text;
134 use_override_prompt_text_ = true;
137 void JavaScriptAppModalDialog::NotifyDelegate(bool success,
138 const base::string16& user_input,
139 bool suppress_js_messages) {
140 if (!IsValid())
141 return;
143 if (!callback_.is_null()) {
144 callback_.Run(success, user_input);
145 callback_.Reset();
148 // The callback_ above may delete web_contents_, thus removing the extra
149 // data from the map owned by ::JavaScriptDialogManager. Make sure
150 // to only use the data if still present. http://crbug.com/236476
151 ExtraDataMap::iterator extra_data = extra_data_map_->find(web_contents());
152 if (extra_data != extra_data_map_->end()) {
153 extra_data->second.last_javascript_message_dismissal_ =
154 base::TimeTicks::Now();
155 extra_data->second.suppress_javascript_messages_ = suppress_js_messages;
158 // On Views, we can end up coming through this code path twice :(.
159 // See crbug.com/63732.
160 AppModalDialog::Invalidate();
163 } // namespace app_modal