| OLD | NEW |
| 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/form_cache.h" | 5 #include "components/autofill/content/renderer/form_cache.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "components/autofill/content/renderer/form_autofill_util.h" | 10 #include "components/autofill/content/renderer/form_autofill_util.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 continue; | 49 continue; |
| 50 std::string msg = std::string("autocomplete='") + deprecated[i] + | 50 std::string msg = std::string("autocomplete='") + deprecated[i] + |
| 51 "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"; | 51 "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"; |
| 52 WebConsoleMessage console_message = WebConsoleMessage( | 52 WebConsoleMessage console_message = WebConsoleMessage( |
| 53 WebConsoleMessage::LevelWarning, | 53 WebConsoleMessage::LevelWarning, |
| 54 WebString(base::ASCIIToUTF16(msg))); | 54 WebString(base::ASCIIToUTF16(msg))); |
| 55 element.document().frame()->addMessageToConsole(console_message); | 55 element.document().frame()->addMessageToConsole(console_message); |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 // To avoid overly expensive computation, we impose a minimum number of | 59 // Determines whether the form is interesting enough to send to the browser |
| 60 // allowable fields. The corresponding maximum number of allowable fields | 60 // for further operations. |
| 61 // is imposed by WebFormElementToFormData(). | 61 bool IsFormInteresting(const FormData& form, size_t num_editable_elements) { |
| 62 bool ShouldIgnoreForm(size_t num_editable_elements, | 62 if (form.fields.empty()) |
| 63 size_t num_control_elements) { | 63 return false; |
| 64 return (num_editable_elements < kRequiredAutofillFields && | 64 |
| 65 num_control_elements > 0); | 65 // If the form has at least one field with an autocomplete attribute, it is a |
| 66 // candidate for autofill. |
| 67 for (const FormFieldData& field : form.fields) { |
| 68 if (!field.autocomplete_attribute.empty()) |
| 69 return true; |
| 70 } |
| 71 |
| 72 // If there are no autocomplete attributes, the form needs to have at least |
| 73 // the required number of editable fields for the prediction routines to be a |
| 74 // candidate for autofill. |
| 75 return num_editable_elements >= kRequiredFieldsForPredictionRoutines; |
| 66 } | 76 } |
| 67 | 77 |
| 68 } // namespace | 78 } // namespace |
| 69 | 79 |
| 70 FormCache::FormCache(const WebFrame& frame) : frame_(frame) { | 80 FormCache::FormCache(const WebFrame& frame) : frame_(frame) { |
| 71 } | 81 } |
| 72 | 82 |
| 73 FormCache::~FormCache() { | 83 FormCache::~FormCache() { |
| 74 } | 84 } |
| 75 | 85 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 94 | 104 |
| 95 size_t num_fields_seen = 0; | 105 size_t num_fields_seen = 0; |
| 96 for (size_t i = 0; i < web_forms.size(); ++i) { | 106 for (size_t i = 0; i < web_forms.size(); ++i) { |
| 97 const WebFormElement& form_element = web_forms[i]; | 107 const WebFormElement& form_element = web_forms[i]; |
| 98 | 108 |
| 99 std::vector<WebFormControlElement> control_elements = | 109 std::vector<WebFormControlElement> control_elements = |
| 100 form_util::ExtractAutofillableElementsInForm(form_element); | 110 form_util::ExtractAutofillableElementsInForm(form_element); |
| 101 size_t num_editable_elements = | 111 size_t num_editable_elements = |
| 102 ScanFormControlElements(control_elements, log_deprecation_messages); | 112 ScanFormControlElements(control_elements, log_deprecation_messages); |
| 103 | 113 |
| 104 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) | 114 if (num_editable_elements == 0) |
| 105 continue; | 115 continue; |
| 106 | 116 |
| 107 FormData form; | 117 FormData form; |
| 108 if (!WebFormElementToFormData(form_element, WebFormControlElement(), | 118 if (!WebFormElementToFormData(form_element, WebFormControlElement(), |
| 109 extract_mask, &form, nullptr)) { | 119 extract_mask, &form, nullptr)) { |
| 110 continue; | 120 continue; |
| 111 } | 121 } |
| 112 | 122 |
| 113 num_fields_seen += form.fields.size(); | 123 num_fields_seen += form.fields.size(); |
| 114 if (num_fields_seen > form_util::kMaxParseableFields) | 124 if (num_fields_seen > form_util::kMaxParseableFields) |
| 115 return forms; | 125 return forms; |
| 116 | 126 |
| 117 if (form.fields.size() >= kRequiredAutofillFields && | 127 if (!ContainsKey(parsed_forms_, form) && |
| 118 !ContainsKey(parsed_forms_, form)) { | 128 IsFormInteresting(form, num_editable_elements)) { |
| 119 for (auto it = parsed_forms_.begin(); it != parsed_forms_.end(); ++it) { | 129 for (auto it = parsed_forms_.begin(); it != parsed_forms_.end(); ++it) { |
| 120 if (it->SameFormAs(form)) { | 130 if (it->SameFormAs(form)) { |
| 121 parsed_forms_.erase(it); | 131 parsed_forms_.erase(it); |
| 122 break; | 132 break; |
| 123 } | 133 } |
| 124 } | 134 } |
| 125 | 135 |
| 126 SaveInitialValues(control_elements); | 136 SaveInitialValues(control_elements); |
| 127 forms.push_back(form); | 137 forms.push_back(form); |
| 128 parsed_forms_.insert(form); | 138 parsed_forms_.insert(form); |
| 129 } | 139 } |
| 130 } | 140 } |
| 131 | 141 |
| 132 // Look for more parseable fields outside of forms. | 142 // Look for more parseable fields outside of forms. |
| 133 std::vector<WebElement> fieldsets; | 143 std::vector<WebElement> fieldsets; |
| 134 std::vector<WebFormControlElement> control_elements = | 144 std::vector<WebFormControlElement> control_elements = |
| 135 form_util::GetUnownedAutofillableFormFieldElements(document.all(), | 145 form_util::GetUnownedAutofillableFormFieldElements(document.all(), |
| 136 &fieldsets); | 146 &fieldsets); |
| 137 | 147 |
| 138 size_t num_editable_elements = | 148 size_t num_editable_elements = |
| 139 ScanFormControlElements(control_elements, log_deprecation_messages); | 149 ScanFormControlElements(control_elements, log_deprecation_messages); |
| 140 | 150 |
| 141 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) | 151 if (num_editable_elements == 0) |
| 142 return forms; | 152 return forms; |
| 143 | 153 |
| 144 FormData synthetic_form; | 154 FormData synthetic_form; |
| 145 if (!UnownedCheckoutFormElementsAndFieldSetsToFormData( | 155 if (!UnownedCheckoutFormElementsAndFieldSetsToFormData( |
| 146 fieldsets, control_elements, nullptr, document, extract_mask, | 156 fieldsets, control_elements, nullptr, document, extract_mask, |
| 147 &synthetic_form, nullptr)) { | 157 &synthetic_form, nullptr)) { |
| 148 return forms; | 158 return forms; |
| 149 } | 159 } |
| 150 | 160 |
| 151 num_fields_seen += synthetic_form.fields.size(); | 161 num_fields_seen += synthetic_form.fields.size(); |
| 152 if (num_fields_seen > form_util::kMaxParseableFields) | 162 if (num_fields_seen > form_util::kMaxParseableFields) |
| 153 return forms; | 163 return forms; |
| 154 | 164 |
| 155 if (synthetic_form.fields.size() >= kRequiredAutofillFields && | 165 if (!parsed_forms_.count(synthetic_form) && |
| 156 !parsed_forms_.count(synthetic_form)) { | 166 IsFormInteresting(synthetic_form, num_editable_elements)) { |
| 157 SaveInitialValues(control_elements); | 167 SaveInitialValues(control_elements); |
| 158 forms.push_back(synthetic_form); | 168 forms.push_back(synthetic_form); |
| 159 parsed_forms_.insert(synthetic_form); | 169 parsed_forms_.insert(synthetic_form); |
| 160 parsed_forms_.erase(synthetic_form_); | 170 parsed_forms_.erase(synthetic_form_); |
| 161 synthetic_form_ = synthetic_form; | 171 synthetic_form_ = synthetic_form; |
| 162 } | 172 } |
| 163 return forms; | 173 return forms; |
| 164 } | 174 } |
| 165 | 175 |
| 166 void FormCache::Reset() { | 176 void FormCache::Reset() { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 const WebInputElement* input_element = toWebInputElement(&element); | 348 const WebInputElement* input_element = toWebInputElement(&element); |
| 339 if (form_util::IsCheckableElement(input_element)) { | 349 if (form_util::IsCheckableElement(input_element)) { |
| 340 initial_checked_state_.insert( | 350 initial_checked_state_.insert( |
| 341 std::make_pair(*input_element, input_element->isChecked())); | 351 std::make_pair(*input_element, input_element->isChecked())); |
| 342 } | 352 } |
| 343 } | 353 } |
| 344 } | 354 } |
| 345 } | 355 } |
| 346 | 356 |
| 347 } // namespace autofill | 357 } // namespace autofill |
| OLD | NEW |