Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / autofill / generated_credit_card_bubble_controller.cc
blobdcfdba88cf233a7df6ddd55010f396e8dd992b2d
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/autofill/generated_credit_card_bubble_controller.h"
7 #include <climits>
9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
15 #include "chrome/browser/ui/autofill/generated_credit_card_bubble_view.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/browser_navigator.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/location_bar/location_bar.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "components/pref_registry/pref_registry_syncable.h"
24 #include "content/public/browser/navigation_details.h"
25 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/web_contents.h"
27 #include "grit/components_strings.h"
28 #include "grit/theme_resources.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
32 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
33 autofill::GeneratedCreditCardBubbleController);
35 namespace autofill {
37 namespace {
39 static const int kMaxGeneratedCardTimesToShow = INT_MAX;
40 static const base::char16 kRangeSeparator = '|';
41 static const char kWalletGeneratedCardLearnMoreLink[] =
42 "http://support.google.com/wallet/bin/answer.py?hl=en&answer=2740044";
44 GeneratedCreditCardBubbleController* GetOrCreate(content::WebContents* wc) {
45 GeneratedCreditCardBubbleController::CreateForWebContents(wc);
46 return GeneratedCreditCardBubbleController::FromWebContents(wc);
49 } // namespace
51 bool TextRange::operator==(const TextRange& other) const {
52 return other.range == range && other.is_link == is_link;
55 GeneratedCreditCardBubbleController::GeneratedCreditCardBubbleController(
56 content::WebContents* web_contents)
57 : WebContentsObserver(web_contents),
58 web_contents_(web_contents),
59 title_text_(l10n_util::GetStringUTF16(
60 IDS_AUTOFILL_GENERATED_CREDIT_CARD_BUBBLE_TITLE)),
61 should_show_anchor_(true),
62 weak_ptr_factory_(this) {}
64 GeneratedCreditCardBubbleController::~GeneratedCreditCardBubbleController() {
65 // In the case that the tab is closed, the controller can be deleted while
66 // bubble is showing. Always calling |Hide()| ensures that the bubble closes.
67 Hide();
70 // static
71 void GeneratedCreditCardBubbleController::RegisterUserPrefs(
72 user_prefs::PrefRegistrySyncable* registry) {
73 registry->RegisterIntegerPref(
74 ::prefs::kAutofillGeneratedCardBubbleTimesShown,
76 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
79 // static
80 void GeneratedCreditCardBubbleController::Show(
81 content::WebContents* contents,
82 const base::string16& fronting_card_name,
83 const base::string16& backing_card_name) {
84 GetOrCreate(contents)->SetupAndShow(fronting_card_name, backing_card_name);
87 void GeneratedCreditCardBubbleController::DidNavigateMainFrame(
88 const content::LoadCommittedDetails& details,
89 const content::FrameNavigateParams& params) {
90 if (!details.entry)
91 return;
93 // Don't destory the bubble due to reloads, form submits, or redirects right
94 // after the dialog succeeds. Merchants often navigate to a confirmation page.
95 ui::PageTransition transition = details.entry->GetTransitionType();
96 if (transition == ui::PAGE_TRANSITION_FORM_SUBMIT ||
97 transition == ui::PAGE_TRANSITION_RELOAD ||
98 ui::PageTransitionIsRedirect(transition)) {
99 return;
102 should_show_anchor_ = false;
103 UpdateAnchor();
104 web_contents()->RemoveUserData(UserDataKey());
105 // |this| is now deleted.
108 bool GeneratedCreditCardBubbleController::IsHiding() const {
109 return bubble_ && bubble_->IsHiding();
112 gfx::Image GeneratedCreditCardBubbleController::AnchorIcon() const {
113 if (!should_show_anchor_)
114 return gfx::Image();
115 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_WALLET_ICON);
118 const base::string16& GeneratedCreditCardBubbleController::TitleText() const {
119 return title_text_;
122 const base::string16& GeneratedCreditCardBubbleController::ContentsText()
123 const {
124 return contents_text_;
127 const std::vector<TextRange>& GeneratedCreditCardBubbleController::
128 ContentsTextRanges() const {
129 return contents_text_ranges_;
132 void GeneratedCreditCardBubbleController::OnAnchorClicked() {
133 Show(true);
136 void GeneratedCreditCardBubbleController::OnLinkClicked() {
137 // Open a new tab to the Online Wallet help link.
138 chrome::NavigateParams params(
139 chrome::FindBrowserWithWebContents(web_contents()),
140 GURL(kWalletGeneratedCardLearnMoreLink),
141 ui::PAGE_TRANSITION_AUTO_BOOKMARK);
142 params.disposition = NEW_FOREGROUND_TAB;
143 chrome::Navigate(&params);
145 Hide();
148 base::WeakPtr<GeneratedCreditCardBubbleController>
149 GeneratedCreditCardBubbleController::GetWeakPtr() {
150 return weak_ptr_factory_.GetWeakPtr();
153 base::WeakPtr<GeneratedCreditCardBubbleView>
154 GeneratedCreditCardBubbleController::CreateBubble() {
155 return GeneratedCreditCardBubbleView::Create(GetWeakPtr());
158 base::WeakPtr<GeneratedCreditCardBubbleView>
159 GeneratedCreditCardBubbleController::bubble() {
160 return bubble_;
163 bool GeneratedCreditCardBubbleController::CanShow() const {
164 Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
165 return web_contents() == browser->tab_strip_model()->GetActiveWebContents();
168 bool GeneratedCreditCardBubbleController::ShouldDisplayBubbleInitially() const {
169 Profile* profile = Profile::FromBrowserContext(
170 web_contents_->GetBrowserContext());
171 int times_shown = profile->GetPrefs()->GetInteger(
172 ::prefs::kAutofillGeneratedCardBubbleTimesShown);
173 return times_shown < kMaxGeneratedCardTimesToShow;
176 void GeneratedCreditCardBubbleController::SetupAndShow(
177 const base::string16& fronting_card_name,
178 const base::string16& backing_card_name) {
179 DCHECK(!fronting_card_name.empty());
180 DCHECK(!backing_card_name.empty());
182 fronting_card_name_ = fronting_card_name;
183 backing_card_name_ = backing_card_name;
185 // Clear any generated state or from the last |SetupAndShow()| call.
186 contents_text_.clear();
187 contents_text_ranges_.clear();
189 base::string16 to_split = l10n_util::GetStringFUTF16(
190 IDS_AUTOFILL_GENERATED_CREDIT_CARD_BUBBLE_CONTENTS,
191 fronting_card_name_,
192 backing_card_name_);
194 // Split the full text on '|' to highlight certain parts. For example, "sly"
195 // and "jumped" would be bolded in "The |sly| fox |jumped| over the lazy dog".
196 std::vector<base::string16> pieces;
197 base::SplitStringDontTrim(to_split, kRangeSeparator, &pieces);
199 while (!pieces.empty()) {
200 base::string16 piece = pieces.front();
202 // Every second piece should be bolded. Because |base::SplitString*()|
203 // leaves an empty "" even if '|' is the first character, this is guaranteed
204 // to work for "|highlighting| starts here". Ignore empty pieces because
205 // there's nothing to highlight.
206 if (!piece.empty() && pieces.size() % 2 == 0) {
207 const size_t start = contents_text_.size();
208 TextRange bold_text;
209 bold_text.range = gfx::Range(start, start + piece.size());
210 bold_text.is_link = false;
211 contents_text_ranges_.push_back(bold_text);
214 // Append the piece whether it's bolded or not and move on to the next one.
215 contents_text_.append(piece);
216 pieces.erase(pieces.begin(), pieces.begin() + 1);
219 // Add a "Learn more" link at the end of the header text if it's a generated
220 // card bubble.
221 base::string16 learn_more = l10n_util::GetStringUTF16(IDS_LEARN_MORE);
222 contents_text_.append(base::ASCIIToUTF16(" ") + learn_more);
223 const size_t header_size = contents_text_.size();
224 TextRange end_link;
225 end_link.range = gfx::Range(header_size - learn_more.size(), header_size);
226 end_link.is_link = true;
227 contents_text_ranges_.push_back(end_link);
229 UpdateAnchor();
231 if (ShouldDisplayBubbleInitially())
232 Show(false);
235 void GeneratedCreditCardBubbleController::Show(bool was_anchor_click) {
236 Hide();
238 if (!CanShow())
239 return;
241 bubble_ = CreateBubble();
242 if (!bubble_) {
243 // TODO(dbeam): Make a bubble on all applicable platforms.
244 return;
247 bubble_->Show();
249 if (!was_anchor_click) {
250 // If the bubble was an automatically created "you generated a card" bubble,
251 // count it as a show. If the user clicked the omnibox icon, don't count it.
252 PrefService* prefs = Profile::FromBrowserContext(
253 web_contents()->GetBrowserContext())->GetPrefs();
254 prefs->SetInteger(::prefs::kAutofillGeneratedCardBubbleTimesShown,
255 prefs->GetInteger(::prefs::kAutofillGeneratedCardBubbleTimesShown) + 1);
259 void GeneratedCreditCardBubbleController::UpdateAnchor() {
260 Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
261 if (browser && browser->window() && browser->window()->GetLocationBar())
262 browser->window()->GetLocationBar()->UpdateGeneratedCreditCardView();
265 void GeneratedCreditCardBubbleController::Hide() {
266 if (bubble_ && !bubble_->IsHiding())
267 bubble_->Hide();
270 } // namespace autofill