Index: chrome/browser/ui/autofill/autofill_popup_controller_impl.cc |
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc |
index 6ca14036702b504654e9ba4fd2f555f2180848a9..469fd6498604c4ddc2fc4e5fb198d54861c250c5 100644 |
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc |
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc |
@@ -13,6 +13,7 @@ |
#include "chrome/browser/ui/autofill/popup_constants.h" |
#include "components/autofill/core/browser/autofill_popup_delegate.h" |
#include "components/autofill/core/browser/popup_item_ids.h" |
+#include "components/autofill/core/browser/suggestion.h" |
#include "content/public/browser/native_web_keyboard_event.h" |
#include "grit/components_scaled_resources.h" |
#include "ui/base/resource/resource_bundle.h" |
@@ -38,7 +39,7 @@ const size_t kRowHeight = 24; |
const size_t kSeparatorHeight = 1; |
#if !defined(OS_ANDROID) |
-// Size difference between name and subtext in pixels. |
+// Size difference between name and label in pixels. |
const int kLabelFontSizeDelta = -2; |
const size_t kNamePadding = AutofillPopupView::kNamePadding; |
@@ -111,13 +112,13 @@ AutofillPopupControllerImpl::AutofillPopupControllerImpl( |
base::Bind(&AutofillPopupControllerImpl::HandleKeyPressEvent, |
base::Unretained(this))); |
#if !defined(OS_ANDROID) |
- subtext_font_list_ = name_font_list_.DeriveWithSizeDelta(kLabelFontSizeDelta); |
- title_font_list_ = name_font_list_.DeriveWithStyle(gfx::Font::BOLD); |
+ label_font_list_ = value_font_list_.DeriveWithSizeDelta(kLabelFontSizeDelta); |
+ title_font_list_ = value_font_list_.DeriveWithStyle(gfx::Font::BOLD); |
#if defined(OS_MACOSX) |
// There is no italic version of the system font. |
- warning_font_list_ = name_font_list_; |
+ warning_font_list_ = value_font_list_; |
#else |
- warning_font_list_ = name_font_list_.DeriveWithStyle(gfx::Font::ITALIC); |
+ warning_font_list_ = value_font_list_.DeriveWithStyle(gfx::Font::ITALIC); |
#endif |
#endif |
} |
@@ -125,11 +126,10 @@ AutofillPopupControllerImpl::AutofillPopupControllerImpl( |
AutofillPopupControllerImpl::~AutofillPopupControllerImpl() {} |
void AutofillPopupControllerImpl::Show( |
- const std::vector<base::string16>& names, |
- const std::vector<base::string16>& subtexts, |
- const std::vector<base::string16>& icons, |
- const std::vector<int>& identifiers) { |
- SetValues(names, subtexts, icons, identifiers); |
+ const std::vector<autofill::Suggestion>& suggestions) { |
+ SetValues(suggestions); |
+ DCHECK_EQ(suggestions_.size(), elided_values_.size()); |
+ DCHECK_EQ(suggestions_.size(), elided_labels_.size()); |
#if !defined(OS_ANDROID) |
// Android displays the long text with ellipsis using the view attributes. |
@@ -137,12 +137,14 @@ void AutofillPopupControllerImpl::Show( |
UpdatePopupBounds(); |
int popup_width = popup_bounds().width(); |
- // Elide the name and subtext strings so that the popup fits in the available |
+ // Elide the name and label strings so that the popup fits in the available |
// space. |
- for (size_t i = 0; i < names_.size(); ++i) { |
- int name_width = gfx::GetStringWidth(names_[i], GetNameFontListForRow(i)); |
- int subtext_width = gfx::GetStringWidth(subtexts_[i], subtext_font_list()); |
- int total_text_length = name_width + subtext_width; |
+ for (size_t i = 0; i < suggestions_.size(); ++i) { |
+ int value_width = |
+ gfx::GetStringWidth(suggestions_[i].value, GetValueFontListForRow(i)); |
+ int label_width = |
+ gfx::GetStringWidth(suggestions_[i].label, GetLabelFontList()); |
+ int total_text_length = value_width + label_width; |
// The line can have no strings if it represents a UI element, such as |
// a separator line. |
@@ -152,13 +154,15 @@ void AutofillPopupControllerImpl::Show( |
int available_width = popup_width - RowWidthWithoutText(i); |
// Each field receives space in proportion to its length. |
- int name_size = available_width * name_width / total_text_length; |
- names_[i] = gfx::ElideText(names_[i], GetNameFontListForRow(i), |
- name_size, gfx::ELIDE_TAIL); |
- |
- int subtext_size = available_width * subtext_width / total_text_length; |
- subtexts_[i] = gfx::ElideText(subtexts_[i], subtext_font_list(), |
- subtext_size, gfx::ELIDE_TAIL); |
+ int value_size = available_width * value_width / total_text_length; |
+ elided_values_[i] = gfx::ElideText(suggestions_[i].value, |
+ GetValueFontListForRow(i), |
+ value_size, gfx::ELIDE_TAIL); |
+ |
+ int label_size = available_width * label_width / total_text_length; |
+ elided_labels_[i] = gfx::ElideText(suggestions_[i].label, |
+ GetLabelFontList(), |
+ label_size, gfx::ELIDE_TAIL); |
} |
#endif |
@@ -179,29 +183,34 @@ void AutofillPopupControllerImpl::Show( |
controller_common_->RegisterKeyPressCallback(); |
delegate_->OnPopupShown(); |
+ |
+ DCHECK_EQ(suggestions_.size(), elided_values_.size()); |
+ DCHECK_EQ(suggestions_.size(), elided_labels_.size()); |
} |
void AutofillPopupControllerImpl::UpdateDataListValues( |
const std::vector<base::string16>& values, |
const std::vector<base::string16>& labels) { |
+ DCHECK_EQ(suggestions_.size(), elided_values_.size()); |
+ DCHECK_EQ(suggestions_.size(), elided_labels_.size()); |
+ |
// Remove all the old data list values, which should always be at the top of |
// the list if they are present. |
- while (!identifiers_.empty() && |
- identifiers_[0] == POPUP_ITEM_ID_DATALIST_ENTRY) { |
- names_.erase(names_.begin()); |
- subtexts_.erase(subtexts_.begin()); |
- icons_.erase(icons_.begin()); |
- identifiers_.erase(identifiers_.begin()); |
+ while (!suggestions_.empty() && |
+ suggestions_[0].frontend_id == POPUP_ITEM_ID_DATALIST_ENTRY) { |
+ suggestions_.erase(suggestions_.begin()); |
+ elided_values_.erase(elided_values_.begin()); |
+ elided_labels_.erase(elided_labels_.begin()); |
} |
// If there are no new data list values, exit (clearing the separator if there |
// is one). |
if (values.empty()) { |
- if (!identifiers_.empty() && identifiers_[0] == POPUP_ITEM_ID_SEPARATOR) { |
- names_.erase(names_.begin()); |
- subtexts_.erase(subtexts_.begin()); |
- icons_.erase(icons_.begin()); |
- identifiers_.erase(identifiers_.begin()); |
+ if (!suggestions_.empty() && |
+ suggestions_[0].frontend_id == POPUP_ITEM_ID_SEPARATOR) { |
+ suggestions_.erase(suggestions_.begin()); |
+ elided_values_.erase(elided_values_.begin()); |
+ elided_labels_.erase(elided_labels_.begin()); |
} |
// The popup contents have changed, so either update the bounds or hide it. |
@@ -214,23 +223,33 @@ void AutofillPopupControllerImpl::UpdateDataListValues( |
} |
// Add a separator if there are any other values. |
- if (!identifiers_.empty() && identifiers_[0] != POPUP_ITEM_ID_SEPARATOR) { |
- names_.insert(names_.begin(), base::string16()); |
- subtexts_.insert(subtexts_.begin(), base::string16()); |
- icons_.insert(icons_.begin(), base::string16()); |
- identifiers_.insert(identifiers_.begin(), POPUP_ITEM_ID_SEPARATOR); |
+ if (!suggestions_.empty() && |
+ suggestions_[0].frontend_id != POPUP_ITEM_ID_SEPARATOR) { |
+ suggestions_.insert(suggestions_.begin(), autofill::Suggestion()); |
+ suggestions_[0].frontend_id = POPUP_ITEM_ID_SEPARATOR; |
+ elided_values_.insert(elided_values_.begin(), base::string16()); |
+ elided_labels_.insert(elided_labels_.begin(), base::string16()); |
} |
- |
- names_.insert(names_.begin(), values.begin(), values.end()); |
- subtexts_.insert(subtexts_.begin(), labels.begin(), labels.end()); |
- |
- // Add the values that are the same for all data list elements. |
- icons_.insert(icons_.begin(), values.size(), base::string16()); |
- identifiers_.insert( |
- identifiers_.begin(), values.size(), POPUP_ITEM_ID_DATALIST_ENTRY); |
+ // Prepend the parameters to the suggestions we already have. |
+ suggestions_.insert(suggestions_.begin(), values.size(), Suggestion()); |
+ elided_values_.insert(elided_values_.begin(), values.size(), |
+ base::string16()); |
+ elided_labels_.insert(elided_labels_.begin(), values.size(), |
+ base::string16()); |
+ for (size_t i = 0; i < values.size(); i++) { |
+ suggestions_[i].value = values[i]; |
+ suggestions_[i].label = labels[i]; |
+ suggestions_[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY; |
+ |
+ // TODO(brettw) it looks like these should be elided. |
+ elided_values_[i] = values[i]; |
+ elided_labels_[i] = labels[i]; |
+ } |
UpdateBoundsAndRedrawPopup(); |
+ DCHECK_EQ(suggestions_.size(), elided_values_.size()); |
+ DCHECK_EQ(suggestions_.size(), elided_labels_.size()); |
} |
void AutofillPopupControllerImpl::Hide() { |
@@ -267,7 +286,7 @@ bool AutofillPopupControllerImpl::HandleKeyPressEvent( |
SelectNextLine(); |
return true; |
case ui::VKEY_NEXT: // Page down. |
- SetSelectedLine(names().size() - 1); |
+ SetSelectedLine(GetLineCount() - 1); |
return true; |
case ui::VKEY_ESCAPE: |
Hide(); |
@@ -309,9 +328,9 @@ bool AutofillPopupControllerImpl::AcceptSelectedLine() { |
return false; |
DCHECK_GE(selected_line_, 0); |
- DCHECK_LT(selected_line_, static_cast<int>(names_.size())); |
+ DCHECK_LT(selected_line_, static_cast<int>(GetLineCount())); |
- if (!CanAccept(identifiers_[selected_line_])) |
+ if (!CanAccept(suggestions_[selected_line_].frontend_id)) |
return false; |
AcceptSuggestion(selected_line_); |
@@ -323,7 +342,8 @@ void AutofillPopupControllerImpl::SelectionCleared() { |
} |
void AutofillPopupControllerImpl::AcceptSuggestion(size_t index) { |
- delegate_->DidAcceptSuggestion(full_names_[index], identifiers_[index]); |
+ const autofill::Suggestion& suggestion = suggestions_[index]; |
+ delegate_->DidAcceptSuggestion(suggestion.value, suggestion.frontend_id); |
} |
int AutofillPopupControllerImpl::GetIconResourceID( |
@@ -339,26 +359,26 @@ int AutofillPopupControllerImpl::GetIconResourceID( |
bool AutofillPopupControllerImpl::CanDelete(size_t index) const { |
// TODO(isherman): Native AddressBook suggestions on Mac and Android should |
// not be considered to be deleteable. |
- int id = identifiers_[index]; |
+ int id = suggestions_[index].frontend_id; |
return id > 0 || id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY || |
id == POPUP_ITEM_ID_PASSWORD_ENTRY; |
} |
bool AutofillPopupControllerImpl::IsWarning(size_t index) const { |
- return identifiers_[index] == POPUP_ITEM_ID_WARNING_MESSAGE; |
+ return suggestions_[index].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE; |
} |
gfx::Rect AutofillPopupControllerImpl::GetRowBounds(size_t index) { |
int top = kPopupBorderThickness; |
for (size_t i = 0; i < index; ++i) { |
- top += GetRowHeightFromId(identifiers()[i]); |
+ top += GetRowHeightFromId(suggestions_[i].frontend_id); |
} |
return gfx::Rect( |
kPopupBorderThickness, |
top, |
popup_bounds_.width() - 2 * kPopupBorderThickness, |
- GetRowHeightFromId(identifiers()[index])); |
+ GetRowHeightFromId(suggestions_[index].frontend_id)); |
} |
void AutofillPopupControllerImpl::SetPopupBounds(const gfx::Rect& bounds) { |
@@ -386,37 +406,39 @@ bool AutofillPopupControllerImpl::IsRTL() const { |
return text_direction_ == base::i18n::RIGHT_TO_LEFT; |
} |
-const std::vector<base::string16>& AutofillPopupControllerImpl::names() const { |
- return names_; |
+size_t AutofillPopupControllerImpl::GetLineCount() const { |
+ return suggestions_.size(); |
} |
-const std::vector<base::string16>& AutofillPopupControllerImpl::subtexts() |
- const { |
- return subtexts_; |
+const autofill::Suggestion& AutofillPopupControllerImpl::GetSuggestionAt( |
+ size_t row) const { |
+ return suggestions_[row]; |
} |
-const std::vector<base::string16>& AutofillPopupControllerImpl::icons() const { |
- return icons_; |
+const base::string16& AutofillPopupControllerImpl::GetElidedValueAt( |
+ size_t row) const { |
+ return elided_values_[row]; |
} |
-const std::vector<int>& AutofillPopupControllerImpl::identifiers() const { |
- return identifiers_; |
+const base::string16& AutofillPopupControllerImpl::GetElidedLabelAt( |
+ size_t row) const { |
+ return elided_labels_[row]; |
} |
#if !defined(OS_ANDROID) |
-const gfx::FontList& AutofillPopupControllerImpl::GetNameFontListForRow( |
+const gfx::FontList& AutofillPopupControllerImpl::GetValueFontListForRow( |
size_t index) const { |
- if (identifiers_[index] == POPUP_ITEM_ID_WARNING_MESSAGE) |
+ if (suggestions_[index].frontend_id == POPUP_ITEM_ID_WARNING_MESSAGE) |
return warning_font_list_; |
- if (identifiers_[index] == POPUP_ITEM_ID_TITLE) |
+ if (suggestions_[index].frontend_id == POPUP_ITEM_ID_TITLE) |
return title_font_list_; |
- return name_font_list_; |
+ return value_font_list_; |
} |
-const gfx::FontList& AutofillPopupControllerImpl::subtext_font_list() const { |
- return subtext_font_list_; |
+const gfx::FontList& AutofillPopupControllerImpl::GetLabelFontList() const { |
+ return label_font_list_; |
} |
#endif |
@@ -429,21 +451,21 @@ void AutofillPopupControllerImpl::SetSelectedLine(int selected_line) { |
return; |
if (selected_line_ != kNoSelection && |
- static_cast<size_t>(selected_line_) < identifiers_.size()) |
+ static_cast<size_t>(selected_line_) < suggestions_.size()) |
InvalidateRow(selected_line_); |
if (selected_line != kNoSelection) { |
InvalidateRow(selected_line); |
- if (!CanAccept(identifiers_[selected_line])) |
+ if (!CanAccept(suggestions_[selected_line].frontend_id)) |
selected_line = kNoSelection; |
} |
selected_line_ = selected_line; |
if (selected_line_ != kNoSelection) { |
- delegate_->DidSelectSuggestion(names_[selected_line_], |
- identifiers_[selected_line_]); |
+ delegate_->DidSelectSuggestion(elided_values_[selected_line_], |
+ suggestions_[selected_line_].frontend_id); |
} else { |
delegate_->ClearPreviewedForm(); |
} |
@@ -453,12 +475,12 @@ void AutofillPopupControllerImpl::SelectNextLine() { |
int new_selected_line = selected_line_ + 1; |
// Skip over any lines that can't be selected. |
- while (static_cast<size_t>(new_selected_line) < names_.size() && |
- !CanAccept(identifiers()[new_selected_line])) { |
+ while (static_cast<size_t>(new_selected_line) < GetLineCount() && |
+ !CanAccept(suggestions_[new_selected_line].frontend_id)) { |
++new_selected_line; |
} |
- if (new_selected_line >= static_cast<int>(names_.size())) |
+ if (new_selected_line >= static_cast<int>(GetLineCount())) |
new_selected_line = 0; |
SetSelectedLine(new_selected_line); |
@@ -469,12 +491,12 @@ void AutofillPopupControllerImpl::SelectPreviousLine() { |
// Skip over any lines that can't be selected. |
while (new_selected_line > kNoSelection && |
- !CanAccept(identifiers()[new_selected_line])) { |
+ !CanAccept(GetSuggestionAt(new_selected_line).frontend_id)) { |
--new_selected_line; |
} |
if (new_selected_line <= kNoSelection) |
- new_selected_line = names_.size() - 1; |
+ new_selected_line = GetLineCount() - 1; |
SetSelectedLine(new_selected_line); |
} |
@@ -484,20 +506,18 @@ bool AutofillPopupControllerImpl::RemoveSelectedLine() { |
return false; |
DCHECK_GE(selected_line_, 0); |
- DCHECK_LT(selected_line_, static_cast<int>(names_.size())); |
+ DCHECK_LT(selected_line_, static_cast<int>(GetLineCount())); |
if (!CanDelete(selected_line_)) |
return false; |
- delegate_->RemoveSuggestion(full_names_[selected_line_], |
- identifiers_[selected_line_]); |
+ delegate_->RemoveSuggestion(suggestions_[selected_line_].value, |
+ suggestions_[selected_line_].frontend_id); |
// Remove the deleted element. |
- names_.erase(names_.begin() + selected_line_); |
- full_names_.erase(full_names_.begin() + selected_line_); |
- subtexts_.erase(subtexts_.begin() + selected_line_); |
- icons_.erase(icons_.begin() + selected_line_); |
- identifiers_.erase(identifiers_.begin() + selected_line_); |
+ suggestions_.erase(suggestions_.begin() + selected_line_); |
+ elided_values_.erase(elided_values_.begin() + selected_line_); |
+ elided_labels_.erase(elided_labels_.begin() + selected_line_); |
SetSelectedLine(kNoSelection); |
@@ -514,15 +534,15 @@ bool AutofillPopupControllerImpl::RemoveSelectedLine() { |
int AutofillPopupControllerImpl::LineFromY(int y) { |
int current_height = kPopupBorderThickness; |
- for (size_t i = 0; i < identifiers().size(); ++i) { |
- current_height += GetRowHeightFromId(identifiers()[i]); |
+ for (size_t i = 0; i < suggestions_.size(); ++i) { |
+ current_height += GetRowHeightFromId(suggestions_[i].frontend_id); |
if (y <= current_height) |
return i; |
} |
// The y value goes beyond the popup so stop the selection at the last line. |
- return identifiers().size() - 1; |
+ return GetLineCount() - 1; |
} |
int AutofillPopupControllerImpl::GetRowHeightFromId(int identifier) const { |
@@ -538,24 +558,25 @@ bool AutofillPopupControllerImpl::CanAccept(int id) { |
} |
bool AutofillPopupControllerImpl::HasSuggestions() { |
- return identifiers_.size() != 0 && |
- (identifiers_[0] > 0 || |
- identifiers_[0] == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY || |
- identifiers_[0] == POPUP_ITEM_ID_PASSWORD_ENTRY || |
- identifiers_[0] == POPUP_ITEM_ID_DATALIST_ENTRY || |
- identifiers_[0] == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS); |
+ if (suggestions_.empty()) |
+ return false; |
+ int id = suggestions_[0].frontend_id; |
+ return id > 0 || |
+ id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY || |
+ id == POPUP_ITEM_ID_PASSWORD_ENTRY || |
+ id == POPUP_ITEM_ID_DATALIST_ENTRY || |
+ id == POPUP_ITEM_ID_MAC_ACCESS_CONTACTS; |
} |
void AutofillPopupControllerImpl::SetValues( |
- const std::vector<base::string16>& names, |
- const std::vector<base::string16>& subtexts, |
- const std::vector<base::string16>& icons, |
- const std::vector<int>& identifiers) { |
- names_ = names; |
- full_names_ = names; |
- subtexts_ = subtexts; |
- icons_ = icons; |
- identifiers_ = identifiers; |
+ const std::vector<autofill::Suggestion>& suggestions) { |
+ suggestions_ = suggestions; |
+ elided_values_.resize(suggestions.size()); |
+ elided_labels_.resize(suggestions.size()); |
+ for (size_t i = 0; i < suggestions.size(); i++) { |
+ elided_values_[i] = suggestions[i].value; |
+ elided_labels_[i] = suggestions[i].label; |
+ } |
} |
void AutofillPopupControllerImpl::ShowView() { |
@@ -564,18 +585,17 @@ void AutofillPopupControllerImpl::ShowView() { |
void AutofillPopupControllerImpl::InvalidateRow(size_t row) { |
DCHECK(0 <= row); |
- DCHECK(row < identifiers_.size()); |
+ DCHECK(row < suggestions_.size()); |
view_->InvalidateRow(row); |
} |
#if !defined(OS_ANDROID) |
int AutofillPopupControllerImpl::GetDesiredPopupWidth() const { |
int popup_width = controller_common_->RoundedElementBounds().width(); |
- DCHECK_EQ(names().size(), subtexts().size()); |
- for (size_t i = 0; i < names().size(); ++i) { |
+ for (size_t i = 0; i < GetLineCount(); ++i) { |
int row_size = |
- gfx::GetStringWidth(names()[i], name_font_list_) + |
- gfx::GetStringWidth(subtexts()[i], subtext_font_list_) + |
+ gfx::GetStringWidth(GetElidedValueAt(i), value_font_list_) + |
+ gfx::GetStringWidth(GetElidedLabelAt(i), label_font_list_) + |
RowWidthWithoutText(i); |
popup_width = std::max(popup_width, row_size); |
@@ -587,8 +607,8 @@ int AutofillPopupControllerImpl::GetDesiredPopupWidth() const { |
int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { |
int popup_height = 2 * kPopupBorderThickness; |
- for (size_t i = 0; i < identifiers().size(); ++i) { |
- popup_height += GetRowHeightFromId(identifiers()[i]); |
+ for (size_t i = 0; i < suggestions_.size(); ++i) { |
+ popup_height += GetRowHeightFromId(suggestions_[i].frontend_id); |
} |
return popup_height; |
@@ -597,13 +617,14 @@ int AutofillPopupControllerImpl::GetDesiredPopupHeight() const { |
int AutofillPopupControllerImpl::RowWidthWithoutText(int row) const { |
int row_size = kEndPadding; |
- if (!subtexts_[row].empty()) |
+ if (!elided_labels_[row].empty()) |
row_size += kNamePadding; |
// Add the Autofill icon size, if required. |
- if (!icons_[row].empty()) { |
+ const base::string16& icon = suggestions_[row].icon; |
+ if (!icon.empty()) { |
int icon_width = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
- GetIconResourceID(icons_[row])).Width(); |
+ GetIconResourceID(icon)).Width(); |
row_size += icon_width + kIconPadding; |
} |
@@ -620,8 +641,7 @@ void AutofillPopupControllerImpl::UpdatePopupBounds() { |
int popup_width = GetDesiredPopupWidth(); |
int popup_height = GetDesiredPopupHeight(); |
- popup_bounds_ = controller_common_->GetPopupBounds(popup_width, |
- popup_height); |
+ popup_bounds_ = controller_common_->GetPopupBounds(popup_width, popup_height); |
} |
#endif // !defined(OS_ANDROID) |
@@ -635,11 +655,9 @@ void AutofillPopupControllerImpl::ClearState() { |
popup_bounds_ = gfx::Rect(); |
- names_.clear(); |
- subtexts_.clear(); |
- icons_.clear(); |
- identifiers_.clear(); |
- full_names_.clear(); |
+ suggestions_.clear(); |
+ elided_values_.clear(); |
+ elided_labels_.clear(); |
selected_line_ = kNoSelection; |
} |