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()
{
// TODO(crbug.com/1098943): Remove once experiment is over.
autofill::features::kAutofillEnableSupportForMoreStructureInNames,
// TODO(crbug.com/1125978): Remove once launched.
autofill::features::kAutofillEnableSupportForHouseNumbers,
},
// Disabled
{autofill::features::kAutofillEnforceMinRequiredFieldsForHeuristics,
......
......@@ -77,7 +77,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner,
MATCH_DEFAULT | MATCH_TEXT_AREA, nullptr,
{log_manager, "kEmailRe"})) {
continue;
} else if (address_field->ParseAddressLines(scanner) ||
} else if (address_field->ParseAddress(scanner) ||
(!is_enabled_merged_city_state_country_zip &&
(address_field->ParseCityStateZipCode(scanner) ||
address_field->ParseCountry(scanner))) ||
......@@ -133,17 +133,7 @@ std::unique_ptr<FormField> AddressField::Parse(AutofillScanner* scanner,
}
AddressField::AddressField(LogManager* 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) {}
: log_manager_(log_manager) {}
void AddressField::AddClassifications(
FieldCandidatesMap* field_candidates) const {
......@@ -172,6 +162,10 @@ void AddressField::AddClassifications(
field_candidates);
AddClassification(country_, ADDRESS_HOME_COUNTRY, kBaseAddressParserScore,
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) {
......@@ -182,6 +176,53 @@ bool AddressField::ParseCompany(AutofillScanner* scanner) {
{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) {
// 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
......
......@@ -53,6 +53,8 @@ class AddressField : public FormField {
explicit AddressField(LogManager* log_manager);
bool ParseCompany(AutofillScanner* scanner);
bool ParseAddress(AutofillScanner* scanner);
bool ParseAddressFieldSequence(AutofillScanner* scanner);
bool ParseAddressLines(AutofillScanner* scanner);
bool ParseCountry(AutofillScanner* scanner);
bool ParseZipCode(AutofillScanner* scanner);
......@@ -91,16 +93,18 @@ class AddressField : public FormField {
ParseNameLabelResult ParseNameAndLabelForState(AutofillScanner* scanner);
LogManager* log_manager_;
AutofillField* company_;
AutofillField* address1_;
AutofillField* address2_;
AutofillField* address3_;
AutofillField* street_address_;
AutofillField* city_;
AutofillField* state_;
AutofillField* zip_;
AutofillField* zip4_; // optional ZIP+4; we don't fill this yet.
AutofillField* country_;
AutofillField* company_ = nullptr;
AutofillField* street_name_ = nullptr;
AutofillField* house_number_ = nullptr;
AutofillField* address1_ = nullptr;
AutofillField* address2_ = nullptr;
AutofillField* address3_ = nullptr;
AutofillField* street_address_ = nullptr;
AutofillField* city_ = nullptr;
AutofillField* state_ = nullptr;
AutofillField* zip_ = nullptr;
AutofillField* zip4_ = nullptr; // optional ZIP+4; we don't fill this yet.
AutofillField* country_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AddressField);
};
......
......@@ -59,6 +59,10 @@ size_t AutofillScanner::SaveCursor() {
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) {
cursor_ = fields.begin();
saved_cursor_ = fields.begin();
......
......@@ -45,6 +45,9 @@ class AutofillScanner {
// |RewindTo()|.
size_t SaveCursor();
// Returns the current cursor position.
size_t CursorPosition();
private:
void Init(const std::vector<AutofillField*>& fields);
......
......@@ -103,6 +103,11 @@ const base::Feature kAutofillEnableSupportForMergingSubsetNames{
"AutofillEnableSupportForMergingSubsetNames",
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
// heuristic field type prediction is run for a form.
const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics{
......
......@@ -36,6 +36,7 @@ extern const base::Feature kAutofillEnableCompanyName;
extern const base::Feature kAutofillEnableHideSuggestionsUI;
extern const base::Feature kAutofillEnableSupportForMoreStructureInNames;
extern const base::Feature kAutofillEnableSupportForMergingSubsetNames;
extern const base::Feature kAutofillEnableSupportForHouseNumbers;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
......
......@@ -30,6 +30,11 @@ const char kCompanyRe[] =
"|单位|公司" // zh-CN
"|شرکت" // fa
"|회사|직장"; // 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[] =
"^address$|address[_-]?line(one)?|address1|addr1|street"
"|(?:shipping|billing)address$"
......
......@@ -11,6 +11,8 @@ extern const char kAttentionIgnoredRe[];
extern const char kRegionIgnoredRe[];
extern const char kAddressNameIgnoredRe[];
extern const char kCompanyRe[];
extern const char kHouseNumberRe[];
extern const char kStreetNameRe[];
extern const char kAddressLine1Re[];
extern const char kAddressLine1LabelRe[];
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