Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: components/autofill/content/renderer/autofill_agent.cc

Issue 2065303002: Modifying Autofill Agent to use synthetic form (i.e., formless elements) when no form is present on… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding browser test Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/autofill/content/renderer/autofill_agent.h" 5 #include "components/autofill/content/renderer/autofill_agent.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <tuple> 9 #include <tuple>
10 10
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 if (frame->parent()) 237 if (frame->parent())
238 return; // Not a top-level navigation. 238 return; // Not a top-level navigation.
239 239
240 if (is_same_page_navigation) { 240 if (is_same_page_navigation) {
241 OnSamePageNavigationCompleted(); 241 OnSamePageNavigationCompleted();
242 } else { 242 } else {
243 // Navigation to a new page or a page refresh. 243 // Navigation to a new page or a page refresh.
244 form_cache_.Reset(); 244 form_cache_.Reset();
245 submitted_forms_.clear(); 245 submitted_forms_.clear();
246 last_interacted_form_.reset(); 246 last_interacted_form_.reset();
247 formless_elements_user_edited_.clear();
247 } 248 }
248 } 249 }
249 250
250 void AutofillAgent::DidFinishDocumentLoad() { 251 void AutofillAgent::DidFinishDocumentLoad() {
251 ProcessForms(); 252 ProcessForms();
252 } 253 }
253 254
254 void AutofillAgent::WillSendSubmitEvent(const WebFormElement& form) { 255 void AutofillAgent::WillSendSubmitEvent(const WebFormElement& form) {
255 FireHostSubmitEvents(form, /*form_submitted=*/false); 256 FireHostSubmitEvents(form, /*form_submitted=*/false);
256 } 257 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 void AutofillAgent::TextFieldDidChangeImpl( 402 void AutofillAgent::TextFieldDidChangeImpl(
402 const WebFormControlElement& element) { 403 const WebFormControlElement& element) {
403 // If the element isn't focused then the changes don't matter. This check is 404 // If the element isn't focused then the changes don't matter. This check is
404 // required to properly handle IME interactions. 405 // required to properly handle IME interactions.
405 if (!element.focused()) 406 if (!element.focused())
406 return; 407 return;
407 408
408 const WebInputElement* input_element = toWebInputElement(&element); 409 const WebInputElement* input_element = toWebInputElement(&element);
409 if (input_element) { 410 if (input_element) {
410 // Remember the last form the user interacted with. 411 // Remember the last form the user interacted with.
411 if (!element.form().isNull()) 412 if (element.form().isNull()) {
413 formless_elements_user_edited_.insert(element);
414 } else {
412 last_interacted_form_ = element.form(); 415 last_interacted_form_ = element.form();
416 }
413 417
414 // |password_autofill_agent_| keeps track of all text changes even if 418 // |password_autofill_agent_| keeps track of all text changes even if
415 // it isn't displaying UI. 419 // it isn't displaying UI.
416 password_autofill_agent_->UpdateStateForTextChange(*input_element); 420 password_autofill_agent_->UpdateStateForTextChange(*input_element);
417 421
418 if (password_generation_agent_ && 422 if (password_generation_agent_ &&
419 password_generation_agent_->TextDidChangeInTextField(*input_element)) { 423 password_generation_agent_->TextDidChangeInTextField(*input_element)) {
420 is_popup_possibly_visible_ = true; 424 is_popup_possibly_visible_ = true;
421 return; 425 return;
422 } 426 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 return; 621 return;
618 622
619 ShowSuggestionsOptions options; 623 ShowSuggestionsOptions options;
620 options.autofill_on_empty_values = true; 624 options.autofill_on_empty_values = true;
621 options.show_full_suggestion_list = true; 625 options.show_full_suggestion_list = true;
622 for (auto element : elements) 626 for (auto element : elements)
623 ShowSuggestions(element, options); 627 ShowSuggestions(element, options);
624 } 628 }
625 629
626 void AutofillAgent::OnSamePageNavigationCompleted() { 630 void AutofillAgent::OnSamePageNavigationCompleted() {
627 if (!last_interacted_form_.isNull()) { 631 if (last_interacted_form_.isNull()) {
628 // Assume form submission only if the form is now gone, either invisible or 632 // If no last interacted form is available (i.e., there is no form tag),
629 // removed from the DOM. 633 // we check if all the elements the user has interacted with are gone,
634 // and reconstruct the inputs for submission.
635 if (formless_elements_user_edited_.size() == 0 ||
636 form_util::IsSomeControlElementVisible(formless_elements_user_edited_))
637 return;
638
639 WebDocument document = render_frame()->GetWebFrame()->document();
640
641 // Build up the FormData from the unowned elements. This logic mostly
642 // mirrors the construction of the synthetic form in form_cache.cc, but
643 // happens at submit-time so we can capture the modifications the user
644 // has made, and doesn't depend on form_cache's internal state.
645 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_
646 std::vector<WebFormControlElement> control_elements =
647 form_util::GetUnownedAutofillableFormFieldElements(document.all(),
648 &fieldsets);
649
650 if (control_elements.size() > form_util::kMaxParseableFields)
651 return;
652
653 FormData constructed_form;
654 const form_util::ExtractMask extract_mask =
655 static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
656 form_util::EXTRACT_OPTIONS);
657
658 if (!form_util::UnownedCheckoutFormElementsAndFieldSetsToFormData(
659 fieldsets, control_elements, nullptr, document, extract_mask,
660 &constructed_form, nullptr))
661 return;
662
663 FireHostSubmitEvents(constructed_form, /*form_submitted=*/true);
664 } else {
665 // Otherwise, assume form submission only if the form is now gone, either
666 // invisible or removed from the DOM.
630 if (form_util::AreFormContentsVisible(last_interacted_form_)) 667 if (form_util::AreFormContentsVisible(last_interacted_form_))
631 return; 668 return;
632 669
633 FireHostSubmitEvents(last_interacted_form_, /*form_submitted=*/true); 670 FireHostSubmitEvents(last_interacted_form_, /*form_submitted=*/true);
634 last_interacted_form_.reset();
635 } 671 }
636 // TODO(tmartino): Else, try using Synthetic Form from form_cache. 672
673 last_interacted_form_.reset();
674 formless_elements_user_edited_.clear();
637 } 675 }
638 676
639 void AutofillAgent::ShowSuggestions(const WebFormControlElement& element, 677 void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
640 const ShowSuggestionsOptions& options) { 678 const ShowSuggestionsOptions& options) {
641 if (!element.isEnabled() || element.isReadOnly()) 679 if (!element.isEnabled() || element.isReadOnly())
642 return; 680 return;
643 if (!element.suggestedValue().isEmpty()) 681 if (!element.suggestedValue().isEmpty())
644 return; 682 return;
645 683
646 const WebInputElement* input_element = toWebInputElement(&element); 684 const WebInputElement* input_element = toWebInputElement(&element);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 void AutofillAgent::LegacyAutofillAgent::OnDestruct() { 863 void AutofillAgent::LegacyAutofillAgent::OnDestruct() {
826 // No-op. Don't delete |this|. 864 // No-op. Don't delete |this|.
827 } 865 }
828 866
829 void AutofillAgent::LegacyAutofillAgent::FocusChangeComplete() { 867 void AutofillAgent::LegacyAutofillAgent::FocusChangeComplete() {
830 if (agent_) 868 if (agent_)
831 agent_->FocusChangeComplete(); 869 agent_->FocusChangeComplete();
832 } 870 }
833 871
834 } // namespace autofill 872 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698