diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 02:18:28 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 02:18:28 +0000 |
commit | dc9144fed7238ba56fa3f39158ef6d7267bd0a23 (patch) | |
tree | ff5adb0ff4c44ddeb3f92a8740a84aca1e38385b | |
parent | 48dbfb25992081e5c4c35bea85bf04ff13c6d042 (diff) | |
download | chromium_src-dc9144fed7238ba56fa3f39158ef6d7267bd0a23.zip chromium_src-dc9144fed7238ba56fa3f39158ef6d7267bd0a23.tar.gz chromium_src-dc9144fed7238ba56fa3f39158ef6d7267bd0a23.tar.bz2 |
Revert 66214 - Display a warning when autofill is disabled for a website.
This depends on a WebKit change being tracked at https://bugs.webkit.org/show_bug.cgi?id=49291
BUG=58509
TEST=unit_tests --gtest_filter=AutoFillManagerTest.*:AutoFillHelperTest.*
Review URL: http://codereview.chromium.org/4591001
TBR=isherman@chromium.org
Review URL: http://codereview.chromium.org/4985003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66220 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 8 | ||||
-rw-r--r-- | chrome/browser/autocomplete_history_manager.cc | 24 | ||||
-rw-r--r-- | chrome/browser/autocomplete_history_manager.h | 4 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.cc | 63 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager_unittest.cc | 273 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.cc | 55 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.h | 19 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure_unittest.cc | 48 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 53 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 16 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host_delegate.h | 17 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 2 | ||||
-rw-r--r-- | chrome/renderer/autofill_helper.cc | 57 | ||||
-rw-r--r-- | chrome/renderer/autofill_helper.h | 16 | ||||
-rw-r--r-- | chrome/renderer/form_manager.cc | 14 |
16 files changed, 230 insertions, 442 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ad681e7..0b47e63 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -6683,12 +6683,6 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM" desc="The entry in the suggestions dropdown that clears an auto-filled form."> Clear form </message> - <message name="IDS_AUTOFILL_WARNING_FORM_DISABLED" desc="Warning text to show when autofill is disabled by the website for a given form."> - This webpage has disabled automatic filling for this form. - </message> - <message name="IDS_AUTOFILL_WARNING_INSECURE_CONNECTION" desc="Warning text to show when credit card autofill is disabled because the website is not using a secure connection."> - Automatic credit card filling is disabled because this form does not use a secure connection. - </message> <if expr="os != 'darwin'"> <message name="IDS_AUTOFILL_OPTIONS_TITLE" desc="The title of the Autofill dialog."> Autofill Options @@ -7419,7 +7413,7 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_SAFE_BROWSING_MALWARE_PROCEED_LINK" desc="SafeBrowsing Malware HTML description, third line proceed link part."> proceed anyway </message> - <message name="IDS_SAFE_BROWSING_MALWARE_DESCRIPTION4" desc="SafeBrowsing Malware HTML description, first line for case of subresource malicious"> + <message name="IDS_SAFE_BROWSING_MALWARE_DESCRIPTION4" desc="SafeBrowsing Malware HTML description, first line for case of subresource malicious"> <ph name="HOST_NAME"><strong>$1<ex>www.malware.com</ex></strong></ph> contains content from <ph name="ELEMENTS_HOST_NAME"><strong>$2<ex>www.evil.cn</ex></strong></ph>, a site known to distribute malware. Your computer might catch a virus if you visit this site. </message> <message name="IDS_SAFE_BROWSING_MALWARE_DESCRIPTION5" desc="SafeBrowsing Malware HTML description, detailed information, click button to span."> diff --git a/chrome/browser/autocomplete_history_manager.cc b/chrome/browser/autocomplete_history_manager.cc index 763445b..2243bcb 100644 --- a/chrome/browser/autocomplete_history_manager.cc +++ b/chrome/browser/autocomplete_history_manager.cc @@ -73,7 +73,8 @@ bool IsSSN(const string16& text) { AutocompleteHistoryManager::AutocompleteHistoryManager( TabContents* tab_contents) : tab_contents_(tab_contents), - pending_query_handle_(0) { + pending_query_handle_(0), + query_id_(0) { DCHECK(tab_contents); profile_ = tab_contents_->profile(); @@ -93,17 +94,17 @@ void AutocompleteHistoryManager::FormSubmitted(const FormData& form) { StoreFormEntriesInWebDatabase(form); } -void AutocompleteHistoryManager::GetAutocompleteSuggestions( - const string16& name, const string16& prefix) { - if (!*autofill_enabled_) { - SendSuggestions(NULL); - return; - } +bool AutocompleteHistoryManager::GetAutocompleteSuggestions( + int query_id, const string16& name, const string16& prefix) { + if (!*autofill_enabled_) + return false; CancelPendingQuery(); + query_id_ = query_id; pending_query_handle_ = web_data_service_->GetFormValuesForElementName( name, prefix, kMaxAutocompleteMenuItems, this); + return true; } void AutocompleteHistoryManager::RemoveAutocompleteEntry( @@ -129,7 +130,8 @@ AutocompleteHistoryManager::AutocompleteHistoryManager( Profile* profile, WebDataService* wds) : tab_contents_(NULL), profile_(profile), web_data_service_(wds), - pending_query_handle_(0) { + pending_query_handle_(0), + query_id_(0) { autofill_enabled_.Init( prefs::kAutoFillEnabled, profile_->GetPrefs(), NULL); } @@ -185,8 +187,10 @@ void AutocompleteHistoryManager::SendSuggestions(const WDTypedResult* result) { DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); const WDResult<std::vector<string16> >* autofill_result = static_cast<const WDResult<std::vector<string16> >*>(result); - host->AutocompleteSuggestionsReturned(autofill_result->GetValue()); + host->AutocompleteSuggestionsReturned( + query_id_, autofill_result->GetValue()); } else { - host->AutocompleteSuggestionsReturned(std::vector<string16>()); + host->AutocompleteSuggestionsReturned( + query_id_, std::vector<string16>()); } } diff --git a/chrome/browser/autocomplete_history_manager.h b/chrome/browser/autocomplete_history_manager.h index 5752942..23493b3 100644 --- a/chrome/browser/autocomplete_history_manager.h +++ b/chrome/browser/autocomplete_history_manager.h @@ -28,7 +28,8 @@ class AutocompleteHistoryManager // RenderViewHostDelegate::Autocomplete implementation. virtual void FormSubmitted(const webkit_glue::FormData& form); - virtual void GetAutocompleteSuggestions(const string16& name, + virtual bool GetAutocompleteSuggestions(int query_id, + const string16& name, const string16& prefix); virtual void RemoveAutocompleteEntry(const string16& name, const string16& value); @@ -58,6 +59,7 @@ class AutocompleteHistoryManager // is queried on another thread, we record the query handle until we // get called back. WebDataService::Handle pending_query_handle_; + int query_id_; DISALLOW_COPY_AND_ASSIGN(AutocompleteHistoryManager); }; diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index 50b31a0..6f89173 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -7,7 +7,6 @@ #include <limits> #include <string> -#include "app/l10n_util.h" #include "base/basictypes.h" #include "base/string16.h" #include "base/utf_string_conversions.h" @@ -23,7 +22,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" -#include "grit/generated_resources.h" #include "webkit/glue/form_data.h" #include "webkit/glue/form_field.h" @@ -134,7 +132,7 @@ void AutoFillManager::FormSubmitted(const FormData& form) { // Grab a copy of the form data. upload_form_structure_.reset(new FormStructure(form)); - if (!upload_form_structure_->IsAutoFillable(true)) + if (!upload_form_structure_->IsAutoFillable()) return; // Determine the possible field types and upload the form structure to the @@ -150,7 +148,8 @@ void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { ParseForms(forms); } -bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, +bool AutoFillManager::GetAutoFillSuggestions(int query_id, + bool field_autofilled, const FormField& field) { if (!IsAutoFillEnabled()) return false; @@ -173,7 +172,7 @@ bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, form = *form_iter; // Don't send suggestions for forms that aren't auto-fillable. - if (!form->IsAutoFillable(false)) + if (!form->IsAutoFillable()) continue; for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); @@ -215,30 +214,6 @@ bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, if (values.empty()) return false; - // Don't provide AutoFill suggestions when AutoFill is disabled, but provide a - // warning to the user. - if (!form->IsAutoFillable(true)) { - values.assign( - 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); - labels.assign(1, string16()); - icons.assign(1, string16()); - unique_ids.assign(1, -1); - host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); - return true; - } - - // Don't provide credit card suggestions for non-HTTPS pages, but provide a - // warning to the user. - if (!FormIsHTTPS(form) && type.group() == AutoFillType::CREDIT_CARD) { - values.assign( - 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)); - labels.assign(1, string16()); - icons.assign(1, string16()); - unique_ids.assign(1, -1); - host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); - return true; - } - // If the form is auto-filled and the renderer is querying for suggestions, // then the user is editing the value of a field. In this case, mimick // autocomplete. In particular, don't display labels, as that information is @@ -256,7 +231,8 @@ bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, } } - host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); + host->AutoFillSuggestionsReturned( + query_id, values, labels, icons, unique_ids); return true; } @@ -549,6 +525,10 @@ void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, std::vector<string16>* labels, std::vector<string16>* icons, std::vector<int>* unique_ids) { + // Don't return CC suggestions for non-HTTPS pages. + if (!FormIsHTTPS(form)) + return; + for (std::vector<CreditCard*>::const_iterator iter = personal_data_->credit_cards().begin(); iter != personal_data_->credit_cards().end(); ++iter) { @@ -619,33 +599,22 @@ void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, } } -void AutoFillManager::ParseForms(const std::vector<FormData>& forms) { - std::vector<FormStructure *> non_queryable_forms; - for (std::vector<FormData>::const_iterator iter = forms.begin(); +void AutoFillManager::ParseForms( + const std::vector<webkit_glue::FormData>& forms) { + for (std::vector<FormData>::const_iterator iter = + forms.begin(); iter != forms.end(); ++iter) { scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); - if (!form_structure->ShouldBeParsed(false)) + if (!form_structure->ShouldBeParsed()) continue; DeterminePossibleFieldTypes(form_structure.get()); - - // Set aside forms with method GET so that they are not included in the - // query to the server. - if (form_structure->ShouldBeParsed(true)) - form_structures_.push_back(form_structure.release()); - else - non_queryable_forms.push_back(form_structure.release()); + form_structures_.push_back(form_structure.release()); } // If none of the forms were parsed, no use querying the server. if (!form_structures_.empty() && !disable_download_manager_requests_) download_manager_.StartQueryRequest(form_structures_); - - for (std::vector<FormStructure *>::const_iterator iter = - non_queryable_forms.begin(); - iter != non_queryable_forms.end(); ++iter) { - form_structures_.push_back(*iter); - } } // When sending IDs (across processes) to the renderer we pack credit card and diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index 60e1468..b0b87bb 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -50,7 +50,8 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // RenderViewHostDelegate::AutoFill implementation: virtual void FormSubmitted(const webkit_glue::FormData& form); virtual void FormsSeen(const std::vector<webkit_glue::FormData>& forms); - virtual bool GetAutoFillSuggestions(bool field_autofilled, + virtual bool GetAutoFillSuggestions(int query_id, + bool field_autofilled, const webkit_glue::FormField& field); virtual bool FillAutoFillFormData(int query_id, const webkit_glue::FormData& form, diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc index 182148d..264dc80 100644 --- a/chrome/browser/autofill/autofill_manager_unittest.cc +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -4,7 +4,6 @@ #include <vector> -#include "app/l10n_util.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/scoped_vector.h" @@ -24,7 +23,6 @@ #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "googleurl/src/gurl.h" -#include "grit/generated_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/glue/form_data.h" #include "webkit/glue/form_field.h" @@ -61,14 +59,6 @@ class TestPersonalDataManager : public PersonalDataManager { web_profiles_->push_back(profile); } - void ClearAutoFillProfiles() { - web_profiles_.reset(); - } - - void ClearCreditCards() { - credit_cards_.reset(); - } - private: void CreateTestAutoFillProfiles(ScopedVector<AutoFillProfile>* profiles) { AutoFillProfile* profile = new AutoFillProfile; @@ -120,8 +110,7 @@ class TestAutoFillManager : public AutoFillManager { public: TestAutoFillManager(TabContents* tab_contents, TestPersonalDataManager* personal_manager) - : AutoFillManager(tab_contents, NULL), - autofill_enabled_(true) { + : AutoFillManager(tab_contents, NULL) { test_personal_data_ = personal_manager; set_personal_data_manager(personal_manager); // Download manager requests are disabled for purposes of this unit-test. @@ -129,11 +118,7 @@ class TestAutoFillManager : public AutoFillManager { set_disable_download_manager_requests(true); } - virtual bool IsAutoFillEnabled() const { return autofill_enabled_; } - - void set_autofill_enabled(bool autofill_enabled) { - autofill_enabled_ = autofill_enabled; - } + virtual bool IsAutoFillEnabled() const { return true; } AutoFillProfile* GetLabeledProfile(const char* label) { return test_personal_data_->GetLabeledProfile(label); @@ -145,7 +130,6 @@ class TestAutoFillManager : public AutoFillManager { private: TestPersonalDataManager* test_personal_data_; - bool autofill_enabled_; DISALLOW_COPY_AND_ASSIGN(TestAutoFillManager); }; @@ -309,12 +293,11 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -355,12 +338,11 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "E", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -412,109 +394,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsUnknownFields) { autofill_test::CreateTestFormField( "Username", "username", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); EXPECT_FALSE( - autofill_manager_->GetAutoFillSuggestions(false, field)); -} - -// Test that we return no suggestions when autofill is disabled. -TEST_F(AutoFillManagerTest, GetProfileSuggestionsAutofillDisabledByUser) { - FormData form; - CreateTestAddressFormData(&form); - - // Set up our FormStructures. - std::vector<FormData> forms; - forms.push_back(form); - autofill_manager_->FormsSeen(forms); - - // Disable AutoFill. - autofill_manager_->set_autofill_enabled(false); - - // The page ID sent to the AutoFillManager from the RenderView, used to send - // an IPC message back to the renderer. - const int kPageID = 1; - - webkit_glue::FormField field; - autofill_test::CreateTestFormField( - "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); -} - -// Test that we return a warning explaining that autofill suggestions are -// unavailable when the form method is GET rather than POST. -TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) { - FormData form; - CreateTestAddressFormData(&form); - form.method = ASCIIToUTF16("GET"); - - // Set up our FormStructures. - std::vector<FormData> forms; - forms.push_back(form); - autofill_manager_->FormsSeen(forms); - - // The page ID sent to the AutoFillManager from the RenderView, used to send - // an IPC message back to the renderer. - const int kPageID = 1; - - webkit_glue::FormField field; - autofill_test::CreateTestFormField( - "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); - - // No suggestions provided, so send an empty vector as the results. - // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); - - // Test that we sent the right message to the renderer. - int page_id = 0; - std::vector<string16> values; - std::vector<string16> labels; - std::vector<string16> icons; - EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, - &icons)); - EXPECT_EQ(kPageID, page_id); - ASSERT_EQ(1U, values.size()); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED), - values[0]); - ASSERT_EQ(1U, labels.size()); - EXPECT_EQ(string16(), labels[0]); - ASSERT_EQ(1U, icons.size()); - EXPECT_EQ(string16(), icons[0]); - - // Now add some Autocomplete suggestions. We should return the autocomplete - // suggestions and the warning; these will be culled by the renderer. - process()->sink().ClearMessages(); - const int kPageID2 = 2; - rvh()->ResetAutoFillState(kPageID2); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); - - std::vector<string16> suggestions; - suggestions.push_back(ASCIIToUTF16("Jay")); - suggestions.push_back(ASCIIToUTF16("Jason")); - rvh()->AutocompleteSuggestionsReturned(suggestions); - - EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, - &icons)); - EXPECT_EQ(kPageID2, page_id); - ASSERT_EQ(3U, values.size()); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED), - values[0]); - EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]); - EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]); - ASSERT_EQ(3U, labels.size()); - EXPECT_EQ(string16(), labels[0]); - EXPECT_EQ(string16(), labels[1]); - EXPECT_EQ(string16(), labels[2]); - ASSERT_EQ(3U, icons.size()); - EXPECT_EQ(string16(), icons[0]); - EXPECT_EQ(string16(), icons[1]); - EXPECT_EQ(string16(), icons[2]); - - // Now clear the test profiles and try again -- we shouldn't return a warning. - test_personal_data_->ClearAutoFillProfiles(); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); + autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); } // Test that we return all credit card profile suggestions when all form fields @@ -535,12 +416,11 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -579,12 +459,11 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "4", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -620,12 +499,11 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -646,8 +524,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]); } -// Test that we return a warning explaining that credit card profile suggestions -// are unavailable when the form is not https. +// Test that we return no credit card profile suggestions when the form is not +// https. TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) { FormData form; CreateTestCreditCardFormData(&form, false); @@ -664,61 +542,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); - - // No suggestions provided, so send an empty vector as the results. - // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); - - // Test that we sent the right message to the renderer. - int page_id = 0; - std::vector<string16> values; - std::vector<string16> labels; - std::vector<string16> icons; - EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, - &icons)); - EXPECT_EQ(kPageID, page_id); - ASSERT_EQ(1U, values.size()); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), - values[0]); - ASSERT_EQ(1U, labels.size()); - EXPECT_EQ(string16(), labels[0]); - ASSERT_EQ(1U, icons.size()); - EXPECT_EQ(string16(), icons[0]); - - // Now add some Autocomplete suggestions. We should show the autocomplete - // suggestions and the warning. - process()->sink().ClearMessages(); - const int kPageID2 = 2; - rvh()->ResetAutoFillState(kPageID2); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); - - std::vector<string16> suggestions; - suggestions.push_back(ASCIIToUTF16("Jay")); - suggestions.push_back(ASCIIToUTF16("Jason")); - rvh()->AutocompleteSuggestionsReturned(suggestions); - - EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, - &icons)); - EXPECT_EQ(kPageID2, page_id); - ASSERT_EQ(3U, values.size()); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), - values[0]); - EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]); - EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]); - ASSERT_EQ(3U, labels.size()); - EXPECT_EQ(string16(), labels[0]); - EXPECT_EQ(string16(), labels[1]); - EXPECT_EQ(string16(), labels[2]); - ASSERT_EQ(3U, icons.size()); - EXPECT_EQ(string16(), icons[0]); - EXPECT_EQ(string16(), icons[1]); - EXPECT_EQ(string16(), icons[2]); - - // Clear the test credit cards and try again -- we shouldn't return a warning. - test_personal_data_->ClearCreditCards(); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_FALSE( + autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); } // Test that we return profile and credit card suggestions for combined forms. @@ -739,12 +564,11 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right address suggestions to the renderer. int page_id = 0; @@ -769,12 +593,11 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { process()->sink().ClearMessages(); autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the credit card suggestions to the renderer. page_id = 0; @@ -793,9 +616,7 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { } // Test that for non-https forms with both address and credit card fields, we -// only return address suggestions. Instead of credit card suggestions, we -// should return a warning explaining that credit card profile suggestions are -// unavailable when the form is not https. +// only return address suggestions. TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { FormData form; CreateTestAddressFormData(&form); @@ -813,12 +634,11 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right address suggestions to the renderer. int page_id = 0; @@ -840,31 +660,10 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { EXPECT_EQ(string16(), icons[0]); EXPECT_EQ(string16(), icons[1]); - process()->sink().ClearMessages(); autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); - - // No suggestions provided, so send an empty vector as the results. - // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); - - // Test that we sent the right message to the renderer. - EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, - &icons)); - EXPECT_EQ(kPageID, page_id); - ASSERT_EQ(1U, values.size()); - EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), - values[0]); - ASSERT_EQ(1U, labels.size()); - EXPECT_EQ(string16(), labels[0]); - ASSERT_EQ(1U, icons.size()); - EXPECT_EQ(string16(), icons[0]); - - // Clear the test credit cards and try again -- we shouldn't return a warning. - test_personal_data_->ClearCreditCards(); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_FALSE( + autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); } // Test that we correctly combine autofill and autocomplete suggestions. @@ -884,15 +683,14 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Add some Autocomplete suggestions. // This triggers the combined message send. std::vector<string16> suggestions; suggestions.push_back(ASCIIToUTF16("Jay")); suggestions.push_back(ASCIIToUTF16("Jason")); - rvh()->AutocompleteSuggestionsReturned(suggestions); + rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions); // Test that we sent the right message to the renderer. int page_id = 0; @@ -937,12 +735,11 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFieldIsAutoFilled) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -981,15 +778,14 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Some Field", "somefield", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(true, field)); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); // Add some Autocomplete suggestions. // This triggers the combined message send. std::vector<string16> suggestions; suggestions.push_back(ASCIIToUTF16("one")); suggestions.push_back(ASCIIToUTF16("two")); - rvh()->AutocompleteSuggestionsReturned(suggestions); + rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions); // Test that we sent the right message to the renderer. int page_id = 0; @@ -1034,12 +830,11 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - rvh()->ResetAutoFillState(kPageID); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field)); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index b5b2db7..0eab86b 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -107,7 +107,7 @@ bool FormStructure::EncodeUploadRequest(bool auto_fill_used, std::string* encoded_xml) const { DCHECK(encoded_xml); encoded_xml->clear(); - bool auto_fillable = IsAutoFillable(false); + bool auto_fillable = IsAutoFillable(); DCHECK(auto_fillable); // Caller should've checked for search pages. if (!auto_fillable) return false; @@ -232,6 +232,8 @@ void FormStructure::ParseQueryResponse(const std::string& response_xml, form->UpdateAutoFillCount(); } + + return; } std::string FormStructure::FormSignature() const { @@ -245,11 +247,11 @@ std::string FormStructure::FormSignature() const { return Hash64Bit(form_string); } -bool FormStructure::IsAutoFillable(bool require_method_post) const { +bool FormStructure::IsAutoFillable() const { if (autofill_count() < kRequiredFillableFields) return false; - return ShouldBeParsed(require_method_post); + return ShouldBeParsed(); } bool FormStructure::HasAutoFillableValues() const { @@ -266,6 +268,46 @@ bool FormStructure::HasAutoFillableValues() const { return false; } +// TODO(jhawkins): Cache this result. +bool FormStructure::HasBillingFields() const { + for (std::vector<AutoFillField*>::const_iterator iter = begin(); + iter != end(); ++iter) { + if (!*iter) + return false; + + AutoFillField* field = *iter; + if (!field) + continue; + + AutoFillType type(field->type()); + if (type.group() == AutoFillType::ADDRESS_BILLING || + type.group() == AutoFillType::CREDIT_CARD) + return true; + } + + return false; +} + +// TODO(jhawkins): Cache this result. +bool FormStructure::HasNonBillingFields() const { + for (std::vector<AutoFillField*>::const_iterator iter = begin(); + iter != end(); ++iter) { + if (!*iter) + return false; + + AutoFillField* field = *iter; + if (!field) + continue; + + AutoFillType type(field->type()); + if (type.group() != AutoFillType::ADDRESS_BILLING && + type.group() != AutoFillType::CREDIT_CARD) + return true; + } + + return false; +} + void FormStructure::UpdateAutoFillCount() { autofill_count_ = 0; for (std::vector<AutoFillField*>::const_iterator iter = begin(); @@ -276,7 +318,7 @@ void FormStructure::UpdateAutoFillCount() { } } -bool FormStructure::ShouldBeParsed(bool require_method_post) const { +bool FormStructure::ShouldBeParsed() const { if (field_count() < kRequiredFillableFields) return false; @@ -286,7 +328,10 @@ bool FormStructure::ShouldBeParsed(bool require_method_post) const { if (target_url_.path() == "/search") return false; - return !require_method_post || (method_ == POST); + if (method_ == GET) + return false; + + return true; } void FormStructure::set_possible_types(int index, const FieldTypeSet& types) { diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h index fe4c5da..77e106f4 100644 --- a/chrome/browser/autofill/form_structure.h +++ b/chrome/browser/autofill/form_structure.h @@ -61,15 +61,22 @@ class FormStructure { // the form name, and the form field names in a 64-bit hash. std::string FormSignature() const; - // Runs a quick heuristic to rule out forms that are obviously not - // auto-fillable, like google/yahoo/msn search, etc. The requirement that the - // form's method be POST is only applied if |require_method_post| is true. - bool IsAutoFillable(bool require_method_post) const; + // Runs a quick heuristic to rule out pages but obviously not auto-fillable, + // like google/yahoo/msn search, etc. + bool IsAutoFillable() const; // Returns true if at least one of the form fields relevant for AutoFill // is not empty. bool HasAutoFillableValues() const; + // Returns true if at least one of the form fields is a billing field, which + // includes billing address fields and credit card fields. + bool HasBillingFields() const; + + // Returns true if at least one of the form fields is a non-billing field, + // which includes billing address fields and credit card fields. + bool HasNonBillingFields() const; + // Resets |autofill_count_| and counts the number of auto-fillable fields. // This is used when we receive server data for form fields. At that time, // we may have more known fields than just the number of fields we matched @@ -77,9 +84,7 @@ class FormStructure { void UpdateAutoFillCount(); // Returns true if this form matches the structural requirements for AutoFill. - // The requirement that the form's method be POST is only applied if - // |require_method_post| is true. - bool ShouldBeParsed(bool require_method_post) const; + bool ShouldBeParsed() const; // Sets the possible types for the field at |index|. void set_possible_types(int index, const FieldTypeSet& types); diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc index 8eb03fd..b5881d6 100644 --- a/chrome/browser/autofill/form_structure_unittest.cc +++ b/chrome/browser/autofill/form_structure_unittest.cc @@ -199,7 +199,7 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable(true)); + EXPECT_FALSE(form_structure->IsAutoFillable()); // We now have three text fields, but only two auto-fillable fields. form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"), @@ -213,7 +213,7 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable(true)); + EXPECT_FALSE(form_structure->IsAutoFillable()); // We now have three auto-fillable fields. form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Email"), @@ -222,25 +222,23 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); - // The method must be 'post', though we can intentionally ignore this - // criterion for the sake of providing a helpful warning message to the user. + // The method must be 'post'. form.method = ASCIIToUTF16("get"); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable(true)); - EXPECT_TRUE(form_structure->IsAutoFillable(false)); + EXPECT_FALSE(form_structure->IsAutoFillable()); // The target cannot include http(s)://*/search... form.method = ASCIIToUTF16("post"); form.action = GURL("http://google.com/search?q=hello"); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable(true)); + EXPECT_FALSE(form_structure->IsAutoFillable()); // But search can be in the URL. form.action = GURL("http://search.com/?q=hello"); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); } TEST(FormStructureTest, HeuristicsContactInfo) { @@ -294,7 +292,7 @@ TEST(FormStructureTest, HeuristicsContactInfo) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. ASSERT_EQ(9U, form_structure->field_count()); @@ -412,7 +410,7 @@ TEST(FormStructureTest, HeuristicsHiddenFields) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. ASSERT_EQ(17U, form_structure->field_count()); @@ -505,7 +503,7 @@ TEST(FormStructureTest, HeuristicsSample8) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(10U, form_structure->field_count()); ASSERT_EQ(9U, form_structure->autofill_count()); @@ -583,7 +581,7 @@ TEST(FormStructureTest, HeuristicsSample6) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(7U, form_structure->field_count()); ASSERT_EQ(6U, form_structure->autofill_count()); @@ -657,7 +655,7 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(9U, form_structure->field_count()); ASSERT_EQ(8U, form_structure->autofill_count()); @@ -718,7 +716,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(6U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -780,7 +778,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(7U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -831,7 +829,7 @@ TEST(FormStructureTest, ThreeAddressLines) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -877,7 +875,7 @@ TEST(FormStructureTest, BillingAndShippingAddresses) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -927,7 +925,7 @@ TEST(FormStructureTest, ThreeAddressLinesExpedia) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -968,7 +966,7 @@ TEST(FormStructureTest, TwoAddressLinesEbay) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(3U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1004,7 +1002,7 @@ TEST(FormStructureTest, HeuristicsStateWithProvince) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(3U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1089,7 +1087,7 @@ TEST(FormStructureTest, HeuristicsWithBilling) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(11U, form_structure->field_count()); ASSERT_EQ(11U, form_structure->autofill_count()); @@ -1138,7 +1136,7 @@ TEST(FormStructureTest, ThreePartPhoneNumber) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1209,7 +1207,7 @@ TEST(FormStructureTest, MatchSpecificInputTypes) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. ASSERT_EQ(10U, form_structure->field_count()); @@ -1268,7 +1266,7 @@ TEST(FormStructureTest, HeuristicsInfernoCC) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. ASSERT_EQ(5U, form_structure->field_count()); diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index f2bffa7..aaebf9f 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1690,27 +1690,33 @@ void RenderViewHost::OnMsgShouldCloseACK(bool proceed) { } void RenderViewHost::OnQueryFormFieldAutoFill( - int query_id, bool field_autofilled, const webkit_glue::FormField& field) { - ResetAutoFillState(query_id); - - // We first query the autofill delegate for suggestions. We keep track of the - // results it gives us, which we will later combine with the autocomplete - // suggestions. + int query_id, bool form_autofilled, const webkit_glue::FormField& field) { RenderViewHostDelegate::AutoFill* autofill_delegate = delegate_->GetAutoFillDelegate(); - if (autofill_delegate) { - autofill_delegate->GetAutoFillSuggestions(field_autofilled, field); + // We first save the AutoFill delegate's suggestions. Then we fetch the + // Autocomplete delegate's suggestions and send the combined results back to + // the render view. + if (autofill_delegate && + autofill_delegate->GetAutoFillSuggestions(query_id, + form_autofilled, + field)) { + } else { + // No suggestions provided, so supply an empty vector as the results. + AutoFillSuggestionsReturned(query_id, + std::vector<string16>(), + std::vector<string16>(), + std::vector<string16>(), + std::vector<int>()); } - // Now query the Autocomplete delegate for suggestions. These will be combined - // with the saved autofill suggestions in |AutocompleteSuggestionsReturned()|. RenderViewHostDelegate::Autocomplete* autocomplete_delegate = delegate_->GetAutocompleteDelegate(); - if (autocomplete_delegate) { - autocomplete_delegate->GetAutocompleteSuggestions(field.name(), - field.value()); + if (autocomplete_delegate && + autocomplete_delegate->GetAutocompleteSuggestions( + query_id, field.name(), field.value())) { } else { - AutocompleteSuggestionsReturned(std::vector<string16>()); + // No suggestions provided, so send an empty vector as the results. + AutocompleteSuggestionsReturned(query_id, std::vector<string16>()); } } @@ -1764,33 +1770,24 @@ void RenderViewHost::OnDidFillAutoFillFormData() { NotificationService::NoDetails()); } -void RenderViewHost::ResetAutoFillState(int query_id) { - autofill_query_id_ = query_id; - - autofill_values_.clear(); - autofill_labels_.clear(); - autofill_icons_.clear(); - autofill_unique_ids_.clear(); -} - void RenderViewHost::AutoFillSuggestionsReturned( - const std::vector<string16>& values, + int query_id, + const std::vector<string16>& names, const std::vector<string16>& labels, const std::vector<string16>& icons, const std::vector<int>& unique_ids) { - autofill_values_.assign(values.begin(), values.end()); + autofill_values_.assign(names.begin(), names.end()); autofill_labels_.assign(labels.begin(), labels.end()); autofill_icons_.assign(icons.begin(), icons.end()); autofill_unique_ids_.assign(unique_ids.begin(), unique_ids.end()); } void RenderViewHost::AutocompleteSuggestionsReturned( - const std::vector<string16>& suggestions) { + int query_id, const std::vector<string16>& suggestions) { // Combine AutoFill and Autocomplete values into values and labels. for (size_t i = 0; i < suggestions.size(); ++i) { bool unique = true; for (size_t j = 0; j < autofill_values_.size(); ++j) { - // TODO(isherman): Why just when the label is empty? // If the AutoFill label is empty, we need to make sure we don't add a // duplicate value. if (autofill_labels_[j].empty() && @@ -1809,7 +1806,7 @@ void RenderViewHost::AutocompleteSuggestionsReturned( } Send(new ViewMsg_AutoFillSuggestionsReturned(routing_id(), - autofill_query_id_, + query_id, autofill_values_, autofill_labels_, autofill_icons_, diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index ba7f552..97d1f5b 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -411,18 +411,18 @@ class RenderViewHost : public RenderWidgetHost { // set to false when creating a renderer-initiated window via window.open. void AllowScriptToClose(bool visible); - // Resets the stored AutoFill state. - void ResetAutoFillState(int query_id); - // Called by the AutoFillManager when the list of suggestions is ready. - void AutoFillSuggestionsReturned(const std::vector<string16>& values, - const std::vector<string16>& labels, - const std::vector<string16>& icons, - const std::vector<int>& unique_ids); + void AutoFillSuggestionsReturned( + int query_id, + const std::vector<string16>& values, + const std::vector<string16>& labels, + const std::vector<string16>& icons, + const std::vector<int>& unique_ids); // Called by the AutocompleteHistoryManager when the list of suggestions is // ready. void AutocompleteSuggestionsReturned( + int query_id, const std::vector<string16>& suggestions); // Called by the AutoFillManager when the FormData has been filled out. @@ -802,14 +802,12 @@ class RenderViewHost : public RenderWidgetHost { // what process type we use. bool is_extension_process_; - // TODO(isherman): Consider splitting these off into a helper class. // AutoFill and Autocomplete suggestions. We accumulate these separately and // send them back to the renderer together. std::vector<string16> autofill_values_; std::vector<string16> autofill_labels_; std::vector<string16> autofill_icons_; std::vector<int> autofill_unique_ids_; - int autofill_query_id_; // Whether the accessibility tree should be saved, for unit testing. bool save_accessibility_tree_for_testing_; diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index c3049e1..020fadc 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -521,7 +521,10 @@ class RenderViewHostDelegate { // query. When the database thread is finished, the AutocompleteHistory // manager retrieves the calling RenderViewHost and then passes the vector // of suggestions to RenderViewHost::AutocompleteSuggestionsReturned. - virtual void GetAutocompleteSuggestions(const string16& field_name, + // Returns true to indicate that FormFieldHistorySuggestionsReturned will be + // called. + virtual bool GetAutocompleteSuggestions(int query_id, + const string16& field_name, const string16& user_text) = 0; // Called when the user has indicated that she wants to remove the specified @@ -546,13 +549,13 @@ class RenderViewHostDelegate { virtual void FormsSeen(const std::vector<webkit_glue::FormData>& forms) = 0; // Called to retrieve a list of AutoFill suggestions from the web database - // given the name of the field, whether it is auto-filled, and what the user - // has already typed in it. If there is a warning to be returned to the - // user, it is stored into |values|, with corresponding unique id -1. - // Returns true to indicate that RenderViewHost::AutoFillSuggestionsReturned - // has been called. + // given the name of the field and what the user has already typed in the + // field. |form_autofilled| is true if the form containing |field| has any + // auto-filled fields. Returns true to indicate that + // RenderViewHost::AutoFillSuggestionsReturned has been called. virtual bool GetAutoFillSuggestions( - bool field_autofilled, + int query_id, + bool form_autofilled, const webkit_glue::FormField& field) = 0; // Called to fill the FormData object with AutoFill profile information that diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index bcc512a82..d4f4132 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -2083,7 +2083,7 @@ IPC_BEGIN_MESSAGES(ViewHost) // Queries the browser for AutoFill suggestions for a form input field. IPC_MESSAGE_ROUTED3(ViewHostMsg_QueryFormFieldAutoFill, int /* id of this message */, - bool /* field autofilled */, + bool /* form_autofilled */, webkit_glue::FormField /* the form field */) // Sent when the popup with AutoFill suggestions for a form is shown. diff --git a/chrome/renderer/autofill_helper.cc b/chrome/renderer/autofill_helper.cc index 7725658..2832f0d 100644 --- a/chrome/renderer/autofill_helper.cc +++ b/chrome/renderer/autofill_helper.cc @@ -54,12 +54,10 @@ AutoFillHelper::AutoFillHelper(RenderView* render_view) suggestions_options_index_(-1) { } -void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node, - bool autofill_disabled) { +void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node) { static int query_counter = 0; autofill_query_id_ = query_counter++; autofill_query_node_ = node; - autofill_disabled_ = autofill_disabled; const WebFormControlElement& element = node.toConst<WebFormControlElement>(); webkit_glue::FormField field; @@ -110,22 +108,6 @@ void AutoFillHelper::SuggestionsReceived(int query_id, std::vector<int> ids(unique_ids); int separator_index = -1; - if (autofill_disabled_) { - // If autofill is disabled and we had suggestions, show a warning instead. - v.assign(1, - l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); - l.assign(1, string16()); - i.assign(1, string16()); - ids.assign(1, -1); - } else if (ids[0] < 0 && ids.size() > 1) { - // If we received a warning instead of suggestions from autofill but regular - // suggestions from autocomplete, don't show the autofill warning. - v.erase(v.begin()); - l.erase(l.begin()); - i.erase(i.begin()); - ids.erase(ids.begin()); - } - // The form has been auto-filled, so give the user the chance to clear the // form. Append the 'Clear form' menu item. if (form_manager_.FormWithNodeIsAutoFilled(autofill_query_node_)) { @@ -134,14 +116,14 @@ void AutoFillHelper::SuggestionsReceived(int query_id, i.push_back(string16()); ids.push_back(0); suggestions_clear_index_ = v.size() - 1; - separator_index = v.size() - 1; + separator_index = values.size(); } // Only include "AutoFill Options" special menu item if we have AutoFill // items, identified by |unique_ids| having at least one valid value. bool show_options = false; for (size_t i = 0; i < ids.size(); ++i) { - if (ids[i] > 0) { + if (ids[i] != 0) { show_options = true; break; } @@ -244,29 +226,33 @@ void AutoFillHelper::FrameDetached(WebFrame* frame) { } void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) { - ShowSuggestions(element, false, true, false); + ShowSuggestions(element, false, true); } bool AutoFillHelper::InputElementClicked(const WebInputElement& element, bool was_focused, bool is_focused) { if (was_focused) - ShowSuggestions(element, true, false, true); + ShowSuggestions(element, true, false); return false; } -void AutoFillHelper::ShowSuggestions(const WebInputElement& element, - bool autofill_on_empty_values, - bool requires_caret_at_end, - bool display_warning_if_disabled) { - bool autofill_disabled = !element.isEnabledFormControl() || - !element.isText() || element.isPasswordField() || - !element.autoComplete() || element.isReadOnly(); - if (autofill_disabled && !display_warning_if_disabled) + +void AutoFillHelper::ShowSuggestions( + const WebInputElement& const_element, + bool autofill_on_empty_values, + bool requires_caret_at_end) { + // We need to call non-const methods. + WebInputElement element(const_element); + if (!element.isEnabledFormControl() || + !element.isText() || + element.isPasswordField() || + !element.autoComplete() || element.isReadOnly()) { return; + } - // If the field has no name, then we won't have values. - if (element.nameForAutofill().isEmpty()) + WebString name = element.nameForAutofill(); + if (name.isEmpty()) // If the field has no name, then we won't have values. return; // Don't attempt to autofill with values that are too large. @@ -279,10 +265,11 @@ void AutoFillHelper::ShowSuggestions(const WebInputElement& element, if (requires_caret_at_end && (element.selectionStart() != element.selectionEnd() || - element.selectionEnd() != static_cast<int>(value.length()))) + element.selectionEnd() != static_cast<int>(value.length()))) { return; + } - QueryAutoFillSuggestions(element, autofill_disabled); + QueryAutoFillSuggestions(element); } void AutoFillHelper::QueryAutoFillFormData(const WebNode& node, diff --git a/chrome/renderer/autofill_helper.h b/chrome/renderer/autofill_helper.h index 13e7ab7..c859725 100644 --- a/chrome/renderer/autofill_helper.h +++ b/chrome/renderer/autofill_helper.h @@ -32,10 +32,8 @@ class AutoFillHelper : public PageClickListener { explicit AutoFillHelper(RenderView* render_view); // Queries the browser for Autocomplete and AutoFill suggestions for the given - // |node|. If |autofill_disabled| is true, the query is guaranteed to return - // no results, but might return a descriptive warning message. - void QueryAutoFillSuggestions(const WebKit::WebNode& node, - bool autofill_disabled); + // |node|. + void QueryAutoFillSuggestions(const WebKit::WebNode& node); // Removes the Autocomplete suggestion |value| for the field named |name|. void RemoveAutocompleteSuggestion(const WebKit::WebString& name, @@ -109,14 +107,9 @@ class AutoFillHelper : public PageClickListener { // when |element| contains no text. // |requires_caret_at_end| specifies whether suggestions should be shown when // the caret is not after the last character in |element|. - // |display_warning_if_disabled| specifies whether a warning should be - // displayed to the user if AutoFill has suggestions available, but cannot - // fill them because it is disabled (e.g. when trying to fill a credit card - // form on a non-secure website). void ShowSuggestions(const WebKit::WebInputElement& element, bool autofill_on_empty_values, - bool requires_caret_at_end, - bool display_warning_if_disabled); + bool requires_caret_at_end); // Queries the AutoFillManager for form data for the form containing |node|. // |value| is the current text in the field, and |unique_id| is the selected @@ -141,9 +134,6 @@ class AutoFillHelper : public PageClickListener { // The node corresponding to the last request sent for form field AutoFill. WebKit::WebNode autofill_query_node_; - // Whether autofill is disabled for |autofill_query_node_| by the website. - bool autofill_disabled_; - // The action to take when receiving AutoFill data from the AutoFillManager. AutoFillAction autofill_action_; diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc index 26fe32b..8a5d559 100644 --- a/chrome/renderer/form_manager.cc +++ b/chrome/renderer/form_manager.cc @@ -489,14 +489,14 @@ void FormManager::ExtractForms(const WebFrame* frame) { frame->forms(web_forms); for (size_t i = 0; i < web_forms.size(); ++i) { - FormElement* form_element = new FormElement; - form_element->form_element = web_forms[i]; + FormElement* form_elements = new FormElement; + form_elements->form_element = web_forms[i]; WebVector<WebFormControlElement> control_elements; - form_element->form_element.getFormControlElements(control_elements); + form_elements->form_element.getFormControlElements(control_elements); for (size_t j = 0; j < control_elements.size(); ++j) { WebFormControlElement element = control_elements[j]; - form_element->control_elements.push_back(element); + form_elements->control_elements.push_back(element); // Save original values of "select-one" inputs so we can restore them // when |ClearFormWithNode()| is invoked. @@ -504,13 +504,13 @@ void FormManager::ExtractForms(const WebFrame* frame) { WebFormControlElement& e = const_cast<WebFormControlElement&>(element); WebSelectElement select_element = e.to<WebSelectElement>(); string16 value = select_element.value(); - form_element->control_values.push_back(value); + form_elements->control_values.push_back(value); } else { - form_element->control_values.push_back(string16()); + form_elements->control_values.push_back(string16()); } } - form_elements_.push_back(form_element); + form_elements_.push_back(form_elements); } } |