Skip to content

Commit b609600

Browse files
author
Changwan Ryu
committed
[WebView Autofill] Post DidChangeScrollOffset outside PerformLayout
If LocalFrameView::PerformLayout() ends up calling LocalFrameView::ViewportSizeChanged(), then it may in turn call AutofillAgent::DidChangeScrollOffset(). However, FindFormAndFieldForFormControlElement() and ElementBoundsInWindow() requires that document life cycle to be mutatable (and thus not in the middle of perform layout). Therefore, posting a task to delay calling these functions outside PerformLayout(). Note that this uses a similar mechanism as FormTracker::TextFieldDidChange(). BUG=804886 Change-Id: Ibe6e6d9921185f075d16c6c955d45d17ad490fd5 Reviewed-on: https://chromium-review.googlesource.com/882664 Reviewed-by: Mathieu Perreault <mathp@chromium.org> Commit-Queue: Changwan Ryu <changwan@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#531528}(cherry picked from commit 9db32db) Reviewed-on: https://chromium-review.googlesource.com/884265 Reviewed-by: Changwan Ryu <changwan@chromium.org> Cr-Commit-Position: refs/branch-heads/3325@{#68} Cr-Branched-From: bc084a8-refs/heads/master@{#530369}
1 parent 9bdbe40 commit b609600

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

components/autofill/content/renderer/autofill_agent.cc

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -212,22 +212,36 @@ void AutofillAgent::DidFinishDocumentLoad() {
212212
}
213213

214214
void AutofillAgent::DidChangeScrollOffset() {
215-
if (!focus_requires_scroll_ && is_popup_possibly_visible_ &&
216-
element_.Focused()) {
217-
FormData form;
218-
FormFieldData field;
219-
if (form_util::FindFormAndFieldForFormControlElement(element_, &form,
220-
&field)) {
221-
GetAutofillDriver()->TextFieldDidScroll(
222-
form, field,
223-
render_frame()->GetRenderView()->ElementBoundsInWindow(element_));
224-
}
215+
if (!focus_requires_scroll_) {
216+
// Post a task here since scroll offset may change during layout.
217+
// (https://crbug.com/804886)
218+
weak_ptr_factory_.InvalidateWeakPtrs();
219+
base::SequencedTaskRunnerHandle::Get()->PostTask(
220+
FROM_HERE, base::BindOnce(&AutofillAgent::DidChangeScrollOffsetImpl,
221+
weak_ptr_factory_.GetWeakPtr(), element_));
222+
} else if (!IsKeyboardAccessoryEnabled()) {
223+
HidePopup();
225224
}
225+
}
226226

227-
if (IsKeyboardAccessoryEnabled())
227+
void AutofillAgent::DidChangeScrollOffsetImpl(
228+
const WebFormControlElement& element) {
229+
if (element != element_ || focus_requires_scroll_ ||
230+
!is_popup_possibly_visible_ || !element_.Focused())
228231
return;
229232

230-
HidePopup();
233+
FormData form;
234+
FormFieldData field;
235+
if (form_util::FindFormAndFieldForFormControlElement(element_, &form,
236+
&field)) {
237+
GetAutofillDriver()->TextFieldDidScroll(
238+
form, field,
239+
render_frame()->GetRenderView()->ElementBoundsInWindow(element_));
240+
}
241+
242+
// Ignore subsequent scroll offset changes.
243+
if (!IsKeyboardAccessoryEnabled())
244+
HidePopup();
231245
}
232246

233247
void AutofillAgent::FocusedNodeChanged(const WebNode& node) {

components/autofill/content/renderer/autofill_agent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class AutofillAgent : public content::RenderFrameObserver,
193193
FRIEND_TEST_ALL_PREFIXES(FormAutocompleteTest, CollectFormlessElements);
194194

195195
void OnTextFieldDidChange(const blink::WebInputElement& element);
196+
void DidChangeScrollOffsetImpl(const blink::WebFormControlElement& element);
196197

197198
// Shows the autofill suggestions for |element|. This call is asynchronous
198199
// and may or may not lead to the showing of a suggestion popup (no popup is

0 commit comments

Comments
 (0)