19720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Copyright 2013 The Chromium Authors. All rights reserved. 29720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Use of this source code is governed by a BSD-style license that can be 39720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// found in the LICENSE file. 49720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 59720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/content/renderer/form_cache.h" 69720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 79720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "base/logging.h" 89720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "base/strings/utf_string_conversions.h" 99720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/content/renderer/form_autofill_util.h" 109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/core/common/autofill_constants.h" 119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/core/common/form_data.h" 129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/core/common/form_data_predictions.h" 139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/core/common/form_field_data.h" 149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "components/autofill/core/common/form_field_data_predictions.h" 159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "grit/components_strings.h" 169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/platform/WebString.h" 179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/platform/WebVector.h" 189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebConsoleMessage.h" 199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebDocument.h" 209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebFormControlElement.h" 219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebFormElement.h" 229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebInputElement.h" 239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebLocalFrame.h" 249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebNodeList.h" 259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebSelectElement.h" 269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "third_party/WebKit/public/web/WebTextAreaElement.h" 279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#include "ui/base/l10n/l10n_util.h" 289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebConsoleMessage; 309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebDocument; 319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebFormControlElement; 329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebFormElement; 339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebFrame; 349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebInputElement; 359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebSelectElement; 369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebTextAreaElement; 379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebString; 389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockusing blink::WebVector; 399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocknamespace autofill { 419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper function to discard state of various WebFormElements when they go out 439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// of web frame's scope. This is done to release memory that we no longer need 449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// to hold. 459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// K should inherit from WebFormControlElement as the function looks to extract 469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// WebFormElement for K.form(). 479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class K, class V> 489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid RemoveOldElements(const WebFrame& frame, std::map<const K, V>* states) { 499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<K> to_remove; 509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (typename std::map<const K, V>::const_iterator it = states->begin(); 519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it != states->end(); ++it) { 529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormElement form_element = it->first.form(); 539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (form_element.isNull()) { 549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block to_remove.push_back(it->first); 559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else { 569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const WebFrame* element_frame = form_element.document().frame(); 579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!element_frame || element_frame == &frame) 589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block to_remove.push_back(it->first); 599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (typename std::vector<K>::const_iterator it = to_remove.begin(); 639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it != to_remove.end(); ++it) { 649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block states->erase(*it); 659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve BlockFormCache::FormCache() { 699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve BlockFormCache::~FormCache() { 729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid FormCache::ExtractNewForms(const WebFrame& frame, 759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<FormData>* forms) { 769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebDocument document = frame.document(); 779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (document.isNull()) 789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return; 799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block web_documents_.insert(document); 819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebVector<WebFormElement> web_forms; 839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block document.forms(web_forms); 849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Log an error message for deprecated attributes, but only the first time 869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // the form is parsed. 879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block bool log_deprecation_messages = 889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block parsed_forms_.find(&frame) == parsed_forms_.end(); 899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block size_t num_fields_seen = 0; 919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t i = 0; i < web_forms.size(); ++i) { 929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormElement form_element = web_forms[i]; 939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<WebFormControlElement> control_elements; 959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, 969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block &control_elements); 979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block size_t num_editable_elements = 0; 999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t j = 0; j < control_elements.size(); ++j) { 1009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormControlElement element = control_elements[j]; 1019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (log_deprecation_messages) { 1039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::string autocomplete_attribute = 1049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF16ToUTF8(element.getAttribute("autocomplete")); 1059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block static const char* const deprecated[] = { "region", "locality" }; 1079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t i = 0; i < arraysize(deprecated); ++i) { 1089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (autocomplete_attribute.find(deprecated[i]) != std::string::npos) { 1099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebConsoleMessage console_message = WebConsoleMessage( 1109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebConsoleMessage::LevelWarning, 1119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebString(base::ASCIIToUTF16(std::string("autocomplete='") + 1129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block deprecated[i] + "' is deprecated and will soon be ignored. " 1139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block "See http://goo.gl/YjeSsW"))); 1149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block element.document().frame()->addMessageToConsole(console_message); 1159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Save original values of <select> elements so we can restore them 1209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // when |ClearFormWithNode()| is invoked. 1219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (IsSelectElement(element)) { 1229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const WebSelectElement select_element = 1239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block element.toConst<WebSelectElement>(); 1249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block initial_select_values_.insert(std::make_pair(select_element, 1259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block select_element.value())); 1269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ++num_editable_elements; 1279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else if (IsTextAreaElement(element)) { 1289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ++num_editable_elements; 1299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else { 1309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const WebInputElement input_element = 1319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block element.toConst<WebInputElement>(); 1329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (IsCheckableElement(&input_element)) { 1339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block initial_checked_state_.insert( 1349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::make_pair(input_element, input_element.isChecked())); 1359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else { 1369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ++num_editable_elements; 1379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // To avoid overly expensive computation, we impose a minimum number of 1429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // allowable fields. The corresponding maximum number of allowable fields 1439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // is imposed by WebFormElementToFormData(). 1449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (num_editable_elements < kRequiredAutofillFields && 1459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block control_elements.size() > 0) { 1469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block continue; 1479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block FormData form; 1509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ExtractMask extract_mask = 1519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); 1529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!WebFormElementToFormData(form_element, WebFormControlElement(), 1549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block REQUIRE_NONE, extract_mask, &form, NULL)) { 1559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block continue; 1569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block num_fields_seen += form.fields.size(); 1599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (num_fields_seen > kMaxParseableFields) 1609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block break; 1619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (form.fields.size() >= kRequiredAutofillFields && 1639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block !parsed_forms_[&frame].count(form)) { 1649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block forms->push_back(form); 1659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block parsed_forms_[&frame].insert(form); 1669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 1699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid FormCache::ResetFrame(const WebFrame& frame) { 1719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<WebDocument> documents_to_delete; 1729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (std::set<WebDocument>::const_iterator it = web_documents_.begin(); 1739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it != web_documents_.end(); ++it) { 1749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const WebFrame* document_frame = it->frame(); 1759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!document_frame || document_frame == &frame) 1769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block documents_to_delete.push_back(*it); 1779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (std::vector<WebDocument>::const_iterator it = 1809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block documents_to_delete.begin(); 1819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it != documents_to_delete.end(); ++it) { 1829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block web_documents_.erase(*it); 1839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block parsed_forms_[&frame].clear(); 1869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block RemoveOldElements(frame, &initial_select_values_); 1879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block RemoveOldElements(frame, &initial_checked_state_); 1889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 1899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool FormCache::ClearFormWithElement(const WebFormControlElement& element) { 1919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormElement form_element = element.form(); 1929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (form_element.isNull()) 1939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 1949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<WebFormControlElement> control_elements; 1969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, 1979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block &control_elements); 1989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t i = 0; i < control_elements.size(); ++i) { 1999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormControlElement control_element = control_elements[i]; 2009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Don't modify the value of disabled fields. 2019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!control_element.isEnabled()) 2029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block continue; 2039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Don't clear field that was not autofilled 2059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!control_element.isAutofilled()) 2069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block continue; 2079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block control_element.setAutofilled(false); 2099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebInputElement* input_element = toWebInputElement(&control_element); 2119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (IsTextInput(input_element) || IsMonthInput(input_element)) { 2129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block input_element->setValue(base::string16(), true); 2139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Clearing the value in the focused node (above) can cause selection 2159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // to be lost. We force selection range to restore the text cursor. 2169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (element == *input_element) { 2179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block int length = input_element->value().length(); 2189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block input_element->setSelectionRange(length, length); 2199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else if (IsTextAreaElement(control_element)) { 2219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block control_element.setValue(base::string16(), true); 2229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else if (IsSelectElement(control_element)) { 2239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebSelectElement select_element = control_element.to<WebSelectElement>(); 2249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::map<const WebSelectElement, base::string16>::const_iterator 2269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block initial_value_iter = initial_select_values_.find(select_element); 2279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (initial_value_iter != initial_select_values_.end() && 2289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block select_element.value() != initial_value_iter->second) { 2299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block select_element.setValue(initial_value_iter->second, true); 2309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } else { 2329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebInputElement input_element = control_element.to<WebInputElement>(); 2339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block DCHECK(IsCheckableElement(&input_element)); 2349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::map<const WebInputElement, bool>::const_iterator it = 2359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block initial_checked_state_.find(input_element); 2369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (it != initial_checked_state_.end() && 2379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block input_element.isChecked() != it->second) { 2389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block input_element.setChecked(it->second, true); 2399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 2449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 2459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool FormCache::ShowPredictions(const FormDataPredictions& form) { 2479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block DCHECK_EQ(form.data.fields.size(), form.fields.size()); 2489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Find the form. 2509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block bool found_form = false; 2519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormElement form_element; 2529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (std::set<WebDocument>::const_iterator it = web_documents_.begin(); 2539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it != web_documents_.end() && !found_form; ++it) { 2549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebVector<WebFormElement> web_forms; 2559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block it->forms(web_forms); 2569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t i = 0; i < web_forms.size(); ++i) { 2589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block form_element = web_forms[i]; 2599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Note: matching on the form name here which is not guaranteed to be 2619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // unique for the page, nor is it guaranteed to be non-empty. Ideally, we 2629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // would have a way to uniquely identify the form cross-process. For now, 2639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // we'll check form name and form action for identity. 2649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Also note that WebString() == WebString(string16()) does not evaluate 2659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // to |true| -- WebKit distinguishes between a "null" string (lhs) and an 2669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // "empty" string (rhs). We don't want that distinction, so forcing to 2679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // string16. 2689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::string16 element_name = GetFormIdentifier(form_element); 2699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block GURL action(form_element.document().completeURL(form_element.action())); 2709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (element_name == form.data.name && action == form.data.action) { 2719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block found_form = true; 2729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block break; 2739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!found_form) 2789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 2799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::vector<WebFormControlElement> control_elements; 2819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ExtractAutofillableElements(form_element, autofill::REQUIRE_NONE, 2829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block &control_elements); 2839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (control_elements.size() != form.fields.size()) { 2849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Keep things simple. Don't show predictions for forms that were modified 2859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // between page load and the server's response to our query. 2869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 2879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (size_t i = 0; i < control_elements.size(); ++i) { 2909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebFormControlElement* element = &control_elements[i]; 2919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (base::string16(element->nameForAutofill()) != 2939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block form.data.fields[i].name) { 2949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Keep things simple. Don't show predictions for elements whose names 2959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // were modified between page load and the server's response to our query. 2969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block continue; 2979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block std::string placeholder = form.fields[i].overall_type; 3009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::string16 title = l10n_util::GetStringFUTF16( 3019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block IDS_AUTOFILL_SHOW_PREDICTIONS_TITLE, 3029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF8ToUTF16(form.fields[i].heuristic_type), 3039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF8ToUTF16(form.fields[i].server_type), 3049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF8ToUTF16(form.fields[i].signature), 3059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF8ToUTF16(form.signature), 3069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block base::UTF8ToUTF16(form.experiment_id)); 3079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!element->hasAttribute("placeholder")) { 3089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block element->setAttribute("placeholder", 3099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block WebString(base::UTF8ToUTF16(placeholder))); 3109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 3119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block element->setAttribute("title", WebString(title)); 3129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 3139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 3159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 3169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} // namespace autofill 3189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block