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

Side by Side Diff: chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc

Issue 1407093007: Autofill: Add legal message footer to save credit card bubble. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
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 "base/i18n/message_formatter.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/ui/autofill/save_card_bubble_view.h" 10 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
8 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_finder.h" 12 #include "chrome/browser/ui/browser_finder.h"
10 #include "chrome/browser/ui/browser_window.h" 13 #include "chrome/browser/ui/browser_window.h"
11 #include "chrome/browser/ui/location_bar/location_bar.h" 14 #include "chrome/browser/ui/location_bar/location_bar.h"
12 #include "components/autofill/core/common/autofill_constants.h" 15 #include "components/autofill/core/common/autofill_constants.h"
13 #include "content/public/browser/navigation_details.h" 16 #include "content/public/browser/navigation_details.h"
14 17
15 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl); 18 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl);
16 19
(...skipping 18 matching lines...) Expand all
35 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() { 38 SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() {
36 if (save_card_bubble_view_) 39 if (save_card_bubble_view_)
37 save_card_bubble_view_->ControllerGone(); 40 save_card_bubble_view_->ControllerGone();
38 } 41 }
39 42
40 void SaveCardBubbleControllerImpl::SetCallback( 43 void SaveCardBubbleControllerImpl::SetCallback(
41 const base::Closure& save_card_callback) { 44 const base::Closure& save_card_callback) {
42 save_card_callback_ = save_card_callback; 45 save_card_callback_ = save_card_callback;
43 } 46 }
44 47
48 bool SaveCardBubbleControllerImpl::SetLegalMessage(
bondd 2015/11/07 02:29:38 I'll add some unit tests for SetLegalMessage() unl
Evan Stade 2015/11/07 03:03:19 this function needs unit tests
49 const base::ListValue& lines) {
50 ClearLegalMessage();
51 base::string16 message;
52 size_t next_range_index = 0;
Evan Stade 2015/11/07 03:03:19 |next_range_index| is not intuitive at all and req
bondd 2015/11/11 01:53:36 Done.
53
54 // Process all lines of the message. See comment in header file for example
55 // of valid |lines| data.
56 for (size_t line_index = 0; line_index < lines.GetSize(); ++line_index) {
57 const base::DictionaryValue* single_line;
58 if (!lines.GetDictionary(line_index, &single_line))
59 return false;
60
61 // |display_texts| elements are the strings that will be substituted for
62 // "{0}", "{1}", etc. in the template string.
63 std::vector<base::string16> display_texts;
64
65 // Process all the template parameters for the current message line.
66 const base::ListValue* template_parameters = nullptr;
67 if (single_line->GetList("template_parameter", &template_parameters)) {
68 for (size_t parameter_index = 0;
69 parameter_index < template_parameters->GetSize();
70 ++parameter_index) {
71 // Get a single element of the "template_parameter" list.
72 const base::DictionaryValue* single_parameter;
73 if (!template_parameters->GetDictionary(parameter_index,
74 &single_parameter))
75 return false;
76
77 // Read and store the "display_text" string.
78 base::string16 text;
Evan Stade 2015/11/07 03:03:19 display_texts.push_back(base::string16()); if (!si
bondd 2015/11/11 01:53:36 Done.
79 if (!single_parameter->GetString("display_text", &text))
80 return false;
81 display_texts.push_back(text);
82
83 // Read and store the "url" string.
84 LegalMessageLink link;
Evan Stade 2015/11/07 03:03:19 ditto
bondd 2015/11/11 01:53:36 Done.
85 if (!single_parameter->GetString("url", &link.url))
86 return false;
87 legal_message_links_.push_back(link);
88 }
89 }
90
91 // Read the template string. It's a small subset of the ICU message format
92 // syntax.
93 base::string16 template_icu;
94 if (!single_line->GetString("template", &template_icu))
Evan Stade 2015/11/07 03:03:19 this function is pretty long and hard to read, can
bondd 2015/11/11 01:53:36 Done. I think the new level of splitting makes sen
95 return false;
96
97 // Escape "$" -> "$$" for ReplaceStringPlaceholders().
98 //
99 // Edge cases:
100 // 1. Two or more consecutive $ characters will be incorrectly expanded
101 // ("$$" -> "$$$$", which ReplaceStringPlaceholders() then turns into
102 // "$$$").
103 //
104 // 2. "${" will cause false to be returned. "${0}" will expand to "$${0}".
105 // FormatWithNumberedArgs() turns it into "$$$1", which
106 // ReplaceStringPlaceholders() then turns into "$$1" without doing the
107 // parameter replacement. This causes false to be returned because each
108 // parameter is not used exactly once.
109 //
110 // Both of these cases are noted in the header file, and are unlikely to
111 // occur in any actual legal message.
112 base::ReplaceChars(template_icu, base::ASCIIToUTF16("$"),
113 base::ASCIIToUTF16("$$"), &template_icu);
114
115 // Replace "{0}" -> "$1", "{1}" -> "$2", ... to prepare |template_dollars|
116 // for ReplaceStringPlaceholders().
117 base::string16 template_dollars =
118 base::i18n::MessageFormatter::FormatWithNumberedArgs(
119 template_icu, "$1", "$2", "$3", "$4", "$5", "$6", "$7");
120
121 // FormatWithNumberedArgs() returns an empty string on failure.
122 if (template_dollars.empty() && !template_icu.empty())
123 return false;
124
125 // Replace "$1", "$2", ... with the display text of each parameter.
126 std::vector<size_t> offsets;
127 base::string16 message_line =
128 ReplaceStringPlaceholders(template_dollars, display_texts, &offsets);
129
130 // Each parameter must be used exactly once. If a parameter is unused or
131 // used more than once then it can't be determined which |offsets| entry
132 // corresponds to which parameter.
133 if (offsets.size() != display_texts.size())
134 return false;
135
136 // Fill in |range| values for all links in this line.
137 for (size_t offset_index = 0; offset_index < offsets.size();
138 ++offset_index) {
139 size_t range_start = message.size() + offsets[offset_index];
140 legal_message_links_[next_range_index++].range = gfx::Range(
141 range_start, range_start + display_texts[offset_index].size());
142 }
143
144 // |message_line| is now the final line that will be displayed. Append it to
145 // |message|, along with a newline if there will be another line after this
146 // one.
147 message.append(message_line);
148 if (line_index + 1 < lines.GetSize())
149 message.push_back('\n');
150 }
151
152 legal_message_ = message;
Evan Stade 2015/11/07 03:03:19 so legal_message_ will be empty on failure but leg
bondd 2015/11/11 01:53:36 Done. Everything is now empty on failure.
153 return true;
154 }
155
156 void SaveCardBubbleControllerImpl::ClearLegalMessage() {
157 legal_message_.clear();
158 legal_message_links_.clear();
159 }
160
45 void SaveCardBubbleControllerImpl::ShowBubble() { 161 void SaveCardBubbleControllerImpl::ShowBubble() {
46 DCHECK(!save_card_callback_.is_null()); 162 DCHECK(!save_card_callback_.is_null());
47 163
48 // Need to create location bar icon before bubble, otherwise bubble will be 164 // Need to create location bar icon before bubble, otherwise bubble will be
49 // unanchored. 165 // unanchored.
50 UpdateIcon(); 166 UpdateIcon();
51 167
52 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); 168 Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
53 save_card_bubble_view_ = 169 save_card_bubble_view_ =
54 browser->window()->ShowSaveCreditCardBubble(web_contents(), this); 170 browser->window()->ShowSaveCreditCardBubble(web_contents(), this);
(...skipping 22 matching lines...) Expand all
77 void SaveCardBubbleControllerImpl::OnSaveButton() { 193 void SaveCardBubbleControllerImpl::OnSaveButton() {
78 save_card_callback_.Run(); 194 save_card_callback_.Run();
79 save_card_callback_.Reset(); 195 save_card_callback_.Reset();
80 } 196 }
81 197
82 void SaveCardBubbleControllerImpl::OnCancelButton() { 198 void SaveCardBubbleControllerImpl::OnCancelButton() {
83 save_card_callback_.Reset(); 199 save_card_callback_.Reset();
84 } 200 }
85 201
86 void SaveCardBubbleControllerImpl::OnLearnMoreClicked() { 202 void SaveCardBubbleControllerImpl::OnLearnMoreClicked() {
87 web_contents()->OpenURL(content::OpenURLParams( 203 OpenUrl(kHelpURL);
88 GURL(kHelpURL), content::Referrer(), NEW_FOREGROUND_TAB, 204 }
89 ui::PAGE_TRANSITION_LINK, false)); 205
206 void SaveCardBubbleControllerImpl::OnLegalMessageLinkClicked(
207 const gfx::Range& link_range) {
208 for (size_t i = 0; i < legal_message_links_.size(); ++i) {
209 if (legal_message_links_[i].range == link_range) {
210 OpenUrl(legal_message_links_[i].url);
211 return;
212 }
213 }
214 // link_range was not found.
215 NOTREACHED();
90 } 216 }
91 217
92 void SaveCardBubbleControllerImpl::OnBubbleClosed() { 218 void SaveCardBubbleControllerImpl::OnBubbleClosed() {
93 save_card_bubble_view_ = nullptr; 219 save_card_bubble_view_ = nullptr;
94 UpdateIcon(); 220 UpdateIcon();
95 } 221 }
96 222
223 const base::string16& SaveCardBubbleControllerImpl::GetLegalMessage() const {
224 return legal_message_;
225 }
226
227 size_t SaveCardBubbleControllerImpl::GetLegalMessageNumLinks() const {
228 return legal_message_links_.size();
229 }
230
231 const gfx::Range& SaveCardBubbleControllerImpl::GetLegalMessageLinkRange(
232 size_t index) const {
233 return legal_message_links_[index].range;
234 }
235
97 void SaveCardBubbleControllerImpl::UpdateIcon() { 236 void SaveCardBubbleControllerImpl::UpdateIcon() {
98 Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); 237 Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
99 LocationBar* location_bar = browser->window()->GetLocationBar(); 238 LocationBar* location_bar = browser->window()->GetLocationBar();
100 location_bar->UpdateSaveCreditCardIcon(); 239 location_bar->UpdateSaveCreditCardIcon();
101 } 240 }
102 241
242 void SaveCardBubbleControllerImpl::OpenUrl(const std::string& url) {
243 web_contents()->OpenURL(
244 content::OpenURLParams(GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
245 ui::PAGE_TRANSITION_LINK, false));
246 }
247
103 void SaveCardBubbleControllerImpl::DidNavigateMainFrame( 248 void SaveCardBubbleControllerImpl::DidNavigateMainFrame(
104 const content::LoadCommittedDetails& details, 249 const content::LoadCommittedDetails& details,
105 const content::FrameNavigateParams& params) { 250 const content::FrameNavigateParams& params) {
106 // Nothing to do if there's no bubble available. 251 // Nothing to do if there's no bubble available.
107 if (save_card_callback_.is_null()) 252 if (save_card_callback_.is_null())
108 return; 253 return;
109 254
110 // Don't react to in-page (fragment) navigations. 255 // Don't react to in-page (fragment) navigations.
111 if (details.is_in_page) 256 if (details.is_in_page)
112 return; 257 return;
113 258
114 // Don't do anything if a navigation occurs before a user could reasonably 259 // Don't do anything if a navigation occurs before a user could reasonably
115 // interact with the bubble. 260 // interact with the bubble.
116 if (timer_->Elapsed() < 261 if (timer_->Elapsed() <
117 base::TimeDelta::FromSeconds(kSurviveNavigationSeconds)) 262 base::TimeDelta::FromSeconds(kSurviveNavigationSeconds))
118 return; 263 return;
119 264
120 // Otherwise, get rid of the bubble and icon. 265 // Otherwise, get rid of the bubble and icon.
121 save_card_callback_.Reset(); 266 save_card_callback_.Reset();
122 if (save_card_bubble_view_) 267 if (save_card_bubble_view_)
123 save_card_bubble_view_->Close(); 268 save_card_bubble_view_->Close();
124 else 269 else
125 UpdateIcon(); 270 UpdateIcon();
126 } 271 }
127 272
128 } // namespace autofill 273 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698