summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 01:14:06 +0000
committerisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 01:14:06 +0000
commitd77ddc80612ad43982c6f7da0de0c9e299f049c4 (patch)
tree5f87cdb5038bf919a6285274cfba6b33f489ef4c
parent8c619149607580303c4050ee908f22c08fcb697c (diff)
downloadchromium_src-d77ddc80612ad43982c6f7da0de0c9e299f049c4.zip
chromium_src-d77ddc80612ad43982c6f7da0de0c9e299f049c4.tar.gz
chromium_src-d77ddc80612ad43982c6f7da0de0c9e299f049c4.tar.bz2
Always include nonzero unique ID with autofill suggestions.
In particular, include the ID when correcting a form field. BUG=62416 TEST=unit_tests --gtest_filter=AutoFillManagerTest.* Review URL: http://codereview.chromium.org/5265002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67192 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autofill/autofill_manager.cc11
-rw-r--r--chrome/browser/autofill/autofill_manager.h20
-rw-r--r--chrome/browser/autofill/autofill_manager_unittest.cc162
-rw-r--r--chrome/renderer/autofill_helper.cc4
-rw-r--r--chrome/renderer/autofill_helper.h3
-rw-r--r--chrome/renderer/form_manager.cc9
-rw-r--r--chrome/renderer/form_manager.h8
-rw-r--r--chrome/renderer/form_manager_browsertest.cc58
8 files changed, 212 insertions, 63 deletions
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 1ba7a45..42051f7 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -240,15 +240,8 @@ bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled,
// redundant. In addition, remove duplicate values.
if (field_autofilled) {
RemoveDuplicateElements(&values, &unique_ids);
- labels.resize(values.size());
- icons.resize(values.size());
- unique_ids.resize(values.size());
-
- for (size_t i = 0; i < labels.size(); ++i) {
- labels[i] = string16();
- icons[i] = string16();
- unique_ids[i] = 0;
- }
+ labels.assign(values.size(), string16());
+ icons.assign(values.size(), string16());
}
host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index bf31052..835f643 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -95,6 +95,16 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill,
personal_data_ = personal_data;
}
+ // Maps GUIDs to and from IDs that are used to identify profiles and credit
+ // cards sent to and from the renderer process.
+ virtual int GUIDToID(const std::string& guid);
+ virtual const std::string IDToGUID(int id);
+
+ // Methods for packing and unpacking credit card and profile IDs for sending
+ // and receiving to and from the renderer process.
+ int PackGUIDs(const std::string& cc_guid, const std::string& profile_guid);
+ void UnpackGUIDs(int id, std::string* cc_guid, std::string* profile_guid);
+
private:
// Returns a list of values from the stored profiles that match |type| and the
// value of |field| and returns the labels of the matching profiles. |labels|
@@ -136,16 +146,6 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill,
// Parses the forms using heuristic matching and querying the AutoFill server.
void ParseForms(const std::vector<webkit_glue::FormData>& forms);
- // Methods for packing and unpacking credit card and profile IDs for sending
- // and receiving to and from the renderer process.
- int PackGUIDs(const std::string& cc_guid, const std::string& profile_guid);
- void UnpackGUIDs(int id, std::string* cc_guid, std::string* profile_guid);
-
- // Maps GUIDs to and from IDs that are used to identify profiles and credit
- // cards sent to and from the renderer process.
- int GUIDToID(const std::string& guid);
- const std::string IDToGUID(int id);
-
// The following function is meant to be called from unit-test only.
void set_disable_download_manager_requests(bool value) {
disable_download_manager_requests_ = value;
diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc
index e830fa3..228bbdb 100644
--- a/chrome/browser/autofill/autofill_manager_unittest.cc
+++ b/chrome/browser/autofill/autofill_manager_unittest.cc
@@ -8,7 +8,9 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/scoped_vector.h"
+#include "base/string_number_conversions.h"
#include "base/string16.h"
+#include "base/stringprintf.h"
#include "base/tuple.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_common_test.h"
@@ -143,6 +145,28 @@ class TestAutoFillManager : public AutoFillManager {
test_personal_data_->AddProfile(profile);
}
+ int GetPackedCreditCardID(int credit_card_id) {
+ return PackGUIDs(IDToGUID(credit_card_id), std::string());
+ }
+
+ protected:
+ virtual int GUIDToID(const std::string& guid) OVERRIDE {
+ if (guid.empty())
+ return 0;
+
+ int id;
+ EXPECT_TRUE(base::StringToInt(guid.substr(guid.rfind("-") + 1), &id));
+ return id;
+ }
+
+ virtual const std::string IDToGUID(int id) OVERRIDE {
+ EXPECT_TRUE(id >= 0);
+ if (id <= 0)
+ return std::string();
+
+ return base::StringPrintf("00000000-0000-0000-0000-%012d", id);
+ }
+
private:
TestPersonalDataManager* test_personal_data_;
bool autofill_enabled_;
@@ -248,7 +272,8 @@ class AutoFillManagerTest : public RenderViewHostTestHarness {
bool GetAutoFillSuggestionsMessage(int* page_id,
std::vector<string16>* values,
std::vector<string16>* labels,
- std::vector<string16>* icons) {
+ std::vector<string16>* icons,
+ std::vector<int>* unique_ids) {
const uint32 kMsgID = ViewMsg_AutoFillSuggestionsReturned::ID;
const IPC::Message* message =
process()->sink().GetFirstMessageMatching(kMsgID);
@@ -265,6 +290,8 @@ class AutoFillManagerTest : public RenderViewHostTestHarness {
*labels = autofill_param.c;
if (icons)
*icons = autofill_param.d;
+ if (unique_ids)
+ *unique_ids = autofill_param.e;
return true;
}
@@ -321,8 +348,9 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -335,6 +363,9 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
}
// Test that we return only matching address profile suggestions when the
@@ -367,8 +398,9 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -376,6 +408,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) {
EXPECT_EQ(ASCIIToUTF16("3734 Elvis Presley Blvd."), labels[0]);
ASSERT_EQ(1U, icons.size());
EXPECT_EQ(string16(), icons[0]);
+ ASSERT_EQ(1U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
}
// Test that we return no suggestions when the form has no relevant fields.
@@ -472,8 +506,9 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED),
@@ -482,6 +517,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) {
EXPECT_EQ(string16(), labels[0]);
ASSERT_EQ(1U, icons.size());
EXPECT_EQ(string16(), icons[0]);
+ ASSERT_EQ(1U, unique_ids.size());
+ EXPECT_EQ(-1, unique_ids[0]);
// Now add some Autocomplete suggestions. We should return the autocomplete
// suggestions and the warning; these will be culled by the renderer.
@@ -495,8 +532,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) {
suggestions.push_back(ASCIIToUTF16("Jason"));
rvh()->AutocompleteSuggestionsReturned(suggestions);
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID2, page_id);
ASSERT_EQ(3U, values.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED),
@@ -511,6 +548,10 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) {
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
EXPECT_EQ(string16(), icons[2]);
+ ASSERT_EQ(3U, unique_ids.size());
+ EXPECT_EQ(-1, unique_ids[0]);
+ EXPECT_EQ(0, unique_ids[1]);
+ EXPECT_EQ(0, unique_ids[2]);
// Now clear the test profiles and try again -- we shouldn't return a warning.
test_personal_data_->ClearAutoFillProfiles();
@@ -547,8 +588,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("************3456"), values[0]);
@@ -559,6 +601,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(ASCIIToUTF16("visaCC"), icons[0]);
EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(4), unique_ids[0]);
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(5), unique_ids[1]);
}
// Test that we return only matching credit card profile suggestions when the
@@ -591,8 +636,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(ASCIIToUTF16("************3456"), values[0]);
@@ -600,6 +646,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) {
EXPECT_EQ(ASCIIToUTF16("*3456"), labels[0]);
ASSERT_EQ(1U, icons.size());
EXPECT_EQ(ASCIIToUTF16("visaCC"), icons[0]);
+ ASSERT_EQ(1U, unique_ids.size());
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(4), unique_ids[0]);
}
// Test that we return credit card profile suggestions when the selected form
@@ -632,8 +680,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis Presley"), values[0]);
@@ -644,6 +693,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(ASCIIToUTF16("visaCC"), icons[0]);
EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(4), unique_ids[0]);
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(5), unique_ids[1]);
}
// Test that we return a warning explaining that credit card profile suggestions
@@ -676,8 +728,9 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
@@ -686,6 +739,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
EXPECT_EQ(string16(), labels[0]);
ASSERT_EQ(1U, icons.size());
EXPECT_EQ(string16(), icons[0]);
+ ASSERT_EQ(1U, unique_ids.size());
+ EXPECT_EQ(-1, unique_ids[0]);
// Now add some Autocomplete suggestions. We should show the autocomplete
// suggestions and the warning.
@@ -699,8 +754,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
suggestions.push_back(ASCIIToUTF16("Jason"));
rvh()->AutocompleteSuggestionsReturned(suggestions);
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID2, page_id);
ASSERT_EQ(3U, values.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
@@ -715,6 +770,10 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
EXPECT_EQ(string16(), icons[2]);
+ ASSERT_EQ(3U, unique_ids.size());
+ EXPECT_EQ(-1, unique_ids[0]);
+ EXPECT_EQ(0, unique_ids[1]);
+ EXPECT_EQ(0, unique_ids[2]);
// Clear the test credit cards and try again -- we shouldn't return a warning.
test_personal_data_->ClearCreditCards();
@@ -751,8 +810,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -765,6 +825,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
process()->sink().ClearMessages();
autofill_test::CreateTestFormField(
@@ -778,8 +841,8 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
// Test that we sent the credit card suggestions to the renderer.
page_id = 0;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("************3456"), values[0]);
@@ -790,6 +853,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(ASCIIToUTF16("visaCC"), icons[0]);
EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(4), unique_ids[0]);
+ EXPECT_EQ(autofill_manager_->GetPackedCreditCardID(5), unique_ids[1]);
}
// Test that for non-https forms with both address and credit card fields, we
@@ -825,8 +891,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -839,6 +906,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
process()->sink().ClearMessages();
autofill_test::CreateTestFormField(
@@ -851,8 +921,8 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
rvh()->AutocompleteSuggestionsReturned(std::vector<string16>());
// Test that we sent the right message to the renderer.
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(1U, values.size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
@@ -861,6 +931,8 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
EXPECT_EQ(string16(), labels[0]);
ASSERT_EQ(1U, icons.size());
EXPECT_EQ(string16(), icons[0]);
+ ASSERT_EQ(1U, unique_ids.size());
+ EXPECT_EQ(-1, unique_ids[0]);
// Clear the test credit cards and try again -- we shouldn't return a warning.
test_personal_data_->ClearCreditCards();
@@ -901,8 +973,9 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(4U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -919,6 +992,11 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) {
EXPECT_EQ(string16(), icons[1]);
EXPECT_EQ(string16(), icons[2]);
EXPECT_EQ(string16(), icons[3]);
+ ASSERT_EQ(4U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
+ EXPECT_EQ(0, unique_ids[2]);
+ EXPECT_EQ(0, unique_ids[3]);
}
// Test that we return autocomplete-like suggestions when trying to autofill
@@ -951,8 +1029,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFieldIsAutoFilled) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -963,6 +1042,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFieldIsAutoFilled) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
}
// Test that nothing breaks when there are autocomplete suggestions but no
@@ -998,8 +1080,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
ASSERT_EQ(2U, labels.size());
@@ -1010,6 +1093,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(0, unique_ids[0]);
+ EXPECT_EQ(0, unique_ids[1]);
}
// Test that we do not return duplicate values drawn from multiple profiles when
@@ -1027,6 +1113,7 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
AutoFillProfile* profile = new AutoFillProfile;
autofill_test::SetProfileInfo(profile, "Duplicate", "Elvis", "", "", "", "",
"", "", "", "", "", "", "", "");
+ profile->set_guid("00000000-0000-0000-0000-000000000101");
autofill_manager_->AddProfile(profile);
// The page ID sent to the AutoFillManager from the RenderView, used to send
@@ -1048,8 +1135,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
std::vector<string16> values;
std::vector<string16> labels;
std::vector<string16> icons;
- EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels,
- &icons));
+ std::vector<int> unique_ids;
+ EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, &icons,
+ &unique_ids));
EXPECT_EQ(kPageID, page_id);
ASSERT_EQ(2U, values.size());
EXPECT_EQ(ASCIIToUTF16("Elvis"), values[0]);
@@ -1060,6 +1148,9 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
ASSERT_EQ(2U, icons.size());
EXPECT_EQ(string16(), icons[0]);
EXPECT_EQ(string16(), icons[1]);
+ ASSERT_EQ(2U, unique_ids.size());
+ EXPECT_EQ(1, unique_ids[0]);
+ EXPECT_EQ(2, unique_ids[1]);
}
// Test that we correctly fill an address form.
@@ -1071,6 +1162,7 @@ TEST_F(AutoFillManagerTest, FillAddressForm) {
"916 16th St.", "Apt. 6", "Lubbock",
"Texas", "79401", "USA",
"12345678901", "");
+ profile->set_guid("00000000-0000-0000-0000-000000000007");
autofill_manager_->AddProfile(profile);
FormData form;
diff --git a/chrome/renderer/autofill_helper.cc b/chrome/renderer/autofill_helper.cc
index 5dc91b4..8b7a1ea 100644
--- a/chrome/renderer/autofill_helper.cc
+++ b/chrome/renderer/autofill_helper.cc
@@ -52,6 +52,7 @@ AutoFillHelper::AutoFillHelper(RenderView* render_view)
: render_view_(render_view),
autofill_query_id_(0),
autofill_action_(AUTOFILL_NONE),
+ was_query_node_autofilled_(false),
suggestions_clear_index_(-1),
suggestions_options_index_(-1) {
}
@@ -218,7 +219,7 @@ void AutoFillHelper::DidAcceptAutoFillSuggestion(const WebNode& node,
}
void AutoFillHelper::DidClearAutoFillSelection(const WebNode& node) {
- form_manager_.ClearPreviewedFormWithNode(node);
+ form_manager_.ClearPreviewedFormWithNode(node, was_query_node_autofilled_);
}
void AutoFillHelper::FrameContentsAvailable(WebFrame* frame) {
@@ -318,6 +319,7 @@ void AutoFillHelper::FillAutoFillFormData(const WebNode& node,
return;
autofill_action_ = action;
+ was_query_node_autofilled_ = element.isAutofilled();
render_view_->Send(new ViewHostMsg_FillAutoFillFormData(
render_view_->routing_id(), autofill_query_id_, form, unique_id));
}
diff --git a/chrome/renderer/autofill_helper.h b/chrome/renderer/autofill_helper.h
index e53a3ac..de1c909 100644
--- a/chrome/renderer/autofill_helper.h
+++ b/chrome/renderer/autofill_helper.h
@@ -144,6 +144,9 @@ class AutoFillHelper : public PageClickListener {
// The action to take when receiving AutoFill data from the AutoFillManager.
AutoFillAction autofill_action_;
+ // Was the query node autofilled prior to previewing the form?
+ bool was_query_node_autofilled_;
+
// The menu index of the "Clear" menu item.
int suggestions_clear_index_;
diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc
index 1006674..e6c1c9a 100644
--- a/chrome/renderer/form_manager.cc
+++ b/chrome/renderer/form_manager.cc
@@ -656,7 +656,8 @@ bool FormManager::ClearFormWithNode(const WebNode& node) {
return true;
}
-bool FormManager::ClearPreviewedFormWithNode(const WebNode& node) {
+bool FormManager::ClearPreviewedFormWithNode(const WebNode& node,
+ bool was_autofilled) {
FormElement* form_element = NULL;
if (!FindCachedFormElementWithNode(node, &form_element))
return false;
@@ -683,14 +684,16 @@ bool FormManager::ClearPreviewedFormWithNode(const WebNode& node) {
// Clear the suggested value. For the initiating node, also restore the
// original value.
- input_element.setSuggestedValue(string16());
+ input_element.setSuggestedValue(WebString());
bool is_initiating_node = (node == input_element);
if (is_initiating_node) {
// Call |setValue()| to force the renderer to update the field's displayed
// value.
input_element.setValue(input_element.value());
+ input_element.setAutofilled(was_autofilled);
+ } else {
+ input_element.setAutofilled(false);
}
- input_element.setAutofilled(false);
// Clearing the suggested value in the focused node (above) can cause
// selection to be lost. We force selection range to restore the text
diff --git a/chrome/renderer/form_manager.h b/chrome/renderer/form_manager.h
index 4371287..910969d 100644
--- a/chrome/renderer/form_manager.h
+++ b/chrome/renderer/form_manager.h
@@ -108,9 +108,11 @@ class FormManager {
bool ClearFormWithNode(const WebKit::WebNode& node);
// Clears the placeholder values and the auto-filled background for any fields
- // in the form containing |node| that have been previewed. Returns false if
- // the form is not found.
- bool ClearPreviewedFormWithNode(const WebKit::WebNode& node);
+ // in the form containing |node| that have been previewed. Resets the
+ // autofilled state of |node| to |was_autofilled|. Returns false if the form
+ // is not found.
+ bool ClearPreviewedFormWithNode(const WebKit::WebNode& node,
+ bool was_autofilled);
// Resets the stored set of forms.
void Reset();
diff --git a/chrome/renderer/form_manager_browsertest.cc b/chrome/renderer/form_manager_browsertest.cc
index ffcfc53..c1d421c 100644
--- a/chrome/renderer/form_manager_browsertest.cc
+++ b/chrome/renderer/form_manager_browsertest.cc
@@ -2710,7 +2710,7 @@ TEST_F(FormManagerTest, ClearPreviewedFormWithNode) {
email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
// Clear the previewed fields.
- EXPECT_TRUE(form_manager.ClearPreviewedFormWithNode(lastname));
+ EXPECT_TRUE(form_manager.ClearPreviewedFormWithNode(lastname, false));
// Fields with empty suggestions suggestions are not modified.
EXPECT_EQ(ASCIIToUTF16("Wyatt"), firstname.value());
@@ -2766,7 +2766,7 @@ TEST_F(FormManagerTest, ClearPreviewedFormWithNonEmptyInitiatingNode) {
email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
// Clear the previewed fields.
- EXPECT_TRUE(form_manager.ClearPreviewedFormWithNode(firstname));
+ EXPECT_TRUE(form_manager.ClearPreviewedFormWithNode(firstname, false));
// Fields with non-empty values are restored.
EXPECT_EQ(ASCIIToUTF16("W"), firstname.value());
@@ -2784,6 +2784,60 @@ TEST_F(FormManagerTest, ClearPreviewedFormWithNonEmptyInitiatingNode) {
EXPECT_FALSE(email.isAutofilled());
}
+TEST_F(FormManagerTest, ClearPreviewedFormWithAutofilledInitiatingNode) {
+ LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
+ " <INPUT type=\"text\" id=\"firstname\" value=\"W\"/>"
+ " <INPUT type=\"text\" id=\"lastname\"/>"
+ " <INPUT type=\"text\" id=\"email\"/>"
+ " <INPUT type=\"submit\" value=\"Send\"/>"
+ "</FORM>");
+
+ WebFrame* web_frame = GetMainFrame();
+ ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
+
+ FormManager form_manager;
+ form_manager.ExtractForms(web_frame);
+
+ // Verify that we have the form.
+ std::vector<FormData> forms;
+ form_manager.GetFormsInFrame(web_frame, FormManager::REQUIRE_NONE, &forms);
+ ASSERT_EQ(1U, forms.size());
+
+ // Set the auto-filled attribute.
+ WebInputElement firstname =
+ web_frame->document().getElementById("firstname").to<WebInputElement>();
+ firstname.setAutofilled(true);
+ WebInputElement lastname =
+ web_frame->document().getElementById("lastname").to<WebInputElement>();
+ lastname.setAutofilled(true);
+ WebInputElement email =
+ web_frame->document().getElementById("email").to<WebInputElement>();
+ email.setAutofilled(true);
+
+ // Set the suggested values on all of the elements.
+ firstname.setSuggestedValue(ASCIIToUTF16("Wyatt"));
+ lastname.setSuggestedValue(ASCIIToUTF16("Earp"));
+ email.setSuggestedValue(ASCIIToUTF16("wyatt@earp.com"));
+
+ // Clear the previewed fields.
+ EXPECT_TRUE(form_manager.ClearPreviewedFormWithNode(firstname, true));
+
+ // Fields with non-empty values are restored.
+ EXPECT_EQ(ASCIIToUTF16("W"), firstname.value());
+ EXPECT_TRUE(firstname.suggestedValue().isEmpty());
+ EXPECT_TRUE(firstname.isAutofilled());
+ EXPECT_EQ(1, firstname.selectionStart());
+ EXPECT_EQ(1, firstname.selectionEnd());
+
+ // Verify the previewed fields are cleared.
+ EXPECT_TRUE(lastname.value().isEmpty());
+ EXPECT_TRUE(lastname.suggestedValue().isEmpty());
+ EXPECT_FALSE(lastname.isAutofilled());
+ EXPECT_TRUE(email.value().isEmpty());
+ EXPECT_TRUE(email.suggestedValue().isEmpty());
+ EXPECT_FALSE(email.isAutofilled());
+}
+
TEST_F(FormManagerTest, FormWithNodeIsAutoFilled) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"Wyatt\"/>"