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

Unified 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: Change interface for retrieving lines + give each line its own StyledLabel. 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
index 2e43699e3f435ffe870588f220a00da460322e94..ecbe43bed0901c9b17348767f5da0cd5820a437e 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -4,6 +4,9 @@
#include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h"
+#include "base/i18n/message_formatter.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/save_card_bubble_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
@@ -21,6 +24,115 @@ namespace {
// TODO(bondd): Share with ManagePasswordsUIController.
const int kSurviveNavigationSeconds = 5;
+// Replace "{0}", "{1}", ... in |template_icu| with corresponding strings
+// from |display_texts|. Sets |out_message| to the resulting string, with
+// start position of each replacement in |out_offsets|.
+// Return false on failure. If false is returned then contents of |out_message|
+// and |out_offsets| are undefined.
+bool ReplaceTemplatePlaceholders(
+ const base::string16& template_icu,
+ const std::vector<base::string16>& display_texts,
+ base::string16& out_message,
+ std::vector<size_t>& out_offsets) {
+ // Escape "$" -> "$$" for ReplaceStringPlaceholders().
+ //
+ // Edge cases:
+ // 1. Two or more consecutive $ characters will be incorrectly expanded
+ // ("$$" -> "$$$$", which ReplaceStringPlaceholders() then turns into
+ // "$$$").
+ //
+ // 2. "${" will cause false to be returned. "${0}" will expand to "$${0}".
+ // FormatWithNumberedArgs() turns it into "$$$1", which
+ // ReplaceStringPlaceholders() then turns into "$$1" without doing the
+ // parameter replacement. This causes false to be returned because each
+ // parameter is not used exactly once.
+ //
+ // Both of these cases are noted in the header file, and are unlikely to
+ // occur in any actual legal message.
+ base::string16 template_icu_escaped;
+ base::ReplaceChars(template_icu, base::ASCIIToUTF16("$"),
+ base::ASCIIToUTF16("$$"), &template_icu_escaped);
+
+ // Replace "{0}" -> "$1", "{1}" -> "$2", ... to prepare |template_dollars|
+ // for ReplaceStringPlaceholders().
+ base::string16 template_dollars =
+ base::i18n::MessageFormatter::FormatWithNumberedArgs(
+ template_icu_escaped, "$1", "$2", "$3", "$4", "$5", "$6", "$7");
+
+ // FormatWithNumberedArgs() returns an empty string on failure.
+ if (template_dollars.empty() && !template_icu.empty())
+ return false;
+
+ // Replace "$1", "$2", ... with the display text of each parameter.
+ out_message =
+ ReplaceStringPlaceholders(template_dollars, display_texts, &out_offsets);
+
+ // Each parameter must be used exactly once. If a parameter is unused or
+ // used more than once then it can't be determined which |offsets| entry
+ // corresponds to which parameter.
+ return out_offsets.size() == display_texts.size();
+}
+
+// Parses |line| and sets |out|.
+// Returns false on failure. |out| is not modified if false is returned.
+bool ParseLegalMessageLine(
+ const base::DictionaryValue& line,
+ autofill::SaveCardBubbleController::LegalMessageLine& out) {
Evan Stade 2015/11/13 01:33:07 outparams must always be pointer type that said,
bondd 2015/11/13 22:30:43 Done. I made it a pointer.
+ autofill::SaveCardBubbleController::LegalMessageLine result;
+
+ // |display_texts| elements are the strings that will be substituted for
+ // "{0}", "{1}", etc. in the template string.
+ std::vector<base::string16> display_texts;
+
+ // Process all the template parameters.
+ const base::ListValue* template_parameters = nullptr;
+ if (line.GetList("template_parameter", &template_parameters)) {
+ for (size_t parameter_index = 0;
+ parameter_index < template_parameters->GetSize(); ++parameter_index) {
+ // Get a single element of the "template_parameter" list.
+ const base::DictionaryValue* single_parameter;
+ if (!template_parameters->GetDictionary(parameter_index,
+ &single_parameter))
+ return false;
+
+ // Read and store the "display_text" string.
+ display_texts.push_back(base::string16());
+ if (!single_parameter->GetString("display_text", &display_texts.back()))
+ return false;
+
+ // Read and store the "url" string.
+ result.links.push_back(
+ autofill::SaveCardBubbleController::LegalMessageLine::Link());
+ if (!single_parameter->GetString("url", &result.links.back().url))
+ return false;
+ }
+ }
+
+ // Read the template string. It's a small subset of the ICU message format
+ // syntax.
+ base::string16 template_icu;
+ if (!line.GetString("template", &template_icu))
+ return false;
+
+ // Replace the placeholders in |template_icu| with strings from
+ // |display_texts|, and store the start position of each replacement in
+ // |offsets|.
+ std::vector<size_t> offsets;
+ if (!ReplaceTemplatePlaceholders(template_icu, display_texts, result.text,
+ offsets))
+ return false;
+
+ // Fill in range values for all links.
+ for (size_t offset_index = 0; offset_index < offsets.size(); ++offset_index) {
+ size_t range_start = offsets[offset_index];
+ result.links[offset_index].range = gfx::Range(
+ range_start, range_start + display_texts[offset_index].size());
+ }
+
+ out = result;
+ return true;
+}
+
} // namespace
namespace autofill {
@@ -42,6 +154,31 @@ void SaveCardBubbleControllerImpl::SetCallback(
save_card_callback_ = save_card_callback;
}
+bool SaveCardBubbleControllerImpl::SetLegalMessage(
+ const base::ListValue& lines) {
+ ClearLegalMessage();
+ std::vector<LegalMessageLine> parsed_lines;
Evan Stade 2015/11/13 01:33:07 parsed_lines? Why not just legal_message_lines_? I
bondd 2015/11/13 22:30:43 Done.
+
+ // Process all lines of the message. See comment in header file for example
+ // of valid |lines| data.
+ for (size_t line_index = 0; line_index < lines.GetSize(); ++line_index) {
+ const base::DictionaryValue* single_line;
+ if (!lines.GetDictionary(line_index, &single_line))
+ return false;
+
+ parsed_lines.push_back(LegalMessageLine());
+ if (!ParseLegalMessageLine(*single_line, parsed_lines.back()))
+ return false;
+ }
+
+ legal_message_lines_ = parsed_lines;
Evan Stade 2015/11/13 01:33:07 if you keep this line you should use swap()
bondd 2015/11/13 22:30:43 Obsolete.
+ return true;
+}
+
+void SaveCardBubbleControllerImpl::ClearLegalMessage() {
Evan Stade 2015/11/13 01:33:07 I don't get the purpose of this fn
bondd 2015/11/13 22:30:43 SaveCardBubbleControllerImpl is per tab, and once
Evan Stade 2015/11/14 00:22:49 I would vote for reusing SetLegalMessage, but this
bondd 2015/11/17 00:12:04 Done.
+ legal_message_lines_.clear();
+}
+
void SaveCardBubbleControllerImpl::ShowBubble() {
DCHECK(!save_card_callback_.is_null());
@@ -84,9 +221,12 @@ void SaveCardBubbleControllerImpl::OnCancelButton() {
}
void SaveCardBubbleControllerImpl::OnLearnMoreClicked() {
- web_contents()->OpenURL(content::OpenURLParams(
- GURL(kHelpURL), content::Referrer(), NEW_FOREGROUND_TAB,
- ui::PAGE_TRANSITION_LINK, false));
+ OpenUrl(kHelpURL);
+}
+
+void SaveCardBubbleControllerImpl::OnLegalMessageLinkClicked(
+ const std::string& url) {
+ OpenUrl(url);
}
void SaveCardBubbleControllerImpl::OnBubbleClosed() {
@@ -94,12 +234,23 @@ void SaveCardBubbleControllerImpl::OnBubbleClosed() {
UpdateIcon();
}
+const std::vector<SaveCardBubbleController::LegalMessageLine>&
+SaveCardBubbleControllerImpl::GetLegalMessageLines() const {
+ return legal_message_lines_;
+}
+
void SaveCardBubbleControllerImpl::UpdateIcon() {
Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
LocationBar* location_bar = browser->window()->GetLocationBar();
location_bar->UpdateSaveCreditCardIcon();
}
+void SaveCardBubbleControllerImpl::OpenUrl(const std::string& url) {
+ web_contents()->OpenURL(
+ content::OpenURLParams(GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
+ ui::PAGE_TRANSITION_LINK, false));
+}
+
void SaveCardBubbleControllerImpl::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {

Powered by Google App Engine
This is Rietveld 408576698