Commit c2818190 authored by Christoph Schwering's avatar Christoph Schwering Committed by Commit Bot

[Autofill] Migrated refill logic to renderer IDs.

This CL replaces the usage of the form's name (<form>'s name or id
attribute) and Autofill::unique_name() in the refill logic with
unique form renderer IDs, if the feature
AutofillRefillWithRendererIds.

Bug: 896689, 1114787
Change-Id: Ib21b838f9dc5f31ac30087e347d7e1b0171aff58
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2235600
Commit-Queue: Christoph Schwering <schwering@google.com>
Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Cr-Commit-Position: refs/heads/master@{#825311}
parent 91ade58a
...@@ -2905,8 +2905,23 @@ class AutofillDynamicFormInteractiveTest : public AutofillInteractiveTestBase { ...@@ -2905,8 +2905,23 @@ class AutofillDynamicFormInteractiveTest : public AutofillInteractiveTestBase {
} }
}; };
class AutofillDynamicFormReplacementInteractiveTest
: public AutofillInteractiveTestBase,
public testing::WithParamInterface<bool> {
public:
AutofillDynamicFormReplacementInteractiveTest()
: refill_with_renderer_ids_(GetParam()) {
scoped_feature_.InitWithFeatureState(
features::kAutofillRefillWithRendererIds, refill_with_renderer_ids_);
}
protected:
bool refill_with_renderer_ids_;
base::test::ScopedFeatureList scoped_feature_;
};
// Test that we can Autofill dynamically generated forms. // Test that we can Autofill dynamically generated forms.
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
DynamicChangingFormFill) { DynamicChangingFormFill) {
CreateTestProfile(); CreateTestProfile();
...@@ -2914,6 +2929,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -2914,6 +2929,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
embedded_test_server()->GetURL("a.com", "/autofill/dynamic_form.html"); embedded_test_server()->GetURL("a.com", "/autofill/dynamic_form.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
TriggerFormFill("firstname"); TriggerFormFill("firstname");
// Wait for the re-fill to happen. // Wait for the re-fill to happen.
...@@ -2932,7 +2953,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -2932,7 +2953,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
ExpectFieldValue("phone_form1", "15125551234"); ExpectFieldValue("phone_form1", "15125551234");
} }
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
TwoDynamicChangingFormsFill) { TwoDynamicChangingFormsFill) {
// Setup that the test expects a re-fill to happen. // Setup that the test expects a re-fill to happen.
test_delegate()->SetIsExpectingDynamicRefill(true); test_delegate()->SetIsExpectingDynamicRefill(true);
...@@ -2943,6 +2964,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -2943,6 +2964,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
"/autofill/two_dynamic_forms.html"); "/autofill/two_dynamic_forms.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
TriggerFormFill("firstname_form1"); TriggerFormFill("firstname_form1");
// Wait for the re-fill to happen. // Wait for the re-fill to happen.
...@@ -2979,7 +3006,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -2979,7 +3006,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
} }
// Test that forms that dynamically change a second time do not get filled. // Test that forms that dynamically change a second time do not get filled.
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
DynamicChangingFormFill_SecondChange) { DynamicChangingFormFill_SecondChange) {
CreateTestProfile(); CreateTestProfile();
...@@ -2987,6 +3014,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -2987,6 +3014,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
"a.com", "/autofill/double_dynamic_form.html"); "a.com", "/autofill/double_dynamic_form.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
TriggerFormFill("firstname"); TriggerFormFill("firstname");
// Wait for two dynamic changes to happen. // Wait for two dynamic changes to happen.
...@@ -3033,7 +3066,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3033,7 +3066,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
} }
// Test that only field of a type group that was filled initially get refilled. // Test that only field of a type group that was filled initially get refilled.
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
DynamicChangingFormFill_AddsNewFieldTypeGroups) { DynamicChangingFormFill_AddsNewFieldTypeGroups) {
CreateTestProfile(); CreateTestProfile();
...@@ -3041,6 +3074,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3041,6 +3074,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
"a.com", "/autofill/dynamic_form_new_field_types.html"); "a.com", "/autofill/dynamic_form_new_field_types.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
TriggerFormFill("firstname"); TriggerFormFill("firstname");
// Wait for the dynamic change to happen. // Wait for the dynamic change to happen.
...@@ -3294,7 +3333,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3294,7 +3333,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
} }
// Test that credit card fields are re-filled. // Test that credit card fields are re-filled.
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
DynamicChangingFormFill_AlsoForCreditCard) { DynamicChangingFormFill_AlsoForCreditCard) {
CreateTestCreditCart(); CreateTestCreditCart();
...@@ -3303,6 +3342,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3303,6 +3342,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
"/autofill/dynamic_form_credit_card.html"); "/autofill/dynamic_form_credit_card.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
// Trigger the initial fill. // Trigger the initial fill.
FocusFieldByName("cc-name"); FocusFieldByName("cc-name");
SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M,
...@@ -3383,7 +3428,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3383,7 +3428,7 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
// Test that we can Autofill dynamically generated forms with no name if the // Test that we can Autofill dynamically generated forms with no name if the
// NameForAutofill of the first field matches. // NameForAutofill of the first field matches.
IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, IN_PROC_BROWSER_TEST_P(AutofillDynamicFormReplacementInteractiveTest,
DynamicChangingFormFill_FormWithoutName) { DynamicChangingFormFill_FormWithoutName) {
CreateTestProfile(); CreateTestProfile();
...@@ -3391,6 +3436,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3391,6 +3436,12 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
"a.com", "/autofill/dynamic_form_no_name.html"); "a.com", "/autofill/dynamic_form_no_name.html");
ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url));
// TODO(crbug/896689): Cleanup feature, also in JS code.
if (refill_with_renderer_ids_) {
ASSERT_TRUE(content::ExecuteScript(
GetWebContents(), "window.kAutofillRefillWithRendererIds = true;"));
}
TriggerFormFill("firstname"); TriggerFormFill("firstname");
// Wait for the re-fill to happen. // Wait for the re-fill to happen.
...@@ -3495,6 +3546,10 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest, ...@@ -3495,6 +3546,10 @@ IN_PROC_BROWSER_TEST_F(AutofillDynamicFormInteractiveTest,
ExpectFieldValue("phone", "15125551234"); ExpectFieldValue("phone", "15125551234");
} }
INSTANTIATE_TEST_SUITE_P(All,
AutofillDynamicFormReplacementInteractiveTest,
testing::Bool());
INSTANTIATE_TEST_SUITE_P(All, INSTANTIATE_TEST_SUITE_P(All,
AutofillRestrictUnownedFieldsTest, AutofillRestrictUnownedFieldsTest,
testing::Bool()); testing::Bool());
......
...@@ -44,7 +44,9 @@ var notify_on_credit_card_name_input_appear = false; ...@@ -44,7 +44,9 @@ var notify_on_credit_card_name_input_appear = false;
function ExpChanged() { function ExpChanged() {
RemoveForm("cc1"); RemoveForm("cc1");
var new_form = document.createElement("form"); var new_form =
(window.kAutofillRefillWithRendererIds && document.getElementById('cc1')) ||
document.createElement('form');
new_form.setAttribute('method',"post"); new_form.setAttribute('method',"post");
//new_form.setAttribute('action',"https://example.com/") //new_form.setAttribute('action',"https://example.com/")
new_form.setAttribute('name',"cc1.1"); new_form.setAttribute('name',"cc1.1");
...@@ -119,4 +121,4 @@ function hasRefilled() { ...@@ -119,4 +121,4 @@ function hasRefilled() {
} }
} }
</script> </script>
\ No newline at end of file
...@@ -7,14 +7,18 @@ ...@@ -7,14 +7,18 @@
/** Removes the initial form. */ /** Removes the initial form. */
function RemoveForm(form_id) { function RemoveForm(form_id) {
var initial_form = document.getElementById(form_id); var initial_form = document.getElementById(form_id);
initial_form.parentNode.removeChild(initial_form);
initial_form.innerHTML = ''; initial_form.innerHTML = '';
initial_form.remove(); if (!window.kAutofillRefillWithRendererIds) {
initial_form.parentNode.removeChild(initial_form);
initial_form.remove();
}
} }
/** Adds a new form and fields for the dynamic form. */ /** Adds a new form and fields for the dynamic form. */
function AddNewFormAndFields(form_id, form_name) { function AddNewFormAndFields(form_id, form_name) {
var new_form = document.createElement('form'); var new_form = (window.kAutofillRefillWithRendererIds &&
document.getElementById(form_id)) ||
document.createElement('form');
new_form.setAttribute('method', 'post'); new_form.setAttribute('method', 'post');
new_form.setAttribute('action', 'https://example.com/') new_form.setAttribute('action', 'https://example.com/')
new_form.setAttribute('name', form_name); new_form.setAttribute('name', form_name);
...@@ -72,4 +76,4 @@ function AddNewFormAndFields(form_id, form_name) { ...@@ -72,4 +76,4 @@ function AddNewFormAndFields(form_id, form_name) {
new_form.appendChild(i); new_form.appendChild(i);
return new_form; return new_form;
} }
\ No newline at end of file
...@@ -451,7 +451,9 @@ AutofillManager::FillingContext::FillingContext( ...@@ -451,7 +451,9 @@ AutofillManager::FillingContext::FillingContext(
*optional_credit_card, *optional_credit_card,
optional_cvc ? *optional_cvc : base::string16())) optional_cvc ? *optional_cvc : base::string16()))
: base::nullopt), : base::nullopt),
filled_field_name(field.unique_name()), filled_field_renderer_id(field.unique_renderer_id),
filled_field_signature(field.GetFieldSignature()),
filled_field_unique_name(field.unique_name()),
original_fill_time(AutofillTickClock::NowTicks()) { original_fill_time(AutofillTickClock::NowTicks()) {
DCHECK(optional_profile || optional_credit_card); DCHECK(optional_profile || optional_credit_card);
DCHECK(optional_credit_card || !optional_cvc); DCHECK(optional_credit_card || !optional_cvc);
...@@ -1613,7 +1615,8 @@ void AutofillManager::Reset() { ...@@ -1613,7 +1615,8 @@ void AutofillManager::Reset() {
credit_card_action_ = AutofillDriver::FORM_DATA_ACTION_PREVIEW; credit_card_action_ = AutofillDriver::FORM_DATA_ACTION_PREVIEW;
initial_interaction_timestamp_ = TimeTicks(); initial_interaction_timestamp_ = TimeTicks();
external_delegate_->Reset(); external_delegate_->Reset();
filling_contexts_map_.clear(); filling_context_by_renderer_id_.clear();
filling_context_by_unique_name_.clear();
} }
AutofillManager::AutofillManager( AutofillManager::AutofillManager(
...@@ -1745,9 +1748,9 @@ void AutofillManager::FillOrPreviewDataModelForm( ...@@ -1745,9 +1748,9 @@ void AutofillManager::FillOrPreviewDataModelForm(
DCHECK_EQ(form_structure->field_count(), form.fields.size()); DCHECK_EQ(form_structure->field_count(), form.fields.size());
if (action == AutofillDriver::FORM_DATA_ACTION_FILL && !is_refill) { if (action == AutofillDriver::FORM_DATA_ACTION_FILL && !is_refill) {
filling_contexts_map_[form_structure->GetIdentifierForRefill()] = SetFillingContext(*form_structure, std::make_unique<FillingContext>(
std::make_unique<FillingContext>(*autofill_field, optional_profile, *autofill_field, optional_profile,
optional_credit_card, optional_cvc); optional_credit_card, optional_cvc));
} }
// Only record the types that are filled for an eventual refill if all the // Only record the types that are filled for an eventual refill if all the
...@@ -1756,11 +1759,7 @@ void AutofillManager::FillOrPreviewDataModelForm( ...@@ -1756,11 +1759,7 @@ void AutofillManager::FillOrPreviewDataModelForm(
// A form with the given name is already filled. // A form with the given name is already filled.
// A refill has not been attempted for that form yet. // A refill has not been attempted for that form yet.
// This fill is not a refill attempt. // This fill is not a refill attempt.
FillingContext* filling_context = nullptr; FillingContext* filling_context = GetFillingContext(*form_structure);
auto itr =
filling_contexts_map_.find(form_structure->GetIdentifierForRefill());
if (itr != filling_contexts_map_.end())
filling_context = itr->second.get();
bool could_attempt_refill = filling_context != nullptr && bool could_attempt_refill = filling_context != nullptr &&
!filling_context->attempted_refill && !is_refill; !filling_context->attempted_refill && !is_refill;
...@@ -2100,10 +2099,8 @@ void AutofillManager::OnFormsParsed(const std::vector<const FormData*>& forms, ...@@ -2100,10 +2099,8 @@ void AutofillManager::OnFormsParsed(const std::vector<const FormData*>& forms,
// been a refill attempt on that form yet, start the process of triggering a // been a refill attempt on that form yet, start the process of triggering a
// refill. // refill.
if (ShouldTriggerRefill(*form_structure)) { if (ShouldTriggerRefill(*form_structure)) {
auto itr = FillingContext* filling_context = GetFillingContext(*form_structure);
filling_contexts_map_.find(form_structure->GetIdentifierForRefill()); DCHECK(filling_context != nullptr);
DCHECK(itr != filling_contexts_map_.end());
FillingContext* filling_context = itr->second.get();
// If a timer for the refill was already running, it means the form // If a timer for the refill was already running, it means the form
// changed again. Stop the timer and start it again. // changed again. Stop the timer and start it again.
...@@ -2470,18 +2467,44 @@ void AutofillManager::FillFieldWithValue(AutofillField* autofill_field, ...@@ -2470,18 +2467,44 @@ void AutofillManager::FillFieldWithValue(AutofillField* autofill_field,
} }
} }
// TODO(crbug/896689): Remove code duplication once experiment is finished.
void AutofillManager::SetFillingContext(
const FormStructure& form,
std::unique_ptr<FillingContext> context) {
if (base::FeatureList::IsEnabled(features::kAutofillRefillWithRendererIds)) {
filling_context_by_renderer_id_[form.unique_renderer_id()] =
std::move(context);
} else {
filling_context_by_unique_name_[form.GetIdentifierForRefill()] =
std::move(context);
}
}
// TODO(crbug/896689): Remove code duplication once experiment is finished.
AutofillManager::FillingContext* AutofillManager::GetFillingContext(
const FormStructure& form) {
if (base::FeatureList::IsEnabled(features::kAutofillRefillWithRendererIds)) {
auto it = filling_context_by_renderer_id_.find(form.unique_renderer_id());
return it != filling_context_by_renderer_id_.end() ? it->second.get()
: nullptr;
} else {
auto it =
filling_context_by_unique_name_.find(form.GetIdentifierForRefill());
return it != filling_context_by_unique_name_.end() ? it->second.get()
: nullptr;
}
}
bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) { bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
// Should not refill if a form with the same name has not been filled // Should not refill if a form with the same FormRendererId has not been
// before. // filled before.
auto itr = FillingContext* filling_context = GetFillingContext(form_structure);
filling_contexts_map_.find(form_structure.GetIdentifierForRefill()); if (filling_context == nullptr)
if (itr == filling_contexts_map_.end())
return false; return false;
address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_, address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_,
form_structure); form_structure);
FillingContext* filling_context = itr->second.get();
base::TimeTicks now = AutofillTickClock::NowTicks(); base::TimeTicks now = AutofillTickClock::NowTicks();
base::TimeDelta delta = now - filling_context->original_fill_time; base::TimeDelta delta = now - filling_context->original_fill_time;
...@@ -2505,16 +2528,14 @@ void AutofillManager::TriggerRefill(const FormData& form) { ...@@ -2505,16 +2528,14 @@ void AutofillManager::TriggerRefill(const FormData& form) {
address_form_event_logger_->OnDidRefill(sync_state_, *form_structure); address_form_event_logger_->OnDidRefill(sync_state_, *form_structure);
auto itr = FillingContext* filling_context = GetFillingContext(*form_structure);
filling_contexts_map_.find(form_structure->GetIdentifierForRefill());
// Since GetIdentifierForRefill() is not stable across dynamic changes, // Since GetIdentifierForRefill() is not stable across dynamic changes,
// |filling_contexts_map_| may not contain the element anymore. // |filling_context_by_unique_name_| may not contain the element anymore.
if (itr == filling_contexts_map_.end()) // TODO(crbug/896689): Can be replaced with DCHECK once experiment is over.
if (filling_context == nullptr)
return; return;
FillingContext* filling_context = itr->second.get();
// The refill attempt can happen from different paths, some of which happen // The refill attempt can happen from different paths, some of which happen
// after waiting for a while. Therefore, although this condition has been // after waiting for a while. Therefore, although this condition has been
// checked prior to calling TriggerRefill, it may not hold, when we get // checked prior to calling TriggerRefill, it may not hold, when we get
...@@ -2525,14 +2546,44 @@ void AutofillManager::TriggerRefill(const FormData& form) { ...@@ -2525,14 +2546,44 @@ void AutofillManager::TriggerRefill(const FormData& form) {
filling_context->attempted_refill = true; filling_context->attempted_refill = true;
// Try to find the field from which the original field originated. // Try to find the field from which the original field originated.
// Precedence is given to look up by |filled_field_renderer_id|.
// If that is unsuccessful, look up is done by |filled_field_signature|.
// TODO(crbug/896689): Clean up after feature launch.
AutofillField* autofill_field = nullptr; AutofillField* autofill_field = nullptr;
for (const std::unique_ptr<AutofillField>& field : *form_structure) { for (const std::unique_ptr<AutofillField>& field : *form_structure) {
if (field->unique_name() == filling_context->filled_field_name) { // TODO(crbug/896689): Clean up once experiment is over.
if ((base::FeatureList::IsEnabled(
features::kAutofillRefillWithRendererIds) &&
field->unique_renderer_id ==
filling_context->filled_field_renderer_id) ||
(!base::FeatureList::IsEnabled(
features::kAutofillRefillWithRendererIds) &&
field->unique_name() == filling_context->filled_field_unique_name)) {
autofill_field = field.get(); autofill_field = field.get();
break; break;
} }
} }
// If the field was deleted, look for one with a matching signature. Prefer
// visible and newer fields over invisible or older ones.
if (base::FeatureList::IsEnabled(features::kAutofillRefillWithRendererIds) &&
autofill_field == nullptr) {
auto is_better = [](const AutofillField& f, const AutofillField& g) {
return std::forward_as_tuple(f.IsVisible(),
f.unique_renderer_id.value()) >
std::forward_as_tuple(g.IsVisible(), g.unique_renderer_id.value());
};
for (const std::unique_ptr<AutofillField>& field : *form_structure) {
if (field->GetFieldSignature() ==
filling_context->filled_field_signature) {
if (autofill_field == nullptr || is_better(*field, *autofill_field)) {
autofill_field = field.get();
}
}
}
}
// If it was not found cancel the refill. // If it was not found cancel the refill.
if (!autofill_field) if (!autofill_field)
return; return;
......
...@@ -409,8 +409,12 @@ class AutofillManager : public AutofillHandler, ...@@ -409,8 +409,12 @@ class AutofillManager : public AutofillHandler,
// empty. // empty.
const base::Optional<AutofillProfile> profile; const base::Optional<AutofillProfile> profile;
const base::Optional<std::pair<CreditCard, base::string16>> credit_card; const base::Optional<std::pair<CreditCard, base::string16>> credit_card;
// The name of the field that was initially filled. // Possible identifiers of the field that was focused when the form was
const base::string16 filled_field_name; // initially filled. A refill shall be triggered from the same field.
// TODO(crbug/896689): Remove |filled_field_unique_name|.
const FieldRendererId filled_field_renderer_id;
const FieldSignature filled_field_signature;
const base::string16 filled_field_unique_name;
// The time at which the initial fill occurred. // The time at which the initial fill occurred.
const base::TimeTicks original_fill_time; const base::TimeTicks original_fill_time;
// The timer used to trigger a refill. // The timer used to trigger a refill.
...@@ -585,7 +589,14 @@ class AutofillManager : public AutofillHandler, ...@@ -585,7 +589,14 @@ class AutofillManager : public AutofillHandler,
uint32_t profile_form_bitmask, uint32_t profile_form_bitmask,
std::string* failure_to_fill); std::string* failure_to_fill);
// Whether there should be an attemps to refill the form. Returns true if all // TODO(crbug/896689): Remove code duplication once experiment is finished.
void SetFillingContext(const FormStructure& form,
std::unique_ptr<FillingContext> context);
// TODO(crbug/896689): Remove code duplication once experiment is finished.
FillingContext* GetFillingContext(const FormStructure& form);
// Whether there should be an attempts to refill the form. Returns true if all
// the following are satisfied: // the following are satisfied:
// There have been no refill on that page yet. // There have been no refill on that page yet.
// A non empty form name was recorded in a previous fill // A non empty form name was recorded in a previous fill
...@@ -621,6 +632,7 @@ class AutofillManager : public AutofillHandler, ...@@ -621,6 +632,7 @@ class AutofillManager : public AutofillHandler,
void SetDataList(const std::vector<base::string16>& values, void SetDataList(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels); const std::vector<base::string16>& labels);
AutofillClient* const client_; AutofillClient* const client_;
LogManager* log_manager_; LogManager* log_manager_;
...@@ -717,8 +729,11 @@ class AutofillManager : public AutofillHandler, ...@@ -717,8 +729,11 @@ class AutofillManager : public AutofillHandler,
// A map of form names to FillingContext instances used to make refill // A map of form names to FillingContext instances used to make refill
// attempts for dynamic forms. // attempts for dynamic forms.
// TODO(crbug/896689): Remove code duplication once experiment is finished.
std::map<FormRendererId, std::unique_ptr<FillingContext>>
filling_context_by_renderer_id_;
std::map<base::string16, std::unique_ptr<FillingContext>> std::map<base::string16, std::unique_ptr<FillingContext>>
filling_contexts_map_; filling_context_by_unique_name_;
// Tracks whether or not rich query encoding is enabled for this client. // Tracks whether or not rich query encoding is enabled for this client.
const bool is_rich_query_enabled_ = false; const bool is_rich_query_enabled_ = false;
......
...@@ -133,6 +133,12 @@ const base::Feature kAutofillExtractAllDatalists{ ...@@ -133,6 +133,12 @@ const base::Feature kAutofillExtractAllDatalists{
const base::Feature kAutofillFixFillableFieldTypes{ const base::Feature kAutofillFixFillableFieldTypes{
"AutofillFixFillableFieldTypes", base::FEATURE_DISABLED_BY_DEFAULT}; "AutofillFixFillableFieldTypes", base::FEATURE_DISABLED_BY_DEFAULT};
// When enabled, Autofill will use FormRendererIds instead of
// GetIdentifierForRefill() to identify forms during refills.
// TODO(crbug/896689): Remove once experiment is finished.
const base::Feature kAutofillRefillWithRendererIds{
"AutofillRefillWithRendererIds", base::FEATURE_DISABLED_BY_DEFAULT};
// When enabled, Autofill will use FieldRendererIds instead of unique_names // When enabled, Autofill will use FieldRendererIds instead of unique_names
// to align forms in FormStructure::RetrieveFromCache(). // to align forms in FormStructure::RetrieveFromCache().
const base::Feature kAutofillRetrieveFromCacheWithRendererIds{ const base::Feature kAutofillRetrieveFromCacheWithRendererIds{
......
...@@ -41,6 +41,7 @@ extern const base::Feature kAutofillEnableSupportForMergingSubsetNames; ...@@ -41,6 +41,7 @@ extern const base::Feature kAutofillEnableSupportForMergingSubsetNames;
extern const base::Feature kAutofillEnableUIForHonorificPrefixesInSettings; extern const base::Feature kAutofillEnableUIForHonorificPrefixesInSettings;
extern const base::Feature kAutofillExtractAllDatalists; extern const base::Feature kAutofillExtractAllDatalists;
extern const base::Feature kAutofillFixFillableFieldTypes; extern const base::Feature kAutofillFixFillableFieldTypes;
extern const base::Feature kAutofillRefillWithRendererIds;
extern const base::Feature kAutofillRetrieveFromCacheWithRendererIds; extern const base::Feature kAutofillRetrieveFromCacheWithRendererIds;
extern const base::Feature kAutofillKeyboardAccessory; extern const base::Feature kAutofillKeyboardAccessory;
extern const base::Feature kAutofillLabelAffixRemoval; extern const base::Feature kAutofillLabelAffixRemoval;
......
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