diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-09 22:56:34 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-09 22:56:34 +0000 |
commit | cf28ec5f4f485d4758de3817cd116e47fdc3edeb (patch) | |
tree | e69ea0cac56aaabe71901a1f2bce2e33061dc88a | |
parent | 5b6699d3ed74c9382c5f9a2aa8c8f2500900c7f8 (diff) | |
download | chromium_src-cf28ec5f4f485d4758de3817cd116e47fdc3edeb.zip chromium_src-cf28ec5f4f485d4758de3817cd116e47fdc3edeb.tar.gz chromium_src-cf28ec5f4f485d4758de3817cd116e47fdc3edeb.tar.bz2 |
AutoFill: Fill the default profile when the AutoFill accelerator combo is pressed (ctrl-shift-a).
BUG=39491
TEST=none
Review URL: http://codereview.chromium.org/1521020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44149 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 277 insertions, 34 deletions
diff --git a/chrome/app/chrome_dll.rc b/chrome/app/chrome_dll.rc index 00c87f7..c9322d3 100644 --- a/chrome/app/chrome_dll.rc +++ b/chrome/app/chrome_dll.rc @@ -136,6 +136,7 @@ BEGIN VK_OEM_PLUS, IDC_ZOOM_PLUS, VIRTKEY, CONTROL VK_OEM_PLUS, IDC_ZOOM_PLUS, VIRTKEY, CONTROL, SHIFT VK_ADD, IDC_ZOOM_PLUS, VIRTKEY, CONTROL + "A", IDC_AUTOFILL_DEFAULT, VIRTKEY, CONTROL, SHIFT END IDR_CHROMEFRAME ACCELERATORS diff --git a/chrome/app/chrome_dll_resource.h b/chrome/app/chrome_dll_resource.h index ed5bc03..917cb01 100644 --- a/chrome/app/chrome_dll_resource.h +++ b/chrome/app/chrome_dll_resource.h @@ -216,6 +216,7 @@ #define IDC_SHOW_PAGE_MENU 40021 #define IDC_SHOW_EXTENSION_SHELF 40022 #define IDC_MANAGE_EXTENSIONS 40023 +#define IDC_AUTOFILL_DEFAULT 40024 // Spell-check // Insert any additional suggestions before _LAST; these have to be consecutive. diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index e4d4aae..bcac2ed 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -449,6 +449,58 @@ bool AutoFillManager::IsAutoFillEnabled() { return prefs->GetBoolean(prefs::kAutoFillEnabled); } +void AutoFillManager::FillDefaultProfile() { + if (!IsAutoFillEnabled()) + return; + + RenderViewHost* host = tab_contents_->render_view_host(); + if (!host) + return; + + // TODO(jhawkins): Do we need to wait for the profiles to be loaded? + const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles(); + const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards(); + if (profiles.empty() && credit_cards.empty()) + return; + + AutoFillProfile* profile = NULL; + int default_profile = personal_data_->DefaultProfile(); + if (default_profile != -1) + profile = profiles[default_profile]; + + CreditCard* credit_card = NULL; + int default_credit_card = personal_data_->DefaultCreditCard(); + if (default_credit_card != -1) + credit_card = credit_cards[default_credit_card]; + + // We'll have either one or the other at this point. + DCHECK(profile || credit_card); + + std::vector<FormData> forms; + for (std::vector<FormStructure*>::const_iterator iter = + form_structures_.begin(); + iter != form_structures_.end(); ++iter) { + const FormStructure* form_structure = *iter; + FormData form = form_structure->ConvertToFormData(); + DCHECK_EQ(form_structure->field_count(), form.fields.size()); + + for (size_t i = 0; i < form_structure->field_count(); ++i) { + const AutoFillField* field = form_structure->field(i); + + AutoFillType type(field->type()); + if (credit_card && type.group() == AutoFillType::CREDIT_CARD) { + form.fields[i].set_value(credit_card->GetFieldText(type)); + } else if (profile) { + form.fields[i].set_value(profile->GetFieldText(type)); + } + } + + forms.push_back(form); + } + + host->AutoFillForms(forms); +} + AutoFillManager::AutoFillManager() : tab_contents_(NULL), personal_data_(NULL), diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index e765bd3..a8fe529 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -95,6 +95,11 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // Returns the value of the AutoFillEnabled pref. bool IsAutoFillEnabled(); + // Fills all the forms in the page with the default profile. + // TODO(jhawkins): Do we really want to fill all of the forms on the page? + // Check how toolbar handles this case. + void FillDefaultProfile(); + protected: // For AutoFillInfoBarDelegateTest. AutoFillManager(); diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index bb91ec9..0c28609 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -12,7 +12,6 @@ #include "chrome/browser/autofill/field_types.h" #include "chrome/browser/autofill/form_field.h" #include "third_party/libjingle/files/talk/xmllite/xmlelement.h" -#include "webkit/glue/form_data.h" #include "webkit/glue/form_field.h" using webkit_glue::FormData; @@ -60,22 +59,24 @@ static std::string Hash64Bit(const std::string& str) { FormStructure::FormStructure(const FormData& form) : form_name_(UTF16ToUTF8(form.name)), source_url_(form.origin), - target_url_(form.action) { + target_url_(form.action), + autofill_count_(0) { // Copy the form fields. std::vector<webkit_glue::FormField>::const_iterator field; for (field = form.fields.begin(); field != form.fields.end(); field++) { - // We currently only handle text and select fields. This prevents us from - // thinking we can autofill other types of controls, e.g., password, hidden, - // submit. - if (!LowerCaseEqualsASCII(field->form_control_type(), kControlTypeText) && - !LowerCaseEqualsASCII(field->form_control_type(), kControlTypeSelect)) - continue; - - // Add all form fields (including with empty names) to signature. - // This is a requirement for AutoFill servers. - form_signature_field_names_.append("&"); - form_signature_field_names_.append(UTF16ToUTF8(field->name())); + // We currently only handle text and select fields; however, we need to + // store all fields in order to match the fields stored in the FormManager. + // We don't append other field types to the form signature though in order + // to match the form signature of the AutoFill servers. + if (LowerCaseEqualsASCII(field->form_control_type(), kControlTypeText) || + LowerCaseEqualsASCII(field->form_control_type(), kControlTypeSelect)) { + // Add all supported form fields (including with empty names) to + // signature. This is a requirement for AutoFill servers. + form_signature_field_names_.append("&"); + form_signature_field_names_.append(UTF16ToUTF8(field->name())); + ++autofill_count_; + } // Generate a unique name for this field by appending a counter to the name. string16 unique_name = field->name() + IntToString16(fields_.size() + 1); @@ -198,7 +199,7 @@ std::string FormStructure::FormSignature() const { } bool FormStructure::IsAutoFillable() const { - if (field_count() < kRequiredFillableFields) + if (autofill_count() < kRequiredFillableFields) return false; // Rule out http(s)://*/search?... @@ -230,6 +231,27 @@ size_t FormStructure::field_count() const { return (field_size == 0) ? 0 : field_size - 1; } +FormData FormStructure::ConvertToFormData() const { + FormData form; + form.name = UTF8ToUTF16(form_name_); + form.origin = source_url_; + form.action = target_url_; + + if (method_ == GET) + form.method = ASCIIToUTF16("GET"); + else if (method_ == POST) + form.method = ASCIIToUTF16("POST"); + else + NOTREACHED(); + + for (std::vector<AutoFillField*>::const_iterator iter = fields_.begin(); + iter != fields_.end() && *iter; ++iter) { + form.fields.push_back(static_cast<webkit_glue::FormField>(**iter)); + } + + return form; +} + bool FormStructure::operator==(const FormData& form) const { // TODO(jhawkins): Is this enough to differentiate a form? if (UTF8ToUTF16(form_name_) == form.name && @@ -289,4 +311,3 @@ bool FormStructure::EncodeFormRequest( } return true; } - diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h index 4028117..c2a25a9 100644 --- a/chrome/browser/autofill/form_structure.h +++ b/chrome/browser/autofill/form_structure.h @@ -13,15 +13,12 @@ #include "chrome/browser/autofill/autofill_type.h" #include "chrome/browser/autofill/field_types.h" #include "googleurl/src/gurl.h" +#include "webkit/glue/form_data.h" namespace buzz { class XmlElement; } // namespace buzz -namespace webkit_glue { -struct FormData; -} // namespace webkit_glue - enum RequestMethod { GET, POST @@ -69,6 +66,12 @@ class FormStructure { const AutoFillField* field(int index) const; size_t field_count() const; + // Returns the number of fields that are able to be autofilled. + size_t autofill_count() const { return autofill_count_; } + + // Converts this object to a FormData object. + webkit_glue::FormData ConvertToFormData() const; + // Used for iterating over the fields. std::vector<AutoFillField*>::const_iterator begin() const { return fields_.begin(); @@ -108,6 +111,9 @@ class FormStructure { bool has_autofillable_field_; bool has_password_fields_; + // The number of fields able to be autofilled. + size_t autofill_count_; + // A vector of all the input fields in the form. The vector is terminated by // a NULL entry. ScopedVector<AutoFillField> fields_; @@ -119,6 +125,8 @@ class FormStructure { // GET or POST. RequestMethod method_; + + DISALLOW_COPY_AND_ASSIGN(FormStructure); }; #endif // CHROME_BROWSER_AUTOFILL_FORM_STRUCTURE_H_ diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc index 4dc4818..2bd5328 100644 --- a/chrome/browser/autofill/form_structure_unittest.cc +++ b/chrome/browser/autofill/form_structure_unittest.cc @@ -4,17 +4,39 @@ #include "base/scoped_ptr.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/autofill/form_structure.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" #include "webkit/glue/form_data.h" +#include "webkit/glue/form_field.h" using webkit_glue::FormData; using WebKit::WebInputElement; namespace { +std::ostream& operator<<(std::ostream& os, const FormData& form) { + os << UTF16ToUTF8(form.name) + << " " + << UTF16ToUTF8(form.method) + << " " + << form.origin.spec() + << " " + << form.action.spec() + << " "; + + for (std::vector<webkit_glue::FormField>::const_iterator iter = + form.fields.begin(); + iter != form.fields.end(); ++iter) { + os << *iter + << " "; + } + + return os; +} + TEST(FormStructureTest, FieldCount) { FormData form; form.method = ASCIIToUTF16("post"); @@ -32,8 +54,58 @@ TEST(FormStructureTest, FieldCount) { ASCIIToUTF16("submit"))); FormStructure form_structure(form); - // Only text fields are counted. - EXPECT_EQ(1U, form_structure.field_count()); + // All fields are counted. + EXPECT_EQ(3U, form_structure.field_count()); +} + +TEST(FormStructureTest, AutoFillCount) { + FormData form; + form.method = ASCIIToUTF16("post"); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("username"), + ASCIIToUTF16("username"), + string16(), + ASCIIToUTF16("text"))); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("password"), + ASCIIToUTF16("password"), + string16(), + ASCIIToUTF16("password"))); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("state"), + ASCIIToUTF16("state"), + string16(), + ASCIIToUTF16("select-one"))); + form.fields.push_back(webkit_glue::FormField(string16(), + ASCIIToUTF16("Submit"), + string16(), + ASCIIToUTF16("submit"))); + FormStructure form_structure(form); + + // Only text and select fields are counted. + EXPECT_EQ(2U, form_structure.autofill_count()); +} + +TEST(FormStructureTest, ConvertToFormData) { + FormData form; + form.method = ASCIIToUTF16("post"); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("username"), + ASCIIToUTF16("username"), + string16(), + ASCIIToUTF16("text"))); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("password"), + ASCIIToUTF16("password"), + string16(), + ASCIIToUTF16("password"))); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("state"), + ASCIIToUTF16("state"), + string16(), + ASCIIToUTF16("select"))); + form.fields.push_back(webkit_glue::FormField(string16(), + ASCIIToUTF16("Submit"), + string16(), + ASCIIToUTF16("submit"))); + FormStructure form_structure(form); + + FormData converted = form_structure.ConvertToFormData(); + EXPECT_EQ(form, converted); } TEST(FormStructureTest, IsAutoFillable) { @@ -131,7 +203,7 @@ TEST(FormStructureTest, HeuristicsContactInfo) { EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. - ASSERT_EQ(8UL, form_structure->field_count()); + ASSERT_EQ(9UL, form_structure->field_count()); // Check that heuristics are initialized as UNKNOWN_TYPE. std::vector<AutoFillField*>::const_iterator iter; @@ -150,7 +222,7 @@ TEST(FormStructureTest, HeuristicsContactInfo) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(8U, form_structure->field_count()); + ASSERT_EQ(9U, form_structure->field_count()); // Check that heuristics are no longer UNKNOWN_TYPE. // First name. @@ -170,6 +242,8 @@ TEST(FormStructureTest, HeuristicsContactInfo) { EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(6)->heuristic_type()); // Zip. EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(7)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(8)->heuristic_type()); } TEST(FormStructureTest, HeuristicsSample8) { @@ -247,7 +321,7 @@ TEST(FormStructureTest, HeuristicsSample8) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(9U, form_structure->field_count()); + ASSERT_EQ(10U, form_structure->field_count()); // Check that heuristics are no longer UNKNOWN_TYPE. // First name. @@ -269,6 +343,8 @@ TEST(FormStructureTest, HeuristicsSample8) { // Phone. EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, form_structure->field(8)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type()); } TEST(FormStructureTest, HeuristicsSample6) { @@ -333,7 +409,7 @@ TEST(FormStructureTest, HeuristicsSample6) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(6U, form_structure->field_count()); + ASSERT_EQ(7U, form_structure->field_count()); // Check that heuristics are no longer UNKNOWN_TYPE. // Email. @@ -348,6 +424,8 @@ TEST(FormStructureTest, HeuristicsSample6) { EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type()); // Zip. EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); } // Tests a sequence of FormFields where only labels are supplied to heuristics @@ -398,7 +476,7 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) { EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. - ASSERT_EQ(8UL, form_structure->field_count()); + ASSERT_EQ(9UL, form_structure->field_count()); // Check that heuristics are initialized as UNKNOWN_TYPE. std::vector<AutoFillField*>::const_iterator iter; @@ -417,7 +495,7 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(8U, form_structure->field_count()); + ASSERT_EQ(9U, form_structure->field_count()); // Check that heuristics are no longer UNKNOWN_TYPE. // First name. @@ -437,6 +515,8 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) { EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(6)->heuristic_type()); // Zip. EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(7)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(8)->heuristic_type()); } TEST(FormStructureTest, HeuristicsCreditCardInfo) { @@ -472,7 +552,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. - ASSERT_EQ(5UL, form_structure->field_count()); + ASSERT_EQ(6UL, form_structure->field_count()); // Check that heuristics are initialized as UNKNOWN_TYPE. std::vector<AutoFillField*>::const_iterator iter; @@ -491,7 +571,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(5U, form_structure->field_count()); + ASSERT_EQ(6U, form_structure->field_count()); // Credit card name. EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); @@ -505,6 +585,8 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { // Credit card cvc. EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, form_structure->field(4)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); } TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { @@ -546,7 +628,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { EXPECT_TRUE(form_structure->IsAutoFillable()); // Expect the correct number of fields. - ASSERT_EQ(6UL, form_structure->field_count()); + ASSERT_EQ(7UL, form_structure->field_count()); // Check that heuristics are initialized as UNKNOWN_TYPE. std::vector<AutoFillField*>::const_iterator iter; @@ -565,7 +647,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { // Compute heuristic types. form_structure->GetHeuristicAutoFillTypes(); - ASSERT_EQ(6UL, form_structure->field_count()); + ASSERT_EQ(7UL, form_structure->field_count()); // Credit card name. EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); @@ -581,6 +663,8 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { // Credit card cvc. EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, form_structure->field(5)->heuristic_type()); + // Submit. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); } } // namespace diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index dffd1cd..09eee48 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -18,6 +18,7 @@ #include "base/thread.h" #include "gfx/point.h" #include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/autofill/autofill_manager.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser_list.h" @@ -1562,6 +1563,14 @@ void Browser::OpenInternetOptionsDialog() { } #endif +void Browser::AutoFillDefaultProfile() { + TabContents* current_tab = GetSelectedTabContents(); + if (!current_tab) // May be NULL during tab restore. + return; + + current_tab->GetAutoFillManager()->FillDefaultProfile(); +} + /////////////////////////////////////////////////////////////////////////////// // static @@ -1812,6 +1821,9 @@ void Browser::ExecuteCommandWithDisposition( case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break; #endif + // AutoFill + case IDC_AUTOFILL_DEFAULT: AutoFillDefaultProfile(); break; + default: LOG(WARNING) << "Received Unimplemented Command: " << id; break; @@ -2851,6 +2863,10 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, non_devtools_window); command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, non_devtools_window); + // AutoFill + command_updater_.UpdateCommandEnabled(IDC_AUTOFILL_DEFAULT, + non_devtools_window); + // Show various bits of UI command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index c82c01c..9d81731 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -492,6 +492,7 @@ class Browser : public TabStripModelDelegate, void OpenSystemOptionsDialog(); void OpenInternetOptionsDialog(); #endif + void AutoFillDefaultProfile(); virtual void UpdateDownloadShelfVisibility(bool visible); diff --git a/chrome/browser/gtk/accelerators_gtk.cc b/chrome/browser/gtk/accelerators_gtk.cc index 42ff3a1..c93d8f0 100644 --- a/chrome/browser/gtk/accelerators_gtk.cc +++ b/chrome/browser/gtk/accelerators_gtk.cc @@ -140,6 +140,10 @@ const struct AcceleratorMapping { { GDK_x, IDC_CUT, GDK_CONTROL_MASK }, { GDK_v, IDC_PASTE, GDK_CONTROL_MASK }, + // AutoFill. + { GDK_a, IDC_AUTOFILL_DEFAULT, + GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, + // Miscellany. { GDK_d, IDC_BOOKMARK_ALL_TABS, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 91ffc97..81a9cd2 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1610,6 +1610,11 @@ void RenderViewHost::AutoFillSuggestionsReturned( routing_id(), query_id, names, labels, default_suggestion_index)); } +void RenderViewHost::AutoFillForms( + const std::vector<webkit_glue::FormData>& forms) { + Send(new ViewMsg_AutoFillForms(routing_id(), forms)); +} + void RenderViewHost::AutocompleteSuggestionsReturned( int query_id, const std::vector<string16>& suggestions, int default_suggestion_index) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 3492603..fb86e94 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -393,6 +393,9 @@ class RenderViewHost : public RenderWidgetHost { const std::vector<string16>& labels, int default_suggestion_index); + // Called by the AutoFillManager to fill out all the forms in the renderer. + void AutoFillForms(const std::vector<webkit_glue::FormData>& forms); + // Called by the AutocompleteHistoryManager when the list of suggestions is // ready. void AutocompleteSuggestionsReturned( diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 4054816f..b783b2c 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -468,6 +468,12 @@ bool TabContents::HostsExtension() const { return GetURL().SchemeIs(chrome::kExtensionScheme); } +AutoFillManager* TabContents::GetAutoFillManager() { + if (autofill_manager_.get() == NULL) + autofill_manager_.reset(new AutoFillManager(this)); + return autofill_manager_.get(); +} + PasswordManager* TabContents::GetPasswordManager() { if (password_manager_.get() == NULL) password_manager_.reset(new PasswordManager(this)); @@ -2117,9 +2123,7 @@ RenderViewHostDelegate::Autocomplete* TabContents::GetAutocompleteDelegate() { } RenderViewHostDelegate::AutoFill* TabContents::GetAutoFillDelegate() { - if (autofill_manager_.get() == NULL) - autofill_manager_.reset(new AutoFillManager(this)); - return autofill_manager_.get(); + return GetAutoFillManager(); } AutomationResourceRoutingDelegate* diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 902e61e..97f688a 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -152,6 +152,9 @@ class TabContents : public PageNavigator, // Returns true if contains content rendered by an extension. bool HostsExtension() const; + // Returns the AutoFillManager, creating it if necessary. + AutoFillManager* GetAutoFillManager(); + // Returns the PasswordManager, creating it if necessary. PasswordManager* GetPasswordManager(); diff --git a/chrome/browser/views/accelerator_table_gtk.cc b/chrome/browser/views/accelerator_table_gtk.cc index 02f996f..9e1f6c9 100644 --- a/chrome/browser/views/accelerator_table_gtk.cc +++ b/chrome/browser/views/accelerator_table_gtk.cc @@ -109,6 +109,9 @@ const AcceleratorMapping kAcceleratorMap[] = { { base::VKEY_F2, false, false, false, IDC_FORWARD }, #endif + // AutoFill. + { base::VKEY_A, true, true, false, IDC_AUTOFILL_DEFAULT }, + // Miscellany. { base::VKEY_D, false, true, false, IDC_BOOKMARK_PAGE }, { base::VKEY_D, true, true, false, IDC_BOOKMARK_ALL_TABS }, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 93b1a76..24cda62 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -637,6 +637,9 @@ IPC_BEGIN_MESSAGES(View) std::vector<string16> /* labels */, int /* index of default suggestion */) + IPC_MESSAGE_ROUTED1(ViewMsg_AutoFillForms, + std::vector<webkit_glue::FormData> /* forms */) + // Reply to the ViewHostMsg_QueryFormFieldAutofill message with the // autocomplete suggestions. IPC_MESSAGE_ROUTED3(ViewMsg_AutocompleteSuggestionsReturned, diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc index d2c80b8..0d202ab 100644 --- a/chrome/renderer/form_manager.cc +++ b/chrome/renderer/form_manager.cc @@ -404,6 +404,13 @@ bool FormManager::FillForm(const FormData& form) { return true; } +void FormManager::FillForms(const std::vector<webkit_glue::FormData>& forms) { + for (std::vector<webkit_glue::FormData>::const_iterator iter = forms.begin(); + iter != forms.end(); ++iter) { + FillForm(*iter); + } +} + void FormManager::Reset() { for (WebFrameFormElementMap::iterator iter = form_elements_map_.begin(); iter != form_elements_map_.end(); ++iter) { diff --git a/chrome/renderer/form_manager.h b/chrome/renderer/form_manager.h index e1176bc..c35da84 100644 --- a/chrome/renderer/form_manager.h +++ b/chrome/renderer/form_manager.h @@ -85,6 +85,9 @@ class FormManager { // store multiple forms with the same names from different frames. bool FillForm(const webkit_glue::FormData& form); + // Fills all of the forms in the cache with form data from |forms|. + void FillForms(const std::vector<webkit_glue::FormData>& forms); + // Resets the stored set of forms. void Reset(); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 9dc6442..7b81bd9 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -602,6 +602,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { OnDisassociateFromPopupCount) IPC_MESSAGE_HANDLER(ViewMsg_AutoFillSuggestionsReturned, OnAutoFillSuggestionsReturned) + IPC_MESSAGE_HANDLER(ViewMsg_AutoFillForms, OnAutoFillForms) IPC_MESSAGE_HANDLER(ViewMsg_AutocompleteSuggestionsReturned, OnAutocompleteSuggestionsReturned) IPC_MESSAGE_HANDLER(ViewMsg_AutoFillFormDataFilled, @@ -1452,6 +1453,11 @@ void RenderView::OnAutoFillSuggestionsReturned( autofill_query_node_.reset(); } +void RenderView::OnAutoFillForms( + const std::vector<webkit_glue::FormData>& forms) { + form_manager_.FillForms(forms); +} + void RenderView::OnAutocompleteSuggestionsReturned( int query_id, const std::vector<string16>& suggestions, diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 6f67b4d..c3a0190 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -750,6 +750,9 @@ class RenderView : public RenderWidget, const std::vector<string16>& labels, int default_suggestions_index); + // Fills all the forms in this RenderView with the form data in |forms|. + void OnAutoFillForms(const std::vector<webkit_glue::FormData>& forms); + // Notification that we have received Autocomplete suggestions. void OnAutocompleteSuggestionsReturned( int query_id, diff --git a/webkit/glue/form_data.h b/webkit/glue/form_data.h index 6af9b28..033cac3 100644 --- a/webkit/glue/form_data.h +++ b/webkit/glue/form_data.h @@ -7,6 +7,7 @@ #include <vector> +#include "base/string_util.h" #include "googleurl/src/gurl.h" #include "webkit/glue/form_field.h" @@ -24,6 +25,15 @@ struct FormData { GURL action; // A vector of all the input fields in the form. std::vector<FormField> fields; + + // Used by FormStructureTest. + inline bool operator==(const FormData& form) const { + return (name == form.name && + StringToLowerASCII(method) == StringToLowerASCII(form.method) && + origin == form.origin && + action == form.action && + fields == form.fields); + } }; } // namespace webkit_glue |