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(
FormData form;
FormFieldData field;
if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(),
&form, &field)) {
GetAutofillDriver()->TextFieldDidScroll(
form, field, render_frame()->ElementBoundsInWindow(element_));
form_util::EXTRACT_BOUNDS, &form,
&field)) {
GetAutofillDriver()->TextFieldDidScroll(form, field, field.bounds);
}
// Ignore subsequent scroll offset changes.
......@@ -272,9 +272,9 @@ void AutofillAgent::FocusedElementChanged(const WebElement& element) {
FormData form;
FormFieldData field;
if (FindFormAndFieldForFormControlElement(element_, field_data_manager_.get(),
&form, &field)) {
GetAutofillDriver()->FocusOnFormField(
form, field, render_frame()->ElementBoundsInWindow(element_));
form_util::EXTRACT_BOUNDS, &form,
&field)) {
GetAutofillDriver()->FocusOnFormField(form, field, field.bounds);
}
}
......@@ -353,10 +353,10 @@ void AutofillAgent::OnTextFieldDidChange(const WebInputElement& element) {
FormData form;
FormFieldData field;
if (FindFormAndFieldForFormControlElement(element, field_data_manager_.get(),
&form, &field)) {
GetAutofillDriver()->TextFieldDidChange(
form, field, render_frame()->ElementBoundsInWindow(element),
AutofillTickClock::NowTicks());
form_util::EXTRACT_BOUNDS, &form,
&field)) {
GetAutofillDriver()->TextFieldDidChange(form, field, field.bounds,
AutofillTickClock::NowTicks());
}
}
......@@ -773,11 +773,15 @@ void AutofillAgent::QueryAutofillSuggestions(
FormData form;
FormFieldData field;
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
// at providing suggestions.
WebFormControlElementToFormField(element, nullptr, form_util::EXTRACT_VALUE,
&field);
WebFormControlElementToFormField(
element, nullptr,
static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
form_util::EXTRACT_BOUNDS),
&field);
}
if (is_secure_context_required_ &&
......@@ -801,10 +805,9 @@ void AutofillAgent::QueryAutofillSuggestions(
is_popup_possibly_visible_ = true;
GetAutofillDriver()->SetDataList(data_list_values, data_list_labels);
GetAutofillDriver()->QueryFormFieldAutofill(
autofill_query_id_, form, field,
render_frame()->ElementBoundsInWindow(element_),
autoselect_first_suggestion);
GetAutofillDriver()->QueryFormFieldAutofill(autofill_query_id_, form, field,
field.bounds,
autoselect_first_suggestion);
}
void AutofillAgent::DoFillFieldWithValue(const base::string16& value,
......@@ -1025,9 +1028,9 @@ void AutofillAgent::OnProvisionallySaveForm(
FormData form;
FormFieldData field;
if (FindFormAndFieldForFormControlElement(
element, field_data_manager_.get(), &form, &field)) {
GetAutofillDriver()->SelectControlDidChange(
form, field, render_frame()->ElementBoundsInWindow(element));
element, field_data_manager_.get(), form_util::EXTRACT_BOUNDS,
&form, &field)) {
GetAutofillDriver()->SelectControlDidChange(form, field, field.bounds);
}
}
}
......
......@@ -33,6 +33,7 @@
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/form_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/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
......@@ -1749,6 +1750,14 @@ void WebFormControlElementToFormField(
&field->option_values,
&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))
return;
......@@ -1986,6 +1995,7 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData(
bool FindFormAndFieldForFormControlElement(
const WebFormControlElement& element,
const FieldDataManager* field_data_manager,
ExtractMask extract_mask,
FormData* form,
FormFieldData* field) {
DCHECK(!element.IsNull());
......@@ -1993,8 +2003,8 @@ bool FindFormAndFieldForFormControlElement(
if (!IsAutofillableElement(element))
return false;
ExtractMask extract_mask =
static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
extract_mask =
static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS | extract_mask);
const WebFormElement form_element = element.Form();
if (form_element.IsNull()) {
// No associated form, try the synthetic form for unowned form elements.
......@@ -2011,6 +2021,15 @@ bool FindFormAndFieldForFormControlElement(
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) {
WebFormElement form_element = element.Form();
if (form_element.IsNull()) {
......
......@@ -56,6 +56,8 @@ enum ExtractMask {
// human readable value is captured.
EXTRACT_OPTIONS = 1 << 2, // Extract options from
// 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
......@@ -214,7 +216,17 @@ bool UnownedPasswordFormElementsAndFieldSetsToFormData(
// Finds the form that contains |element| and returns it in |form|. If |field|
// 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(
const blink::WebFormControlElement& element,
const FieldDataManager* field_data_manager,
......
......@@ -740,6 +740,45 @@ TEST_F(FormAutofillUtilsTest, IsActionEmptyTrue) {
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 form_util
} // 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