diff options
-rw-r--r-- | chrome/browser/autofill/name_field.cc | 20 | ||||
-rw-r--r-- | chrome/browser/autofill/name_field_unittest.cc | 52 | ||||
-rw-r--r-- | chrome/renderer/form_manager.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/form_manager_unittest.cc | 43 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 10 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 4 | ||||
-rw-r--r-- | chrome/renderer/translate_helper.cc | 3 |
7 files changed, 128 insertions, 15 deletions
diff --git a/chrome/browser/autofill/name_field.cc b/chrome/browser/autofill/name_field.cc index e04b4c3..7d87030 100644 --- a/chrome/browser/autofill/name_field.cc +++ b/chrome/browser/autofill/name_field.cc @@ -74,9 +74,9 @@ FirstLastNameField* FirstLastNameField::Parse2( // so we match "initials" here (and just fill in a first name there, // American-style). // The ".*first$" matches fields ending in "first" (example in sample8.html). - if (!ParseText(&q, - ASCIIToUTF16("first name|firstname|initials|fname|.*first$"), - &v.first_name_)) + string16 match = + ASCIIToUTF16("first name|first_name|firstname|initials|fname|.*first$"); + if (!ParseText(&q, match, &v.first_name_)) return NULL; // We check for a middle initial before checking for a middle name @@ -84,19 +84,17 @@ FirstLastNameField* FirstLastNameField::Parse2( // as both (the label text is "MI" and the element name is // "txtmiddlename"); such a field probably actually represents a // middle initial. - if (ParseText(&q, - ASCIIToUTF16("^mi$|middle initial|middleinitial|m.i."), - &v.middle_name_)) { + match = ASCIIToUTF16("^mi$|middle initial|middleinitial|m.i."); + if (ParseText(&q, match, &v.middle_name_)) { v.middle_initial_ = true; } else { - ParseText( - &q, ASCIIToUTF16("middle name|mname|middlename"), &v.middle_name_); + match = ASCIIToUTF16("middle name|mname|middlename"); + ParseText(&q, match, &v.middle_name_); } // The ".*last$" matches fields ending in "last" (example in sample8.html). - if (!ParseText(&q, - ASCIIToUTF16("last name|lastname|lname|surname|.*last$"), - &v.last_name_)) + match = ASCIIToUTF16("last name|last_name|lastname|lname|surname|.*last$"); + if (!ParseText(&q, match, &v.last_name_)) return NULL; *iter = q; diff --git a/chrome/browser/autofill/name_field_unittest.cc b/chrome/browser/autofill/name_field_unittest.cc index d338c83..f8a3d1c 100644 --- a/chrome/browser/autofill/name_field_unittest.cc +++ b/chrome/browser/autofill/name_field_unittest.cc @@ -95,4 +95,56 @@ TEST_F(NameFieldTest, FirstMiddleLast2) { EXPECT_EQ(NAME_LAST, field_type_map_[ASCIIToUTF16("name3")]); } +TEST_F(NameFieldTest, FirstLast) { + list_.push_back( + new AutoFillField(webkit_glue::FormField(string16(), + ASCIIToUTF16("first_name"), + string16(), + ASCIIToUTF16("text")), + ASCIIToUTF16("name1"))); + list_.push_back( + new AutoFillField(webkit_glue::FormField(string16(), + ASCIIToUTF16("last_name"), + string16(), + ASCIIToUTF16("text")), + ASCIIToUTF16("name2"))); + list_.push_back(NULL); + iter_ = list_.begin(); + field_.reset(NameField::Parse(&iter_, false)); + ASSERT_NE(static_cast<NameField*>(NULL), field_.get()); + ASSERT_TRUE(field_->GetFieldInfo(&field_type_map_)); + ASSERT_TRUE( + field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end()); + EXPECT_EQ(NAME_FIRST, field_type_map_[ASCIIToUTF16("name1")]); + ASSERT_TRUE( + field_type_map_.find(ASCIIToUTF16("name2")) != field_type_map_.end()); + EXPECT_EQ(NAME_LAST, field_type_map_[ASCIIToUTF16("name2")]); +} + +TEST_F(NameFieldTest, FirstLast2) { + list_.push_back( + new AutoFillField(webkit_glue::FormField(ASCIIToUTF16("Name"), + ASCIIToUTF16("first_name"), + string16(), + ASCIIToUTF16("text")), + ASCIIToUTF16("name1"))); + list_.push_back( + new AutoFillField(webkit_glue::FormField(ASCIIToUTF16("Name"), + ASCIIToUTF16("last_name"), + string16(), + ASCIIToUTF16("text")), + ASCIIToUTF16("name2"))); + list_.push_back(NULL); + iter_ = list_.begin(); + field_.reset(NameField::Parse(&iter_, false)); + ASSERT_NE(static_cast<NameField*>(NULL), field_.get()); + ASSERT_TRUE(field_->GetFieldInfo(&field_type_map_)); + ASSERT_TRUE( + field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end()); + EXPECT_EQ(NAME_FIRST, field_type_map_[ASCIIToUTF16("name1")]); + ASSERT_TRUE( + field_type_map_.find(ASCIIToUTF16("name2")) != field_type_map_.end()); + EXPECT_EQ(NAME_LAST, field_type_map_[ASCIIToUTF16("name2")]); +} + } // namespace diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc index 19ae004..59704d1 100644 --- a/chrome/renderer/form_manager.cc +++ b/chrome/renderer/form_manager.cc @@ -45,13 +45,16 @@ namespace { // it's not necessary. const size_t kRequiredAutoFillFields = 3; -// Returns the node value of the first child of |element| if the first child -// is text. This is faster alternative to |innerText()| for performance -// critical operations when the child structure of element is known. +// Returns the node value of the first offspring of |element| that is a text +// node. This is a faster alternative to |innerText()| for performance +// critical operations when the child structure of |element| is known. string16 GetChildText(const WebElement& element) { string16 element_text; WebNode child = element.firstChild(); - if (!child.isNull() && child.isTextNode()) { + // Find the text node. + while (!child.isNull() && !child.isTextNode()) + child = child.firstChild(); + if (!child.isNull()) { element_text = child.nodeValue(); TrimWhitespace(element_text, TRIM_ALL, &element_text); } diff --git a/chrome/renderer/form_manager_unittest.cc b/chrome/renderer/form_manager_unittest.cc index 15f548f..2f37362 100644 --- a/chrome/renderer/form_manager_unittest.cc +++ b/chrome/renderer/form_manager_unittest.cc @@ -466,6 +466,49 @@ TEST_F(FormManagerTest, Labels) { fields[2]); } +TEST_F(FormManagerTest, LabelsWithSpans) { + LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" + " <LABEL for=\"firstname\"><span>First name: </span></LABEL>" + " <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>" + " <LABEL for=\"lastname\"><span>Last name: </span></LABEL>" + " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>" + " <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>" + "</FORM>"); + + WebFrame* web_frame = GetMainFrame(); + ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame); + + FormManager form_manager; + form_manager.ExtractForms(web_frame); + + std::vector<FormData> forms; + form_manager.GetForms(FormManager::REQUIRE_NONE, &forms); + ASSERT_EQ(1U, forms.size()); + + const FormData& form = forms[0]; + EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); + EXPECT_EQ(GURL(web_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(ASCIIToUTF16("First name:"), + ASCIIToUTF16("firstname"), + ASCIIToUTF16("John"), + ASCIIToUTF16("text")), + fields[0]); + EXPECT_EQ(FormField(ASCIIToUTF16("Last name:"), + ASCIIToUTF16("lastname"), + ASCIIToUTF16("Smith"), + ASCIIToUTF16("text")), + fields[1]); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("reply-send"), + ASCIIToUTF16("Send"), + ASCIIToUTF16("submit")), + fields[2]); +} + // This test is different from FormManagerTest.Labels in that the label elements // for= attribute is set to the name of the form control element it is a label // for instead of the id of the form control element. This is invalid because diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index f744ce1..07eb0e6 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -4945,6 +4945,16 @@ bool RenderView::ScheduleFileChooser( return true; } +void RenderView::OnPageTranslated() { + WebFrame* frame = webview()->mainFrame(); + if (!frame) + return; + + // The page is translated, so try to extract the form data again. + form_manager_.ExtractForms(frame); + SendForms(frame); +} + WebKit::WebGeolocationService* RenderView::geolocationService() { if (!geolocation_dispatcher_.get()) geolocation_dispatcher_.reset(new GeolocationDispatcher(this)); diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index d8bb27a..5d55af9 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -515,6 +515,10 @@ class RenderView : public RenderWidget, bool ScheduleFileChooser(const ViewHostMsg_RunFileChooser_Params& params, WebKit::WebFileChooserCompletion* completion); + // Called when the translate helper has finished translating the page. We use + // this signal to re-scan the page for forms. + void OnPageTranslated(); + // The language code used when the page language is unknown. static const char* const kUnknownLanguageCode; diff --git a/chrome/renderer/translate_helper.cc b/chrome/renderer/translate_helper.cc index d6d8569..1fea5b7 100644 --- a/chrome/renderer/translate_helper.cc +++ b/chrome/renderer/translate_helper.cc @@ -196,6 +196,9 @@ void TranslateHelper::CheckTranslateStatus() { translation_pending_ = false; + // Notify the renderer we are done. + render_view_->OnPageTranslated(); + // Notify the browser we are done. render_view_->Send(new ViewHostMsg_PageTranslated( render_view_->routing_id(), render_view_->page_id(), |