Commit f9893298 authored by Mariia Shvedchenko's avatar Mariia Shvedchenko Committed by Commit Bot

Reland "[Autofill] Returns all patterns that match given language and fieldtype."

This is a reland of f1b689af

Reland, since the CL was not the culprit for the builder failures.

Original change's description:
> [Autofill] Returns all patterns that match given language and fieldtype.
>
> This CL provides new structure MatchingPattern that replace using
> single regular expressions, but store more information about concret
> pattern. Also it contains splitted MatchType into MatchFieldTypes
> and MatchAttributes and sceleton of PatternProvider class.
>
>
> Change-Id: I5acebf12aafaca67ae87260b2c897bdf35a38bea
> Bug: 1121990
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2385282
> Reviewed-by: Christoph Schwering <schwering@google.com>
> Reviewed-by: Matthias Körber <koerber@google.com>
> Commit-Queue: Mariia Shvedchenko <mariiash@google.com>
> Cr-Commit-Position: refs/heads/master@{#806125}

Bug: 1121990
Change-Id: I18e615e2019894d1cda1b8b1dac95218ead4949a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2414068Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Commit-Queue: Mariia Shvedchenko <mariiash@google.com>
Cr-Commit-Position: refs/heads/master@{#807431}
parent 4734eac1
......@@ -129,6 +129,8 @@ static_library("browser") {
"form_data_importer.h",
"form_parsing/address_field.cc",
"form_parsing/address_field.h",
"form_parsing/autofill_parsing_utils.cc",
"form_parsing/autofill_parsing_utils.h",
"form_parsing/autofill_scanner.cc",
"form_parsing/autofill_scanner.h",
"form_parsing/credit_card_field.cc",
......@@ -187,6 +189,8 @@ static_library("browser") {
"metrics/form_event_logger_base.cc",
"metrics/form_event_logger_base.h",
"metrics/form_events.h",
"pattern_provider/pattern_provider.cc",
"pattern_provider/pattern_provider.h",
"payments/account_info_getter.h",
"payments/autofill_offer_manager.cc",
"payments/autofill_offer_manager.h",
......@@ -633,6 +637,7 @@ source_set("unit_tests") {
"logging/log_buffer_submitter_unittest.cc",
"logging/log_manager_unittest.cc",
"logging/log_router_unittest.cc",
"pattern_provider/pattern_provider_unittest.cc",
"payments/credit_card_access_manager_unittest.cc",
"payments/credit_card_cvc_authenticator_unittest.cc",
"payments/credit_card_save_manager_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
namespace autofill {
MatchingPattern::MatchingPattern() = default;
MatchingPattern::MatchingPattern(const MatchingPattern& mp) = default;
MatchingPattern& MatchingPattern::operator=(const MatchingPattern& mp) =
default;
MatchingPattern::~MatchingPattern() = default;
autofill::MatchingPattern GetCompanyPatternEn() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternEn";
m_p.positive_pattern = "company|business|organization|organisation";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "en";
return m_p;
}
autofill::MatchingPattern GetCompanyPatternDe() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternDe";
m_p.positive_pattern = "|(?<!con)firma|firmenname";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_LABEL | autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "de";
return m_p;
}
} // namespace autofill
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#include <string>
namespace autofill {
// A bit-field used for matching specific parts of a field in question.
// Attributes.
enum MatchAttributes {
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
MATCH_ATTRIBUTES_DEFAULT = MATCH_LABEL | MATCH_NAME,
};
// A bit-field used for matching specific parts of a field in question.
// Input types.
enum MatchFieldTypes {
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE | MATCH_SELECT |
MATCH_TEXT_AREA | MATCH_PASSWORD | MATCH_NUMBER |
MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_INPUTS_DEFAULT = MATCH_TEXT,
};
constexpr int MATCH_DEFAULT = MATCH_ATTRIBUTES_DEFAULT | MATCH_INPUTS_DEFAULT;
// Structure for a better organization of data and regular expressions
// for autofill regex_constants. In the future, to implement faster
// changes without global updates also for having a quick possibility
// to recognize incorrect matches.
struct MatchingPattern {
MatchingPattern();
MatchingPattern(const MatchingPattern& mp);
MatchingPattern& operator=(const MatchingPattern& mp);
~MatchingPattern();
std::string pattern_identifier;
std::string positive_pattern;
float positive_score = 1.1f;
std::string negative_pattern;
int match_field_attributes;
int match_field_input_types;
std::string language;
};
// Use these functions instead of storing "non standats type" constants that
// bots might complaining over.
MatchingPattern GetCompanyPatternEn();
MatchingPattern GetCompanyPatternDe();
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_PARSING_UTILS_H_
......@@ -159,10 +159,10 @@ bool FormField::ParseField(AutofillScanner* scanner,
return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match, logging);
}
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging) {
if (scanner->IsEnd())
......@@ -170,10 +170,25 @@ bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const AutofillField* field = scanner->Cursor();
if (!MatchesFormControlType(field->form_control_type, match_type))
if (!MatchesFormControlType(field->form_control_type,
match_field_input_types))
return false;
return MatchAndAdvance(scanner, pattern, match_type, match, logging);
return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_input_types, match, logging);
}
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return ParseFieldSpecifics(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
}
// static
......@@ -196,14 +211,15 @@ void FormField::AddClassification(const AutofillField* field,
candidates.AddFieldCandidate(type, score);
}
// static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging) {
AutofillField* field = scanner->Cursor();
if (FormField::Match(field, pattern, match_type, logging)) {
if (FormField::Match(field, pattern, match_field_attributes,
match_field_input_types, logging)) {
if (match)
*match = field;
scanner->Advance();
......@@ -213,22 +229,35 @@ bool FormField::MatchAndAdvance(AutofillScanner* scanner,
return false;
}
// static
// static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
}
bool FormField::Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging) {
bool found_match = false;
base::StringPiece match_type_string;
base::StringPiece16 value;
base::string16 match;
if ((match_type & FormField::MATCH_LABEL) &&
if ((match_field_attributes & MATCH_LABEL) &&
MatchesPattern(field->label, pattern, &match)) {
found_match = true;
match_type_string = "Match in label";
value = field->label;
} else if ((match_type & FormField::MATCH_NAME) &&
} else if ((match_field_attributes & MATCH_NAME) &&
MatchesPattern(field->parseable_name(), pattern, &match)) {
found_match = true;
match_type_string = "Match in name";
......@@ -251,6 +280,18 @@ bool FormField::Match(const AutofillField* field,
return found_match;
}
// static
bool FormField::Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return Match(field, pattern, match_field_attributes, match_field_types,
logging);
}
// static
void FormField::ParseFormFieldsPass(ParseFunction parse,
const std::vector<AutofillField*>& fields,
......
......@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/browser/form_parsing/field_candidates.h"
namespace autofill {
......@@ -45,29 +46,6 @@ class FormField {
LogManager* log_manager = nullptr);
protected:
// A bit-field used for matching specific parts of a field in question.
enum MatchType {
// Attributes.
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
// Input types.
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE |
MATCH_SELECT | MATCH_TEXT_AREA | MATCH_PASSWORD |
MATCH_NUMBER | MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_DEFAULT = MATCH_LABEL | MATCH_NAME | MATCH_TEXT,
};
// Initial values assigned to FieldCandidates by their corresponding parsers.
static const float kBaseEmailParserScore;
static const float kBasePhoneParserScore;
......@@ -99,6 +77,15 @@ class FormField {
AutofillField** match,
const RegExLogging& logging = {});
// The same as ParseFieldSpecifics but with splitted match_types into
// MatchAttributes and MatchFieldTypes.
static bool ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Attempts to parse a field with an empty label. Returns true
// on success and fills |match| with a pointer to the field.
static bool ParseEmptyLabel(AutofillScanner* scanner, AutofillField** match);
......@@ -139,13 +126,30 @@ class FormField {
AutofillField** match,
const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of |field|
// as specified in the |match_type| bit field (see |MatchType|).
// The same as MatchAndAdvance but with splitted match_types into
// MatchAttributes and MatchFieldTypes.
static bool MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of
// |field| as specified in the |match_type| bit field (see |MatchType|).
static bool Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
const RegExLogging& logging = {});
// The same as Match but with splitted match_types into MatchAttributes
// and MatchFieldTypes.
static bool Match(const AutofillField* field,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging = {});
// Perform a "pass" over the |fields| where each pass uses the supplied
// |parse| method to match content to a given field type.
// |fields| is both an input and an output parameter. Upon exit |fields|
......
......@@ -23,109 +23,91 @@ TEST(FormFieldTest, Match) {
AutofillField field;
// Empty strings match.
EXPECT_TRUE(
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
// Empty pattern matches non-empty string.
field.label = ASCIIToUTF16("a");
EXPECT_TRUE(
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
// Strictly empty pattern matches empty string.
field.label = base::string16();
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
// Strictly empty pattern does not match non-empty string.
field.label = ASCIIToUTF16("a");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
// Non-empty pattern doesn't match empty string.
field.label = base::string16();
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("a"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("a"), MATCH_LABEL));
// Beginning of line.
field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^head"), FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^tail"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail"), MATCH_LABEL));
// End of line.
field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("head$"), FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("tail$"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head$"), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail$"), MATCH_LABEL));
// Exact.
field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^head$"), FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^tail$"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head_tail$"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^head$"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail$"), MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^head_tail$"), MATCH_LABEL));
// Escaped dots.
field.label = ASCIIToUTF16("m.i.");
// Note: This pattern is misleading as the "." characters are wild cards.
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
field.label = ASCIIToUTF16("mXiX");
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
// Repetition.
field.label = ASCIIToUTF16("headtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headtail");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
// Alternation.
field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head|other"),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail|other"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head|other"), MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("tail|other"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"), MATCH_LABEL));
// Case sensitivity.
field.label = ASCIIToUTF16("xxxHeAd_tAiLxxx");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"), MATCH_LABEL));
// Word boundaries.
field.label = ASCIIToUTF16("contains word:");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("\\bword\\b"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("\\bword\\b"), MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"), MATCH_LABEL));
// Make sure the circumflex in 'crepe' is not treated as a word boundary.
field.label = base::UTF8ToUTF16("cr\xC3\xAApe");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"), MATCH_LABEL));
}
// Test that we ignore checkable elements.
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <algorithm>
#include <iostream>
#include <string>
#include "components/autofill/core/browser/autofill_type.h"
namespace autofill {
PatternProvider::PatternProvider(autofill::ServerFieldType type) {
autofill::MatchingPattern kCompanyPatternEn = autofill::GetCompanyPatternEn();
autofill::MatchingPattern kCompanyPatternDe = autofill::GetCompanyPatternDe();
patterns_[AutofillType(COMPANY_NAME).ToString()]["en"] = kCompanyPatternEn;
patterns_[AutofillType(COMPANY_NAME).ToString()]["de"] = kCompanyPatternDe;
}
PatternProvider::~PatternProvider() {
patterns_.clear();
}
autofill::MatchingPattern PatternProvider::GetSingleMatchPattern(
autofill::ServerFieldType type,
const std::string& page_language) {
base::StringPiece type_s = autofill::FieldTypeToStringPiece(type);
return patterns_[type_s.as_string()][page_language];
}
} // namespace autofill
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#include <string>
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
#include "third_party/re2/src/re2/re2.h"
namespace autofill {
class PatternProvider {
public:
PatternProvider();
PatternProvider(ServerFieldType type, const std::string& page_language);
explicit PatternProvider(ServerFieldType type);
~PatternProvider();
// Provides us with all patterns that can match our field type and page
// language.
const std::vector<MatchingPattern>& GetMatchPatterns(
ServerFieldType type,
const std::string& page_language);
const std::vector<MatchingPattern>& GetMatchPatterns(
const std::string& pattern_name,
const std::string& page_launguage);
// Provides us with all patterns that can match our field type.
const std::vector<MatchingPattern>& GetAllPatternsBaseOnType(
ServerFieldType type);
// Function that returns pattern that match our field type and page language.
MatchingPattern GetSingleMatchPattern(ServerFieldType type,
const std::string& page_language);
private:
// Func to sort the incoming map by score.
void SortPatternsByScore(std::vector<MatchingPattern>& patterns);
// Local map to store patterns keyed by field type and page language.
std::map<std::string, std::map<std::string, MatchingPattern>> patterns_;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <stddef.h>
#include <map>
#include <string>
#include <vector>
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
bool operator==(const MatchingPattern& mp1, const MatchingPattern& mp2) {
return (mp1.language == mp2.language &&
mp1.match_field_attributes == mp2.match_field_attributes &&
mp1.match_field_input_types == mp2.match_field_input_types &&
mp1.negative_pattern == mp2.negative_pattern &&
mp1.pattern_identifier == mp2.pattern_identifier &&
mp1.positive_pattern == mp2.positive_pattern &&
mp1.positive_score == mp2.positive_score);
}
TEST(AutofillPatternProvider, Single_Match) {
MatchingPattern kCompanyPatternEn = GetCompanyPatternEn();
MatchingPattern kCompanyPatternDe = GetCompanyPatternDe();
PatternProvider pattern_provider(COMPANY_NAME);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "en"),
kCompanyPatternEn);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "de"),
kCompanyPatternDe);
}
} // namespace autofill
\ No newline at end of file
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