Commit d9c02cf5 authored by Tao Bai's avatar Tao Bai Committed by Commit Bot

Aw Autofill: Pull coordinates in renderer.

Only pull the coordinates where the focused field's coordinates
already required, this change will not trigger any new layout, so
there is no performance regression.

Bug: 1064420
Change-Id: I67c3e5bbafcc4852b471b22a9d8d4edcb527187a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2125608Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Commit-Queue: Tao Bai <michaelbai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754670}
parent 672d8669
...@@ -223,9 +223,9 @@ void AutofillAgent::DidChangeScrollOffsetImpl( ...@@ -223,9 +223,9 @@ void AutofillAgent::DidChangeScrollOffsetImpl(
FormData form; FormData form;
FormFieldData field; FormFieldData field;
if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(), if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(),
&form, &field)) { form_util::EXTRACT_BOUNDS, &form,
GetAutofillDriver()->TextFieldDidScroll( &field)) {
form, field, render_frame()->ElementBoundsInWindow(element_)); GetAutofillDriver()->TextFieldDidScroll(form, field, field.bounds);
} }
// Ignore subsequent scroll offset changes. // Ignore subsequent scroll offset changes.
...@@ -272,9 +272,9 @@ void AutofillAgent::FocusedElementChanged(const WebElement& element) { ...@@ -272,9 +272,9 @@ void AutofillAgent::FocusedElementChanged(const WebElement& element) {
FormData form; FormData form;
FormFieldData field; FormFieldData field;
if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(), if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(),
&form, &field)) { form_util::EXTRACT_BOUNDS, &form,
GetAutofillDriver()->FocusOnFormField( &field)) {
form, field, render_frame()->ElementBoundsInWindow(element_)); GetAutofillDriver()->FocusOnFormField(form, field, field.bounds);
} }
} }
...@@ -353,10 +353,10 @@ void AutofillAgent::OnTextFieldDidChange(const WebInputElement& element) { ...@@ -353,10 +353,10 @@ void AutofillAgent::OnTextFieldDidChange(const WebInputElement& element) {
FormData form; FormData form;
FormFieldData field; FormFieldData field;
if (FindFormAndFieldForFormControlElement(element, field_data_manager_.get(), if (FindFormAndFieldForFormControlElement(element, field_data_manager_.get(),
&form, &field)) { form_util::EXTRACT_BOUNDS, &form,
GetAutofillDriver()->TextFieldDidChange( &field)) {
form, field, render_frame()->ElementBoundsInWindow(element), GetAutofillDriver()->TextFieldDidChange(form, field, field.bounds,
AutofillTickClock::NowTicks()); AutofillTickClock::NowTicks());
} }
} }
...@@ -773,11 +773,15 @@ void AutofillAgent::QueryAutofillSuggestions( ...@@ -773,11 +773,15 @@ void AutofillAgent::QueryAutofillSuggestions(
FormData form; FormData form;
FormFieldData field; FormFieldData field;
if (!FindFormAndFieldForFormControlElement(element, field_data_manager_.get(), if (!FindFormAndFieldForFormControlElement(element, field_data_manager_.get(),
&form, &field)) { form_util::EXTRACT_BOUNDS, &form,
&field)) {
// If we didn't find the cached form, at least let autocomplete have a shot // If we didn't find the cached form, at least let autocomplete have a shot
// at providing suggestions. // at providing suggestions.
WebFormControlElementToFormField(element, nullptr, form_util::EXTRACT_VALUE, WebFormControlElementToFormField(
&field); element, nullptr,
static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
form_util::EXTRACT_BOUNDS),
&field);
} }
if (is_secure_context_required_ && if (is_secure_context_required_ &&
...@@ -801,10 +805,9 @@ void AutofillAgent::QueryAutofillSuggestions( ...@@ -801,10 +805,9 @@ void AutofillAgent::QueryAutofillSuggestions(
is_popup_possibly_visible_ = true; is_popup_possibly_visible_ = true;
GetAutofillDriver()->SetDataList(data_list_values, data_list_labels); GetAutofillDriver()->SetDataList(data_list_values, data_list_labels);
GetAutofillDriver()->QueryFormFieldAutofill( GetAutofillDriver()->QueryFormFieldAutofill(autofill_query_id_, form, field,
autofill_query_id_, form, field, field.bounds,
render_frame()->ElementBoundsInWindow(element_), autoselect_first_suggestion);
autoselect_first_suggestion);
} }
void AutofillAgent::DoFillFieldWithValue(const base::string16& value, void AutofillAgent::DoFillFieldWithValue(const base::string16& value,
...@@ -1025,9 +1028,9 @@ void AutofillAgent::OnProvisionallySaveForm( ...@@ -1025,9 +1028,9 @@ void AutofillAgent::OnProvisionallySaveForm(
FormData form; FormData form;
FormFieldData field; FormFieldData field;
if (FindFormAndFieldForFormControlElement( if (FindFormAndFieldForFormControlElement(
element, field_data_manager_.get(), &form, &field)) { element, field_data_manager_.get(), form_util::EXTRACT_BOUNDS,
GetAutofillDriver()->SelectControlDidChange( &form, &field)) {
form, field, render_frame()->ElementBoundsInWindow(element)); GetAutofillDriver()->SelectControlDidChange(form, field, field.bounds);
} }
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/form_field_data.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/url_conversion.h" #include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/platform/web_vector.h"
...@@ -1749,6 +1750,14 @@ void WebFormControlElementToFormField( ...@@ -1749,6 +1750,14 @@ void WebFormControlElementToFormField(
&field->option_values, &field->option_values,
&field->option_contents); &field->option_contents);
} }
if (extract_mask & EXTRACT_BOUNDS) {
if (auto* local_frame = element.GetDocument().GetFrame()) {
if (auto* render_frame =
content::RenderFrame::FromWebFrame(local_frame)) {
field->bounds = render_frame->ElementBoundsInWindow(element);
}
}
}
if (!(extract_mask & EXTRACT_VALUE)) if (!(extract_mask & EXTRACT_VALUE))
return; return;
...@@ -1986,6 +1995,7 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData( ...@@ -1986,6 +1995,7 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData(
bool FindFormAndFieldForFormControlElement( bool FindFormAndFieldForFormControlElement(
const WebFormControlElement& element, const WebFormControlElement& element,
const FieldDataManager* field_data_manager, const FieldDataManager* field_data_manager,
ExtractMask extract_mask,
FormData* form, FormData* form,
FormFieldData* field) { FormFieldData* field) {
DCHECK(!element.IsNull()); DCHECK(!element.IsNull());
...@@ -1993,8 +2003,8 @@ bool FindFormAndFieldForFormControlElement( ...@@ -1993,8 +2003,8 @@ bool FindFormAndFieldForFormControlElement(
if (!IsAutofillableElement(element)) if (!IsAutofillableElement(element))
return false; return false;
ExtractMask extract_mask = extract_mask =
static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS | extract_mask);
const WebFormElement form_element = element.Form(); const WebFormElement form_element = element.Form();
if (form_element.IsNull()) { if (form_element.IsNull()) {
// No associated form, try the synthetic form for unowned form elements. // No associated form, try the synthetic form for unowned form elements.
...@@ -2011,6 +2021,15 @@ bool FindFormAndFieldForFormControlElement( ...@@ -2011,6 +2021,15 @@ bool FindFormAndFieldForFormControlElement(
extract_mask, form, field); extract_mask, form, field);
} }
bool FindFormAndFieldForFormControlElement(
const WebFormControlElement& element,
const FieldDataManager* field_data_manager,
FormData* form,
FormFieldData* field) {
return FindFormAndFieldForFormControlElement(
element, field_data_manager, form_util::EXTRACT_NONE, form, field);
}
void FillForm(const FormData& form, const WebFormControlElement& element) { void FillForm(const FormData& form, const WebFormControlElement& element) {
WebFormElement form_element = element.Form(); WebFormElement form_element = element.Form();
if (form_element.IsNull()) { if (form_element.IsNull()) {
......
...@@ -56,6 +56,8 @@ enum ExtractMask { ...@@ -56,6 +56,8 @@ enum ExtractMask {
// human readable value is captured. // human readable value is captured.
EXTRACT_OPTIONS = 1 << 2, // Extract options from EXTRACT_OPTIONS = 1 << 2, // Extract options from
// WebFormControlElement. // WebFormControlElement.
EXTRACT_BOUNDS = 1 << 3, // Extract bounds from WebFormControlElement,
// could trigger layout if needed.
}; };
// The maximum number of form fields we are willing to parse, due to // The maximum number of form fields we are willing to parse, due to
...@@ -214,7 +216,17 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData( ...@@ -214,7 +216,17 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData(
// Finds the form that contains |element| and returns it in |form|. If |field| // Finds the form that contains |element| and returns it in |form|. If |field|
// is non-NULL, fill it with the FormField representation for |element|. // is non-NULL, fill it with the FormField representation for |element|.
// Returns false if the form is not found or cannot be serialized. // |additional_extract_mask| control what to extract beside the default mask
// which is EXTRACT_VALUE | EXTRACT_OPTIONS. Returns false if the form is not
// found or cannot be serialized.
bool FindFormAndFieldForFormControlElement(
const blink::WebFormControlElement& element,
const FieldDataManager* field_data_manager,
ExtractMask additional_extract_mask,
FormData* form,
FormFieldData* field);
// Same as above but with default ExtractMask.
bool FindFormAndFieldForFormControlElement( bool FindFormAndFieldForFormControlElement(
const blink::WebFormControlElement& element, const blink::WebFormControlElement& element,
const FieldDataManager* field_data_manager, const FieldDataManager* field_data_manager,
......
...@@ -740,6 +740,45 @@ TEST_F(FormAutofillUtilsTest, IsActionEmptyTrue) { ...@@ -740,6 +740,45 @@ TEST_F(FormAutofillUtilsTest, IsActionEmptyTrue) {
EXPECT_TRUE(form_data.is_action_empty); EXPECT_TRUE(form_data.is_action_empty);
} }
TEST_F(FormAutofillUtilsTest, ExtractBounds) {
LoadHTML("<body><form id='form1'><input id='i1'></form></body>");
WebDocument doc = GetMainFrame()->GetDocument();
auto web_control = doc.GetElementById("i1").To<WebFormControlElement>();
FormData form_data;
ASSERT_TRUE(FindFormAndFieldForFormControlElement(
web_control, nullptr /*field_data_manager*/, EXTRACT_BOUNDS, &form_data,
nullptr /* FormFieldData */));
EXPECT_FALSE(form_data.fields.back().bounds.IsEmpty());
}
TEST_F(FormAutofillUtilsTest, NotExtractBounds) {
LoadHTML("<body><form id='form1'><input id='i1'></form></body>");
WebDocument doc = GetMainFrame()->GetDocument();
auto web_control = doc.GetElementById("i1").To<WebFormControlElement>();
FormData form_data;
ASSERT_TRUE(FindFormAndFieldForFormControlElement(
web_control, nullptr /*field_data_manager*/, &form_data,
nullptr /* FormFieldData */));
EXPECT_TRUE(form_data.fields.back().bounds.IsEmpty());
}
TEST_F(FormAutofillUtilsTest, ExtractUnownedBounds) {
LoadHTML("<body><input id='i1'></body>");
WebDocument doc = GetMainFrame()->GetDocument();
auto web_control = doc.GetElementById("i1").To<WebFormControlElement>();
FormData form_data;
ASSERT_TRUE(FindFormAndFieldForFormControlElement(
web_control, nullptr /*field_data_manager*/, EXTRACT_BOUNDS, &form_data,
nullptr /* FormFieldData */));
EXPECT_FALSE(form_data.fields.back().bounds.IsEmpty());
}
} // namespace } // namespace
} // namespace form_util } // namespace form_util
} // namespace autofill } // namespace autofill
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