Mac: Fix performance issues with remote CoreAnimation
[chromium-blink-merge.git] / components / app_modal / javascript_app_modal_dialog.cc
blob27ccd3d3087356dcd6c518eb1236ee317c6468dc
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 "content/public/browser/web_contents.h"
10 #include "ui/gfx/text_elider.h"
12 #if defined(USE_AURA)
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_event_dispatcher.h"
15 #endif
17 using content::WebContents;
19 namespace app_modal {
20 namespace {
22 // Control maximum sizes of various texts passed to us from javascript.
23 #if defined(OS_POSIX) && !defined(OS_MACOSX)
24 // 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).
27 const int kMessageTextMaxRows = 32;
28 const int kMessageTextMaxCols = 132;
29 const int kDefaultPromptMaxRows = 24;
30 const int kDefaultPromptMaxCols = 132;
31 void EnforceMaxTextSize(const base::string16& in_string,
32 base::string16* out_string) {
33 gfx::ElideRectangleString(in_string, kMessageTextMaxRows,
34 kMessageTextMaxCols, false, out_string);
36 void EnforceMaxPromptSize(const base::string16& in_string,
37 base::string16* out_string) {
38 gfx::ElideRectangleString(in_string, kDefaultPromptMaxRows,
39 kDefaultPromptMaxCols, false, out_string);
41 #else
42 // One-dimensional eliding. Trust the window system to break the string
43 // appropriately, but limit its overall length to something reasonable.
44 const int kMessageTextMaxSize = 3000;
45 const int kDefaultPromptMaxSize = 2000;
46 void EnforceMaxTextSize(const base::string16& in_string,
47 base::string16* out_string) {
48 gfx::ElideString(in_string, kMessageTextMaxSize, out_string);
50 void EnforceMaxPromptSize(const base::string16& in_string,
51 base::string16* out_string) {
52 gfx::ElideString(in_string, kDefaultPromptMaxSize, out_string);
54 #endif
56 } // namespace
58 ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
59 : suppress_javascript_messages_(false) {
62 JavaScriptAppModalDialog::JavaScriptAppModalDialog(
63 WebContents* web_contents,
64 ExtraDataMap* extra_data_map,
65 const base::string16& title,
66 content::JavaScriptMessageType javascript_message_type,
67 const base::string16& message_text,
68 const base::string16& default_prompt_text,
69 bool display_suppress_checkbox,
70 bool is_before_unload_dialog,
71 bool is_reload,
72 const content::JavaScriptDialogManager::DialogClosedCallback& callback)
73 : AppModalDialog(web_contents, title),
74 extra_data_map_(extra_data_map),
75 javascript_message_type_(javascript_message_type),
76 display_suppress_checkbox_(display_suppress_checkbox),
77 is_before_unload_dialog_(is_before_unload_dialog),
78 is_reload_(is_reload),
79 callback_(callback),
80 use_override_prompt_text_(false) {
81 EnforceMaxTextSize(message_text, &message_text_);
82 EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
85 JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
88 NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
89 gfx::NativeWindow parent_window = web_contents()->GetTopLevelNativeWindow();
91 #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;
97 #endif // defined(USE_AURA)
98 return JavaScriptDialogManager::GetInstance()->native_dialog_factory()->
99 CreateNativeJavaScriptDialog(this, parent_window);
102 bool JavaScriptAppModalDialog::IsJavaScriptModalDialog() {
103 return true;
106 void JavaScriptAppModalDialog::Invalidate() {
107 if (!IsValid())
108 return;
110 AppModalDialog::Invalidate();
111 if (!callback_.is_null()) {
112 callback_.Run(false, base::string16());
113 callback_.Reset();
115 if (native_dialog())
116 CloseModalDialog();
119 void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
120 // 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();
128 NotifyDelegate(false, base::string16(), suppress_js_messages);
131 void JavaScriptAppModalDialog::OnAccept(const base::string16& prompt_text,
132 bool suppress_js_messages) {
133 base::string16 prompt_text_to_use = prompt_text;
134 // This is only for testing.
135 if (use_override_prompt_text_)
136 prompt_text_to_use = override_prompt_text_;
138 CompleteDialog();
139 NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
142 void JavaScriptAppModalDialog::OnClose() {
143 NotifyDelegate(false, base::string16(), false);
146 void JavaScriptAppModalDialog::SetOverridePromptText(
147 const base::string16& override_prompt_text) {
148 override_prompt_text_ = override_prompt_text;
149 use_override_prompt_text_ = true;
152 void JavaScriptAppModalDialog::NotifyDelegate(bool success,
153 const base::string16& user_input,
154 bool suppress_js_messages) {
155 if (!IsValid())
156 return;
158 if (!callback_.is_null()) {
159 callback_.Run(success, user_input);
160 callback_.Reset();
163 // The callback_ above may delete web_contents_, thus removing the extra
164 // data from the map owned by ::JavaScriptDialogManager. Make sure
165 // 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;
173 // On Views, we can end up coming through this code path twice :(.
174 // See crbug.com/63732.
175 AppModalDialog::Invalidate();
178 } // namespace app_modal