Commit a4519ce6 authored by Matthias Körber's avatar Matthias Körber Committed by Commit Bot

[Autofill][Leizig] Add parsing for house number fields.

Change-Id: Ied46d737413cfb5fcd1eae5995c2bea8c1be50d4
Bug: 978014, 1099202
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2282752
Auto-Submit: Matthias Körber <koerber@google.com>
Commit-Queue: Christoph Schwering <schwering@google.com>
Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Cr-Commit-Position: refs/heads/master@{#804899}
parent 6e66952e
...@@ -152,6 +152,8 @@ FormStructureBrowserTest::FormStructureBrowserTest() ...@@ -152,6 +152,8 @@ FormStructureBrowserTest::FormStructureBrowserTest()
{ {
// TODO(crbug.com/1098943): Remove once experiment is over. // TODO(crbug.com/1098943): Remove once experiment is over.
autofill::features::kAutofillEnableSupportForMoreStructureInNames, autofill::features::kAutofillEnableSupportForMoreStructureInNames,
// TODO(crbug.com/1125978): Remove once launched.
autofill::features::kAutofillEnableSupportForHouseNumbers,
}, },
// Disabled // Disabled
{autofill::features::kAutofillEnforceMinRequiredFieldsForHeuristics, {autofill::features::kAutofillEnforceMinRequiredFieldsForHeuristics,
......
...@@ -77,7 +77,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner, ...@@ -77,7 +77,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner,
MATCH_DEFAULT | MATCH_TEXT_AREA, nullptr, MATCH_DEFAULT | MATCH_TEXT_AREA, nullptr,
{log_manager, "kEmailRe"})) { {log_manager, "kEmailRe"})) {
continue; continue;
} else if (address_field->ParseAddressLines(scanner) || } else if (address_field->ParseAddress(scanner) ||
(!is_enabled_merged_city_state_country_zip && (!is_enabled_merged_city_state_country_zip &&
(address_field->ParseCityStateZipCode(scanner) || (address_field->ParseCityStateZipCode(scanner) ||
address_field->ParseCountry(scanner))) || address_field->ParseCountry(scanner))) ||
...@@ -133,17 +133,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner, ...@@ -133,17 +133,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner,
} }
AddressField::AddressField(LogManager* log_manager) AddressField::AddressField(LogManager* log_manager)
: log_manager_(log_manager), : log_manager_(log_manager) {}
company_(nullptr),
address1_(nullptr),
address2_(nullptr),
address3_(nullptr),
street_address_(nullptr),
city_(nullptr),
state_(nullptr),
zip_(nullptr),
zip4_(nullptr),
country_(nullptr) {}
void AddressField::AddClassifications( void AddressField::AddClassifications(
FieldCandidatesMap* field_candidates) const { FieldCandidatesMap* field_candidates) const {
...@@ -172,6 +162,10 @@ void AddressField::AddClassifications( ...@@ -172,6 +162,10 @@ void AddressField::AddClassifications(
field_candidates); field_candidates);
AddClassification(country_, ADDRESS_HOME_COUNTRY, kBaseAddressParserScore, AddClassification(country_, ADDRESS_HOME_COUNTRY, kBaseAddressParserScore,
field_candidates); field_candidates);
AddClassification(house_number_, ADDRESS_HOME_HOUSE_NUMBER,
kBaseAddressParserScore, field_candidates);
AddClassification(street_name_, ADDRESS_HOME_STREET_NAME,
kBaseAddressParserScore, field_candidates);
} }
bool AddressField::ParseCompany(AutofillScanner* scanner) { bool AddressField::ParseCompany(AutofillScanner* scanner) {
...@@ -182,6 +176,53 @@ bool AddressField::ParseCompany(AutofillScanner* scanner) { ...@@ -182,6 +176,53 @@ bool AddressField::ParseCompany(AutofillScanner* scanner) {
{log_manager_, "kCompanyRe"}); {log_manager_, "kCompanyRe"});
} }
bool AddressField::ParseAddressFieldSequence(AutofillScanner* scanner) {
// Search for a sequence of a street name field followed by a house number
// field. Only if both are found in an abitrary order, the parsing is
// considered successful.
// TODO(crbug.com/1125978): Remove once launched.
if (!base::FeatureList::IsEnabled(
features::kAutofillEnableSupportForHouseNumbers)) {
return false;
}
const size_t cursor_position = scanner->CursorPosition();
while (!scanner->IsEnd()) {
if (!street_name_ &&
ParseFieldSpecifics(scanner, UTF8ToUTF16(kStreetNameRe), MATCH_DEFAULT,
&street_name_, {log_manager_, "kStreetNameRe"})) {
continue;
}
if (!house_number_ &&
ParseFieldSpecifics(scanner, UTF8ToUTF16(kHouseNumberRe), MATCH_DEFAULT,
&house_number_, {log_manager_, "kHouseNumberRe"})) {
continue;
}
break;
}
if (street_name_ && house_number_)
return true;
// Reset both fields in case one of them was found.
if (street_name_ || house_number_) {
street_name_ = nullptr;
house_number_ = nullptr;
}
scanner->RewindTo(cursor_position);
return false;
}
bool AddressField::ParseAddress(AutofillScanner* scanner) {
if (street_name_ && house_number_) {
return false;
}
return ParseAddressFieldSequence(scanner) || ParseAddressLines(scanner);
}
bool AddressField::ParseAddressLines(AutofillScanner* scanner) { bool AddressField::ParseAddressLines(AutofillScanner* scanner) {
// We only match the string "address" in page text, not in element names, // We only match the string "address" in page text, not in element names,
// because sometimes every element in a group of address fields will have // because sometimes every element in a group of address fields will have
......
...@@ -53,6 +53,8 @@ class AddressField : public FormField { ...@@ -53,6 +53,8 @@ class AddressField : public FormField {
explicit AddressField(LogManager* log_manager); explicit AddressField(LogManager* log_manager);
bool ParseCompany(AutofillScanner* scanner); bool ParseCompany(AutofillScanner* scanner);
bool ParseAddress(AutofillScanner* scanner);
bool ParseAddressFieldSequence(AutofillScanner* scanner);
bool ParseAddressLines(AutofillScanner* scanner); bool ParseAddressLines(AutofillScanner* scanner);
bool ParseCountry(AutofillScanner* scanner); bool ParseCountry(AutofillScanner* scanner);
bool ParseZipCode(AutofillScanner* scanner); bool ParseZipCode(AutofillScanner* scanner);
...@@ -91,16 +93,18 @@ class AddressField : public FormField { ...@@ -91,16 +93,18 @@ class AddressField : public FormField {
ParseNameLabelResult ParseNameAndLabelForState(AutofillScanner* scanner); ParseNameLabelResult ParseNameAndLabelForState(AutofillScanner* scanner);
LogManager* log_manager_; LogManager* log_manager_;
AutofillField* company_; AutofillField* company_ = nullptr;
AutofillField* address1_; AutofillField* street_name_ = nullptr;
AutofillField* address2_; AutofillField* house_number_ = nullptr;
AutofillField* address3_; AutofillField* address1_ = nullptr;
AutofillField* street_address_; AutofillField* address2_ = nullptr;
AutofillField* city_; AutofillField* address3_ = nullptr;
AutofillField* state_; AutofillField* street_address_ = nullptr;
AutofillField* zip_; AutofillField* city_ = nullptr;
AutofillField* zip4_; // optional ZIP+4; we don't fill this yet. AutofillField* state_ = nullptr;
AutofillField* country_; AutofillField* zip_ = nullptr;
AutofillField* zip4_ = nullptr; // optional ZIP+4; we don't fill this yet.
AutofillField* country_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AddressField); DISALLOW_COPY_AND_ASSIGN(AddressField);
}; };
......
...@@ -59,6 +59,10 @@ size_t AutofillScanner::SaveCursor() { ...@@ -59,6 +59,10 @@ size_t AutofillScanner::SaveCursor() {
return static_cast<size_t>(cursor_ - begin_); return static_cast<size_t>(cursor_ - begin_);
} }
size_t AutofillScanner::CursorPosition() {
return static_cast<size_t>(cursor_ - begin_);
}
void AutofillScanner::Init(const std::vector<AutofillField*>& fields) { void AutofillScanner::Init(const std::vector<AutofillField*>& fields) {
cursor_ = fields.begin(); cursor_ = fields.begin();
saved_cursor_ = fields.begin(); saved_cursor_ = fields.begin();
......
...@@ -45,6 +45,9 @@ class AutofillScanner { ...@@ -45,6 +45,9 @@ class AutofillScanner {
// |RewindTo()|. // |RewindTo()|.
size_t SaveCursor(); size_t SaveCursor();
// Returns the current cursor position.
size_t CursorPosition();
private: private:
void Init(const std::vector<AutofillField*>& fields); void Init(const std::vector<AutofillField*>& fields);
......
...@@ -103,6 +103,11 @@ const base::Feature kAutofillEnableSupportForMergingSubsetNames{ ...@@ -103,6 +103,11 @@ const base::Feature kAutofillEnableSupportForMergingSubsetNames{
"AutofillEnableSupportForMergingSubsetNames", "AutofillEnableSupportForMergingSubsetNames",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
// Enables filling support for separate house number fields.
// TODO(crbug.com/1125978): Remove once launched.
const base::Feature kAutofillEnableSupportForHouseNumbers{
"AutofillEnableSupportForHouseNumbers", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether or not a minimum number of fields is required before // Controls whether or not a minimum number of fields is required before
// heuristic field type prediction is run for a form. // heuristic field type prediction is run for a form.
const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics{ const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics{
......
...@@ -36,6 +36,7 @@ extern const base::Feature kAutofillEnableCompanyName; ...@@ -36,6 +36,7 @@ extern const base::Feature kAutofillEnableCompanyName;
extern const base::Feature kAutofillEnableHideSuggestionsUI; extern const base::Feature kAutofillEnableHideSuggestionsUI;
extern const base::Feature kAutofillEnableSupportForMoreStructureInNames; extern const base::Feature kAutofillEnableSupportForMoreStructureInNames;
extern const base::Feature kAutofillEnableSupportForMergingSubsetNames; extern const base::Feature kAutofillEnableSupportForMergingSubsetNames;
extern const base::Feature kAutofillEnableSupportForHouseNumbers;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics; extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery; extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload; extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
......
...@@ -30,6 +30,11 @@ const char kCompanyRe[] = ...@@ -30,6 +30,11 @@ const char kCompanyRe[] =
"|单位|公司" // zh-CN "|单位|公司" // zh-CN
"|شرکت" // fa "|شرکت" // fa
"|회사|직장"; // ko-KR "|회사|직장"; // ko-KR
const char kStreetNameRe[] =
"stra(ss|ß)e" // de
"|street" // en
"|rua|avenida"; // br
const char kHouseNumberRe[] = "(house |^)number|(haus|^)nummer|^número$";
const char kAddressLine1Re[] = const char kAddressLine1Re[] =
"^address$|address[_-]?line(one)?|address1|addr1|street" "^address$|address[_-]?line(one)?|address1|addr1|street"
"|(?:shipping|billing)address$" "|(?:shipping|billing)address$"
......
...@@ -11,6 +11,8 @@ extern const char kAttentionIgnoredRe[]; ...@@ -11,6 +11,8 @@ extern const char kAttentionIgnoredRe[];
extern const char kRegionIgnoredRe[]; extern const char kRegionIgnoredRe[];
extern const char kAddressNameIgnoredRe[]; extern const char kAddressNameIgnoredRe[];
extern const char kCompanyRe[]; extern const char kCompanyRe[];
extern const char kHouseNumberRe[];
extern const char kStreetNameRe[];
extern const char kAddressLine1Re[]; extern const char kAddressLine1Re[];
extern const char kAddressLine1LabelRe[]; extern const char kAddressLine1LabelRe[];
extern const char kAddressLine2Re[]; extern const char kAddressLine2Re[];
......
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form id="delivery-details" method="POST">
<label id="customer-postcode-label" class="form-label" for="customer-postcode">Postleitzahl</label>
<input value="" placeholder="" id="customer-postcode" type="text" class="form-control" name="Customer.Postcode">
<label id="customer-street-name-label" for="customer-street-name" class="form-label">
Straßenname
</label>
<input class="form-control" value="" id="customer-street-name" type="text" name="Customer.Street" >
<label id="customer-street-no-label" for="customer-street-no" class="form-label">
Hausnummer
</label>
<input value="" id="customer-street-no" class="form-control" type="text" name="Customer.StreetNo" >
<input type="checkbox" id="at_remember-my-details" name="Customer.RememberMyDetails" value="true">
<label class="form-label checkbox" id="remember-my-details-label" for="at_remember-my-details">Filialauswahl merken</label>
</form>
</body>
</html>
ADDRESS_HOME_ZIP | Customer.Postcode | Postleitzahl | | Customer.Postcode_1-default
ADDRESS_HOME_STREET_NAME | Customer.Street | Straßenname | | Customer.Postcode_1-default
ADDRESS_HOME_HOUSE_NUMBER | Customer.StreetNo | Hausnummer | | Customer.Postcode_1-default
UNKNOWN_TYPE | Customer.RememberMyDetails | Filialauswahl merken | true | Customer.Postcode_1-default
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