Chromium Code Reviews| Index: components/autofill/content/renderer/autofill_agent.cc |
| diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc |
| index 16533e7ecf9ab5d63cbc83834c676f937a4bdff4..331d150104501f2dd404ac07a1f09527c94d4471 100644 |
| --- a/components/autofill/content/renderer/autofill_agent.cc |
| +++ b/components/autofill/content/renderer/autofill_agent.cc |
| @@ -244,6 +244,7 @@ void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation, |
| form_cache_.Reset(); |
| submitted_forms_.clear(); |
| last_interacted_form_.reset(); |
| + formless_elements_user_edited_.clear(); |
| } |
| } |
| @@ -408,8 +409,11 @@ void AutofillAgent::TextFieldDidChangeImpl( |
| const WebInputElement* input_element = toWebInputElement(&element); |
| if (input_element) { |
| // Remember the last form the user interacted with. |
| - if (!element.form().isNull()) |
| + if (element.form().isNull()) { |
| + formless_elements_user_edited_.insert(element); |
| + } else { |
| last_interacted_form_ = element.form(); |
| + } |
| // |password_autofill_agent_| keeps track of all text changes even if |
| // it isn't displaying UI. |
| @@ -624,16 +628,50 @@ void AutofillAgent::OnShowInitialPasswordAccountSuggestions( |
| } |
| void AutofillAgent::OnSamePageNavigationCompleted() { |
| - if (!last_interacted_form_.isNull()) { |
| - // Assume form submission only if the form is now gone, either invisible or |
| - // removed from the DOM. |
| + if (last_interacted_form_.isNull()) { |
| + // If no last interacted form is available (i.e., there is no form tag), |
| + // we check if all the elements the user has interacted with are gone, |
| + // and reconstruct the inputs for submission. |
| + if (formless_elements_user_edited_.size() == 0 || |
| + form_util::IsSomeControlElementVisible(formless_elements_user_edited_)) |
| + return; |
| + |
| + WebDocument document = render_frame()->GetWebFrame()->document(); |
| + |
| + // Build up the FormData from the unowned elements. This logic mostly |
| + // mirrors the construction of the synthetic form in form_cache.cc, but |
| + // happens at submit-time so we can capture the modifications the user |
| + // has made, and doesn't depend on form_cache's internal state. |
| + std::vector<WebElement> fieldsets; |
|
Mathieu
2016/06/21 18:04:07
Would be great to extract this in a function in th
tmartino
2016/06/21 23:38:30
Done. It's not quite doing the same thing as form_
|
| + std::vector<WebFormControlElement> control_elements = |
| + form_util::GetUnownedAutofillableFormFieldElements(document.all(), |
| + &fieldsets); |
| + |
| + if (control_elements.size() > form_util::kMaxParseableFields) |
| + return; |
| + |
| + FormData constructed_form; |
| + const form_util::ExtractMask extract_mask = |
| + static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE | |
| + form_util::EXTRACT_OPTIONS); |
| + |
| + if (!form_util::UnownedCheckoutFormElementsAndFieldSetsToFormData( |
| + fieldsets, control_elements, nullptr, document, extract_mask, |
| + &constructed_form, nullptr)) |
| + return; |
| + |
| + FireHostSubmitEvents(constructed_form, /*form_submitted=*/true); |
| + } else { |
| + // Otherwise, assume form submission only if the form is now gone, either |
| + // invisible or removed from the DOM. |
| if (form_util::AreFormContentsVisible(last_interacted_form_)) |
| return; |
| FireHostSubmitEvents(last_interacted_form_, /*form_submitted=*/true); |
| - last_interacted_form_.reset(); |
| } |
| - // TODO(tmartino): Else, try using Synthetic Form from form_cache. |
| + |
| + last_interacted_form_.reset(); |
| + formless_elements_user_edited_.clear(); |
| } |
| void AutofillAgent::ShowSuggestions(const WebFormControlElement& element, |