Commit ff02e6d9 authored by estade's avatar estade Committed by Commit bot

Autofill: one FormCache per WebFrame.

BUG=425756

Review URL: https://codereview.chromium.org/803673002

Cr-Commit-Position: refs/heads/master@{#308419}
parent 1328cb0f
...@@ -195,8 +195,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -195,8 +195,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
const FormData& form = forms[0]; const FormData& form = forms[0];
...@@ -255,8 +255,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -255,8 +255,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -486,8 +486,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -486,8 +486,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -566,8 +566,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -566,8 +566,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the textarea element we want to find. // Get the textarea element we want to find.
...@@ -656,8 +656,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -656,8 +656,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -744,8 +744,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -744,8 +744,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -816,8 +816,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -816,8 +816,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -891,8 +891,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -891,8 +891,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
const size_t expected_size = unowned ? 1 : 2; const size_t expected_size = unowned ? 1 : 2;
ASSERT_EQ(expected_size, forms.size()); ASSERT_EQ(expected_size, forms.size());
...@@ -974,8 +974,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -974,8 +974,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Get the input element we want to find. // Get the input element we want to find.
...@@ -1070,8 +1070,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1070,8 +1070,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the auto-filled attribute. // Set the auto-filled attribute.
...@@ -1166,8 +1166,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1166,8 +1166,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the auto-filled attribute. // Set the auto-filled attribute.
...@@ -1232,8 +1232,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1232,8 +1232,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the auto-filled attribute. // Set the auto-filled attribute.
...@@ -1286,8 +1286,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1286,8 +1286,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the auto-filled attribute. // Set the auto-filled attribute.
...@@ -1340,8 +1340,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1340,8 +1340,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the auto-filled attribute. // Set the auto-filled attribute.
...@@ -1394,8 +1394,8 @@ class FormAutofillTest : public ChromeRenderViewTest { ...@@ -1394,8 +1394,8 @@ class FormAutofillTest : public ChromeRenderViewTest {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Set the autofilled attribute. // Set the autofilled attribute.
...@@ -2087,8 +2087,8 @@ TEST_F(FormAutofillTest, ExtractMultipleForms) { ...@@ -2087,8 +2087,8 @@ TEST_F(FormAutofillTest, ExtractMultipleForms) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(2U, forms.size()); ASSERT_EQ(2U, forms.size());
// First form. // First form.
...@@ -2150,12 +2150,12 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) { ...@@ -2150,12 +2150,12 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
// Second call should give nothing as there are no new forms. // Second call should give nothing as there are no new forms.
forms = form_cache.ExtractNewForms(*web_frame); forms = form_cache.ExtractNewForms();
ASSERT_TRUE(forms.empty()); ASSERT_TRUE(forms.empty());
// Append to the current form will re-extract. // Append to the current form will re-extract.
...@@ -2167,7 +2167,7 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) { ...@@ -2167,7 +2167,7 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) {
"document.getElementById('testform').appendChild(newInput);"); "document.getElementById('testform').appendChild(newInput);");
msg_loop_.RunUntilIdle(); msg_loop_.RunUntilIdle();
forms = form_cache.ExtractNewForms(*web_frame); forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
const std::vector<FormFieldData>& fields = forms[0].fields; const std::vector<FormFieldData>& fields = forms[0].fields;
...@@ -2220,7 +2220,7 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) { ...@@ -2220,7 +2220,7 @@ TEST_F(FormAutofillTest, OnlyExtractNewForms) {
msg_loop_.RunUntilIdle(); msg_loop_.RunUntilIdle();
web_frame = GetMainFrame(); web_frame = GetMainFrame();
forms = form_cache.ExtractNewForms(*web_frame); forms = form_cache.ExtractNewForms();
ASSERT_EQ(1U, forms.size()); ASSERT_EQ(1U, forms.size());
const std::vector<FormFieldData>& fields2 = forms[0].fields; const std::vector<FormFieldData>& fields2 = forms[0].fields;
...@@ -2250,8 +2250,8 @@ TEST_F(FormAutofillTest, ExtractFormsTooFewFields) { ...@@ -2250,8 +2250,8 @@ TEST_F(FormAutofillTest, ExtractFormsTooFewFields) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_TRUE(forms.empty()); ASSERT_TRUE(forms.empty());
} }
...@@ -2265,8 +2265,8 @@ TEST_F(FormAutofillTest, ExtractFormsSkippedForms) { ...@@ -2265,8 +2265,8 @@ TEST_F(FormAutofillTest, ExtractFormsSkippedForms) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_TRUE(forms.empty()); ASSERT_TRUE(forms.empty());
} }
...@@ -2278,8 +2278,8 @@ TEST_F(FormAutofillTest, ExtractFormsNoFields) { ...@@ -2278,8 +2278,8 @@ TEST_F(FormAutofillTest, ExtractFormsNoFields) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_TRUE(forms.empty()); ASSERT_TRUE(forms.empty());
} }
...@@ -2297,8 +2297,8 @@ TEST_F(FormAutofillTest, ExtractFormsTooFewFieldsSkipsCheckable) { ...@@ -2297,8 +2297,8 @@ TEST_F(FormAutofillTest, ExtractFormsTooFewFieldsSkipsCheckable) {
WebFrame* web_frame = GetMainFrame(); WebFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame); ASSERT_NE(nullptr, web_frame);
FormCache form_cache; FormCache form_cache(*web_frame);
std::vector<FormData> forms = form_cache.ExtractNewForms(*web_frame); std::vector<FormData> forms = form_cache.ExtractNewForms();
ASSERT_TRUE(forms.empty()); ASSERT_TRUE(forms.empty());
} }
......
...@@ -133,6 +133,7 @@ AutofillAgent::AutofillAgent(content::RenderFrame* render_frame, ...@@ -133,6 +133,7 @@ AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
PasswordAutofillAgent* password_autofill_agent, PasswordAutofillAgent* password_autofill_agent,
PasswordGenerationAgent* password_generation_agent) PasswordGenerationAgent* password_generation_agent)
: content::RenderFrameObserver(render_frame), : content::RenderFrameObserver(render_frame),
form_cache_(*render_frame->GetWebFrame()),
password_autofill_agent_(password_autofill_agent), password_autofill_agent_(password_autofill_agent),
password_generation_agent_(password_generation_agent), password_generation_agent_(password_generation_agent),
legacy_(render_frame->GetRenderView(), this), legacy_(render_frame->GetRenderView(), this),
...@@ -179,8 +180,7 @@ bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { ...@@ -179,8 +180,7 @@ bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
} }
void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation) { void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation) {
// TODO(estade): |form_cache_| shouldn't track multiple frames. form_cache_.Reset();
form_cache_.ResetFrame(*render_frame()->GetWebFrame());
} }
void AutofillAgent::DidFinishDocumentLoad() { void AutofillAgent::DidFinishDocumentLoad() {
...@@ -191,7 +191,7 @@ void AutofillAgent::FrameDetached(WebFrame* frame) { ...@@ -191,7 +191,7 @@ void AutofillAgent::FrameDetached(WebFrame* frame) {
if (frame != render_frame()->GetWebFrame()) if (frame != render_frame()->GetWebFrame())
return; return;
form_cache_.ResetFrame(*frame); form_cache_.Reset();
} }
void AutofillAgent::WillSubmitForm(WebLocalFrame* frame, void AutofillAgent::WillSubmitForm(WebLocalFrame* frame,
...@@ -760,7 +760,7 @@ void AutofillAgent::ProcessForms() { ...@@ -760,7 +760,7 @@ void AutofillAgent::ProcessForms() {
base::TimeTicks forms_seen_timestamp = base::TimeTicks::Now(); base::TimeTicks forms_seen_timestamp = base::TimeTicks::Now();
WebLocalFrame* frame = render_frame()->GetWebFrame(); WebLocalFrame* frame = render_frame()->GetWebFrame();
std::vector<FormData> forms = form_cache_.ExtractNewForms(*frame); std::vector<FormData> forms = form_cache_.ExtractNewForms();
// Always communicate to browser process for topmost frame. // Always communicate to browser process for topmost frame.
if (!forms.empty() || !frame->parent()) { if (!forms.empty() || !frame->parent()) {
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "components/autofill/content/renderer/form_autofill_util.h" #include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/form_data_predictions.h"
#include "grit/components_strings.h" #include "grit/components_strings.h"
#include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebString.h"
...@@ -42,32 +41,6 @@ namespace autofill { ...@@ -42,32 +41,6 @@ namespace autofill {
namespace { namespace {
// Helper function to discard state of various WebFormElements when they go out
// of web frame's scope. This is done to release memory that we no longer need
// to hold.
// K should inherit from WebFormControlElement as the function looks to extract
// WebFormElement for K.form().
template <class K, class V>
void RemoveOldElements(const WebFrame& frame, std::map<const K, V>* states) {
std::vector<K> to_remove;
for (typename std::map<const K, V>::const_iterator it = states->begin();
it != states->end(); ++it) {
const WebFormElement& form_element = it->first.form();
if (form_element.isNull()) {
to_remove.push_back(it->first);
} else {
const WebFrame* element_frame = form_element.document().frame();
if (!element_frame || element_frame == &frame)
to_remove.push_back(it->first);
}
}
for (typename std::vector<K>::const_iterator it = to_remove.begin();
it != to_remove.end(); ++it) {
states->erase(*it);
}
}
void LogDeprecationMessages(const WebFormControlElement& element) { void LogDeprecationMessages(const WebFormControlElement& element) {
std::string autocomplete_attribute = std::string autocomplete_attribute =
base::UTF16ToUTF8(element.getAttribute("autocomplete")); base::UTF16ToUTF8(element.getAttribute("autocomplete"));
...@@ -96,27 +69,24 @@ bool ShouldIgnoreForm(size_t num_editable_elements, ...@@ -96,27 +69,24 @@ bool ShouldIgnoreForm(size_t num_editable_elements,
} // namespace } // namespace
FormCache::FormCache() { FormCache::FormCache(const WebFrame& frame) : frame_(frame) {
} }
FormCache::~FormCache() { FormCache::~FormCache() {
} }
std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) { std::vector<FormData> FormCache::ExtractNewForms() {
std::vector<FormData> forms; std::vector<FormData> forms;
WebDocument document = frame.document(); WebDocument document = frame_.document();
if (document.isNull()) if (document.isNull())
return forms; return forms;
if (!ContainsKey(documents_to_synthetic_form_map_, document))
documents_to_synthetic_form_map_[document] = FormData();
WebVector<WebFormElement> web_forms; WebVector<WebFormElement> web_forms;
document.forms(web_forms); document.forms(web_forms);
// Log an error message for deprecated attributes, but only the first time // Log an error message for deprecated attributes, but only the first time
// the form is parsed. // the form is parsed.
bool log_deprecation_messages = !ContainsKey(parsed_forms_, &frame); bool log_deprecation_messages = parsed_forms_.empty();
const ExtractMask extract_mask = const ExtractMask extract_mask =
static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
...@@ -144,9 +114,9 @@ std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) { ...@@ -144,9 +114,9 @@ std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) {
return forms; return forms;
if (form.fields.size() >= kRequiredAutofillFields && if (form.fields.size() >= kRequiredAutofillFields &&
!ContainsKey(parsed_forms_[&frame], form)) { !ContainsKey(parsed_forms_, form)) {
forms.push_back(form); forms.push_back(form);
parsed_forms_[&frame].insert(form); parsed_forms_.insert(form);
} }
} }
...@@ -161,41 +131,32 @@ std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) { ...@@ -161,41 +131,32 @@ std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) {
if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) if (ShouldIgnoreForm(num_editable_elements, control_elements.size()))
return forms; return forms;
FormData form; FormData synthetic_form;
if (!UnownedFormElementsAndFieldSetsToFormData(fieldsets, control_elements, if (!UnownedFormElementsAndFieldSetsToFormData(fieldsets, control_elements,
nullptr, document.url(), nullptr, document.url(),
REQUIRE_NONE, extract_mask, REQUIRE_NONE, extract_mask,
&form, nullptr)) { &synthetic_form, nullptr)) {
return forms; return forms;
} }
num_fields_seen += form.fields.size(); num_fields_seen += synthetic_form.fields.size();
if (num_fields_seen > kMaxParseableFields) if (num_fields_seen > kMaxParseableFields)
return forms; return forms;
if (form.fields.size() >= kRequiredAutofillFields && if (synthetic_form.fields.size() >= kRequiredAutofillFields &&
!parsed_forms_[&frame].count(form)) { !parsed_forms_.count(synthetic_form)) {
forms.push_back(form); forms.push_back(synthetic_form);
parsed_forms_[&frame].insert(form); parsed_forms_.insert(synthetic_form);
documents_to_synthetic_form_map_[document] = form; synthetic_form_ = synthetic_form;
} }
return forms; return forms;
} }
void FormCache::ResetFrame(const WebFrame& frame) { void FormCache::Reset() {
std::vector<WebDocument> documents_to_delete; synthetic_form_ = FormData();
for (const auto& it : documents_to_synthetic_form_map_) { parsed_forms_.clear();
const WebFrame* document_frame = it.first.frame(); initial_select_values_.clear();
if (!document_frame || document_frame == &frame) initial_checked_state_.clear();
documents_to_delete.push_back(it.first);
}
for (const auto& it : documents_to_delete)
documents_to_synthetic_form_map_.erase(it);
parsed_forms_[&frame].clear();
RemoveOldElements(frame, &initial_select_values_);
RemoveOldElements(frame, &initial_checked_state_);
} }
bool FormCache::ClearFormWithElement(const WebFormControlElement& element) { bool FormCache::ClearFormWithElement(const WebFormControlElement& element) {
...@@ -261,47 +222,39 @@ bool FormCache::ShowPredictions(const FormDataPredictions& form) { ...@@ -261,47 +222,39 @@ bool FormCache::ShowPredictions(const FormDataPredictions& form) {
std::vector<WebFormControlElement> control_elements; std::vector<WebFormControlElement> control_elements;
// First check the synthetic forms. // First check the synthetic form.
bool found_synthetic_form = false; bool found_synthetic_form = false;
for (const auto& it : documents_to_synthetic_form_map_) { if (form.data.SameFormAs(synthetic_form_)) {
const FormData& form_data = it.second;
if (!form_data.SameFormAs(form.data))
continue;
found_synthetic_form = true; found_synthetic_form = true;
WebDocument document = it.first; WebDocument document = frame_.document();
control_elements = control_elements =
GetUnownedAutofillableFormFieldElements(document.all(), nullptr); GetUnownedAutofillableFormFieldElements(document.all(), nullptr);
break;
} }
if (!found_synthetic_form) { if (!found_synthetic_form) {
// Find the real form by searching through the WebDocuments. // Find the real form by searching through the WebDocuments.
bool found_form = false; bool found_form = false;
WebFormElement form_element; WebFormElement form_element;
for (const auto& it : documents_to_synthetic_form_map_) { WebVector<WebFormElement> web_forms;
WebVector<WebFormElement> web_forms; frame_.document().forms(web_forms);
it.first.forms(web_forms);
for (size_t i = 0; i < web_forms.size(); ++i) {
for (size_t i = 0; i < web_forms.size(); ++i) { form_element = web_forms[i];
form_element = web_forms[i]; // Note: matching on the form name here which is not guaranteed to be
// unique for the page, nor is it guaranteed to be non-empty. Ideally,
// Note: matching on the form name here which is not guaranteed to be // we would have a way to uniquely identify the form cross-process. For
// unique for the page, nor is it guaranteed to be non-empty. Ideally, // now, we'll check form name and form action for identity.
// we would have a way to uniquely identify the form cross-process. For // Also note that WebString() == WebString(string16()) does not evaluate
// now, we'll check form name and form action for identity. // to |true| -- WebKit distinguishes between a "null" string (lhs) and
// Also note that WebString() == WebString(string16()) does not evaluate // an "empty" string (rhs). We don't want that distinction, so forcing
// to |true| -- WebKit distinguishes between a "null" string (lhs) and // to string16.
// an "empty" string (rhs). We don't want that distinction, so forcing base::string16 element_name = GetFormIdentifier(form_element);
// to string16. GURL action(form_element.document().completeURL(form_element.action()));
base::string16 element_name = GetFormIdentifier(form_element); if (element_name == form.data.name && action == form.data.action) {
GURL action(form_element.document().completeURL(form_element.action())); found_form = true;
if (element_name == form.data.name && action == form.data.action) { control_elements =
found_form = true; ExtractAutofillableElementsInForm(form_element, REQUIRE_NONE);
control_elements = break;
ExtractAutofillableElementsInForm(form_element, REQUIRE_NONE);
break;
}
} }
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <vector> #include <vector>
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/autofill/core/common/form_data.h"
namespace blink { namespace blink {
class WebDocument; class WebDocument;
...@@ -23,21 +24,20 @@ class WebSelectElement; ...@@ -23,21 +24,20 @@ class WebSelectElement;
namespace autofill { namespace autofill {
struct FormData;
struct FormDataPredictions; struct FormDataPredictions;
// Manages the forms in a RenderView. // Manages the forms in a single RenderFrame.
class FormCache { class FormCache {
public: public:
FormCache(); explicit FormCache(const blink::WebFrame& frame);
~FormCache(); ~FormCache();
// Scans the DOM in |frame| extracting and storing forms that have not been // Scans the DOM in |frame_| extracting and storing forms that have not been
// seen before. Returns the extracted forms. // seen before. Returns the extracted forms.
std::vector<FormData> ExtractNewForms(const blink::WebFrame& frame); std::vector<FormData> ExtractNewForms();
// Resets the forms for the specified |frame|. // Resets the forms.
void ResetFrame(const blink::WebFrame& frame); void Reset();
// Clears the values of all input elements in the form that contains // Clears the values of all input elements in the form that contains
// |element|. Returns false if the form is not found. // |element|. Returns false if the form is not found.
...@@ -58,13 +58,15 @@ class FormCache { ...@@ -58,13 +58,15 @@ class FormCache {
const std::vector<blink::WebFormControlElement>& control_elements, const std::vector<blink::WebFormControlElement>& control_elements,
bool log_deprecation_messages); bool log_deprecation_messages);
// The cached web frames and their corresponding synthetic FormData. // The frame this FormCache is associated with.
const blink::WebFrame& frame_;
// The cached forms. Used to prevent re-extraction of forms.
std::set<FormData> parsed_forms_;
// The synthetic FormData is for all the fieldsets in the document without a // The synthetic FormData is for all the fieldsets in the document without a
// form owner. // form owner.
std::map<blink::WebDocument, FormData> documents_to_synthetic_form_map_; FormData synthetic_form_;
// The cached forms per frame. Used to prevent re-extraction of forms.
std::map<const blink::WebFrame*, std::set<FormData> > parsed_forms_;
// The cached initial values for <select> elements. // The cached initial values for <select> elements.
std::map<const blink::WebSelectElement, base::string16> std::map<const blink::WebSelectElement, base::string16>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment