summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-05 22:01:04 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-05 22:01:04 +0000
commitb715f7fea3d0a39e36b860a62010b89f1d6a1b12 (patch)
tree77dd1a6217e35cf44eb3b9c7fbda62bb48640edf /chrome/renderer
parentde56fa14154a5b7f263b75e55763f01c64e2d35e (diff)
downloadchromium_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.cc62
-rw-r--r--chrome/renderer/form_manager.h12
-rw-r--r--chrome/renderer/form_manager_unittest.cc45
-rw-r--r--chrome/renderer/render_view.cc18
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));