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" |
11 #include "components/autofill/core/common/autofill_constants.h" | 11 #include "components/autofill/core/common/autofill_constants.h" |
12 #include "components/autofill/core/common/form_data.h" | 12 #include "components/autofill/core/common/form_data.h" |
13 #include "components/autofill/core/common/form_data_predictions.h" | 13 #include "components/autofill/core/common/form_data_predictions.h" |
14 #include "grit/components_strings.h" | 14 #include "grit/components_strings.h" |
15 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
16 #include "third_party/WebKit/public/platform/WebVector.h" | 16 #include "third_party/WebKit/public/platform/WebVector.h" |
17 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | 17 #include "third_party/WebKit/public/web/WebConsoleMessage.h" |
18 #include "third_party/WebKit/public/web/WebDocument.h" | 18 #include "third_party/WebKit/public/web/WebDocument.h" |
19 #include "third_party/WebKit/public/web/WebElementCollection.h" | |
20 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 19 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
21 #include "third_party/WebKit/public/web/WebFormElement.h" | 20 #include "third_party/WebKit/public/web/WebFormElement.h" |
22 #include "third_party/WebKit/public/web/WebInputElement.h" | 21 #include "third_party/WebKit/public/web/WebInputElement.h" |
23 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 22 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
24 #include "third_party/WebKit/public/web/WebNodeList.h" | 23 #include "third_party/WebKit/public/web/WebNodeList.h" |
25 #include "third_party/WebKit/public/web/WebSelectElement.h" | 24 #include "third_party/WebKit/public/web/WebSelectElement.h" |
26 #include "third_party/WebKit/public/web/WebTextAreaElement.h" | 25 #include "third_party/WebKit/public/web/WebTextAreaElement.h" |
27 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
28 | 27 |
29 using blink::WebConsoleMessage; | 28 using blink::WebConsoleMessage; |
30 using blink::WebDocument; | 29 using blink::WebDocument; |
31 using blink::WebElement; | 30 using blink::WebElement; |
32 using blink::WebElementCollection; | |
33 using blink::WebFormControlElement; | 31 using blink::WebFormControlElement; |
34 using blink::WebFormElement; | 32 using blink::WebFormElement; |
35 using blink::WebFrame; | 33 using blink::WebFrame; |
36 using blink::WebInputElement; | 34 using blink::WebInputElement; |
37 using blink::WebNode; | 35 using blink::WebNode; |
38 using blink::WebSelectElement; | 36 using blink::WebSelectElement; |
39 using blink::WebString; | 37 using blink::WebString; |
40 using blink::WebTextAreaElement; | 38 using blink::WebTextAreaElement; |
41 using blink::WebVector; | 39 using blink::WebVector; |
42 | 40 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 continue; | 78 continue; |
81 std::string msg = std::string("autocomplete='") + deprecated[i] + | 79 std::string msg = std::string("autocomplete='") + deprecated[i] + |
82 "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"; | 80 "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"; |
83 WebConsoleMessage console_message = WebConsoleMessage( | 81 WebConsoleMessage console_message = WebConsoleMessage( |
84 WebConsoleMessage::LevelWarning, | 82 WebConsoleMessage::LevelWarning, |
85 WebString(base::ASCIIToUTF16(msg))); | 83 WebString(base::ASCIIToUTF16(msg))); |
86 element.document().frame()->addMessageToConsole(console_message); | 84 element.document().frame()->addMessageToConsole(console_message); |
87 } | 85 } |
88 } | 86 } |
89 | 87 |
90 bool IsElementInsideFormOrFieldSet(const WebElement& element) { | |
91 for (WebNode parent_node = element.parentNode(); | |
92 !parent_node.isNull(); | |
93 parent_node = parent_node.parentNode()) { | |
94 if (!parent_node.isElementNode()) | |
95 continue; | |
96 | |
97 WebElement cur_element = parent_node.to<WebElement>(); | |
98 if (cur_element.hasHTMLTagName("form") || | |
99 cur_element.hasHTMLTagName("fieldset")) { | |
100 return true; | |
101 } | |
102 } | |
103 return false; | |
104 } | |
105 | |
106 // To avoid overly expensive computation, we impose a minimum number of | 88 // To avoid overly expensive computation, we impose a minimum number of |
107 // allowable fields. The corresponding maximum number of allowable fields | 89 // allowable fields. The corresponding maximum number of allowable fields |
108 // is imposed by WebFormElementToFormData(). | 90 // is imposed by WebFormElementToFormData(). |
109 bool ShouldIgnoreForm(size_t num_editable_elements, | 91 bool ShouldIgnoreForm(size_t num_editable_elements, |
110 size_t num_control_elements) { | 92 size_t num_control_elements) { |
111 return (num_editable_elements < kRequiredAutofillFields && | 93 return (num_editable_elements < kRequiredAutofillFields && |
112 num_control_elements > 0); | 94 num_control_elements > 0); |
113 } | 95 } |
114 | 96 |
115 } // namespace | 97 } // namespace |
116 | 98 |
117 FormCache::FormCache() { | 99 FormCache::FormCache() { |
118 } | 100 } |
119 | 101 |
120 FormCache::~FormCache() { | 102 FormCache::~FormCache() { |
121 } | 103 } |
122 | 104 |
123 // static | |
124 std::vector<WebFormControlElement> | |
125 FormCache::GetUnownedAutofillableFormFieldElements( | |
126 const WebElementCollection& elements, | |
127 std::vector<WebElement>* fieldsets) { | |
128 std::vector<WebFormControlElement> unowned_fieldset_children; | |
129 for (WebElement element = elements.firstItem(); | |
130 !element.isNull(); | |
131 element = elements.nextItem()) { | |
132 if (element.isFormControlElement()) { | |
133 WebFormControlElement control = element.to<WebFormControlElement>(); | |
134 if (control.form().isNull()) | |
135 unowned_fieldset_children.push_back(control); | |
136 } | |
137 | |
138 if (fieldsets && element.hasHTMLTagName("fieldset") && | |
139 !IsElementInsideFormOrFieldSet(element)) { | |
140 fieldsets->push_back(element); | |
141 } | |
142 } | |
143 return ExtractAutofillableElementsFromSet(unowned_fieldset_children, | |
144 REQUIRE_NONE); | |
145 } | |
146 | |
147 std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) { | 105 std::vector<FormData> FormCache::ExtractNewForms(const WebFrame& frame) { |
148 std::vector<FormData> forms; | 106 std::vector<FormData> forms; |
149 WebDocument document = frame.document(); | 107 WebDocument document = frame.document(); |
150 if (document.isNull()) | 108 if (document.isNull()) |
151 return forms; | 109 return forms; |
152 | 110 |
153 if (!ContainsKey(documents_to_synthetic_form_map_, document)) | 111 if (!ContainsKey(documents_to_synthetic_form_map_, document)) |
154 documents_to_synthetic_form_map_[document] = FormData(); | 112 documents_to_synthetic_form_map_[document] = FormData(); |
155 | 113 |
156 WebVector<WebFormElement> web_forms; | 114 WebVector<WebFormElement> web_forms; |
(...skipping 13 matching lines...) Expand all Loading... |
170 std::vector<WebFormControlElement> control_elements = | 128 std::vector<WebFormControlElement> control_elements = |
171 ExtractAutofillableElementsInForm(form_element, REQUIRE_NONE); | 129 ExtractAutofillableElementsInForm(form_element, REQUIRE_NONE); |
172 size_t num_editable_elements = | 130 size_t num_editable_elements = |
173 ScanFormControlElements(control_elements, log_deprecation_messages); | 131 ScanFormControlElements(control_elements, log_deprecation_messages); |
174 | 132 |
175 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) | 133 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) |
176 continue; | 134 continue; |
177 | 135 |
178 FormData form; | 136 FormData form; |
179 if (!WebFormElementToFormData(form_element, WebFormControlElement(), | 137 if (!WebFormElementToFormData(form_element, WebFormControlElement(), |
180 REQUIRE_NONE, extract_mask, &form, NULL)) { | 138 REQUIRE_NONE, extract_mask, &form, nullptr)) { |
181 continue; | 139 continue; |
182 } | 140 } |
183 | 141 |
184 num_fields_seen += form.fields.size(); | 142 num_fields_seen += form.fields.size(); |
185 if (num_fields_seen > kMaxParseableFields) | 143 if (num_fields_seen > kMaxParseableFields) |
186 return forms; | 144 return forms; |
187 | 145 |
188 if (form.fields.size() >= kRequiredAutofillFields && | 146 if (form.fields.size() >= kRequiredAutofillFields && |
189 !ContainsKey(parsed_forms_[&frame], form)) { | 147 !ContainsKey(parsed_forms_[&frame], form)) { |
190 forms.push_back(form); | 148 forms.push_back(form); |
191 parsed_forms_[&frame].insert(form); | 149 parsed_forms_[&frame].insert(form); |
192 } | 150 } |
193 } | 151 } |
194 | 152 |
195 // Look for more parseable fields outside of forms. | 153 // Look for more parseable fields outside of forms. |
196 std::vector<WebElement> fieldsets; | 154 std::vector<WebElement> fieldsets; |
197 std::vector<WebFormControlElement> control_elements = | 155 std::vector<WebFormControlElement> control_elements = |
198 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); | 156 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); |
199 | 157 |
200 size_t num_editable_elements = | 158 size_t num_editable_elements = |
201 ScanFormControlElements(control_elements, log_deprecation_messages); | 159 ScanFormControlElements(control_elements, log_deprecation_messages); |
202 | 160 |
203 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) | 161 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) |
204 return forms; | 162 return forms; |
205 | 163 |
206 FormData form; | 164 FormData form; |
207 if (!UnownedFormElementsAndFieldSetsToFormData(fieldsets, control_elements, | 165 if (!UnownedFormElementsAndFieldSetsToFormData(fieldsets, control_elements, |
208 document.url(), extract_mask, | 166 nullptr, document.url(), |
209 &form)) { | 167 REQUIRE_NONE, extract_mask, |
| 168 &form, nullptr)) { |
210 return forms; | 169 return forms; |
211 } | 170 } |
212 | 171 |
213 num_fields_seen += form.fields.size(); | 172 num_fields_seen += form.fields.size(); |
214 if (num_fields_seen > kMaxParseableFields) | 173 if (num_fields_seen > kMaxParseableFields) |
215 return forms; | 174 return forms; |
216 | 175 |
217 if (form.fields.size() >= kRequiredAutofillFields && | 176 if (form.fields.size() >= kRequiredAutofillFields && |
218 !parsed_forms_[&frame].count(form)) { | 177 !parsed_forms_[&frame].count(form)) { |
219 forms.push_back(form); | 178 forms.push_back(form); |
(...skipping 14 matching lines...) Expand all Loading... |
234 for (const auto& it : documents_to_delete) | 193 for (const auto& it : documents_to_delete) |
235 documents_to_synthetic_form_map_.erase(it); | 194 documents_to_synthetic_form_map_.erase(it); |
236 | 195 |
237 parsed_forms_[&frame].clear(); | 196 parsed_forms_[&frame].clear(); |
238 RemoveOldElements(frame, &initial_select_values_); | 197 RemoveOldElements(frame, &initial_select_values_); |
239 RemoveOldElements(frame, &initial_checked_state_); | 198 RemoveOldElements(frame, &initial_checked_state_); |
240 } | 199 } |
241 | 200 |
242 bool FormCache::ClearFormWithElement(const WebFormControlElement& element) { | 201 bool FormCache::ClearFormWithElement(const WebFormControlElement& element) { |
243 WebFormElement form_element = element.form(); | 202 WebFormElement form_element = element.form(); |
244 if (form_element.isNull()) | 203 std::vector<WebFormControlElement> control_elements; |
245 return false; | 204 if (form_element.isNull()) { |
246 | 205 control_elements = GetUnownedAutofillableFormFieldElements( |
247 std::vector<WebFormControlElement> control_elements = | 206 element.document().all(), nullptr); |
248 ExtractAutofillableElementsInForm(form_element, REQUIRE_NONE); | 207 } else { |
| 208 control_elements = ExtractAutofillableElementsInForm( |
| 209 form_element, REQUIRE_NONE); |
| 210 } |
249 for (size_t i = 0; i < control_elements.size(); ++i) { | 211 for (size_t i = 0; i < control_elements.size(); ++i) { |
250 WebFormControlElement control_element = control_elements[i]; | 212 WebFormControlElement control_element = control_elements[i]; |
251 // Don't modify the value of disabled fields. | 213 // Don't modify the value of disabled fields. |
252 if (!control_element.isEnabled()) | 214 if (!control_element.isEnabled()) |
253 continue; | 215 continue; |
254 | 216 |
255 // Don't clear field that was not autofilled | 217 // Don't clear field that was not autofilled |
256 if (!control_element.isAutofilled()) | 218 if (!control_element.isAutofilled()) |
257 continue; | 219 continue; |
258 | 220 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 std::make_pair(input_element, input_element.isChecked())); | 370 std::make_pair(input_element, input_element.isChecked())); |
409 } else { | 371 } else { |
410 ++num_editable_elements; | 372 ++num_editable_elements; |
411 } | 373 } |
412 } | 374 } |
413 } | 375 } |
414 return num_editable_elements; | 376 return num_editable_elements; |
415 } | 377 } |
416 | 378 |
417 } // namespace autofill | 379 } // namespace autofill |
OLD | NEW |