OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/autofill_credit_card_bubble_controller.h" | 5 #include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
13 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
15 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h" | 18 #include "chrome/browser/ui/autofill/autofill_credit_card_bubble.h" |
18 #include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h" | 19 #include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h" |
19 #include "chrome/browser/ui/browser_finder.h" | 20 #include "chrome/browser/ui/browser_finder.h" |
20 #include "chrome/browser/ui/browser_navigator.h" | 21 #include "chrome/browser/ui/browser_navigator.h" |
21 #include "chrome/browser/ui/browser_window.h" | 22 #include "chrome/browser/ui/browser_window.h" |
22 #include "chrome/browser/ui/omnibox/location_bar.h" | 23 #include "chrome/browser/ui/omnibox/location_bar.h" |
23 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 24 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
24 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
26 #include "components/autofill/core/browser/autofill_profile.h" | |
27 #include "components/autofill/core/browser/credit_card.h" | |
25 #include "components/user_prefs/pref_registry_syncable.h" | 28 #include "components/user_prefs/pref_registry_syncable.h" |
26 #include "content/public/browser/navigation_details.h" | 29 #include "content/public/browser/navigation_details.h" |
27 #include "content/public/browser/navigation_entry.h" | 30 #include "content/public/browser/navigation_entry.h" |
28 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
32 #include "grit/chromium_strings.h" | |
29 #include "grit/generated_resources.h" | 33 #include "grit/generated_resources.h" |
30 #include "grit/theme_resources.h" | 34 #include "grit/theme_resources.h" |
31 #include "grit/webkit_resources.h" | |
32 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
33 #include "ui/base/range/range.h" | |
34 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
35 #include "ui/gfx/image/image.h" | |
36 | 37 |
37 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::AutofillCreditCardBubbleController); | 38 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::AutofillCreditCardBubbleController); |
38 | 39 |
39 namespace autofill { | 40 namespace autofill { |
40 | 41 |
41 namespace { | 42 namespace { |
42 | 43 |
43 static const int kMaxGeneratedCardTimesToShow = 5; | 44 static const int kMaxGeneratedCardTimesToShow = 5; |
44 static const char kWalletGeneratedCardLearnMoreLink[] = | 45 static const char kWalletGeneratedCardLearnMoreLink[] = |
45 "http://support.google.com/wallet/bin/answer.py?hl=en&answer=2740044"; | 46 "http://support.google.com/wallet/bin/answer.py?hl=en&answer=2740044"; |
46 | 47 |
47 AutofillCreditCardBubbleController* GetOrCreate(content::WebContents* wc) { | 48 AutofillCreditCardBubbleController* GetOrCreate(content::WebContents* wc) { |
48 AutofillCreditCardBubbleController::CreateForWebContents(wc); | 49 AutofillCreditCardBubbleController::CreateForWebContents(wc); |
49 return AutofillCreditCardBubbleController::FromWebContents(wc); | 50 return AutofillCreditCardBubbleController::FromWebContents(wc); |
50 } | 51 } |
51 | 52 |
52 } // namespace | 53 } // namespace |
53 | 54 |
55 CreditCardDescription::CreditCardDescription() {} | |
56 CreditCardDescription::~CreditCardDescription() {} | |
57 | |
54 AutofillCreditCardBubbleController::AutofillCreditCardBubbleController( | 58 AutofillCreditCardBubbleController::AutofillCreditCardBubbleController( |
55 content::WebContents* web_contents) | 59 content::WebContents* web_contents) |
56 : WebContentsObserver(web_contents), | 60 : WebContentsObserver(web_contents), |
57 web_contents_(web_contents), | 61 web_contents_(web_contents), |
58 should_show_anchor_(true), | 62 should_show_anchor_(true), |
59 weak_ptr_factory_(this) {} | 63 weak_ptr_factory_(this) {} |
60 | 64 |
61 AutofillCreditCardBubbleController::~AutofillCreditCardBubbleController() { | 65 AutofillCreditCardBubbleController::~AutofillCreditCardBubbleController() { |
62 Hide(); | 66 Hide(); |
63 } | 67 } |
64 | 68 |
65 // static | 69 // static |
66 void AutofillCreditCardBubbleController::RegisterUserPrefs( | 70 void AutofillCreditCardBubbleController::RegisterUserPrefs( |
67 user_prefs::PrefRegistrySyncable* registry) { | 71 user_prefs::PrefRegistrySyncable* registry) { |
68 registry->RegisterIntegerPref( | 72 registry->RegisterIntegerPref( |
69 ::prefs::kAutofillGeneratedCardBubbleTimesShown, | 73 ::prefs::kAutofillGeneratedCardBubbleTimesShown, |
70 0, | 74 0, |
71 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 75 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
72 } | 76 } |
73 | 77 |
74 // static | 78 // static |
75 void AutofillCreditCardBubbleController::ShowGeneratedCardUI( | 79 void AutofillCreditCardBubbleController::ShowGeneratedCardBubble( |
76 content::WebContents* contents, | 80 content::WebContents* contents, |
77 const base::string16& fronting_card_name, | 81 const base::string16& fronting_card_name, |
78 const base::string16& backing_card_name) { | 82 const base::string16& backing_card_name) { |
79 GetOrCreate(contents)->ShowAsGeneratedCardBubble(fronting_card_name, | 83 GetOrCreate(contents)->ShowAsGeneratedCardBubble(fronting_card_name, |
80 backing_card_name); | 84 backing_card_name); |
81 } | 85 } |
82 | 86 |
83 // static | 87 // static |
84 void AutofillCreditCardBubbleController::ShowNewCardSavedBubble( | 88 void AutofillCreditCardBubbleController::ShowNewCardSavedBubble( |
85 content::WebContents* contents, | 89 content::WebContents* contents, |
86 const base::string16& new_card_name) { | 90 scoped_ptr<CreditCard> new_card, |
87 GetOrCreate(contents)->ShowAsNewCardSavedBubble(new_card_name); | 91 scoped_ptr<AutofillProfile> billing_profile) { |
92 GetOrCreate(contents)->ShowAsNewCardSavedBubble(new_card.Pass(), | |
93 billing_profile.Pass()); | |
88 } | 94 } |
89 | 95 |
90 void AutofillCreditCardBubbleController::DidNavigateMainFrame( | 96 void AutofillCreditCardBubbleController::DidNavigateMainFrame( |
91 const content::LoadCommittedDetails& details, | 97 const content::LoadCommittedDetails& details, |
92 const content::FrameNavigateParams& params) { | 98 const content::FrameNavigateParams& params) { |
93 if (details.entry && | 99 if (details.entry && |
94 !content::PageTransitionIsRedirect(details.entry->GetTransitionType())) { | 100 !content::PageTransitionIsRedirect(details.entry->GetTransitionType())) { |
95 should_show_anchor_ = false; | 101 should_show_anchor_ = false; |
96 UpdateAnchor(); | 102 UpdateAnchor(); |
97 web_contents()->RemoveUserData(UserDataKey()); | 103 web_contents()->RemoveUserData(UserDataKey()); |
98 // |this| is now deleted. | 104 // |this| is now deleted. |
99 } | 105 } |
100 } | 106 } |
101 | 107 |
102 bool AutofillCreditCardBubbleController::IsHiding() const { | 108 bool AutofillCreditCardBubbleController::IsHiding() const { |
103 return bubble_ && bubble_->IsHiding(); | 109 return bubble_ && bubble_->IsHiding(); |
104 } | 110 } |
105 | 111 |
106 gfx::Image AutofillCreditCardBubbleController::AnchorIcon() const { | 112 bool AutofillCreditCardBubbleController::AnchorToSettingsMenu() const { |
107 if (!should_show_anchor_) | 113 return !IsGeneratedCardBubble(); |
108 return gfx::Image(); | |
109 | |
110 return ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
111 IsGeneratedCardBubble() ? IDR_WALLET_ICON : IDR_AUTOFILL_CC_GENERIC); | |
112 } | 114 } |
113 | 115 |
114 base::string16 AutofillCreditCardBubbleController::BubbleTitle() const { | 116 gfx::Image AutofillCreditCardBubbleController::AnchorIcon() const { |
115 return !IsGeneratedCardBubble() ? ASCIIToUTF16("Lorem ipsum, savum cardum") : | 117 if (!should_show_anchor_ || !IsGeneratedCardBubble()) |
116 l10n_util::GetStringUTF16( | 118 return gfx::Image(); |
117 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TITLE); | 119 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_WALLET_ICON); |
118 } | 120 } |
119 | 121 |
120 base::string16 AutofillCreditCardBubbleController::BubbleText() const { | 122 const base::string16& AutofillCreditCardBubbleController::TitleText() const { |
121 DCHECK(IsSetup()); | 123 return title_text_; |
122 return bubble_text_; | |
123 } | 124 } |
124 | 125 |
125 const std::vector<ui::Range>& AutofillCreditCardBubbleController:: | 126 const base::string16& AutofillCreditCardBubbleController::HeaderText() const { |
126 BubbleTextRanges() const { | 127 return header_text_; |
127 DCHECK(IsSetup()); | |
128 return bubble_text_ranges_; | |
129 } | 128 } |
130 | 129 |
131 base::string16 AutofillCreditCardBubbleController::LinkText() const { | 130 const std::vector<TextRange>& AutofillCreditCardBubbleController:: |
132 return l10n_util::GetStringUTF16(IsGeneratedCardBubble() ? | 131 HeaderTextRanges() const { |
133 IDS_LEARN_MORE : IDS_AUTOFILL_CREDIT_CARD_BUBBLE_MANAGE_CARDS); | 132 return header_text_ranges_; |
133 } | |
134 | |
135 const CreditCardDescription* AutofillCreditCardBubbleController::Description() | |
136 const { | |
137 return card_desc_.get(); | |
138 } | |
139 | |
140 const base::string16& AutofillCreditCardBubbleController::LinkText() const { | |
141 return link_text_; | |
134 } | 142 } |
135 | 143 |
136 void AutofillCreditCardBubbleController::OnAnchorClicked() { | 144 void AutofillCreditCardBubbleController::OnAnchorClicked() { |
137 Show(true); | 145 Show(true); |
138 } | 146 } |
139 | 147 |
148 void AutofillCreditCardBubbleController::OnBubbleDestroyed() { | |
149 if (AnchorToSettingsMenu()) | |
150 web_contents()->RemoveUserData(UserDataKey()); | |
151 // |this| may now be deleted. | |
152 } | |
153 | |
140 void AutofillCreditCardBubbleController::OnLinkClicked() { | 154 void AutofillCreditCardBubbleController::OnLinkClicked() { |
141 if (IsGeneratedCardBubble()) { | 155 if (IsGeneratedCardBubble()) { |
142 #if !defined(OS_ANDROID) | 156 #if !defined(OS_ANDROID) |
143 chrome::NavigateParams params( | 157 chrome::NavigateParams params( |
144 chrome::FindBrowserWithWebContents(web_contents()), | 158 chrome::FindBrowserWithWebContents(web_contents()), |
145 GURL(kWalletGeneratedCardLearnMoreLink), | 159 GURL(kWalletGeneratedCardLearnMoreLink), |
146 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 160 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
147 params.disposition = NEW_FOREGROUND_TAB; | 161 params.disposition = NEW_FOREGROUND_TAB; |
148 chrome::Navigate(¶ms); | 162 chrome::Navigate(¶ms); |
149 #else | 163 #else |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 fronting_card_name_ = fronting_card_name; | 212 fronting_card_name_ = fronting_card_name; |
199 backing_card_name_ = backing_card_name; | 213 backing_card_name_ = backing_card_name; |
200 | 214 |
201 SetUp(); | 215 SetUp(); |
202 | 216 |
203 if (ShouldDisplayBubbleInitially()) | 217 if (ShouldDisplayBubbleInitially()) |
204 Show(false); | 218 Show(false); |
205 } | 219 } |
206 | 220 |
207 void AutofillCreditCardBubbleController::ShowAsNewCardSavedBubble( | 221 void AutofillCreditCardBubbleController::ShowAsNewCardSavedBubble( |
208 const base::string16& new_card_name) { | 222 scoped_ptr<CreditCard> new_card, |
223 scoped_ptr<AutofillProfile> billing_profile) { | |
209 Reset(); | 224 Reset(); |
210 | 225 |
211 DCHECK(!new_card_name.empty()); | 226 DCHECK(new_card); |
212 new_card_name_ = new_card_name; | 227 DCHECK(billing_profile); |
228 new_card_ = new_card.Pass(); | |
229 billing_profile_ = billing_profile.Pass(); | |
213 | 230 |
214 SetUp(); | 231 SetUp(); |
215 Show(false); | 232 Show(false); |
216 } | 233 } |
217 | 234 |
218 void AutofillCreditCardBubbleController::Reset() { | 235 void AutofillCreditCardBubbleController::Reset() { |
219 Hide(); | 236 Hide(); |
220 | 237 |
221 fronting_card_name_.clear(); | 238 fronting_card_name_.clear(); |
222 backing_card_name_.clear(); | 239 backing_card_name_.clear(); |
223 new_card_name_.clear(); | 240 new_card_.reset(); |
224 bubble_text_.clear(); | 241 billing_profile_.reset(); |
225 bubble_text_ranges_.clear(); | 242 |
243 title_text_.clear(); | |
244 header_text_.clear(); | |
245 header_text_ranges_.clear(); | |
246 card_desc_.reset(); | |
247 link_text_.clear(); | |
226 | 248 |
227 DCHECK(!IsSetup()); | 249 DCHECK(!IsSetup()); |
228 } | 250 } |
229 | 251 |
230 void AutofillCreditCardBubbleController::SetUp() { | 252 void AutofillCreditCardBubbleController::SetUp() { |
231 base::string16 full_text; | 253 // Set the title if it's a generated card bubble. |
232 if (IsGeneratedCardBubble()) { | 254 if (IsGeneratedCardBubble()) { |
233 full_text = l10n_util::GetStringFUTF16( | 255 title_text_ = l10n_util::GetStringUTF16( |
256 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TITLE); | |
257 } | |
258 | |
259 base::string16 to_split; | |
260 if (IsGeneratedCardBubble()) { | |
261 to_split = l10n_util::GetStringFUTF16( | |
234 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TEXT, | 262 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_GENERATED_TEXT, |
235 fronting_card_name_, | 263 fronting_card_name_, |
236 backing_card_name_); | 264 backing_card_name_); |
237 } else { | 265 } else { |
238 full_text = ReplaceStringPlaceholders( | 266 to_split = l10n_util::GetStringUTF16( |
239 ASCIIToUTF16("Lorem ipsum, savum cardem |$1|. Replacem before launch."), | 267 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_NEW_CARD_TEXT); |
240 new_card_name_, | |
241 NULL); | |
242 } | 268 } |
243 | 269 |
244 base::char16 separator('|'); | 270 base::char16 separator('|'); |
245 std::vector<base::string16> pieces; | 271 std::vector<base::string16> pieces; |
246 base::SplitStringDontTrim(full_text, separator, &pieces); | 272 base::SplitStringDontTrim(to_split, separator, &pieces); |
247 | 273 |
248 while (!pieces.empty()) { | 274 while (!pieces.empty()) { |
249 base::string16 piece = pieces.front(); | 275 base::string16 piece = pieces.front(); |
250 if (!piece.empty() && pieces.size() % 2 == 0) { | 276 if (!piece.empty() && pieces.size() % 2 == 0) { |
251 const size_t start = bubble_text_.size(); | 277 const size_t start = header_text_.size(); |
252 bubble_text_ranges_.push_back(ui::Range(start, start + piece.size())); | 278 TextRange bold_text; |
279 bold_text.range = ui::Range(start, start + piece.size()); | |
280 bold_text.is_link = false; | |
281 header_text_ranges_.push_back(bold_text); | |
253 } | 282 } |
254 bubble_text_.append(piece); | 283 header_text_.append(piece); |
255 pieces.erase(pieces.begin(), pieces.begin() + 1); | 284 pieces.erase(pieces.begin(), pieces.begin() + 1); |
256 } | 285 } |
257 | 286 |
287 // Add a "Learn more" link at the end of the header text if it's a generated | |
288 // card bubble. | |
289 if (IsGeneratedCardBubble()) { | |
290 base::string16 learn_more = l10n_util::GetStringUTF16(IDS_LEARN_MORE); | |
291 header_text_.append(ASCIIToUTF16(" ") + learn_more); | |
292 const size_t header_size = header_text_.size(); | |
293 TextRange end_link; | |
294 end_link.range = ui::Range(header_size - learn_more.size(), header_size); | |
295 end_link.is_link = true; | |
296 header_text_ranges_.push_back(end_link); | |
297 } | |
298 | |
299 // Create a description if it's a newly saved card bubble. | |
300 if (!IsGeneratedCardBubble()) { | |
Evan Stade
2013/08/02 16:29:45
use else?
Dan Beam
2013/08/06 02:41:35
doesn't exist any more
| |
301 card_desc_.reset(new CreditCardDescription); | |
302 | |
303 const base::string16 card_number = | |
304 new_card_->GetRawInfo(CREDIT_CARD_NUMBER); | |
305 ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
306 card_desc_->icon = rb.GetImageNamed( | |
307 CreditCard::IconResourceId(CreditCard::GetCreditCardType(card_number))); | |
308 | |
309 card_desc_->title = card_number.substr(0, 4) + ASCIIToUTF16(" - ") + | |
Evan Stade
2013/08/02 16:29:45
I think this belongs alongside the other "ForDispl
Dan Beam
2013/08/06 02:41:35
changed to TypeAndLastFourDigits() and started thr
| |
310 card_number.substr(4, 4) + ASCIIToUTF16(" - ") + | |
311 card_number.substr(8, 4) + ASCIIToUTF16(" - ") + | |
312 card_number.substr(12); | |
313 const base::string16 kNewLine = ASCIIToUTF16("\n"); | |
314 const std::string& locale = g_browser_process->GetApplicationLocale(); | |
315 card_desc_->description = billing_profile_->Label() + kNewLine + | |
316 billing_profile_->GetInfo(EMAIL_ADDRESS, locale) + kNewLine + | |
317 billing_profile_->GetRawInfo(PHONE_BILLING_WHOLE_NUMBER); | |
318 } | |
319 | |
320 // Add a link by setting the link text if it's a newly saved card bubble. | |
321 if (!IsGeneratedCardBubble()) { | |
Evan Stade
2013/08/02 16:29:45
nit: put this in the above block that's guarded by
Dan Beam
2013/08/06 02:41:35
doesn't exist any more
| |
322 link_text_ = l10n_util::GetStringUTF16( | |
323 IDS_AUTOFILL_CREDIT_CARD_BUBBLE_MANAGE_CARDS); | |
324 } | |
325 | |
258 UpdateAnchor(); | 326 UpdateAnchor(); |
259 DCHECK(IsSetup()); | 327 DCHECK(IsSetup()); |
260 } | 328 } |
261 | 329 |
262 bool AutofillCreditCardBubbleController::IsSetup() const { | 330 bool AutofillCreditCardBubbleController::IsSetup() const { |
263 DCHECK_EQ(bubble_text_.empty(), bubble_text_ranges_.empty()); | 331 return !header_text_.empty(); |
264 return !bubble_text_.empty(); | |
265 } | 332 } |
266 | 333 |
267 bool AutofillCreditCardBubbleController::IsGeneratedCardBubble() const { | 334 bool AutofillCreditCardBubbleController::IsGeneratedCardBubble() const { |
268 DCHECK_EQ(fronting_card_name_.empty(), backing_card_name_.empty()); | |
269 DCHECK_NE(backing_card_name_.empty(), new_card_name_.empty()); | |
270 return !fronting_card_name_.empty(); | 335 return !fronting_card_name_.empty(); |
271 } | 336 } |
272 | 337 |
273 void AutofillCreditCardBubbleController::Show(bool was_anchor_click) { | 338 void AutofillCreditCardBubbleController::Show(bool was_anchor_click) { |
274 if (!CanShow()) | 339 if (!CanShow()) |
275 return; | 340 return; |
276 | 341 |
277 bubble_ = CreateBubble(); | 342 bubble_ = CreateBubble(); |
278 if (!bubble_) { | 343 if (!bubble_) { |
279 // TODO(dbeam): Make a bubble on all applicable platforms. | 344 // TODO(dbeam): Make a bubble on all applicable platforms. |
(...skipping 26 matching lines...) Expand all Loading... | |
306 // Sever |bubble_|'s reference to the controller and hide (if it exists). | 371 // Sever |bubble_|'s reference to the controller and hide (if it exists). |
307 weak_ptr_factory_.InvalidateWeakPtrs(); | 372 weak_ptr_factory_.InvalidateWeakPtrs(); |
308 | 373 |
309 if (bubble_ && !bubble_->IsHiding()) | 374 if (bubble_ && !bubble_->IsHiding()) |
310 bubble_->Hide(); | 375 bubble_->Hide(); |
311 | 376 |
312 DCHECK(!bubble_ || bubble_->IsHiding()); | 377 DCHECK(!bubble_ || bubble_->IsHiding()); |
313 } | 378 } |
314 | 379 |
315 } // namespace autofill | 380 } // namespace autofill |
OLD | NEW |