diff options
author | dgwallinga@chromium.org <dgwallinga@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 21:33:08 +0000 |
---|---|---|
committer | dgwallinga@chromium.org <dgwallinga@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 21:33:08 +0000 |
commit | 17b6be77f10220c35d5eda624a8d4570ea4bdfbc (patch) | |
tree | 3507ab64be5f535faa677529f80aab9195a7256b | |
parent | e7bd97ddcf62efc9f737c537cd0e92f1712d400f (diff) | |
download | chromium_src-17b6be77f10220c35d5eda624a8d4570ea4bdfbc.zip chromium_src-17b6be77f10220c35d5eda624a8d4570ea4bdfbc.tar.gz chromium_src-17b6be77f10220c35d5eda624a8d4570ea4bdfbc.tar.bz2 |
Requery the autofill server when forms and input fields are dynamically added.
BUG=224802
Review URL: https://chromiumcodereview.appspot.com/13264002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197479 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/renderer/autofill/autofill_renderer_browsertest.cc | 55 | ||||
-rw-r--r-- | components/autofill/browser/autofill_manager.cc | 17 | ||||
-rw-r--r-- | components/autofill/browser/autofill_manager.h | 3 | ||||
-rw-r--r-- | components/autofill/browser/autofill_manager_unittest.cc | 48 | ||||
-rw-r--r-- | components/autofill/browser/autofill_metrics_unittest.cc | 37 | ||||
-rw-r--r-- | components/autofill/common/autofill_messages.h | 4 | ||||
-rw-r--r-- | components/autofill/common/forms_seen_state.h | 22 | ||||
-rw-r--r-- | components/autofill/renderer/autofill_agent.cc | 47 | ||||
-rw-r--r-- | components/autofill/renderer/autofill_agent.h | 13 |
9 files changed, 225 insertions, 21 deletions
diff --git a/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chrome/renderer/autofill/autofill_renderer_browsertest.cc index c09c4c2..c2b57b2 100644 --- a/chrome/renderer/autofill/autofill_renderer_browsertest.cc +++ b/chrome/renderer/autofill/autofill_renderer_browsertest.cc @@ -125,6 +125,61 @@ TEST_F(ChromeRenderViewTest, SendForms) { EXPECT_FORM_FIELD_DATA_EQUALS(expected, form2.fields[2]); } +TEST_F(ChromeRenderViewTest, SendDynamicForms) { + // Don't want any delay for form state sync changes. This will still post a + // message so updates will get coalesced, but as soon as we spin the message + // loop, it will generate an update. + SendContentStateImmediately(); + + LoadHTML("<form method=\"POST\" id=\"testform\">" + " <input type=\"text\" id=\"firstname\"/>" + " <input type=\"text\" id=\"middlename\"/>" + " <input type=\"text\" id=\"lastname\" autoComplete=\"off\"/>" + " <input type=\"hidden\" id=\"email\"/>" + " <select id=\"state\"/>" + " <option>?</option>" + " <option>California</option>" + " <option>Texas</option>" + " </select>" + "</form>"); + + // Verify that "FormsSeen" sends the expected number of fields. + const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching( + AutofillHostMsg_FormsSeen::ID); + ASSERT_NE(static_cast<IPC::Message*>(NULL), message); + AutofillHostMsg_FormsSeen::Param params; + AutofillHostMsg_FormsSeen::Read(message, ¶ms); + const std::vector<FormData>& forms = params.a; + ASSERT_EQ(1UL, forms.size()); + ASSERT_EQ(4UL, forms[0].fields.size()); + + autofill_agent_->OnAutocheckoutSupported(); + render_thread_->sink().ClearMessages(); + ExecuteJavaScript("var newInput=document.createElement(\"input\");" + "newInput.setAttribute(\"type\",\"text\");" + "newInput.setAttribute(\"id\", \"telephone\");" + "document.getElementById(\"testform\")" + ".appendChild(newInput);"); + msg_loop_.RunUntilIdle(); + + // Verify that FormsSeen is present with the new field. + const IPC::Message* message2 = render_thread_->sink().GetFirstMessageMatching( + AutofillHostMsg_FormsSeen::ID); + ASSERT_NE(static_cast<IPC::Message*>(NULL), message2); + AutofillHostMsg_FormsSeen::Read(message2, ¶ms); + const std::vector<FormData>& new_forms = params.a; + ASSERT_EQ(1UL, new_forms.size()); + ASSERT_EQ(5UL, new_forms[0].fields.size()); + + FormFieldData expected; + + expected.name = ASCIIToUTF16("telephone"); + expected.value = string16(); + expected.form_control_type = "text"; + expected.max_length = WebInputElement::defaultMaxLength(); + EXPECT_FORM_FIELD_DATA_EQUALS(expected, forms[0].fields[4]); +} + TEST_F(ChromeRenderViewTest, FillFormElement) { // Don't want any delay for form state sync changes. This will still post a // message so updates will get coalesced, but as soon as we spin the message diff --git a/components/autofill/browser/autofill_manager.cc b/components/autofill/browser/autofill_manager.cc index 20c16e8..f2e2907 100644 --- a/components/autofill/browser/autofill_manager.cc +++ b/components/autofill/browser/autofill_manager.cc @@ -381,17 +381,28 @@ bool AutofillManager::OnFormSubmitted(const FormData& form, void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms, const TimeTicks& timestamp, - bool has_more_forms) { + autofill::FormsSeenState state) { + bool is_post_document_load = state == autofill::DYNAMIC_FORMS_SEEN; + bool has_more_forms = state == autofill::PARTIAL_FORMS_SEEN; + // If new forms were added via AJAX or DHML, treat as new page. + if (is_post_document_load) + Reset(); + RenderViewHost* host = web_contents()->GetRenderViewHost(); if (!host) return; if (!GetAutocheckoutURLPrefix().empty()) { // If whitelisted URL, fetch all the forms. - if (has_more_forms) { + if (has_more_forms) host->Send(new AutofillMsg_GetAllForms(host->GetRoutingID())); - return; + if (!is_post_document_load) { + host->Send( + new AutofillMsg_AutocheckoutSupported(host->GetRoutingID())); } + // Now return early, as OnFormsSeen will get called again with all forms. + if (has_more_forms) + return; } autocheckout_manager_.OnFormsSeen(); diff --git a/components/autofill/browser/autofill_manager.h b/components/autofill/browser/autofill_manager.h index 9912c23..9fd261b 100644 --- a/components/autofill/browser/autofill_manager.h +++ b/components/autofill/browser/autofill_manager.h @@ -29,6 +29,7 @@ #include "components/autofill/browser/personal_data_manager.h" #include "components/autofill/common/autocheckout_status.h" #include "components/autofill/common/form_data.h" +#include "components/autofill/common/forms_seen_state.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/ssl_status.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" @@ -214,7 +215,7 @@ class AutofillManager : public content::WebContentsObserver, void OnFormsSeen(const std::vector<FormData>& forms, const base::TimeTicks& timestamp, - bool has_more_forms); + autofill::FormsSeenState state); void OnTextFieldDidChange(const FormData& form, const FormFieldData& field, const base::TimeTicks& timestamp); diff --git a/components/autofill/browser/autofill_manager_unittest.cc b/components/autofill/browser/autofill_manager_unittest.cc index 0c9b9ce0..1c9bd68 100644 --- a/components/autofill/browser/autofill_manager_unittest.cc +++ b/components/autofill/browser/autofill_manager_unittest.cc @@ -38,6 +38,7 @@ #include "components/autofill/common/autofill_messages.h" #include "components/autofill/common/form_data.h" #include "components/autofill/common/form_field_data.h" +#include "components/autofill/common/forms_seen_state.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_render_process_host.h" @@ -697,11 +698,18 @@ class AutofillManagerTest : public ChromeRenderViewHostTestHarness { } void FormsSeen(const std::vector<FormData>& forms) { - autofill_manager_->OnFormsSeen(forms, base::TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, base::TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); } void PartialFormsSeen(const std::vector<FormData>& forms) { - autofill_manager_->OnFormsSeen(forms, base::TimeTicks(), true); + autofill_manager_->OnFormsSeen(forms, base::TimeTicks(), + autofill::PARTIAL_FORMS_SEEN); + } + + void DynamicFormsSeen(const std::vector<FormData>& forms) { + autofill_manager_->OnFormsSeen(forms, base::TimeTicks(), + autofill::DYNAMIC_FORMS_SEEN); } void FormSubmitted(const FormData& form) { @@ -907,6 +915,42 @@ TEST_F(AutofillManagerTest, AutocheckoutFormsSeen) { EXPECT_EQ("/form.html", form_structures[2]->source_url().path()); } +// Test that in the case of Autocheckout, forms seen are in order supplied. +TEST_F(AutofillManagerTest, DynamicFormsSeen) { + FormData shipping_options; + CreateTestShippingOptionsFormData(&shipping_options); + FormData user_supplied; + CreateTestFormWithAutocompleteAttribute(&user_supplied); + FormData address; + CreateTestAddressFormData(&address); + + autofill_manager_->set_autocheckout_url_prefix("test-prefix"); + // Push user_supplied only + std::vector<FormData> forms; + forms.push_back(user_supplied); + + // Make sure normal form is handled correctly. + FormsSeen(forms); + std::vector<FormStructure*> form_structures; + form_structures = autofill_manager_->GetFormStructures(); + ASSERT_EQ(1U, form_structures.size()); + EXPECT_EQ("/userspecified.html", form_structures[0]->source_url().path()); + + // Push other forms + forms.push_back(shipping_options); + forms.push_back(address); + + // FormStructure should contain three and only three forms. Otherwise, it + // would indicate that the manager didn't reset upon being notified of + // the new forms; + DynamicFormsSeen(forms); + form_structures = autofill_manager_->GetFormStructures(); + ASSERT_EQ(3U, form_structures.size()); + EXPECT_EQ("/userspecified.html", form_structures[0]->source_url().path()); + EXPECT_EQ("/shipping.html", form_structures[1]->source_url().path()); + EXPECT_EQ("/form.html", form_structures[2]->source_url().path()); +} + // Test that we return only matching address profile suggestions when the // selected form field has been partially filled out. TEST_F(AutofillManagerTest, GetProfileSuggestionsMatchCharacter) { diff --git a/components/autofill/browser/autofill_metrics_unittest.cc b/components/autofill/browser/autofill_metrics_unittest.cc index b6df550..14c5c19 100644 --- a/components/autofill/browser/autofill_metrics_unittest.cc +++ b/components/autofill/browser/autofill_metrics_unittest.cc @@ -22,6 +22,7 @@ #include "components/autofill/browser/personal_data_manager.h" #include "components/autofill/common/form_data.h" #include "components/autofill/common/form_field_data.h" +#include "components/autofill/common/forms_seen_state.h" #include "components/webdata/common/web_data_results.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_utils.h" @@ -777,7 +778,8 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) { { EXPECT_CALL(*autofill_manager_->metric_logger(), LogDeveloperEngagementMetric(_)).Times(0); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->Reset(); Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); } @@ -797,7 +799,8 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) { *autofill_manager_->metric_logger(), LogDeveloperEngagementMetric( AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS)).Times(0); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->Reset(); Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); } @@ -828,7 +831,8 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) { *autofill_manager_->metric_logger(), LogDeveloperEngagementMetric( AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS)).Times(1); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->Reset(); Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); } @@ -1103,7 +1107,8 @@ TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { LogIsAutofillEnabledAtPageLoad(true)).Times(1); autofill_manager_->set_autofill_enabled(true); - autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks(), false); + autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); // Reset the autofill manager state. autofill_manager_->Reset(); @@ -1113,7 +1118,8 @@ TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { LogIsAutofillEnabledAtPageLoad(false)).Times(1); autofill_manager_->set_autofill_enabled(false); - autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks(), false); + autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); } // Test that credit card infobar metrics are logged correctly. @@ -1226,7 +1232,8 @@ TEST_F(AutofillMetricsTest, UserHappinessFormLoadAndSubmission) { { EXPECT_CALL(*autofill_manager_->metric_logger(), LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)).Times(0); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); } @@ -1262,7 +1269,8 @@ TEST_F(AutofillMetricsTest, UserHappinessFormLoadAndSubmission) { { EXPECT_CALL(*autofill_manager_->metric_logger(), LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); } // Expect a notification when the form is submitted. @@ -1362,7 +1370,8 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) { { EXPECT_CALL(*autofill_manager_->metric_logger(), LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)); - autofill_manager_->OnFormsSeen(forms, TimeTicks(), false); + autofill_manager_->OnFormsSeen(forms, TimeTicks(), + autofill::NO_SPECIAL_FORMS_SEEN); } // Simulate typing. @@ -1482,7 +1491,8 @@ TEST_F(AutofillMetricsTest, FormFillDuration) { EXPECT_CALL(*autofill_manager_->metric_logger(), LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); autofill_manager_->OnFormsSeen( - forms, TimeTicks::FromInternalValue(1), false); + forms, TimeTicks::FromInternalValue(1), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); autofill_manager_->Reset(); Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); @@ -1501,7 +1511,8 @@ TEST_F(AutofillMetricsTest, FormFillDuration) { LogFormFillDurationFromInteractionWithoutAutofill( TimeDelta::FromInternalValue(14))); autofill_manager_->OnFormsSeen( - forms, TimeTicks::FromInternalValue(1), false); + forms, TimeTicks::FromInternalValue(1), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), TimeTicks::FromInternalValue(3)); autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); @@ -1523,7 +1534,8 @@ TEST_F(AutofillMetricsTest, FormFillDuration) { EXPECT_CALL(*autofill_manager_->metric_logger(), LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); autofill_manager_->OnFormsSeen( - forms, TimeTicks::FromInternalValue(1), false); + forms, TimeTicks::FromInternalValue(1), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->OnDidFillAutofillFormData( TimeTicks::FromInternalValue(5)); autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); @@ -1546,7 +1558,8 @@ TEST_F(AutofillMetricsTest, FormFillDuration) { EXPECT_CALL(*autofill_manager_->metric_logger(), LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); autofill_manager_->OnFormsSeen( - forms, TimeTicks::FromInternalValue(1), false); + forms, TimeTicks::FromInternalValue(1), + autofill::NO_SPECIAL_FORMS_SEEN); autofill_manager_->OnDidFillAutofillFormData( TimeTicks::FromInternalValue(5)); autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), diff --git a/components/autofill/common/autofill_messages.h b/components/autofill/common/autofill_messages.h index abcb0be..f8efa89 100644 --- a/components/autofill/common/autofill_messages.h +++ b/components/autofill/common/autofill_messages.h @@ -12,6 +12,7 @@ #include "components/autofill/common/form_data_predictions.h" #include "components/autofill/common/form_field_data.h" #include "components/autofill/common/form_field_data_predictions.h" +#include "components/autofill/common/forms_seen_state.h" #include "components/autofill/common/password_form_fill_data.h" #include "components/autofill/common/web_element_descriptor.h" #include "content/public/common/common_param_traits.h" @@ -27,6 +28,7 @@ #define IPC_MESSAGE_START AutofillMsgStart IPC_ENUM_TRAITS(autofill::AutocheckoutStatus) +IPC_ENUM_TRAITS(autofill::FormsSeenState) IPC_STRUCT_TRAITS_BEGIN(autofill::WebElementDescriptor) IPC_STRUCT_TRAITS_MEMBER(descriptor) @@ -181,7 +183,7 @@ IPC_MESSAGE_ROUTED0(AutofillMsg_AutocheckoutSupported) IPC_MESSAGE_ROUTED3(AutofillHostMsg_FormsSeen, std::vector<autofill::FormData> /* forms */, base::TimeTicks /* timestamp */, - bool /* has_more_forms */) + autofill::FormsSeenState /* state */) // Notification that password forms have been seen that are candidates for // filling/submitting by the password manager. diff --git a/components/autofill/common/forms_seen_state.h b/components/autofill/common/forms_seen_state.h new file mode 100644 index 0000000..5f6f582 --- /dev/null +++ b/components/autofill/common/forms_seen_state.h @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_COMMON_FORMS_SEEN_PARAM_H_ +#define COMPONENTS_AUTOFILL_COMMON_FORMS_SEEN_PARAM_H_ + +namespace autofill { + +// Specifies the nature of the forms triggering the call. +enum FormsSeenState { + // Forms present on page load with no additional unsent forms. + NO_SPECIAL_FORMS_SEEN = 0, + // If this an Autocheckout page, there are more that should be checked. + PARTIAL_FORMS_SEEN = 1, + // Forms were added dynamically post-page load. + DYNAMIC_FORMS_SEEN = 2, +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_COMMON_FORMS_SEEN_PARAM_H_ diff --git a/components/autofill/renderer/autofill_agent.cc b/components/autofill/renderer/autofill_agent.cc index beefed0..fa2b8a8 100644 --- a/components/autofill/renderer/autofill_agent.cc +++ b/components/autofill/renderer/autofill_agent.cc @@ -151,6 +151,8 @@ AutofillAgent::AutofillAgent(content::RenderView* render_view, has_shown_autofill_popup_for_current_edit_(false), did_set_node_text_(false), autocheckout_click_in_progress_(false), + is_autocheckout_supported_(false), + has_new_forms_for_browser_(false), try_to_show_autocheckout_bubble_(false), ignore_text_changes_(false), weak_ptr_factory_(this) { @@ -214,11 +216,14 @@ void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { form_cache_.ExtractForms(*frame, &forms); } + autofill::FormsSeenState state = has_more_forms ? + autofill::PARTIAL_FORMS_SEEN : autofill::NO_SPECIAL_FORMS_SEEN; + // Always communicate to browser process for topmost frame. if (!forms.empty() || !frame->parent()) { Send(new AutofillHostMsg_FormsSeen(routing_id(), forms, forms_seen_timestamp_, - has_more_forms)); + state)); } } @@ -736,7 +741,8 @@ void AutofillAgent::OnGetAllForms() { // Report to AutofillManager that all forms are being sent. Send(new AutofillHostMsg_FormsSeen(routing_id(), forms, - forms_seen_timestamp_, false)); + forms_seen_timestamp_, + NO_SPECIAL_FORMS_SEEN)); } void AutofillAgent::OnRequestAutocompleteResult( @@ -783,7 +789,10 @@ void AutofillAgent::OnFillFormsAndClick( } void AutofillAgent::OnAutocheckoutSupported() { + is_autocheckout_supported_ = true; try_to_show_autocheckout_bubble_ = true; + if (has_new_forms_for_browser_) + MaybeSendDynamicFormsSeen(); MaybeShowAutocheckoutBubble(); } @@ -945,4 +954,38 @@ void AutofillAgent::HideHostAutofillUi() { Send(new AutofillHostMsg_HideAutofillUi(routing_id())); } +void AutofillAgent::didAssociateFormControls( + const WebKit::WebVector<WebKit::WebNode>& nodes) { + for (size_t i = 0; i < nodes.size(); ++i) { + WebKit::WebNode node = nodes[i]; + if (node.document().frame() == topmost_frame_) { + forms_seen_timestamp_ = base::TimeTicks::Now(); + has_new_forms_for_browser_ = true; + break; + } + } + + if (has_new_forms_for_browser_ && is_autocheckout_supported_) + MaybeSendDynamicFormsSeen(); +} + +void AutofillAgent::MaybeSendDynamicFormsSeen() { + has_new_forms_for_browser_ = false; + form_elements_.clear(); + std::vector<FormData> forms; + // This will only be called for Autocheckout flows, so send all forms to + // save an IPC. + form_cache_.ExtractFormsAndFormElements( + *topmost_frame_, 0, &forms, &form_elements_); + autofill::FormsSeenState state = autofill::DYNAMIC_FORMS_SEEN; + + if (!forms.empty()) { + if (click_timer_.IsRunning()) + click_timer_.Stop(); + Send(new AutofillHostMsg_FormsSeen(routing_id(), forms, + forms_seen_timestamp_, + state)); + } +} + } // namespace autofill diff --git a/components/autofill/renderer/autofill_agent.h b/components/autofill/renderer/autofill_agent.h index d47ab77..7d882b1 100644 --- a/components/autofill/renderer/autofill_agent.h +++ b/components/autofill/renderer/autofill_agent.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/time.h" #include "base/timer.h" +#include "components/autofill/common/forms_seen_state.h" #include "components/autofill/renderer/form_cache.h" #include "components/autofill/renderer/page_click_listener.h" #include "content/public/renderer/render_view_observer.h" @@ -103,6 +104,8 @@ class AutofillAgent : public content::RenderViewObserver, WebKit::WebFrame* frame, const WebKit::WebFormElement& form) OVERRIDE; virtual void setIgnoreTextChanges(bool ignore) OVERRIDE; + virtual void didAssociateFormControls( + const WebKit::WebVector<WebKit::WebNode>& nodes) OVERRIDE; void OnSuggestionsReturned(int query_id, const std::vector<base::string16>& values, @@ -206,6 +209,8 @@ class AutofillAgent : public content::RenderViewObserver, // Hides any currently showing Autofill UI in the browser only. void HideHostAutofillUi(); + void MaybeSendDynamicFormsSeen(); + // Send |AutofillHostMsg_MaybeShowAutocheckoutBubble| to browser if needed. void MaybeShowAutocheckoutBubble(); @@ -256,6 +261,13 @@ class AutofillAgent : public content::RenderViewObserver, // Autocheckout flow. bool autocheckout_click_in_progress_; + // Whether or not |topmost_frame_| is whitelisted for Autocheckout. + bool is_autocheckout_supported_; + + // Whether or not new forms/fields have been dynamically added + // since the last loaded forms were sent to the browser process. + bool has_new_forms_for_browser_; + // Whether or not we should try to offer the user Autocheckout functionality // by sending |AutofillHostMsg_MaybeShowAutocheckoutBubble| to the browser. bool try_to_show_autocheckout_bubble_; @@ -273,6 +285,7 @@ class AutofillAgent : public content::RenderViewObserver, friend class PasswordAutofillAgentTest; FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, FillFormElement); FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendForms); + FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, SendDynamicForms); FRIEND_TEST_ALL_PREFIXES(ChromeRenderViewTest, ShowAutofillWarning); FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, WaitUsername); FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, SuggestionAccept); |