// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/renderer/autofill/form_cache.h" #include "base/logging.h" #include "base/utf_string_conversions.h" #include "chrome/common/form_data.h" #include "chrome/common/form_data_predictions.h" #include "chrome/common/form_field_data.h" #include "chrome/common/form_field_data_predictions.h" #include "chrome/renderer/autofill/form_autofill_util.h" #include "grit/generated_resources.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSelectElement.h" #include "ui/base/l10n/l10n_util.h" using WebKit::WebDocument; using WebKit::WebFormControlElement; using WebKit::WebFormElement; using WebKit::WebFrame; using WebKit::WebInputElement; using WebKit::WebSelectElement; using WebKit::WebString; using WebKit::WebVector; namespace { // The number of fields required by Autofill. Ideally we could send the forms // to Autofill no matter how many fields are in the forms; however, finding the // label for each field is a costly operation and we can't spare the cycles if // it's not necessary. const size_t kRequiredAutofillFields = 3; } // namespace namespace autofill { // Helper function to discard state of various WebFormElements when they go out // of web frame's scope. This is done to release memory that we no longer need // to hold. // K should inherit from WebFormControlElement as the function looks to extract // WebFormElement for K.form(). template void RemoveOldElements(const WebFrame& frame, std::map* states) { std::vector to_remove; for (typename std::map::const_iterator it = states->begin(); it != states->end(); ++it) { WebFormElement form_element = it->first.form(); if (form_element.isNull()) { to_remove.push_back(it->first); } else { const WebFrame* element_frame = form_element.document().frame(); if (!element_frame || element_frame == &frame) to_remove.push_back(it->first); } } for (typename std::vector::const_iterator it = to_remove.begin(); it != to_remove.end(); ++it) { states->erase(*it); } } FormCache::FormCache() { } FormCache::~FormCache() { } void FormCache::ExtractForms(const WebFrame& frame, std::vector* forms) { ExtractFormsAndFormElements(frame, forms, NULL); } void FormCache::ExtractFormsAndFormElements( const WebFrame& frame, std::vector* forms, std::vector* web_form_elements) { // Reset the cache for this frame. ResetFrame(frame); WebDocument document = frame.document(); if (document.isNull()) return; web_documents_.insert(document); WebVector web_forms; document.forms(web_forms); size_t num_fields_seen = 0; for (size_t i = 0; i < web_forms.size(); ++i) { WebFormElement form_element = web_forms[i]; std::vector control_elements; ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, &control_elements); for (size_t j = 0; j < control_elements.size(); ++j) { WebFormControlElement element = control_elements[j]; // Save original values of