diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 22:01:04 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 22:01:04 +0000 |
commit | b715f7fea3d0a39e36b860a62010b89f1d6a1b12 (patch) | |
tree | 77dd1a6217e35cf44eb3b9c7fbda62bb48640edf /chrome/renderer | |
parent | de56fa14154a5b7f263b75e55763f01c64e2d35e (diff) | |
download | chromium_src-b715f7fea3d0a39e36b860a62010b89f1d6a1b12.zip chromium_src-b715f7fea3d0a39e36b860a62010b89f1d6a1b12.tar.gz chromium_src-b715f7fea3d0a39e36b860a62010b89f1d6a1b12.tar.bz2 |
AutoFill: Implement WebFormElementToFormData and use this to send form data to
the AutoFillManager. Don't check field labels for equality until we parse
labels again.
BUG=40297
TEST=FormManagerTest.WebFormElementToFormData
Review URL: http://codereview.chromium.org/1609007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43657 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/form_manager.cc | 62 | ||||
-rw-r--r-- | chrome/renderer/form_manager.h | 12 | ||||
-rw-r--r-- | chrome/renderer/form_manager_unittest.cc | 45 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 18 |
4 files changed, 126 insertions, 11 deletions
diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc index 7063e97..3d313b6 100644 --- a/chrome/renderer/form_manager.cc +++ b/chrome/renderer/form_manager.cc @@ -67,11 +67,11 @@ void FormManager::WebFormControlElementToFormField( // TODO(jhawkins): In WebKit, move value() and setValue() to // WebFormControlElement. string16 value; - if (element.formControlType() == ASCIIToUTF16("text")) { + if (element.formControlType() == WebString::fromUTF8("text")) { const WebInputElement& input_element = element.toConstElement<WebInputElement>(); value = input_element.value(); - } else if (element.formControlType() == ASCIIToUTF16("select-one")) { + } else if (element.formControlType() == WebString::fromUTF8("select-one")) { // TODO(jhawkins): This is ugly. WebSelectElement::value() is a non-const // method. Look into fixing this on the WebKit side. WebFormControlElement& e = const_cast<WebFormControlElement&>(element); @@ -81,6 +81,53 @@ void FormManager::WebFormControlElementToFormField( field->set_value(value); } +// static +bool FormManager::WebFormElementToFormData(const WebFormElement& element, + RequirementsMask requirements, + FormData* form) { + DCHECK(form); + + const WebFrame* frame = element.frame(); + if (!frame) + return false; + + if (requirements & REQUIRE_AUTOCOMPLETE && !element.autoComplete()) + return false; + + form->name = element.name(); + form->method = element.method(); + form->origin = frame->url(); + form->action = frame->completeURL(element.action()); + + // If the completed URL is not valid, just use the action we get from + // WebKit. + if (!form->action.is_valid()) + form->action = GURL(element.action()); + + WebVector<WebFormControlElement> control_elements; + element.getFormControlElements(control_elements); + for (size_t i = 0; i < control_elements.size(); ++i) { + const WebFormControlElement& control_element = control_elements[i]; + + if (requirements & REQUIRE_AUTOCOMPLETE && + control_element.formControlType() == WebString::fromUTF8("text")) { + const WebInputElement& input_element = + control_element.toConstElement<WebInputElement>(); + if (!input_element.autoComplete()) + continue; + } + + if (requirements & REQUIRE_ELEMENTS_ENABLED && !control_element.isEnabled()) + continue; + + FormField field; + WebFormControlElementToFormField(control_element, &field); + form->fields.push_back(field); + } + + return !form->fields.empty(); +} + void FormManager::ExtractForms(const WebFrame* frame) { DCHECK(frame); @@ -253,13 +300,14 @@ bool FormManager::FillForm(const FormData& form) { DCHECK_EQ(form.fields[i].name(), iter->second.nameForAutofill()); if (!form.fields[i].value().empty() && - iter->second.formControlType() != ASCIIToUTF16("submit")) { - if (iter->second.formControlType() == ASCIIToUTF16("text")) { + iter->second.formControlType() != WebString::fromUTF8("submit")) { + if (iter->second.formControlType() == WebString::fromUTF8("text")) { WebInputElement input_element = iter->second.toElement<WebInputElement>(); input_element.setValue(form.fields[i].value()); input_element.setAutofilled(true); - } else if (iter->second.formControlType() == ASCIIToUTF16("select-one")) { + } else if (iter->second.formControlType() == + WebString::fromUTF8("select-one")) { WebSelectElement select_element = iter->second.toElement<WebSelectElement>(); select_element.setValue(form.fields[i].value()); @@ -292,7 +340,7 @@ bool FormManager::FormElementToFormData(const WebFrame* frame, form->origin = frame->url(); form->action = frame->completeURL(form_element->form_element.action()); - // If the completed ULR is not valid, just use the action we get from + // If the completed URL is not valid, just use the action we get from // WebKit. if (!form->action.is_valid()) form->action = GURL(form_element->form_element.action()); @@ -304,7 +352,7 @@ bool FormManager::FormElementToFormData(const WebFrame* frame, WebFormControlElement control_element = element_iter->second; if (requirements & REQUIRE_AUTOCOMPLETE && - control_element.formControlType() == ASCIIToUTF16("text")) { + control_element.formControlType() == WebString::fromUTF8("text")) { const WebInputElement& input_element = control_element.toConstElement<WebInputElement>(); if (!input_element.autoComplete()) diff --git a/chrome/renderer/form_manager.h b/chrome/renderer/form_manager.h index 28b2d8d..a410294 100644 --- a/chrome/renderer/form_manager.h +++ b/chrome/renderer/form_manager.h @@ -34,11 +34,21 @@ class FormManager { FormManager(); virtual ~FormManager(); - // Creates a FormField object from a given WebFormControlElement. + // Fills out a FormField object from a given WebFormControlElement. static void WebFormControlElementToFormField( const WebKit::WebFormControlElement& element, webkit_glue::FormField* field); + // Fills out a FormData object from a given WebFormElement. Returns true if + // |form| is filled out; it's possible that |element| won't meet the + // requirements in |requirements|. This also returns false if there are no + // fields in |form|. + // TODO(jhawkins): Remove the user of this in RenderView and move this to + // private. + static bool WebFormElementToFormData(const WebKit::WebFormElement& element, + RequirementsMask requirements, + webkit_glue::FormData* form); + // Scans the DOM in |frame| extracting and storing forms. void ExtractForms(const WebKit::WebFrame* frame); diff --git a/chrome/renderer/form_manager_unittest.cc b/chrome/renderer/form_manager_unittest.cc index feda04d..4b6b05a 100644 --- a/chrome/renderer/form_manager_unittest.cc +++ b/chrome/renderer/form_manager_unittest.cc @@ -7,14 +7,18 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFormElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "webkit/glue/form_data.h" using WebKit::WebElement; +using WebKit::WebFormElement; using WebKit::WebFrame; using WebKit::WebInputElement; using WebKit::WebString; +using WebKit::WebVector; using webkit_glue::FormData; using webkit_glue::FormField; @@ -23,6 +27,47 @@ namespace { typedef RenderViewTest FormManagerTest; +TEST_F(FormManagerTest, WebFormElementToFormData) { + LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" + " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" + " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>" + " <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>" + "</FORM>"); + + WebFrame* frame = GetMainFrame(); + ASSERT_NE(static_cast<WebFrame*>(NULL), frame); + + WebVector<WebFormElement> forms; + frame->forms(forms); + ASSERT_EQ(1U, forms.size()); + + FormData form; + EXPECT_TRUE(FormManager::WebFormElementToFormData(forms[0], + FormManager::REQUIRE_NONE, + &form)); + EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); + EXPECT_EQ(GURL(frame->url()), form.origin); + EXPECT_EQ(GURL("http://cnn.com"), form.action); + + const std::vector<FormField>& fields = form.fields; + ASSERT_EQ(3U, fields.size()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("firstname"), + ASCIIToUTF16("John"), + ASCIIToUTF16("text")), + fields[0]); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("lastname"), + ASCIIToUTF16("Smith"), + ASCIIToUTF16("text")), + fields[1]); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("reply-send"), + ASCIIToUTF16("Send"), + ASCIIToUTF16("submit")), + fields[2]); +} + TEST_F(FormManagerTest, ExtractForms) { LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 3aba9a3..0527889 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2322,7 +2322,7 @@ void RenderView::willSubmitForm(WebFrame* frame, const WebFormElement& form) { PasswordFormDomManager::CreatePasswordForm(form)); FormData form_data; - if (form_manager_.FindForm( + if (FormManager::WebFormElementToFormData( form, FormManager::REQUIRE_AUTOCOMPLETE, &form_data)) Send(new ViewHostMsg_FormSubmitted(routing_id_, form_data)); } @@ -4648,12 +4648,24 @@ void RenderView::focusAccessibilityObject( } void RenderView::SendForms(WebFrame* frame) { + // TODO(jhawkins): Use FormManager once we have strict ordering of form + // control elements in the cache. + WebVector<WebFormElement> web_forms; + frame->forms(web_forms); + std::vector<FormData> forms; - FormManager::RequirementsMask requirements = + for (size_t i = 0; i < web_forms.size(); ++i) { + const WebFormElement& web_form = web_forms[i]; + + FormData form; + FormManager::RequirementsMask requirements = static_cast<FormManager::RequirementsMask>( FormManager::REQUIRE_AUTOCOMPLETE | FormManager::REQUIRE_ELEMENTS_ENABLED); - form_manager_.GetFormsInFrame(frame, requirements, &forms); + if (FormManager::WebFormElementToFormData( + web_form, requirements, &form)) + forms.push_back(form); + } if (!forms.empty()) Send(new ViewHostMsg_FormsSeen(routing_id_, forms)); |