blob: 31f24c75199792202293201a1675078d1f8d7809 [file] [log] [blame]
[email protected]f07e4442013-06-06 23:03:481// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]679f128f2010-07-22 22:57:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f07e4442013-06-06 23:03:485#include "components/autofill/content/renderer/autofill_agent.h"
[email protected]679f128f2010-07-22 22:57:446
avi4310d522015-12-25 19:37:597#include <stddef.h>
8
brettw9c68c512015-11-20 23:26:389#include <tuple>
10
rouslan6a3f8d92015-04-28 01:00:0111#include "base/auto_reset.h"
[email protected]a1cb57f2011-09-28 22:41:2912#include "base/bind.h"
[email protected]f920d6e2013-03-12 20:20:5013#include "base/command_line.h"
brettw94a2cc22015-07-01 19:26:5414#include "base/i18n/case_conversion.h"
skyostilb0daa012015-06-02 19:03:4815#include "base/location.h"
mathp4f6b0382016-04-12 20:41:1216#include "base/metrics/field_trial.h"
skyostilb0daa012015-06-02 19:03:4817#include "base/single_thread_task_runner.h"
mgiuca30f75882017-03-28 02:07:1918#include "base/strings/string_piece.h"
[email protected]1988e1c2013-02-28 20:27:4219#include "base/strings/string_split.h"
[email protected]c72674b2013-06-11 04:16:4320#include "base/strings/string_util.h"
[email protected]d2d79d52013-06-07 22:23:4821#include "base/strings/utf_string_conversions.h"
gab7966d312016-05-11 20:35:0122#include "base/threading/thread_task_runner_handle.h"
[email protected]bbd8da92013-06-28 02:12:2023#include "base/time/time.h"
avi4310d522015-12-25 19:37:5924#include "build/build_config.h"
[email protected]f07e4442013-06-06 23:03:4825#include "components/autofill/content/renderer/form_autofill_util.h"
[email protected]f07e4442013-06-06 23:03:4826#include "components/autofill/content/renderer/password_autofill_agent.h"
[email protected]3cbdf9362014-01-31 23:12:2327#include "components/autofill/content/renderer/password_generation_agent.h"
jwwfb2a1432016-06-13 22:44:1528#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
[email protected]d04f81912013-06-18 14:52:1329#include "components/autofill/core/common/autofill_constants.h"
[email protected]d86263dcd2014-01-09 10:35:2130#include "components/autofill/core/common/autofill_data_validation.h"
[email protected]d04f81912013-06-18 14:52:1331#include "components/autofill/core/common/autofill_switches.h"
rouslanc31f81d2015-08-24 17:33:5232#include "components/autofill/core/common/autofill_util.h"
[email protected]d04f81912013-06-18 14:52:1333#include "components/autofill/core/common/form_data.h"
34#include "components/autofill/core/common/form_data_predictions.h"
35#include "components/autofill/core/common/form_field_data.h"
[email protected]e620d362013-09-09 08:01:5336#include "components/autofill/core/common/password_form.h"
jwwfb2a1432016-06-13 22:44:1537#include "components/autofill/core/common/password_form_fill_data.h"
38#include "components/autofill/core/common/save_password_progress_logger.h"
[email protected]fed9d4f2013-12-17 21:32:4739#include "content/public/common/content_switches.h"
[email protected]ca5190f2013-07-08 11:10:3140#include "content/public/common/url_constants.h"
estadeb1bc9bd2014-12-02 22:44:1141#include "content/public/renderer/render_frame.h"
[email protected]a2ef54c2011-10-10 16:20:3142#include "content/public/renderer/render_view.h"
[email protected]ca5190f2013-07-08 11:10:3143#include "net/cert/cert_status_flags.h"
ben803dba302017-04-27 20:41:4944#include "services/service_manager/public/cpp/binder_registry.h"
rockot734fb662016-10-15 16:41:3045#include "services/service_manager/public/cpp/interface_provider.h"
dtapuskaa64845d2017-01-20 21:20:4546#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
[email protected]f07e4442013-06-06 23:03:4847#include "third_party/WebKit/public/platform/WebURLRequest.h"
[email protected]dbdd60272014-04-14 22:48:4048#include "third_party/WebKit/public/web/WebConsoleMessage.h"
[email protected]a0962a92013-06-20 18:27:3449#include "third_party/WebKit/public/web/WebDataSource.h"
50#include "third_party/WebKit/public/web/WebDocument.h"
[email protected]961783a2014-02-07 18:38:0551#include "third_party/WebKit/public/web/WebElementCollection.h"
[email protected]a0962a92013-06-20 18:27:3452#include "third_party/WebKit/public/web/WebFormControlElement.h"
53#include "third_party/WebKit/public/web/WebFormElement.h"
[email protected]80504652014-04-18 04:41:5054#include "third_party/WebKit/public/web/WebLocalFrame.h"
[email protected]a0962a92013-06-20 18:27:3455#include "third_party/WebKit/public/web/WebNode.h"
[email protected]a0962a92013-06-20 18:27:3456#include "third_party/WebKit/public/web/WebOptionElement.h"
rouslan6a3f8d92015-04-28 01:00:0157#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
[email protected]a0962a92013-06-20 18:27:3458#include "third_party/WebKit/public/web/WebView.h"
[email protected]c051a1b2011-01-21 23:30:1759#include "ui/base/l10n/l10n_util.h"
[email protected]7e9acd082013-09-17 23:31:1660#include "ui/events/keycodes/keyboard_codes.h"
[email protected]679f128f2010-07-22 22:57:4461
[email protected]a1221aea2013-11-07 01:31:3062using blink::WebAutofillClient;
[email protected]dbdd60272014-04-14 22:48:4063using blink::WebConsoleMessage;
rouslanf7ebd8832015-01-22 01:54:1464using blink::WebDocument;
[email protected]5e7e8612014-03-20 14:43:1965using blink::WebElement;
66using blink::WebElementCollection;
[email protected]a1221aea2013-11-07 01:31:3067using blink::WebFormControlElement;
68using blink::WebFormElement;
69using blink::WebFrame;
70using blink::WebInputElement;
71using blink::WebKeyboardEvent;
[email protected]c5041c322014-04-08 05:06:4772using blink::WebLocalFrame;
[email protected]a1221aea2013-11-07 01:31:3073using blink::WebNode;
[email protected]a1221aea2013-11-07 01:31:3074using blink::WebOptionElement;
75using blink::WebString;
rouslan6a3f8d92015-04-28 01:00:0176using blink::WebUserGestureIndicator;
[email protected]5e7e8612014-03-20 14:43:1977using blink::WebVector;
[email protected]679f128f2010-07-22 22:57:4478
[email protected]d86263dcd2014-01-09 10:35:2179namespace autofill {
80
[email protected]e47aec52010-08-12 00:50:3081namespace {
82
mathp4f6b0382016-04-12 20:41:1283// Whether the "single click" autofill feature is enabled, through command-line
84// or field trial.
85bool IsSingleClickEnabled() {
86// On Android, default to showing the dropdown on field focus.
87// On desktop, require an extra click after field focus by default, unless the
88// experiment is active.
89#if defined(OS_ANDROID)
90 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
91 switches::kDisableSingleClickAutofill);
92#endif
93 const std::string group_name =
94 base::FieldTrialList::FindFullName("AutofillSingleClick");
95
96 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
97 switches::kEnableSingleClickAutofill))
98 return true;
99 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
100 switches::kDisableSingleClickAutofill))
101 return false;
102
103 return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
104}
105
[email protected]45a07942013-07-26 08:28:21106// Gets all the data list values (with corresponding label) for the given
107// element.
[email protected]5e7e8612014-03-20 14:43:19108void GetDataListSuggestions(const WebInputElement& element,
[email protected]45a07942013-07-26 08:28:21109 std::vector<base::string16>* values,
110 std::vector<base::string16>* labels) {
Blink Reformat1c4d759e2017-04-09 16:34:54111 for (const auto& option : element.FilteredDataListOptions()) {
112 values->push_back(option.Value().Utf16());
113 if (option.Value() != option.Label())
114 labels->push_back(option.Label().Utf16());
[email protected]bef7f9272012-04-17 10:47:49115 else
[email protected]d5ca8fb2013-04-11 17:54:31116 labels->push_back(base::string16());
[email protected]bef7f9272012-04-17 10:47:49117 }
118}
119
[email protected]ead7fb02013-07-18 18:50:12120// Trim the vector before sending it to the browser process to ensure we
[email protected]5c8de6b92012-06-08 21:24:08121// don't send too much data through the IPC.
[email protected]ead7fb02013-07-18 18:50:12122void TrimStringVectorForIPC(std::vector<base::string16>* strings) {
123 // Limit the size of the vector.
[email protected]d86263dcd2014-01-09 10:35:21124 if (strings->size() > kMaxListSize)
125 strings->resize(kMaxListSize);
[email protected]5c8de6b92012-06-08 21:24:08126
[email protected]ead7fb02013-07-18 18:50:12127 // Limit the size of the strings in the vector.
128 for (size_t i = 0; i < strings->size(); ++i) {
[email protected]d86263dcd2014-01-09 10:35:21129 if ((*strings)[i].length() > kMaxDataLength)
130 (*strings)[i].resize(kMaxDataLength);
[email protected]5c8de6b92012-06-08 21:24:08131 }
132}
133
[email protected]e47aec52010-08-12 00:50:30134} // namespace
135
brettwb505b7a2014-11-26 22:05:32136AutofillAgent::ShowSuggestionsOptions::ShowSuggestionsOptions()
137 : autofill_on_empty_values(false),
138 requires_caret_at_end(false),
brettwb505b7a2014-11-26 22:05:32139 show_full_suggestion_list(false),
140 show_password_suggestions_only(false) {
141}
142
estadeb1bc9bd2014-12-02 22:44:11143AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
[email protected]3cbdf9362014-01-31 23:12:23144 PasswordAutofillAgent* password_autofill_agent,
145 PasswordGenerationAgent* password_generation_agent)
estadeb1bc9bd2014-12-02 22:44:11146 : content::RenderFrameObserver(render_frame),
estadeff02e6d2014-12-15 21:18:31147 form_cache_(*render_frame->GetWebFrame()),
[email protected]ad19b302013-04-03 07:42:19148 password_autofill_agent_(password_autofill_agent),
[email protected]3cbdf9362014-01-31 23:12:23149 password_generation_agent_(password_generation_agent),
[email protected]679f128f2010-07-22 22:57:44150 autofill_query_id_(0),
[email protected]d77ddc8062010-11-24 01:14:06151 was_query_node_autofilled_(false),
[email protected]90f26252013-02-15 19:48:32152 ignore_text_changes_(false),
[email protected]b648f242014-02-25 13:49:06153 is_popup_possibly_visible_(false),
gcastocdd33e0d2015-06-17 22:10:05154 is_generation_popup_possibly_visible_(false),
ekaramad27ca69b12017-04-20 18:34:29155 page_click_tracker_(new PageClickTracker(render_frame, this)),
leon.han90fd63b2016-07-26 01:23:55156 binding_(this),
[email protected]2c305252013-04-26 19:57:05157 weak_ptr_factory_(this) {
Blink Reformat1c4d759e2017-04-09 16:34:54158 render_frame->GetWebFrame()->SetAutofillClient(this);
leon.han90fd63b2016-07-26 01:23:55159 password_autofill_agent->SetAutofillAgent(this);
estade78d655f82015-01-30 01:55:08160
leon.hande852902016-05-04 09:16:38161 // AutofillAgent is guaranteed to outlive |render_frame|.
ben155ecf82016-06-21 22:43:26162 render_frame->GetInterfaceRegistry()->AddInterface(
leon.hande852902016-05-04 09:16:38163 base::Bind(&AutofillAgent::BindRequest, base::Unretained(this)));
[email protected]679f128f2010-07-22 22:57:44164}
165
[email protected]a64fdc32013-07-31 09:21:13166AutofillAgent::~AutofillAgent() {}
[email protected]d2f05d02011-01-27 18:51:01167
leon.hande852902016-05-04 09:16:38168void AutofillAgent::BindRequest(mojom::AutofillAgentRequest request) {
leon.han90fd63b2016-07-26 01:23:55169 binding_.Bind(std::move(request));
leon.hande852902016-05-04 09:16:38170}
171
mathp692aba82015-03-06 20:55:02172bool AutofillAgent::FormDataCompare::operator()(const FormData& lhs,
173 const FormData& rhs) const {
brettw9c68c512015-11-20 23:26:38174 return std::tie(lhs.name, lhs.origin, lhs.action, lhs.is_form_tag) <
175 std::tie(rhs.name, rhs.origin, rhs.action, rhs.is_form_tag);
mathp692aba82015-03-06 20:55:02176}
177
mlamouri9ef14c22015-02-27 13:30:54178void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation,
eugenebut5ae751e2017-03-28 17:10:37179 bool is_same_document_navigation) {
mathpffc78e22015-09-01 14:10:50180 blink::WebFrame* frame = render_frame()->GetWebFrame();
181 // TODO(dvadym): check if we need to check if it is main frame navigation
182 // http://crbug.com/443155
Blink Reformat1c4d759e2017-04-09 16:34:54183 if (frame->Parent())
mathpffc78e22015-09-01 14:10:50184 return; // Not a top-level navigation.
185
eugenebut5ae751e2017-03-28 17:10:37186 if (is_same_document_navigation) {
187 OnSameDocumentNavigationCompleted();
rouslan6f1f93c2015-10-07 22:17:30188 } else {
189 // Navigation to a new page or a page refresh.
mathpffc78e22015-09-01 14:10:50190 form_cache_.Reset();
191 submitted_forms_.clear();
Blink Reformat1c4d759e2017-04-09 16:34:54192 last_interacted_form_.Reset();
tmartino283dda12016-06-23 21:43:54193 formless_elements_user_edited_.clear();
mathpffc78e22015-09-01 14:10:50194 }
[email protected]676126f72011-01-15 00:03:51195}
196
estadeb1bc9bd2014-12-02 22:44:11197void AutofillAgent::DidFinishDocumentLoad() {
198 ProcessForms();
[email protected]3609c962014-07-11 03:18:25199}
200
mathp692aba82015-03-06 20:55:02201void AutofillAgent::WillSendSubmitEvent(const WebFormElement& form) {
tmartino1c5348c92016-05-26 18:50:56202 FireHostSubmitEvents(form, /*form_submitted=*/false);
mathp692aba82015-03-06 20:55:02203}
204
estade13da3e42014-12-18 02:10:24205void AutofillAgent::WillSubmitForm(const WebFormElement& form) {
tmartino1c5348c92016-05-26 18:50:56206 FireHostSubmitEvents(form, /*form_submitted=*/true);
[email protected]2a5b1732011-04-01 23:55:55207}
208
estade2792527072014-12-17 00:41:47209void AutofillAgent::DidChangeScrollOffset() {
rouslanc31f81d2015-08-24 17:33:52210 if (IsKeyboardAccessoryEnabled())
estadeb5efbab62015-04-28 18:07:42211 return;
rouslanc31f81d2015-08-24 17:33:52212
estadeb1bc9bd2014-12-02 22:44:11213 HidePopup();
214}
215
[email protected]5e7e8612014-03-20 14:43:19216void AutofillAgent::FocusedNodeChanged(const WebNode& node) {
ekaramad27ca69b12017-04-20 18:34:29217 page_click_tracker_->FocusedNodeChanged(node);
218
[email protected]91dcc6d32014-07-30 00:01:33219 HidePopup();
220
Blink Reformat1c4d759e2017-04-09 16:34:54221 if (node.IsNull() || !node.IsElementNode()) {
222 if (!last_interacted_form_.IsNull()) {
mathp8ac68ce2015-12-08 21:49:06223 // Focus moved away from the last interacted form to somewhere else on
224 // the page.
leon.han90fd63b2016-07-26 01:23:55225 GetAutofillDriver()->FocusNoLongerOnForm();
mathp8ac68ce2015-12-08 21:49:06226 }
estadeb1bc9bd2014-12-02 22:44:11227 return;
mathp8ac68ce2015-12-08 21:49:06228 }
estadeb1bc9bd2014-12-02 22:44:11229
Blink Reformat1c4d759e2017-04-09 16:34:54230 WebElement web_element = node.ToConst<WebElement>();
231 const WebInputElement* element = ToWebInputElement(&web_element);
mathpb4cf7b82015-12-11 16:42:24232
Blink Reformat1c4d759e2017-04-09 16:34:54233 if (!last_interacted_form_.IsNull() &&
234 (!element || last_interacted_form_ != element->Form())) {
mathp8ac68ce2015-12-08 21:49:06235 // The focused element is not part of the last interacted form (could be
236 // in a different form).
leon.han90fd63b2016-07-26 01:23:55237 GetAutofillDriver()->FocusNoLongerOnForm();
mathp8ac68ce2015-12-08 21:49:06238 return;
239 }
[email protected]f920d6e2013-03-12 20:20:50240
Blink Reformat1c4d759e2017-04-09 16:34:54241 if (!element || !element->IsEnabled() || element->IsReadOnly() ||
242 !element->IsTextField())
[email protected]f920d6e2013-03-12 20:20:50243 return;
244
[email protected]e5057a22013-04-22 12:41:39245 element_ = *element;
[email protected]e5057a22013-04-22 12:41:39246}
247
vabrd62bc3e2016-05-04 15:58:52248void AutofillAgent::OnDestruct() {
249 Shutdown();
250 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
251}
252
tmartino1c5348c92016-05-26 18:50:56253void AutofillAgent::FireHostSubmitEvents(const WebFormElement& form,
254 bool form_submitted) {
255 FormData form_data;
256 if (!form_util::ExtractFormData(form, &form_data))
257 return;
258
259 FireHostSubmitEvents(form_data, form_submitted);
260}
261
262void AutofillAgent::FireHostSubmitEvents(const FormData& form_data,
263 bool form_submitted) {
264 // We remember when we have fired this IPC for this form in this frame load,
265 // because forms with a submit handler may fire both WillSendSubmitEvent
266 // and WillSubmitForm, and we don't want duplicate messages.
267 if (!submitted_forms_.count(form_data)) {
leon.han90fd63b2016-07-26 01:23:55268 GetAutofillDriver()->WillSubmitForm(form_data, base::TimeTicks::Now());
tmartino1c5348c92016-05-26 18:50:56269 submitted_forms_.insert(form_data);
270 }
271
leon.han90fd63b2016-07-26 01:23:55272 if (form_submitted) {
273 GetAutofillDriver()->FormSubmitted(form_data);
274 }
tmartino1c5348c92016-05-26 18:50:56275}
276
vabrd62bc3e2016-05-04 15:58:52277void AutofillAgent::Shutdown() {
leon.han7e8c85b2016-09-08 14:24:42278 binding_.Close();
vabrd62bc3e2016-05-04 15:58:52279 weak_ptr_factory_.InvalidateWeakPtrs();
280}
281
rouslanf7ebd8832015-01-22 01:54:14282
[email protected]e9d29d392014-03-25 01:15:15283void AutofillAgent::FormControlElementClicked(
284 const WebFormControlElement& element,
285 bool was_focused) {
Blink Reformat1c4d759e2017-04-09 16:34:54286 const WebInputElement* input_element = ToWebInputElement(&element);
mathp9172c62a2015-10-08 18:51:14287 if (!input_element && !form_util::IsTextAreaElement(element))
[email protected]e9d29d392014-03-25 01:15:15288 return;
289
brettwb505b7a2014-11-26 22:05:32290 ShowSuggestionsOptions options;
291 options.autofill_on_empty_values = true;
Blink Reformat1c4d759e2017-04-09 16:34:54292 options.show_full_suggestion_list = element.IsAutofilled();
gcasto2c6462272014-11-04 01:14:11293
mathp4f6b0382016-04-12 20:41:12294 if (!IsSingleClickEnabled()) {
brettwb505b7a2014-11-26 22:05:32295 // Show full suggestions when clicking on an already-focused form field. On
296 // the initial click (not focused yet), only show password suggestions.
brettwb505b7a2014-11-26 22:05:32297 options.show_full_suggestion_list =
298 options.show_full_suggestion_list || was_focused;
299 options.show_password_suggestions_only = !was_focused;
gcasto2c6462272014-11-04 01:14:11300 }
brettwb505b7a2014-11-26 22:05:32301 ShowSuggestions(element, options);
[email protected]676126f72011-01-15 00:03:51302}
303
Blink Reformat1c4d759e2017-04-09 16:34:54304void AutofillAgent::TextFieldDidEndEditing(const WebInputElement& element) {
leon.han90fd63b2016-07-26 01:23:55305 GetAutofillDriver()->DidEndTextFieldEditing();
[email protected]676126f72011-01-15 00:03:51306}
307
Blink Reformat1c4d759e2017-04-09 16:34:54308void AutofillAgent::TextFieldDidChange(const WebFormControlElement& element) {
309 DCHECK(ToWebInputElement(&element) || form_util::IsTextAreaElement(element));
ellyjonesdb20fae12015-12-04 16:47:55310
[email protected]90f26252013-02-15 19:48:32311 if (ignore_text_changes_)
312 return;
313
ellyjonesdb20fae12015-12-04 16:47:55314 // Disregard text changes that aren't caused by user gestures or pastes. Note
315 // that pastes aren't necessarily user gestures because Blink's conception of
316 // user gestures is centered around creating new windows/tabs.
317 if (!IsUserGesture() && !render_frame()->IsPasting())
[email protected]b96a1d12012-11-30 22:44:32318 return;
[email protected]b37043c2012-05-31 17:08:12319
[email protected]663bd9e2011-03-21 01:07:01320 // We post a task for doing the Autofill as the caret position is not set
[email protected]676126f72011-01-15 00:03:51321 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
322 // it is needed to trigger autofill.
[email protected]5219146e2013-02-28 11:42:30323 weak_ptr_factory_.InvalidateWeakPtrs();
skyostilb0daa012015-06-02 19:03:48324 base::ThreadTaskRunnerHandle::Get()->PostTask(
325 FROM_HERE, base::Bind(&AutofillAgent::TextFieldDidChangeImpl,
326 weak_ptr_factory_.GetWeakPtr(), element));
[email protected]676126f72011-01-15 00:03:51327}
328
[email protected]e9d29d392014-03-25 01:15:15329void AutofillAgent::TextFieldDidChangeImpl(
330 const WebFormControlElement& element) {
[email protected]f9af2832012-12-14 04:20:43331 // If the element isn't focused then the changes don't matter. This check is
332 // required to properly handle IME interactions.
Blink Reformat1c4d759e2017-04-09 16:34:54333 if (!element.Focused())
[email protected]f9af2832012-12-14 04:20:43334 return;
335
Blink Reformat1c4d759e2017-04-09 16:34:54336 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15337 if (input_element) {
mathpffc78e22015-09-01 14:10:50338 // Remember the last form the user interacted with.
Blink Reformat1c4d759e2017-04-09 16:34:54339 if (element.Form().IsNull()) {
tmartino283dda12016-06-23 21:43:54340 formless_elements_user_edited_.insert(element);
341 } else {
Blink Reformat1c4d759e2017-04-09 16:34:54342 last_interacted_form_ = element.Form();
tmartino283dda12016-06-23 21:43:54343 }
mathpffc78e22015-09-01 14:10:50344
gcasto5c13d762015-06-03 23:44:45345 // |password_autofill_agent_| keeps track of all text changes even if
346 // it isn't displaying UI.
347 password_autofill_agent_->UpdateStateForTextChange(*input_element);
348
[email protected]e9d29d392014-03-25 01:15:15349 if (password_generation_agent_ &&
350 password_generation_agent_->TextDidChangeInTextField(*input_element)) {
[email protected]7e048272014-04-17 03:38:52351 is_popup_possibly_visible_ = true;
[email protected]e9d29d392014-03-25 01:15:15352 return;
353 }
[email protected]3cbdf9362014-01-31 23:12:23354
[email protected]e9d29d392014-03-25 01:15:15355 if (password_autofill_agent_->TextDidChangeInTextField(*input_element)) {
rouslan2f5993f2015-01-29 00:18:31356 is_popup_possibly_visible_ = true;
[email protected]e9d29d392014-03-25 01:15:15357 element_ = element;
358 return;
359 }
[email protected]e7e83472012-04-05 02:56:26360 }
[email protected]676126f72011-01-15 00:03:51361
brettwb505b7a2014-11-26 22:05:32362 ShowSuggestionsOptions options;
363 options.requires_caret_at_end = true;
364 ShowSuggestions(element, options);
[email protected]7d24db72011-08-26 06:02:31365
[email protected]1ecbe862012-10-05 01:29:14366 FormData form;
367 FormFieldData field;
mathp9172c62a2015-10-08 18:51:14368 if (form_util::FindFormAndFieldForFormControlElement(element, &form,
369 &field)) {
leon.han90fd63b2016-07-26 01:23:55370 GetAutofillDriver()->TextFieldDidChange(form, field,
371 base::TimeTicks::Now());
[email protected]1d14f582011-09-02 20:42:04372 }
[email protected]676126f72011-01-15 00:03:51373}
374
Blink Reformat1c4d759e2017-04-09 16:34:54375void AutofillAgent::TextFieldDidReceiveKeyDown(const WebInputElement& element,
[email protected]2fa18c22011-06-14 23:40:43376 const WebKeyboardEvent& event) {
Blink Reformat1c4d759e2017-04-09 16:34:54377 if (event.windows_key_code == ui::VKEY_DOWN ||
378 event.windows_key_code == ui::VKEY_UP) {
brettwb505b7a2014-11-26 22:05:32379 ShowSuggestionsOptions options;
380 options.autofill_on_empty_values = true;
381 options.requires_caret_at_end = true;
brettwb505b7a2014-11-26 22:05:32382 ShowSuggestions(element, options);
383 }
[email protected]efeb565f2013-12-12 17:16:41384}
385
Blink Reformat1c4d759e2017-04-09 16:34:54386void AutofillAgent::OpenTextDataListChooser(const WebInputElement& element) {
brettwb505b7a2014-11-26 22:05:32387 ShowSuggestionsOptions options;
388 options.autofill_on_empty_values = true;
brettwb505b7a2014-11-26 22:05:32389 ShowSuggestions(element, options);
[email protected]676126f72011-01-15 00:03:51390}
391
Blink Reformat1c4d759e2017-04-09 16:34:54392void AutofillAgent::DataListOptionsChanged(const WebInputElement& element) {
393 if (!is_popup_possibly_visible_ || !element.Focused())
estadedf5088a2014-12-15 02:04:07394 return;
395
396 TextFieldDidChangeImpl(element);
397}
398
vasiliifd0e8ca2017-04-12 11:11:22399void AutofillAgent::UserGestureObserved() {
400 password_autofill_agent_->UserGestureObserved();
[email protected]fc22ae52014-04-23 13:48:04401}
402
leon.han90fd63b2016-07-26 01:23:55403void AutofillAgent::DoAcceptDataListSuggestion(
[email protected]d5ca8fb2013-04-11 17:54:31404 const base::string16& suggested_value) {
Blink Reformat1c4d759e2017-04-09 16:34:54405 WebInputElement* input_element = ToWebInputElement(&element_);
[email protected]e9d29d392014-03-25 01:15:15406 DCHECK(input_element);
[email protected]d5ca8fb2013-04-11 17:54:31407 base::string16 new_value = suggested_value;
[email protected]71a90b32012-05-18 09:16:53408 // If this element takes multiple values then replace the last part with
409 // the suggestion.
Blink Reformat1c4d759e2017-04-09 16:34:54410 if (input_element->IsMultiple() && input_element->IsEmailField()) {
mgiuca30f75882017-03-28 02:07:19411 std::vector<base::StringPiece16> parts = base::SplitStringPiece(
Blink Reformat1c4d759e2017-04-09 16:34:54412 input_element->EditingValue().Utf16(), base::ASCIIToUTF16(","),
kinuko0073e7c82017-01-24 00:42:40413 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]71a90b32012-05-18 09:16:53414 if (parts.size() == 0)
mgiuca30f75882017-03-28 02:07:19415 parts.push_back(base::StringPiece16());
[email protected]71a90b32012-05-18 09:16:53416
mgiuca30f75882017-03-28 02:07:19417 base::string16 last_part = parts.back().as_string();
[email protected]71a90b32012-05-18 09:16:53418 // We want to keep just the leading whitespace.
419 for (size_t i = 0; i < last_part.size(); ++i) {
brettwb3413062015-06-24 00:39:02420 if (!base::IsUnicodeWhitespace(last_part[i])) {
[email protected]71a90b32012-05-18 09:16:53421 last_part = last_part.substr(0, i);
422 break;
423 }
424 }
425 last_part.append(suggested_value);
thestigee1440b2016-07-08 01:06:55426 parts.back() = last_part;
[email protected]71a90b32012-05-18 09:16:53427
brettwd94a22142015-07-15 05:19:26428 new_value = base::JoinString(parts, base::ASCIIToUTF16(","));
[email protected]71a90b32012-05-18 09:16:53429 }
leon.han90fd63b2016-07-26 01:23:55430 DoFillFieldWithValue(new_value, input_element);
[email protected]63560b32014-03-04 07:06:26431}
432
leon.hande852902016-05-04 09:16:38433// mojom::AutofillAgent:
leon.han90fd63b2016-07-26 01:23:55434void AutofillAgent::FillForm(int32_t id, const FormData& form) {
mathpf43ced42016-08-04 18:28:23435 if (id != autofill_query_id_ && id != kNoQueryId)
leon.han90fd63b2016-07-26 01:23:55436 return;
437
Blink Reformat1c4d759e2017-04-09 16:34:54438 was_query_node_autofilled_ = element_.IsAutofilled();
leon.han90fd63b2016-07-26 01:23:55439 form_util::FillForm(form, element_);
Blink Reformat1c4d759e2017-04-09 16:34:54440 if (!element_.Form().IsNull())
441 last_interacted_form_ = element_.Form();
leon.han90fd63b2016-07-26 01:23:55442
443 GetAutofillDriver()->DidFillAutofillFormData(form, base::TimeTicks::Now());
[email protected]8527a78f2014-06-12 12:49:15444}
445
leon.han90fd63b2016-07-26 01:23:55446void AutofillAgent::PreviewForm(int32_t id, const FormData& form) {
447 if (id != autofill_query_id_)
[email protected]63560b32014-03-04 07:06:26448 return;
449
Blink Reformat1c4d759e2017-04-09 16:34:54450 was_query_node_autofilled_ = element_.IsAutofilled();
mathp9172c62a2015-10-08 18:51:14451 form_util::PreviewForm(form, element_);
leon.han90fd63b2016-07-26 01:23:55452
453 GetAutofillDriver()->DidPreviewAutofillFormData();
[email protected]6f001a6cf2012-02-09 15:21:53454}
455
leon.han90fd63b2016-07-26 01:23:55456void AutofillAgent::FieldTypePredictionsAvailable(
leon.han35ae41c2016-07-29 03:30:58457 const std::vector<FormDataPredictions>& forms) {
leon.han90fd63b2016-07-26 01:23:55458 for (const auto& form : forms) {
459 form_cache_.ShowPredictions(form);
460 }
461}
462
463void AutofillAgent::ClearForm() {
[email protected]bef7f9272012-04-17 10:47:49464 form_cache_.ClearFormWithElement(element_);
[email protected]6f001a6cf2012-02-09 15:21:53465}
466
leon.han90fd63b2016-07-26 01:23:55467void AutofillAgent::ClearPreviewedForm() {
Blink Reformat1c4d759e2017-04-09 16:34:54468 if (!element_.IsNull()) {
[email protected]b5b1d69f2014-01-23 23:49:32469 if (password_autofill_agent_->DidClearAutofillSelection(element_))
470 return;
471
mathp9172c62a2015-10-08 18:51:14472 form_util::ClearPreviewedFormWithElement(element_,
473 was_query_node_autofilled_);
[email protected]93f2e502013-12-20 09:47:25474 } else {
475 // TODO(isherman): There seem to be rare cases where this code *is*
476 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would
477 // understand those cases and fix the code to avoid them. However, so far I
478 // have been unable to reproduce such a case locally. If you hit this
479 // NOTREACHED(), please file a bug against me.
480 NOTREACHED();
481 }
[email protected]6f001a6cf2012-02-09 15:21:53482}
483
leon.han35ae41c2016-07-29 03:30:58484void AutofillAgent::FillFieldWithValue(const base::string16& value) {
Blink Reformat1c4d759e2017-04-09 16:34:54485 WebInputElement* input_element = ToWebInputElement(&element_);
ziran.sunee0fd4432014-08-27 10:10:49486 if (input_element) {
leon.han35ae41c2016-07-29 03:30:58487 DoFillFieldWithValue(value, input_element);
Blink Reformat1c4d759e2017-04-09 16:34:54488 input_element->SetAutofilled(true);
ziran.sunee0fd4432014-08-27 10:10:49489 }
[email protected]ac9b92f2014-03-15 00:48:32490}
491
leon.han35ae41c2016-07-29 03:30:58492void AutofillAgent::PreviewFieldWithValue(const base::string16& value) {
Blink Reformat1c4d759e2017-04-09 16:34:54493 WebInputElement* input_element = ToWebInputElement(&element_);
[email protected]e9d29d392014-03-25 01:15:15494 if (input_element)
leon.han35ae41c2016-07-29 03:30:58495 DoPreviewFieldWithValue(value, input_element);
[email protected]6f001a6cf2012-02-09 15:21:53496}
497
leon.han35ae41c2016-07-29 03:30:58498void AutofillAgent::AcceptDataListSuggestion(const base::string16& value) {
499 DoAcceptDataListSuggestion(value);
[email protected]5c8de6b92012-06-08 21:24:08500}
501
leon.han35ae41c2016-07-29 03:30:58502void AutofillAgent::FillPasswordSuggestion(const base::string16& username,
503 const base::string16& password) {
504 bool handled =
505 password_autofill_agent_->FillSuggestion(element_, username, password);
[email protected]126b1ad2014-05-21 22:37:33506 DCHECK(handled);
507}
508
leon.han35ae41c2016-07-29 03:30:58509void AutofillAgent::PreviewPasswordSuggestion(const base::string16& username,
510 const base::string16& password) {
kinuko0073e7c82017-01-24 00:42:40511 bool handled = password_autofill_agent_->PreviewSuggestion(
Blink Reformat1c4d759e2017-04-09 16:34:54512 element_, blink::WebString::FromUTF16(username),
513 blink::WebString::FromUTF16(password));
[email protected]e7e83472012-04-05 02:56:26514 DCHECK(handled);
515}
516
leon.han90fd63b2016-07-26 01:23:55517void AutofillAgent::ShowInitialPasswordAccountSuggestions(
518 int32_t key,
jwwfb2a1432016-06-13 22:44:15519 const PasswordFormFillData& form_data) {
520 std::vector<blink::WebInputElement> elements;
521 std::unique_ptr<RendererSavePasswordProgressLogger> logger;
522 if (password_autofill_agent_->logging_state_active()) {
leon.han97e8f752016-09-06 06:13:20523 logger.reset(new RendererSavePasswordProgressLogger(
524 GetPasswordManagerDriver().get()));
jwwfb2a1432016-06-13 22:44:15525 logger->LogMessage(SavePasswordProgressLogger::
526 STRING_ON_SHOW_INITIAL_PASSWORD_ACCOUNT_SUGGESTIONS);
527 }
528 password_autofill_agent_->GetFillableElementFromFormData(
529 key, form_data, logger.get(), &elements);
530
531 // If wait_for_username is true, we don't want to initially show form options
532 // until the user types in a valid username.
533 if (form_data.wait_for_username)
534 return;
535
536 ShowSuggestionsOptions options;
537 options.autofill_on_empty_values = true;
538 options.show_full_suggestion_list = true;
539 for (auto element : elements)
540 ShowSuggestions(element, options);
541}
542
estark50592c02017-01-04 01:52:40543void AutofillAgent::ShowNotSecureWarning(
544 const blink::WebInputElement& element) {
545 if (is_generation_popup_possibly_visible_)
546 return;
estark50592c02017-01-04 01:52:40547 password_autofill_agent_->ShowNotSecureWarning(element);
548 is_popup_possibly_visible_ = true;
549}
550
eugenebut5ae751e2017-03-28 17:10:37551void AutofillAgent::OnSameDocumentNavigationCompleted() {
Blink Reformat1c4d759e2017-04-09 16:34:54552 if (last_interacted_form_.IsNull()) {
tmartino283dda12016-06-23 21:43:54553 // If no last interacted form is available (i.e., there is no form tag),
554 // we check if all the elements the user has interacted with are gone,
555 // to decide if submission has occurred.
556 if (formless_elements_user_edited_.size() == 0 ||
557 form_util::IsSomeControlElementVisible(formless_elements_user_edited_))
558 return;
559
560 FormData constructed_form;
561 if (CollectFormlessElements(&constructed_form))
562 FireHostSubmitEvents(constructed_form, /*form_submitted=*/true);
563 } else {
564 // Otherwise, assume form submission only if the form is now gone, either
565 // invisible or removed from the DOM.
tmartino1c5348c92016-05-26 18:50:56566 if (form_util::AreFormContentsVisible(last_interacted_form_))
567 return;
mathpffc78e22015-09-01 14:10:50568
tmartino1c5348c92016-05-26 18:50:56569 FireHostSubmitEvents(last_interacted_form_, /*form_submitted=*/true);
tmartino1c5348c92016-05-26 18:50:56570 }
tmartino283dda12016-06-23 21:43:54571
Blink Reformat1c4d759e2017-04-09 16:34:54572 last_interacted_form_.Reset();
tmartino283dda12016-06-23 21:43:54573 formless_elements_user_edited_.clear();
574}
575
576bool AutofillAgent::CollectFormlessElements(FormData* output) {
Blink Reformat1c4d759e2017-04-09 16:34:54577 WebDocument document = render_frame()->GetWebFrame()->GetDocument();
tmartino283dda12016-06-23 21:43:54578
579 // Build up the FormData from the unowned elements. This logic mostly
580 // mirrors the construction of the synthetic form in form_cache.cc, but
581 // happens at submit-time so we can capture the modifications the user
582 // has made, and doesn't depend on form_cache's internal state.
583 std::vector<WebElement> fieldsets;
584 std::vector<WebFormControlElement> control_elements =
Blink Reformat1c4d759e2017-04-09 16:34:54585 form_util::GetUnownedAutofillableFormFieldElements(document.All(),
tmartino283dda12016-06-23 21:43:54586 &fieldsets);
587
588 if (control_elements.size() > form_util::kMaxParseableFields)
589 return false;
590
591 const form_util::ExtractMask extract_mask =
592 static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
593 form_util::EXTRACT_OPTIONS);
594
595 return form_util::UnownedCheckoutFormElementsAndFieldSetsToFormData(
596 fieldsets, control_elements, nullptr, document, extract_mask, output,
597 nullptr);
mathpffc78e22015-09-01 14:10:50598}
599
[email protected]e9d29d392014-03-25 01:15:15600void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
brettwb505b7a2014-11-26 22:05:32601 const ShowSuggestionsOptions& options) {
Blink Reformat1c4d759e2017-04-09 16:34:54602 if (!element.IsEnabled() || element.IsReadOnly())
[email protected]efeb565f2013-12-12 17:16:41603 return;
Blink Reformat1c4d759e2017-04-09 16:34:54604 if (!element.SuggestedValue().IsEmpty())
[email protected]580c38052014-07-16 07:28:09605 return;
[email protected]e9d29d392014-03-25 01:15:15606
Blink Reformat1c4d759e2017-04-09 16:34:54607 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15608 if (input_element) {
Blink Reformat1c4d759e2017-04-09 16:34:54609 if (!input_element->IsTextField())
[email protected]e9d29d392014-03-25 01:15:15610 return;
Blink Reformat1c4d759e2017-04-09 16:34:54611 if (!input_element->SuggestedValue().IsEmpty())
[email protected]e9d29d392014-03-25 01:15:15612 return;
613 } else {
mathp9172c62a2015-10-08 18:51:14614 DCHECK(form_util::IsTextAreaElement(element));
Blink Reformat1c4d759e2017-04-09 16:34:54615 if (!element.ToConst<WebFormControlElement>().SuggestedValue().IsEmpty())
[email protected]e9d29d392014-03-25 01:15:15616 return;
617 }
[email protected]e47aec52010-08-12 00:50:30618
[email protected]1c69f8b72012-03-14 03:18:50619 // Don't attempt to autofill with values that are too large or if filling
620 // criteria are not met.
Blink Reformat1c4d759e2017-04-09 16:34:54621 WebString value = element.EditingValue();
mathp5f90bce22015-11-22 20:16:58622 if (value.length() > kMaxDataLength ||
Blink Reformat1c4d759e2017-04-09 16:34:54623 (!options.autofill_on_empty_values && value.IsEmpty()) ||
mathp5f90bce22015-11-22 20:16:58624 (options.requires_caret_at_end &&
Blink Reformat1c4d759e2017-04-09 16:34:54625 (element.SelectionStart() != element.SelectionEnd() ||
626 element.SelectionEnd() != static_cast<int>(value.length())))) {
[email protected]1c69f8b72012-03-14 03:18:50627 // Any popup currently showing is obsolete.
[email protected]b648f242014-02-25 13:49:06628 HidePopup();
[email protected]e47aec52010-08-12 00:50:30629 return;
[email protected]1c69f8b72012-03-14 03:18:50630 }
[email protected]e47aec52010-08-12 00:50:30631
[email protected]bef7f9272012-04-17 10:47:49632 element_ = element;
mathp9172c62a2015-10-08 18:51:14633 if (form_util::IsAutofillableInputElement(input_element) &&
gcastocdd33e0d2015-06-17 22:10:05634 password_autofill_agent_->ShowSuggestions(
635 *input_element, options.show_full_suggestion_list,
636 is_generation_popup_possibly_visible_)) {
[email protected]b648f242014-02-25 13:49:06637 is_popup_possibly_visible_ = true;
[email protected]c66ba982013-04-05 09:56:17638 return;
[email protected]b648f242014-02-25 13:49:06639 }
[email protected]bef7f9272012-04-17 10:47:49640
gcastocdd33e0d2015-06-17 22:10:05641 if (is_generation_popup_possibly_visible_)
642 return;
643
644 if (options.show_password_suggestions_only)
645 return;
646
jww20355072014-12-12 21:00:55647 // Password field elements should only have suggestions shown by the password
648 // autofill agent.
Blink Reformat1c4d759e2017-04-09 16:34:54649 if (input_element && input_element->IsPasswordField())
jww20355072014-12-12 21:00:55650 return;
651
mathp5f90bce22015-11-22 20:16:58652 QueryAutofillSuggestions(element);
[email protected]77bb0da2010-11-20 01:55:30653}
654
[email protected]e9d29d392014-03-25 01:15:15655void AutofillAgent::QueryAutofillSuggestions(
mathp5f90bce22015-11-22 20:16:58656 const WebFormControlElement& element) {
Blink Reformat1c4d759e2017-04-09 16:34:54657 if (!element.GetDocument().GetFrame())
[email protected]e69b5f72013-01-24 00:59:13658 return;
659
Blink Reformat1c4d759e2017-04-09 16:34:54660 DCHECK(ToWebInputElement(&element) || form_util::IsTextAreaElement(element));
[email protected]e9d29d392014-03-25 01:15:15661
[email protected]77bb0da2010-11-20 01:55:30662 static int query_counter = 0;
663 autofill_query_id_ = query_counter++;
estade0ee91262014-10-23 19:29:19664
[email protected]1ecbe862012-10-05 01:29:14665 FormData form;
666 FormFieldData field;
mathp9172c62a2015-10-08 18:51:14667 if (!form_util::FindFormAndFieldForFormControlElement(element, &form,
668 &field)) {
[email protected]7837be62011-01-18 23:45:08669 // If we didn't find the cached form, at least let autocomplete have a shot
670 // at providing suggestions.
kolos66b4c292016-07-29 17:54:53671 WebFormControlElementToFormField(element, nullptr, form_util::EXTRACT_VALUE,
672 &field);
[email protected]7837be62011-01-18 23:45:08673 }
[email protected]77bb0da2010-11-20 01:55:30674
[email protected]7d0ea5362014-05-01 23:39:43675 std::vector<base::string16> data_list_values;
676 std::vector<base::string16> data_list_labels;
Blink Reformat1c4d759e2017-04-09 16:34:54677 const WebInputElement* input_element = ToWebInputElement(&element);
[email protected]e9d29d392014-03-25 01:15:15678 if (input_element) {
679 // Find the datalist values and send them to the browser process.
[email protected]e9d29d392014-03-25 01:15:15680 GetDataListSuggestions(*input_element,
[email protected]e9d29d392014-03-25 01:15:15681 &data_list_values,
682 &data_list_labels);
683 TrimStringVectorForIPC(&data_list_values);
684 TrimStringVectorForIPC(&data_list_labels);
[email protected]e9d29d392014-03-25 01:15:15685 }
[email protected]5c8de6b92012-06-08 21:24:08686
[email protected]b648f242014-02-25 13:49:06687 is_popup_possibly_visible_ = true;
[email protected]7d0ea5362014-05-01 23:39:43688
leon.han35ae41c2016-07-29 03:30:58689 GetAutofillDriver()->SetDataList(data_list_values, data_list_labels);
leon.han90fd63b2016-07-26 01:23:55690 GetAutofillDriver()->QueryFormFieldAutofill(
691 autofill_query_id_, form, field,
692 render_frame()->GetRenderView()->ElementBoundsInWindow(element_));
[email protected]e47aec52010-08-12 00:50:30693}
694
leon.han90fd63b2016-07-26 01:23:55695void AutofillAgent::DoFillFieldWithValue(const base::string16& value,
696 WebInputElement* node) {
rouslan6a3f8d92015-04-28 01:00:01697 base::AutoReset<bool> auto_reset(&ignore_text_changes_, true);
Blink Reformat1c4d759e2017-04-09 16:34:54698 node->SetEditingValue(
699 blink::WebString::FromUTF16(value.substr(0, node->MaxLength())));
[email protected]ac9b92f2014-03-15 00:48:32700}
701
leon.han90fd63b2016-07-26 01:23:55702void AutofillAgent::DoPreviewFieldWithValue(const base::string16& value,
703 WebInputElement* node) {
Blink Reformat1c4d759e2017-04-09 16:34:54704 was_query_node_autofilled_ = element_.IsAutofilled();
705 node->SetSuggestedValue(
706 blink::WebString::FromUTF16(value.substr(0, node->MaxLength())));
707 node->SetAutofilled(true);
708 form_util::PreviewSuggestion(node->SuggestedValue().Utf16(),
709 node->Value().Utf16(), node);
[email protected]6f001a6cf2012-02-09 15:21:53710}
711
estadeb1bc9bd2014-12-02 22:44:11712void AutofillAgent::ProcessForms() {
[email protected]5193ea52014-05-14 01:10:02713 // Record timestamp of when the forms are first seen. This is used to
714 // measure the overhead of the Autofill feature.
715 base::TimeTicks forms_seen_timestamp = base::TimeTicks::Now();
716
estadeb1bc9bd2014-12-02 22:44:11717 WebLocalFrame* frame = render_frame()->GetWebFrame();
estadeff02e6d2014-12-15 21:18:31718 std::vector<FormData> forms = form_cache_.ExtractNewForms();
[email protected]5193ea52014-05-14 01:10:02719
720 // Always communicate to browser process for topmost frame.
Blink Reformat1c4d759e2017-04-09 16:34:54721 if (!forms.empty() || !frame->Parent()) {
leon.han35ae41c2016-07-29 03:30:58722 GetAutofillDriver()->FormsSeen(forms, forms_seen_timestamp);
[email protected]5193ea52014-05-14 01:10:02723 }
[email protected]5193ea52014-05-14 01:10:02724}
725
[email protected]b648f242014-02-25 13:49:06726void AutofillAgent::HidePopup() {
727 if (!is_popup_possibly_visible_)
728 return;
[email protected]b648f242014-02-25 13:49:06729 is_popup_possibly_visible_ = false;
gcastocdd33e0d2015-06-17 22:10:05730 is_generation_popup_possibly_visible_ = false;
leon.han90fd63b2016-07-26 01:23:55731
732 GetAutofillDriver()->HidePopup();
[email protected]81cd52332012-11-05 20:36:07733}
734
rouslan42b090872015-05-17 05:04:33735bool AutofillAgent::IsUserGesture() const {
Blink Reformat1c4d759e2017-04-09 16:34:54736 return WebUserGestureIndicator::IsProcessingUserGesture();
rouslan42b090872015-05-17 05:04:33737}
738
Blink Reformat1c4d759e2017-04-09 16:34:54739void AutofillAgent::DidAssociateFormControlsDynamically() {
vasilii31ba8c6c2017-04-28 21:35:08740 // If the control flow is here than the document was at least loaded. The
741 // whole page doesn't have to be loaded.
742 ProcessForms();
743 password_autofill_agent_->OnDynamicFormsSeen();
744 if (password_generation_agent_)
745 password_generation_agent_->OnDynamicFormsSeen();
[email protected]17b6be72013-04-30 21:33:08746}
747
ekaramad27ca69b12017-04-20 18:34:29748void AutofillAgent::DidCompleteFocusChangeInFrame() {
749 WebDocument doc = render_frame()->GetWebFrame()->GetDocument();
750 WebElement focused_element;
751 if (!doc.IsNull())
752 focused_element = doc.FocusedElement();
753 // PasswordGenerationAgent needs to know about focus changes, even if there is
754 // no focused element.
755 if (password_generation_agent_ &&
756 password_generation_agent_->FocusedNodeHasChanged(focused_element)) {
757 is_generation_popup_possibly_visible_ = true;
758 is_popup_possibly_visible_ = true;
759 }
760 if (!focused_element.IsNull() && password_autofill_agent_)
761 password_autofill_agent_->FocusedNodeHasChanged(focused_element);
762
763 // PageClickTracker needs to be notified after
764 // |is_generation_popup_possibly_visible_| has been updated.
765 page_click_tracker_->DidCompleteFocusChangeInFrame();
766}
767
768void AutofillAgent::DidReceiveLeftMouseDownOrGestureTapInNode(
769 const WebNode& node) {
770 page_click_tracker_->DidReceiveLeftMouseDownOrGestureTapInNode(node);
771}
772
Blink Reformat1c4d759e2017-04-09 16:34:54773void AutofillAgent::AjaxSucceeded() {
eugenebut5ae751e2017-03-28 17:10:37774 OnSameDocumentNavigationCompleted();
xunlu23ca2b572015-07-10 16:58:26775 password_autofill_agent_->AJAXSucceeded();
gcastoc21f1c4c2015-03-19 21:57:03776}
777
leon.han90fd63b2016-07-26 01:23:55778const mojom::AutofillDriverPtr& AutofillAgent::GetAutofillDriver() {
leon.han97e8f752016-09-06 06:13:20779 if (!autofill_driver_) {
leon.han90fd63b2016-07-26 01:23:55780 render_frame()->GetRemoteInterfaces()->GetInterface(
blundelle0a9f1582016-12-20 11:23:32781 mojo::MakeRequest(&autofill_driver_));
leon.han90fd63b2016-07-26 01:23:55782 }
leon.hande852902016-05-04 09:16:38783
leon.han97e8f752016-09-06 06:13:20784 return autofill_driver_;
785}
786
787const mojom::PasswordManagerDriverPtr&
788AutofillAgent::GetPasswordManagerDriver() {
789 DCHECK(password_autofill_agent_);
790 return password_autofill_agent_->GetPasswordManagerDriver();
leon.hande852902016-05-04 09:16:38791}
792
[email protected]78192082011-01-29 05:43:44793} // namespace autofill