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