Commit 0ddbd0a3 authored by Parastoo Geranmayeh's avatar Parastoo Geranmayeh Committed by Commit Bot

[Autofill] Reflected Synthetic Fields

Reflected synthetic fields:

Reflected synthetic fields are synthetic fields for which
if one changes the visibility of the corresponding hidden
select field in the source code, and select an option on
that, as a user would do, the change would be reflected
on the synthetic field.

Solution:

we can fill a reflected multiple field, by making an exception for
select fields. Previously, this exception was made for non-focusable
ones, meaning that a non-focusable select field would get autofilled,
even though it wasn’t visible. We need to broaden this exception to
include the fields with ‘role=presentation’. This will fix the problem.

Fixes:

chapters.indigo.com
www.newbalance.com


See: go/synthetic-fields for more on this issue.

Bug: 836949
Change-Id: Iefad5de1432e5c2a8a64c0ec9bf79a6db9f557b1
Reviewed-on: https://chromium-review.googlesource.com/1028721
Commit-Queue: Parastoo Geranmayeh <parastoog@google.com>
Reviewed-by: default avatarRoger McFarlane <rogerm@chromium.org>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554446}
parent 31f18f57
...@@ -1395,15 +1395,14 @@ void AutofillManager::FillOrPreviewDataModelForm( ...@@ -1395,15 +1395,14 @@ void AutofillManager::FillOrPreviewDataModelForm(
AutofillField* cached_field = form_structure->field(i); AutofillField* cached_field = form_structure->field(i);
FieldTypeGroup field_group_type = cached_field->Type().group(); FieldTypeGroup field_group_type = cached_field->Type().group();
// Don't fill non-focusable fields, with the exception of <select> fields. // Don't fill hidden fields, with the exception of <select> fields, for
if (!cached_field->is_focusable && // the sake of filling the synthetic fields.
if ((!cached_field->is_focusable ||
cached_field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION) &&
result.fields[i].form_control_type != "select-one") { result.fields[i].form_control_type != "select-one") {
continue; continue;
} }
if (cached_field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION)
continue;
// Don't fill previously autofilled fields except the initiating field or // Don't fill previously autofilled fields except the initiating field or
// when it's a refill. // when it's a refill.
if (result.fields[i].is_autofilled && !cached_field->SameFieldAs(field) && if (result.fields[i].is_autofilled && !cached_field->SameFieldAs(field) &&
......
...@@ -3613,6 +3613,73 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_HiddenFieldShouldNotCount) { ...@@ -3613,6 +3613,73 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_HiddenFieldShouldNotCount) {
} }
} }
// The hidden and the presentational fields should be filled, only if their
// control type is 'select-one'. This exception is made to support synthetic
// fields.
TEST_F(AutofillManagerTest, FormWithHiddenOrPresentationalSelects) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
form.origin = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First name", "firstname", "", "text", &field);
form.fields.push_back(field);
test::CreateTestFormField("Last name", "lastname", "", "text", &field);
form.fields.push_back(field);
{
const std::vector<const char*> values{"CA", "US", "BR"};
const std::vector<const char*> contents{"Canada", "United States",
"Banana Republic"};
test::CreateTestSelectField("Country", "country", "", values, contents,
values.size(), &field);
field.is_focusable = false;
form.fields.push_back(field);
}
{
const std::vector<const char*> values{"NY", "CA", "TN"};
const std::vector<const char*> contents{"New York", "California",
"Tennessee"};
test::CreateTestSelectField("State", "state", "", values, contents,
values.size(), &field);
field.role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
form.fields.push_back(field);
}
test::CreateTestFormField("City", "city", "", "text", &field);
field.is_focusable = false;
form.fields.push_back(field);
test::CreateTestFormField("Street Address", "address", "", "text", &field);
field.role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
form.fields.push_back(field);
std::vector<FormData> forms(1, form);
FormsSeen(forms);
const char guid[] = "00000000-0000-0000-0000-000000000001";
int response_page_id = 0;
FormData response_data;
FillAutofillFormDataAndSaveResults(kDefaultPageID, form, form.fields[0],
MakeFrontendID(std::string(), guid),
&response_page_id, &response_data);
ExpectFilledField("First name", "firstname", "Elvis", "text",
response_data.fields[0]);
ExpectFilledField("Last name", "lastname", "Presley", "text",
response_data.fields[1]);
ExpectFilledField("Country", "country", "US", "select-one",
response_data.fields[2]);
ExpectFilledField("State", "state", "TN", "select-one",
response_data.fields[3]);
ExpectFilledField("City", "city", "", "text", response_data.fields[4]);
ExpectFilledField("Street Address", "address", "", "text",
response_data.fields[5]);
}
TEST_F(AutofillManagerTest, TEST_F(AutofillManagerTest,
FillFirstPhoneNumber_MultipleSectionFilledCorrectly) { FillFirstPhoneNumber_MultipleSectionFilledCorrectly) {
AutofillProfile* work_profile = AutofillProfile* work_profile =
......
...@@ -48,10 +48,11 @@ FieldCandidatesMap FormField::ParseFormFields( ...@@ -48,10 +48,11 @@ FieldCandidatesMap FormField::ParseFormFields(
// Ignore checkable fields as they interfere with parsers assuming context. // Ignore checkable fields as they interfere with parsers assuming context.
// Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1 // Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1
// interferes with correctly understanding ADDRESS_LINE2. // interferes with correctly understanding ADDRESS_LINE2.
// Ignore fields marked as presentational. See // Ignore fields marked as presentational, unless for 'select' fields (for
// http://www.w3.org/TR/wai-aria/roles#presentation // synthetic fields.)
if (IsCheckable(field->check_status) || if (IsCheckable(field->check_status) ||
field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION) { (field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION &&
field->form_control_type != "select-one")) {
continue; continue;
} }
processed_fields.push_back(field.get()); processed_fields.push_back(field.get());
......
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