Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: components/autofill/core/browser/legal_message_line.cc

Issue 1540423004: Add card details and legal message to Android save credit card infobar. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: components/autofill review. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "components/autofill/core/browser/legal_message_line.h"
6
7 #include "base/i18n/message_formatter.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12
13 namespace autofill {
14 namespace {
15
16 // Replace "{0}", "{1}", ... in |template_icu| with corresponding strings
17 // from |display_texts|. Sets |out_message| to the resulting string, with
18 // start position of each replacement in |out_offsets|.
19 // Return false on failure. If false is returned then contents of |out_message|
20 // and |out_offsets| are undefined.
21 bool ReplaceTemplatePlaceholders(
22 const base::string16& template_icu,
23 const std::vector<base::string16>& display_texts,
24 base::string16* out_message,
25 std::vector<size_t>* out_offsets) {
26 // Escape "$" -> "$$" for ReplaceStringPlaceholders().
27 //
28 // Edge cases:
29 // 1. Two or more consecutive $ characters will be incorrectly expanded
30 // ("$$" -> "$$$$", which ReplaceStringPlaceholders() then turns into
31 // "$$$").
32 //
33 // 2. "${" will cause false to be returned. "${0}" will expand to "$${0}".
34 // FormatWithNumberedArgs() turns it into "$$$1", which
35 // ReplaceStringPlaceholders() then turns into "$$1" without doing the
36 // parameter replacement. This causes false to be returned because each
37 // parameter is not used exactly once.
38 //
39 // Both of these cases are noted in the header file, and are unlikely to
40 // occur in any actual legal message.
41 base::string16 template_icu_escaped;
42 base::ReplaceChars(template_icu, base::ASCIIToUTF16("$"),
43 base::ASCIIToUTF16("$$"), &template_icu_escaped);
44
45 // Replace "{0}" -> "$1", "{1}" -> "$2", ... to prepare |template_dollars|
46 // for ReplaceStringPlaceholders().
47 base::string16 template_dollars =
48 base::i18n::MessageFormatter::FormatWithNumberedArgs(
49 template_icu_escaped, "$1", "$2", "$3", "$4", "$5", "$6", "$7");
50
51 // FormatWithNumberedArgs() returns an empty string on failure.
52 if (template_dollars.empty() && !template_icu.empty())
53 return false;
54
55 // Replace "$1", "$2", ... with the display text of each parameter.
56 *out_message = base::ReplaceStringPlaceholders(template_dollars,
57 display_texts, out_offsets);
58
59 // Each parameter must be used exactly once. If a parameter is unused or
60 // used more than once then it can't be determined which |offsets| entry
61 // corresponds to which parameter.
62 return out_offsets->size() == display_texts.size();
63 }
64
65 } // namespace
66
67 LegalMessageLine::Link::Link(size_t start,
68 size_t end,
69 const std::string& url_spec)
70 : range(start, end), url(url_spec) {}
71
72 LegalMessageLine::Link::~Link() {}
73
74 LegalMessageLine::LegalMessageLine() {}
75
76 LegalMessageLine::~LegalMessageLine() {}
77
78 // static
79 bool LegalMessageLine::Parse(const base::DictionaryValue& legal_message,
80 LegalMessageLines* out) {
81 const base::ListValue* lines_list = nullptr;
82 if (legal_message.GetList("line", &lines_list)) {
83 LegalMessageLines lines;
84 lines.reserve(lines_list->GetSize());
85 for (size_t i = 0; i < lines_list->GetSize(); ++i) {
86 lines.emplace_back(LegalMessageLine());
87 const base::DictionaryValue* single_line;
88 if (!lines_list->GetDictionary(i, &single_line) ||
89 !lines.back().ParseLine(*single_line))
90 return false;
91 }
92
93 out->swap(lines);
94 }
95
96 return true;
97 }
98
99 bool LegalMessageLine::ParseLine(const base::DictionaryValue& line) {
100 DCHECK(text_.empty());
101 DCHECK(links_.empty());
102
103 // |display_texts| elements are the strings that will be substituted for
104 // "{0}", "{1}", etc. in the template string.
105 std::vector<base::string16> display_texts;
106
107 // Process all the template parameters.
108 const base::ListValue* template_parameters = nullptr;
109 if (line.GetList("template_parameter", &template_parameters)) {
110 display_texts.resize(template_parameters->GetSize());
111 links_.reserve(template_parameters->GetSize());
112
113 for (size_t parameter_index = 0;
114 parameter_index < template_parameters->GetSize(); ++parameter_index) {
115 const base::DictionaryValue* single_parameter;
116 std::string url;
117 if (!template_parameters->GetDictionary(parameter_index,
118 &single_parameter) ||
119 !single_parameter->GetString("display_text",
120 &display_texts[parameter_index]) ||
121 !single_parameter->GetString("url", &url))
122 return false;
123
124 links_.emplace_back(0, 0, url);
125 }
126 }
127
128 // Read the template string. It's a small subset of the ICU message format
129 // syntax.
130 base::string16 template_icu;
131 if (!line.GetString("template", &template_icu))
132 return false;
133
134 // Replace the placeholders in |template_icu| with strings from
135 // |display_texts|, and store the start position of each replacement in
136 // |offsets|.
137 std::vector<size_t> offsets;
138 if (!ReplaceTemplatePlaceholders(template_icu, display_texts, &text_,
139 &offsets))
140 return false;
141
142 // Fill in range values for all links.
143 for (size_t offset_index = 0; offset_index < offsets.size(); ++offset_index) {
144 size_t range_start = offsets[offset_index];
145 links_[offset_index].range = gfx::Range(
146 range_start, range_start + display_texts[offset_index].size());
147 }
148
149 return true;
150 }
151
152 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/legal_message_line.h ('k') | components/autofill/core/browser/legal_message_line_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698