OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" | 5 #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/i18n/message_formatter.h" | 9 #include "base/i18n/message_formatter.h" |
Justin Donnelly
2015/12/30 18:06:37
Remove this and I think the next two lines as well
please use gerrit instead
2016/01/07 01:39:25
Done.
| |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/ui/autofill/save_card_bubble_view.h" | 12 #include "chrome/browser/ui/autofill/save_card_bubble_view.h" |
13 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
14 #include "chrome/browser/ui/browser_finder.h" | 14 #include "chrome/browser/ui/browser_finder.h" |
15 #include "chrome/browser/ui/browser_window.h" | 15 #include "chrome/browser/ui/browser_window.h" |
16 #include "chrome/browser/ui/location_bar/location_bar.h" | 16 #include "chrome/browser/ui/location_bar/location_bar.h" |
17 #include "components/autofill/core/browser/autofill_metrics.h" | 17 #include "components/autofill/core/browser/autofill_metrics.h" |
18 #include "components/autofill/core/common/autofill_constants.h" | 18 #include "components/autofill/core/common/autofill_constants.h" |
19 #include "content/public/browser/navigation_details.h" | 19 #include "content/public/browser/navigation_details.h" |
20 #include "grit/components_strings.h" | 20 #include "grit/components_strings.h" |
21 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
22 | 22 |
23 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl); | 23 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl); |
24 | 24 |
25 namespace autofill { | 25 namespace autofill { |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 // Number of seconds the bubble and icon will survive navigations, starting | 29 // Number of seconds the bubble and icon will survive navigations, starting |
30 // from when the bubble is shown. | 30 // from when the bubble is shown. |
31 // TODO(bondd): Share with ManagePasswordsUIController. | 31 // TODO(bondd): Share with ManagePasswordsUIController. |
32 const int kSurviveNavigationSeconds = 5; | 32 const int kSurviveNavigationSeconds = 5; |
33 | 33 |
34 // Replace "{0}", "{1}", ... in |template_icu| with corresponding strings | |
35 // from |display_texts|. Sets |out_message| to the resulting string, with | |
36 // start position of each replacement in |out_offsets|. | |
37 // Return false on failure. If false is returned then contents of |out_message| | |
38 // and |out_offsets| are undefined. | |
39 bool ReplaceTemplatePlaceholders( | |
40 const base::string16& template_icu, | |
41 const std::vector<base::string16>& display_texts, | |
42 base::string16* out_message, | |
43 std::vector<size_t>* out_offsets) { | |
44 // Escape "$" -> "$$" for ReplaceStringPlaceholders(). | |
45 // | |
46 // Edge cases: | |
47 // 1. Two or more consecutive $ characters will be incorrectly expanded | |
48 // ("$$" -> "$$$$", which ReplaceStringPlaceholders() then turns into | |
49 // "$$$"). | |
50 // | |
51 // 2. "${" will cause false to be returned. "${0}" will expand to "$${0}". | |
52 // FormatWithNumberedArgs() turns it into "$$$1", which | |
53 // ReplaceStringPlaceholders() then turns into "$$1" without doing the | |
54 // parameter replacement. This causes false to be returned because each | |
55 // parameter is not used exactly once. | |
56 // | |
57 // Both of these cases are noted in the header file, and are unlikely to | |
58 // occur in any actual legal message. | |
59 base::string16 template_icu_escaped; | |
60 base::ReplaceChars(template_icu, base::ASCIIToUTF16("$"), | |
61 base::ASCIIToUTF16("$$"), &template_icu_escaped); | |
62 | |
63 // Replace "{0}" -> "$1", "{1}" -> "$2", ... to prepare |template_dollars| | |
64 // for ReplaceStringPlaceholders(). | |
65 base::string16 template_dollars = | |
66 base::i18n::MessageFormatter::FormatWithNumberedArgs( | |
67 template_icu_escaped, "$1", "$2", "$3", "$4", "$5", "$6", "$7"); | |
68 | |
69 // FormatWithNumberedArgs() returns an empty string on failure. | |
70 if (template_dollars.empty() && !template_icu.empty()) | |
71 return false; | |
72 | |
73 // Replace "$1", "$2", ... with the display text of each parameter. | |
74 *out_message = base::ReplaceStringPlaceholders(template_dollars, | |
75 display_texts, out_offsets); | |
76 | |
77 // Each parameter must be used exactly once. If a parameter is unused or | |
78 // used more than once then it can't be determined which |offsets| entry | |
79 // corresponds to which parameter. | |
80 return out_offsets->size() == display_texts.size(); | |
81 } | |
82 | |
83 // Parses |line| and sets |out|. | |
84 // Returns false on failure. |out| is not modified if false is returned. | |
85 bool ParseLegalMessageLine(const base::DictionaryValue& line, | |
86 SaveCardBubbleController::LegalMessageLine* out) { | |
87 SaveCardBubbleController::LegalMessageLine result; | |
88 | |
89 // |display_texts| elements are the strings that will be substituted for | |
90 // "{0}", "{1}", etc. in the template string. | |
91 std::vector<base::string16> display_texts; | |
92 | |
93 // Process all the template parameters. | |
94 const base::ListValue* template_parameters = nullptr; | |
95 if (line.GetList("template_parameter", &template_parameters)) { | |
96 display_texts.resize(template_parameters->GetSize()); | |
97 result.links.resize(template_parameters->GetSize()); | |
98 | |
99 for (size_t parameter_index = 0; | |
100 parameter_index < template_parameters->GetSize(); ++parameter_index) { | |
101 const base::DictionaryValue* single_parameter; | |
102 std::string url; | |
103 if (!template_parameters->GetDictionary(parameter_index, | |
104 &single_parameter) || | |
105 !single_parameter->GetString("display_text", | |
106 &display_texts[parameter_index]) || | |
107 !single_parameter->GetString("url", &url)) { | |
108 return false; | |
109 } | |
110 result.links[parameter_index].url = GURL(url); | |
111 } | |
112 } | |
113 | |
114 // Read the template string. It's a small subset of the ICU message format | |
115 // syntax. | |
116 base::string16 template_icu; | |
117 if (!line.GetString("template", &template_icu)) | |
118 return false; | |
119 | |
120 // Replace the placeholders in |template_icu| with strings from | |
121 // |display_texts|, and store the start position of each replacement in | |
122 // |offsets|. | |
123 std::vector<size_t> offsets; | |
124 if (!ReplaceTemplatePlaceholders(template_icu, display_texts, &result.text, | |
125 &offsets)) { | |
126 return false; | |
127 } | |
128 | |
129 // Fill in range values for all links. | |
130 for (size_t offset_index = 0; offset_index < offsets.size(); ++offset_index) { | |
131 size_t range_start = offsets[offset_index]; | |
132 result.links[offset_index].range = gfx::Range( | |
133 range_start, range_start + display_texts[offset_index].size()); | |
134 } | |
135 | |
136 *out = result; | |
137 return true; | |
138 } | |
139 | |
140 } // namespace | 34 } // namespace |
141 | 35 |
142 SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl( | 36 SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl( |
143 content::WebContents* web_contents) | 37 content::WebContents* web_contents) |
144 : content::WebContentsObserver(web_contents), | 38 : content::WebContentsObserver(web_contents), |
145 save_card_bubble_view_(nullptr) { | 39 save_card_bubble_view_(nullptr) { |
146 DCHECK(web_contents); | 40 DCHECK(web_contents); |
147 } | 41 } |
148 | 42 |
149 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() { | 43 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() { |
(...skipping 15 matching lines...) Expand all Loading... | |
165 | 59 |
166 void SaveCardBubbleControllerImpl::ShowBubbleForUpload( | 60 void SaveCardBubbleControllerImpl::ShowBubbleForUpload( |
167 const base::Closure& save_card_callback, | 61 const base::Closure& save_card_callback, |
168 scoped_ptr<base::DictionaryValue> legal_message) { | 62 scoped_ptr<base::DictionaryValue> legal_message) { |
169 is_uploading_ = true; | 63 is_uploading_ = true; |
170 is_reshow_ = false; | 64 is_reshow_ = false; |
171 AutofillMetrics::LogSaveCardPromptMetric( | 65 AutofillMetrics::LogSaveCardPromptMetric( |
172 AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, | 66 AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, |
173 is_reshow_); | 67 is_reshow_); |
174 | 68 |
175 const base::ListValue* lines = nullptr; | 69 if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_)) { |
176 if (legal_message->GetList("line", &lines)) { | |
177 // Process all lines of the legal message. See comment in header file for | |
178 // example of valid |legal_message| data. | |
179 legal_message_lines_.resize(lines->GetSize()); | |
180 for (size_t i = 0; i < lines->GetSize(); ++i) { | |
181 const base::DictionaryValue* single_line; | |
182 if (!lines->GetDictionary(i, &single_line) || | |
183 !ParseLegalMessageLine(*single_line, &legal_message_lines_[i])) { | |
184 lines = nullptr; | |
185 break; | |
186 } | |
187 } | |
188 } | |
189 | |
190 if (!lines) { | |
191 AutofillMetrics::LogSaveCardPromptMetric( | 70 AutofillMetrics::LogSaveCardPromptMetric( |
192 AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE, | 71 AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE, |
193 is_uploading_, is_reshow_); | 72 is_uploading_, is_reshow_); |
194 | |
195 legal_message_lines_.clear(); | |
196 return; | 73 return; |
197 } | 74 } |
198 | 75 |
199 save_card_callback_ = save_card_callback; | 76 save_card_callback_ = save_card_callback; |
200 ShowBubble(); | 77 ShowBubble(); |
201 } | 78 } |
202 | 79 |
203 void SaveCardBubbleControllerImpl::ReshowBubble() { | 80 void SaveCardBubbleControllerImpl::ReshowBubble() { |
204 is_reshow_ = true; | 81 is_reshow_ = true; |
205 AutofillMetrics::LogSaveCardPromptMetric( | 82 AutofillMetrics::LogSaveCardPromptMetric( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 AutofillMetrics::LogSaveCardPromptMetric( | 133 AutofillMetrics::LogSaveCardPromptMetric( |
257 AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE, | 134 AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE, |
258 is_uploading_, is_reshow_); | 135 is_uploading_, is_reshow_); |
259 } | 136 } |
260 | 137 |
261 void SaveCardBubbleControllerImpl::OnBubbleClosed() { | 138 void SaveCardBubbleControllerImpl::OnBubbleClosed() { |
262 save_card_bubble_view_ = nullptr; | 139 save_card_bubble_view_ = nullptr; |
263 UpdateIcon(); | 140 UpdateIcon(); |
264 } | 141 } |
265 | 142 |
266 const SaveCardBubbleController::LegalMessageLines& | 143 const LegalMessageLines& SaveCardBubbleControllerImpl::GetLegalMessageLines() |
267 SaveCardBubbleControllerImpl::GetLegalMessageLines() const { | 144 const { |
268 return legal_message_lines_; | 145 return legal_message_lines_; |
269 } | 146 } |
270 | 147 |
271 base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const { | 148 base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const { |
272 return timer_->Elapsed(); | 149 return timer_->Elapsed(); |
273 } | 150 } |
274 | 151 |
275 void SaveCardBubbleControllerImpl::DidNavigateMainFrame( | 152 void SaveCardBubbleControllerImpl::DidNavigateMainFrame( |
276 const content::LoadCommittedDetails& details, | 153 const content::LoadCommittedDetails& details, |
277 const content::FrameNavigateParams& params) { | 154 const content::FrameNavigateParams& params) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 location_bar->UpdateSaveCreditCardIcon(); | 212 location_bar->UpdateSaveCreditCardIcon(); |
336 } | 213 } |
337 | 214 |
338 void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) { | 215 void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) { |
339 web_contents()->OpenURL( | 216 web_contents()->OpenURL( |
340 content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB, | 217 content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB, |
341 ui::PAGE_TRANSITION_LINK, false)); | 218 ui::PAGE_TRANSITION_LINK, false)); |
342 } | 219 } |
343 | 220 |
344 } // namespace autofill | 221 } // namespace autofill |
OLD | NEW |