Commit a489cbbf authored by isherman@chromium.org's avatar isherman@chromium.org

Allow word separators in a few more Autofill regexes.

This also fixes an issue where inferred sections were not being updated after server types were returned.

BUG=93595
TEST=browser_tests --gtest_filter=*DataDrivenHeuristics*16*


Review URL: http://codereview.chromium.org/7981047

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102251 0039d316-1c4b-4281-b951-d872f2087c98
parent f0debcc1
...@@ -122,7 +122,7 @@ const char kShippingDesignatorRe[] = "ship"; ...@@ -122,7 +122,7 @@ const char kShippingDesignatorRe[] = "ship";
// credit_card_field.cc // credit_card_field.cc
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
const char kNameOnCardRe[] = const char kNameOnCardRe[] =
"card.?holder|name.?on.?card|ccname|ccfullname|owner" "card.?holder|name.?on.?card|cc.?name|cc.?full.?name|owner"
"|karteninhaber" // de-DE "|karteninhaber" // de-DE
"|nombre.*tarjeta" // es "|nombre.*tarjeta" // es
"|nom.*carte" // fr-FR "|nom.*carte" // fr-FR
...@@ -134,7 +134,7 @@ const char kNameOnCardRe[] = ...@@ -134,7 +134,7 @@ const char kNameOnCardRe[] =
const char kNameOnCardContextualRe[] = const char kNameOnCardContextualRe[] =
"name"; "name";
const char kCardNumberRe[] = const char kCardNumberRe[] =
"card.?number|card.?#|card.?no|ccnum|acctnum" "card.?number|card.?#|card.?no|cc.?num|acct.?num"
"|nummer" // de-DE "|nummer" // de-DE
"|credito|numero|número" // es "|credito|numero|número" // es
"|numéro" // fr-FR "|numéro" // fr-FR
......
...@@ -279,9 +279,9 @@ void FormStructure::DetermineHeuristicTypes() { ...@@ -279,9 +279,9 @@ void FormStructure::DetermineHeuristicTypes() {
// First, try to detect field types based on the fields' |autocompletetype| // First, try to detect field types based on the fields' |autocompletetype|
// attributes. If there is at least one form field with this attribute, don't // attributes. If there is at least one form field with this attribute, don't
// try to apply other heuristics to match fields in this form. // try to apply other heuristics to match fields in this form.
bool found_sections; bool has_author_specified_sections;
ParseAutocompletetypeAttributes(&has_author_specified_types_, ParseAutocompletetypeAttributes(&has_author_specified_types_,
&found_sections); &has_author_specified_sections);
if (!has_author_specified_types_) { if (!has_author_specified_types_) {
FieldTypeMap field_type_map; FieldTypeMap field_type_map;
...@@ -295,21 +295,7 @@ void FormStructure::DetermineHeuristicTypes() { ...@@ -295,21 +295,7 @@ void FormStructure::DetermineHeuristicTypes() {
} }
UpdateAutofillCount(); UpdateAutofillCount();
IdentifySections(has_author_specified_sections);
if (!found_sections)
IdentifySections();
// Ensure that credit card and address fields are in separate sections.
// This simplifies the section-aware logic in autofill_manager.cc.
for (std::vector<AutofillField*>::iterator field = fields_->begin();
field != fields_->end(); ++field) {
AutofillType::FieldTypeGroup field_type_group =
AutofillType((*field)->type()).group();
if (field_type_group == AutofillType::CREDIT_CARD)
(*field)->set_section((*field)->section() + ASCIIToUTF16("-cc"));
else
(*field)->set_section((*field)->section() + ASCIIToUTF16("-default"));
}
} }
bool FormStructure::EncodeUploadRequest( bool FormStructure::EncodeUploadRequest(
...@@ -464,6 +450,7 @@ void FormStructure::ParseQueryResponse(const std::string& response_xml, ...@@ -464,6 +450,7 @@ void FormStructure::ParseQueryResponse(const std::string& response_xml,
} }
form->UpdateAutofillCount(); form->UpdateAutofillCount();
form->IdentifySections(false);
} }
AutofillMetrics::ServerQueryMetric metric; AutofillMetrics::ServerQueryMetric metric;
...@@ -923,50 +910,65 @@ void FormStructure::ParseAutocompletetypeAttributes(bool* found_attribute, ...@@ -923,50 +910,65 @@ void FormStructure::ParseAutocompletetypeAttributes(bool* found_attribute,
} }
} }
void FormStructure::IdentifySections() { void FormStructure::IdentifySections(bool has_author_specified_sections) {
if (fields_.empty()) if (fields_.empty())
return; return;
// Name sections after the first field in the section. if (!has_author_specified_sections) {
string16 current_section = fields_->front()->unique_name(); // Name sections after the first field in the section.
string16 current_section = fields_->front()->unique_name();
// Keep track of the types we've seen in this section.
std::set<AutofillFieldType> seen_types;
AutofillFieldType previous_type = UNKNOWN_TYPE;
for (std::vector<AutofillField*>::iterator field = fields_->begin();
field != fields_->end(); ++field) {
const AutofillFieldType current_type =
AutofillType::GetEquivalentFieldType((*field)->type());
bool already_saw_current_type = seen_types.count(current_type) > 0;
// Forms often ask for multiple phone numbers -- e.g. both a daytime and
// evening phone number. Our phone number detection is also generally a
// little off. Hence, ignore this field type as a signal here.
if (AutofillType(current_type).group() == AutofillType::PHONE_HOME)
already_saw_current_type = false;
// Some forms have adjacent fields of the same type. Two common examples:
// * Forms with two email fields, where the second is meant to "confirm"
// the first.
// * Forms with a <select> menu for states in some countries, and a
// freeform <input> field for states in other countries. (Usually,
// only one of these two will be visible for any given choice of
// country.)
// Generally, adjacent fields of the same type belong in the same logical
// section.
if (current_type == previous_type)
already_saw_current_type = false;
previous_type = current_type;
if (current_type != UNKNOWN_TYPE && already_saw_current_type) {
// We reached the end of a section, so start a new section.
seen_types.clear();
current_section = (*field)->unique_name();
}
// Keep track of the types we've seen in this section. seen_types.insert(current_type);
std::set<AutofillFieldType> seen_types; (*field)->set_section(current_section);
AutofillFieldType previous_type = UNKNOWN_TYPE; }
}
// Ensure that credit card and address fields are in separate sections.
// This simplifies the section-aware logic in autofill_manager.cc.
for (std::vector<AutofillField*>::iterator field = fields_->begin(); for (std::vector<AutofillField*>::iterator field = fields_->begin();
field != fields_->end(); ++field) { field != fields_->end(); ++field) {
const AutofillFieldType current_type = AutofillType::FieldTypeGroup field_type_group =
AutofillType::GetEquivalentFieldType((*field)->type()); AutofillType((*field)->type()).group();
if (field_type_group == AutofillType::CREDIT_CARD)
bool already_saw_current_type = seen_types.count(current_type) > 0; (*field)->set_section((*field)->section() + ASCIIToUTF16("-cc"));
else
// Forms often ask for multiple phone numbers -- e.g. both a daytime and (*field)->set_section((*field)->section() + ASCIIToUTF16("-default"));
// evening phone number. Our phone number detection is also generally a
// little off. Hence, ignore this field type as a signal here.
if (AutofillType(current_type).group() == AutofillType::PHONE_HOME)
already_saw_current_type = false;
// Some forms have adjacent fields of the same type. Two common examples:
// * Forms with two email fields, where the second is meant to "confirm"
// the first.
// * Forms with a <select> menu for states in some countries, and a
// freeform <input> field for states in other countries. (Usually, only
// one of these two will be visible for any given choice of country.)
// Generally, adjacent fields of the same type belong in the same logical
// section.
if (current_type == previous_type)
already_saw_current_type = false;
previous_type = current_type;
if (current_type != UNKNOWN_TYPE && already_saw_current_type) {
// We reached the end of a section, so start a new section.
seen_types.clear();
current_section = (*field)->unique_name();
}
seen_types.insert(current_type);
(*field)->set_section(current_section);
} }
} }
...@@ -173,8 +173,11 @@ class FormStructure { ...@@ -173,8 +173,11 @@ class FormStructure {
// Classifies each field in |fields_| into a logical section. // Classifies each field in |fields_| into a logical section.
// Sections are identified by the heuristic that a logical section should not // Sections are identified by the heuristic that a logical section should not
// include multiple fields of the same autofill type (with some exceptions, as // include multiple fields of the same autofill type (with some exceptions, as
// described in the implementation). // described in the implementation). Sections are furthermore distinguished
void IdentifySections(); // as either credit card or non-credit card sections.
// If |has_author_specified_sections| is true, only the second pass --
// distinguishing credit card sections from non-credit card ones -- is made.
void IdentifySections(bool has_author_specified_sections);
// The name of the form. // The name of the form.
string16 form_name_; string16 form_name_;
......
<!-- https://www.jbox.com/checkout/payment# -->
<form name="paymentForm" method="post" action="#" id="paymentForm">
<div id="errors"></div>
<fieldset id="paymentchoose">
<legend>Choose a payment method</legend>
<div>
<select id="paymentoption" accesskeyclass="element select medium" name="payment_method" onchange="changePayment()">
<option selected="selected">
Visa
</option>
<option>
Mastercard
</option>
<option>
American Express
</option>
<option>
Discover
</option>
<option>
Card on File (provide CVV2)
</option>
<option>
Check / Money Order
</option>
<option>
Gift Certificate / Credit
</option>
<option>
Western Union (we'll send instructions)
</option>
<option value="PayPal">
PayPal
</option>
<option value="Google Checkout">
Google Checkout
</option>
</select>
</div>
</fieldset>
<fieldset id="ccinput">
<legend>Credit Card Details</legend>
<div>
<input name="cc_number" class="element text medium" type="text" maxlength="255" value=""> <label for="address1"><b>Credit Card Number</b></label>
</div>
<div>
<input name="cc_name" class="element text medium" type="text" maxlength="60" value=""> <label for="address1">Name On Card | Ex: <i>Peter Payne</i></label>
</div>
<div class="left">
<span><input name="cc_exp" class="element text small" type="text" maxlength="255" value=""> <label for="cc_exp">Expiration date<br>
(MM/YY)</label></span>
</div>
<div>
<span><input name="cc_cvv2" class="element text small" type="text" maxlength="255" value=""> <label for="cc_cvv2">CVV2 / Security Code:</label></span>
</div>
</fieldset>
<fieldset>
<legend>If an item is not available:</legend> <select name="field_17">
<option value="Select an option...">
Select an option...
</option>
<option value="Cancel the item">
Cancel the item
</option>
<option value="Wait for all items to be available">
Wait for all items to be available
</option>
<option value="Split and send separately (additional fees apply)">
Split and send separately (additional fees apply)
</option>
</select>
</fieldset>
<fieldset>
<legend>Please confirm your age</legend> <input name="age" class="element text small" type="text" maxlength="255" value="">
</fieldset>
<fieldset>
<legend>Comment or Special Instructions (if any)</legend>
<textarea id="element_6" name="comments" class="element textarea small"></textarea>
</fieldset><input type="hidden" name="paymentForm" value="259215"> <input id="placeorder" class="button_text" type="submit" name="submit" value="Place Order">
</form>
UNKNOWN_TYPE | payment_method | | Visa
CREDIT_CARD_NUMBER | cc_number | |
CREDIT_CARD_NAME | cc_name | |
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | cc_exp | Expiration date (MM/YY) |
UNKNOWN_TYPE | cc_cvv2 | CVV2 / Security Code: |
UNKNOWN_TYPE | field_17 | | Select an option...
UNKNOWN_TYPE | age | |
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