Index: components/autofill/core/browser/address_field.cc |
diff --git a/components/autofill/core/browser/address_field.cc b/components/autofill/core/browser/address_field.cc |
index 23644cd7f82e1973aeb4b927be387ef91ea0776e..ed598758c27120040f4dce9c935c73bd146be980 100644 |
--- a/components/autofill/core/browser/address_field.cc |
+++ b/components/autofill/core/browser/address_field.cc |
@@ -20,6 +20,29 @@ using base::UTF8ToUTF16; |
namespace autofill { |
+namespace { |
+ |
+bool SetFieldAndAdvanceCursor(AutofillScanner* scanner, AutofillField** field) { |
+ *field = scanner->Cursor(); |
+ scanner->Advance(); |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+// Some sites use type="tel" for zip fields (to get a numerical input). |
+// http://crbug.com/426958 |
+// static |
Evan Stade
2015/03/24 00:04:32
don't think the // static notation is useful for c
Lei Zhang
2015/03/25 00:42:28
Done.
|
+const int AddressField::kZipCodeMatchType = |
+ MATCH_DEFAULT | MATCH_TELEPHONE | MATCH_NUMBER; |
+ |
+// Select fields are allowed here. This occurs on top-100 site rediff.com. |
+// static |
+const int AddressField::kCityMatchType = MATCH_DEFAULT | MATCH_SELECT; |
+ |
+// static |
+const int AddressField::kStateMatchType = MATCH_DEFAULT | MATCH_SELECT; |
+ |
scoped_ptr<FormField> AddressField::Parse(AutofillScanner* scanner) { |
if (scanner->IsEnd()) |
return NULL; |
@@ -37,9 +60,7 @@ scoped_ptr<FormField> AddressField::Parse(AutofillScanner* scanner) { |
while (!scanner->IsEnd()) { |
const size_t cursor = scanner->SaveCursor(); |
if (address_field->ParseAddressLines(scanner) || |
- address_field->ParseCity(scanner) || |
- address_field->ParseState(scanner) || |
- address_field->ParseZipCode(scanner) || |
+ address_field->ParseCityStateZipCode(scanner) || |
address_field->ParseCountry(scanner) || |
address_field->ParseCompany(scanner)) { |
has_trailing_non_labeled_fields = false; |
@@ -221,21 +242,16 @@ bool AddressField::ParseZipCode(AutofillScanner* scanner) { |
if (zip_) |
return false; |
- // Some sites use type="tel" for zip fields (to get a numerical input). |
- // http://crbug.com/426958 |
if (!ParseFieldSpecifics(scanner, |
UTF8ToUTF16(kZipCodeRe), |
- MATCH_DEFAULT | MATCH_TELEPHONE, |
+ kZipCodeMatchType, |
&zip_)) { |
return false; |
} |
// Look for a zip+4, whose field name will also often contain |
// the substring "zip". |
- ParseFieldSpecifics(scanner, |
- UTF8ToUTF16(kZip4Re), |
- MATCH_DEFAULT | MATCH_TELEPHONE, |
- &zip4_); |
+ ParseFieldSpecifics(scanner, UTF8ToUTF16(kZip4Re), kZipCodeMatchType, &zip4_); |
return true; |
} |
@@ -245,10 +261,9 @@ bool AddressField::ParseCity(AutofillScanner* scanner) { |
if (city_) |
return false; |
- // Select fields are allowed here. This occurs on top-100 site rediff.com. |
return ParseFieldSpecifics(scanner, |
UTF8ToUTF16(kCityRe), |
- MATCH_DEFAULT | MATCH_SELECT, |
+ kCityMatchType, |
&city_); |
} |
@@ -258,8 +273,118 @@ bool AddressField::ParseState(AutofillScanner* scanner) { |
return ParseFieldSpecifics(scanner, |
UTF8ToUTF16(kStateRe), |
- MATCH_DEFAULT | MATCH_SELECT, |
+ kStateMatchType, |
&state_); |
} |
+bool AddressField::ParseCityStateZipCode(AutofillScanner* scanner) { |
+ // Simple cases. |
+ if (scanner->IsEnd()) |
+ return false; |
+ if (city_ && state_ && zip_) |
+ return false; |
+ if (state_ && zip_) |
+ return ParseCity(scanner); |
+ if (city_ && zip_) |
+ return ParseState(scanner); |
+ if (city_ && state_) |
+ return ParseZipCode(scanner); |
+ |
+ // Check for name + label matches. |
Evan Stade
2015/03/24 00:04:32
nit: "Check for matches to both name and label."
Lei Zhang
2015/03/25 00:42:28
Done.
|
+ ParseNameLabelResult city_result = ParseNameAndLabelForCity(scanner); |
+ if (city_result == RESULT_MATCH_NAME_LABEL) |
+ return true; |
+ ParseNameLabelResult state_result = ParseNameAndLabelForState(scanner); |
+ if (state_result == RESULT_MATCH_NAME_LABEL) |
+ return true; |
+ ParseNameLabelResult zip_result = ParseNameAndLabelForZipCode(scanner); |
+ if (zip_result == RESULT_MATCH_NAME_LABEL) |
+ return true; |
+ |
+ // Check if there is only one potential match. |
+ bool maybe_city = (city_result != RESULT_MATCH_NONE); |
Evan Stade
2015/03/24 00:04:32
nit: remove excess parens
Lei Zhang
2015/03/25 00:42:28
Done.
|
+ bool maybe_state = (state_result != RESULT_MATCH_NONE); |
+ bool maybe_zip = (zip_result != RESULT_MATCH_NONE); |
+ if (maybe_city && !maybe_state && !maybe_zip) |
+ return SetFieldAndAdvanceCursor(scanner, &city_); |
+ if (maybe_state && !maybe_city && !maybe_zip) |
+ return SetFieldAndAdvanceCursor(scanner, &state_); |
+ if (maybe_zip && !maybe_city && !maybe_state) |
+ return ParseZipCode(scanner); |
+ |
+ // Otherwise give name priority over label. |
+ if (city_result == RESULT_MATCH_NAME) |
+ return SetFieldAndAdvanceCursor(scanner, &city_); |
+ if (state_result == RESULT_MATCH_NAME) |
+ return SetFieldAndAdvanceCursor(scanner, &state_); |
+ if (zip_result == RESULT_MATCH_NAME) |
+ return ParseZipCode(scanner); |
+ |
+ if (city_result == RESULT_MATCH_LABEL) |
+ return SetFieldAndAdvanceCursor(scanner, &city_); |
+ if (state_result == RESULT_MATCH_LABEL) |
+ return SetFieldAndAdvanceCursor(scanner, &state_); |
+ if (zip_result == RESULT_MATCH_LABEL) |
+ return ParseZipCode(scanner); |
+ |
+ return false; |
+} |
+ |
+AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForZipCode( |
+ AutofillScanner* scanner) { |
+ // Parse a zip code. On some UK pages (e.g. The China Shop2.html) this |
+ // is called a "post code". |
+ if (zip_) |
+ return RESULT_MATCH_NONE; |
+ |
+ ParseNameLabelResult result = ParseNameAndLabelSeparately( |
+ scanner, UTF8ToUTF16(kZipCodeRe), kZipCodeMatchType, &zip_); |
+ |
+ if (result != RESULT_MATCH_NAME_LABEL || scanner->IsEnd()) |
+ return result; |
+ |
+ size_t saved_cursor = scanner->SaveCursor(); |
+ bool found_non_zip4 = ParseCity(scanner); |
+ if (found_non_zip4) |
+ city_ = nullptr; |
+ scanner->RewindTo(saved_cursor); |
+ if (!found_non_zip4) { |
+ found_non_zip4 = ParseState(scanner); |
+ if (found_non_zip4) |
+ state_ = nullptr; |
+ scanner->RewindTo(saved_cursor); |
+ } |
+ |
+ if (!found_non_zip4) { |
+ // Look for a zip+4, whose field name will also often contain |
+ // the substring "zip". |
+ ParseFieldSpecifics(scanner, |
+ UTF8ToUTF16(kZip4Re), |
+ kZipCodeMatchType, |
+ &zip4_); |
+ } |
+ return result; |
+} |
+ |
+AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForCity( |
+ AutofillScanner* scanner) { |
+ // Parse a city name. Some UK pages (e.g. The China Shop2.html) use |
Evan Stade
2015/03/24 00:04:32
I dunno where this comment belongs, but not here
Lei Zhang
2015/03/25 00:42:28
That's because it started it out as a copy + paste
|
+ // the term "town". |
+ if (city_) |
+ return RESULT_MATCH_NONE; |
+ |
+ // Select fields are allowed here. This occurs on top-100 site rediff.com. |
Evan Stade
2015/03/24 00:04:32
repeated comment
Lei Zhang
2015/03/25 00:42:28
deleted
|
+ return ParseNameAndLabelSeparately( |
+ scanner, UTF8ToUTF16(kCityRe), kCityMatchType, &city_); |
+} |
+ |
+AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForState( |
+ AutofillScanner* scanner) { |
+ if (state_) |
+ return RESULT_MATCH_NONE; |
+ |
+ return ParseNameAndLabelSeparately( |
+ scanner, UTF8ToUTF16(kStateRe), kStateMatchType, &state_); |
+} |
+ |
} // namespace autofill |