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/password_form_conversion_utils.h" | 5 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
6 | 6 |
7 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
8 #include "components/autofill/content/renderer/form_autofill_util.h" | 8 #include "components/autofill/content/renderer/form_autofill_util.h" |
9 #include "components/autofill/core/common/form_data_predictions.h" | |
9 #include "components/autofill/core/common/password_form.h" | 10 #include "components/autofill/core/common/password_form.h" |
10 #include "third_party/WebKit/public/platform/WebString.h" | 11 #include "third_party/WebKit/public/platform/WebString.h" |
11 #include "third_party/WebKit/public/web/WebDocument.h" | 12 #include "third_party/WebKit/public/web/WebDocument.h" |
12 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 13 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
13 #include "third_party/WebKit/public/web/WebInputElement.h" | 14 #include "third_party/WebKit/public/web/WebInputElement.h" |
14 | 15 |
15 using blink::WebDocument; | 16 using blink::WebDocument; |
16 using blink::WebFormControlElement; | 17 using blink::WebFormControlElement; |
17 using blink::WebFormElement; | 18 using blink::WebFormElement; |
18 using blink::WebInputElement; | 19 using blink::WebInputElement; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 *new_password = passwords[0]; | 101 *new_password = passwords[0]; |
101 } else { | 102 } else { |
102 // Three different passwords, or first and last match with middle | 103 // Three different passwords, or first and last match with middle |
103 // different. No idea which is which, so no luck. | 104 // different. No idea which is which, so no luck. |
104 return false; | 105 return false; |
105 } | 106 } |
106 } | 107 } |
107 return true; | 108 return true; |
108 } | 109 } |
109 | 110 |
111 void FindPredictedUsernameElement( | |
112 const WebFormElement& form, | |
113 const std::map<autofill::FormData, autofill::FormFieldData>& | |
114 form_predictions, | |
115 WebVector<WebFormControlElement>* control_elements, | |
116 WebInputElement& predicted_username_element) { | |
Ilya Sherman
2015/03/26 00:30:04
You should never pass a value by non-const referen
dvadym
2015/03/26 12:29:13
Done.
| |
117 FormData form_data; | |
118 if (!WebFormElementToFormData(form, WebFormControlElement(), REQUIRE_NONE, | |
119 EXTRACT_NONE, &form_data, nullptr)) | |
120 return; | |
121 | |
122 // Prediction forms are not user submitted, but |form| can be user submitted. | |
123 // We don't care about this flag for finding predictions, so set it to false. | |
124 form_data.user_submitted = false; | |
125 auto predictions_iterator = form_predictions.find(form_data); | |
126 if (predictions_iterator == form_predictions.end()) | |
127 return; | |
128 | |
129 std::vector<blink::WebFormControlElement> autofillable_elements = | |
130 ExtractAutofillableElementsFromSet(*control_elements, REQUIRE_NONE); | |
131 DCHECK_EQ(autofillable_elements.size(), form_data.fields.size()); | |
132 | |
133 const autofill::FormFieldData& username_field = predictions_iterator->second; | |
134 autofill::FormFieldData form_field; | |
135 for (size_t i = 0; i < autofillable_elements.size(); ++i) { | |
136 if (form_data.fields[i].SameFieldAs(username_field)) { | |
137 predicted_username_element = | |
138 *toWebInputElement(&autofillable_elements[i]); | |
139 break; | |
140 } | |
141 } | |
142 } | |
143 | |
110 // Get information about a login form encapsulated in a PasswordForm struct. | 144 // Get information about a login form encapsulated in a PasswordForm struct. |
111 // If an element of |form| has an entry in |nonscript_modified_values|, the | 145 // If an element of |form| has an entry in |nonscript_modified_values|, the |
112 // associated string is used instead of the element's value to create | 146 // associated string is used instead of the element's value to create |
113 // the PasswordForm. | 147 // the PasswordForm. |
114 void GetPasswordForm( | 148 void GetPasswordForm( |
115 const WebFormElement& form, | 149 const WebFormElement& form, |
116 PasswordForm* password_form, | 150 PasswordForm* password_form, |
117 const std::map<const blink::WebInputElement, blink::WebString>* | 151 const std::map<const blink::WebInputElement, blink::WebString>* |
118 nonscript_modified_values) { | 152 nonscript_modified_values, |
153 const std::map<autofill::FormData, autofill::FormFieldData>* | |
154 form_predictions) { | |
119 WebInputElement latest_input_element; | 155 WebInputElement latest_input_element; |
120 WebInputElement username_element; | 156 WebInputElement username_element; |
121 password_form->username_marked_by_site = false; | 157 password_form->username_marked_by_site = false; |
122 std::vector<WebInputElement> passwords; | 158 std::vector<WebInputElement> passwords; |
123 std::vector<base::string16> other_possible_usernames; | 159 std::vector<base::string16> other_possible_usernames; |
124 | 160 |
125 WebVector<WebFormControlElement> control_elements; | 161 WebVector<WebFormControlElement> control_elements; |
126 form.getFormControlElements(control_elements); | 162 form.getFormControlElements(control_elements); |
127 | 163 |
128 for (size_t i = 0; i < control_elements.size(); ++i) { | 164 for (size_t i = 0; i < control_elements.size(); ++i) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 // alternative, at least for now. | 224 // alternative, at least for now. |
189 if (username_element.isNull()) | 225 if (username_element.isNull()) |
190 latest_input_element = *input_element; | 226 latest_input_element = *input_element; |
191 if (!input_element->value().isEmpty()) | 227 if (!input_element->value().isEmpty()) |
192 other_possible_usernames.push_back(input_element->value()); | 228 other_possible_usernames.push_back(input_element->value()); |
193 } | 229 } |
194 } | 230 } |
195 } | 231 } |
196 } | 232 } |
197 | 233 |
234 WebInputElement predicted_username_element; | |
235 if (form_predictions) { | |
236 FindPredictedUsernameElement(form, *form_predictions, &control_elements, | |
237 predicted_username_element); | |
238 } | |
239 // Now server predictions has more priority then autocomplete='username'. It | |
vabr (Chromium)
2015/03/26 09:43:55
An attempt at making this comment shorter and clea
dvadym
2015/03/26 12:29:13
Done.
| |
240 // was decided to do in such way since it is more flexible. It allows to make | |
241 // fixes from server side without changing code. | |
242 if (!predicted_username_element.isNull() && | |
243 username_element != predicted_username_element) { | |
244 auto it = | |
245 find(other_possible_usernames.begin(), other_possible_usernames.end(), | |
246 predicted_username_element.value()); | |
247 if (it != other_possible_usernames.end()) | |
248 other_possible_usernames.erase(it); | |
249 if (!username_element.isNull()) { | |
250 other_possible_usernames.push_back(username_element.value()); | |
251 } | |
252 username_element = predicted_username_element; | |
253 password_form->parsed_using_autofill_predictions = true; | |
254 } | |
255 | |
198 if (!username_element.isNull()) { | 256 if (!username_element.isNull()) { |
199 password_form->username_element = username_element.nameForAutofill(); | 257 password_form->username_element = username_element.nameForAutofill(); |
200 base::string16 username_value = username_element.value(); | 258 base::string16 username_value = username_element.value(); |
201 if (nonscript_modified_values != nullptr) { | 259 if (nonscript_modified_values != nullptr) { |
202 auto username_iterator = | 260 auto username_iterator = |
203 nonscript_modified_values->find(username_element); | 261 nonscript_modified_values->find(username_element); |
204 if (username_iterator != nonscript_modified_values->end()) { | 262 if (username_iterator != nonscript_modified_values->end()) { |
205 base::string16 typed_username_value = username_iterator->second; | 263 base::string16 typed_username_value = username_iterator->second; |
206 if (!StartsWith(username_value, typed_username_value, false)) { | 264 if (!StartsWith(username_value, typed_username_value, false)) { |
207 // We check that |username_value| was not obtained by autofilling | 265 // We check that |username_value| was not obtained by autofilling |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 password_form->preferred = false; | 324 password_form->preferred = false; |
267 password_form->blacklisted_by_user = false; | 325 password_form->blacklisted_by_user = false; |
268 password_form->type = PasswordForm::TYPE_MANUAL; | 326 password_form->type = PasswordForm::TYPE_MANUAL; |
269 } | 327 } |
270 | 328 |
271 } // namespace | 329 } // namespace |
272 | 330 |
273 scoped_ptr<PasswordForm> CreatePasswordForm( | 331 scoped_ptr<PasswordForm> CreatePasswordForm( |
274 const WebFormElement& web_form, | 332 const WebFormElement& web_form, |
275 const std::map<const blink::WebInputElement, blink::WebString>* | 333 const std::map<const blink::WebInputElement, blink::WebString>* |
276 nonscript_modified_values) { | 334 nonscript_modified_values, |
335 const std::map<autofill::FormData, autofill::FormFieldData>* | |
336 form_predictions) { | |
277 if (web_form.isNull()) | 337 if (web_form.isNull()) |
278 return scoped_ptr<PasswordForm>(); | 338 return scoped_ptr<PasswordForm>(); |
279 | 339 |
280 scoped_ptr<PasswordForm> password_form(new PasswordForm()); | 340 scoped_ptr<PasswordForm> password_form(new PasswordForm()); |
281 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values); | 341 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, |
342 form_predictions); | |
282 | 343 |
283 if (!password_form->action.is_valid()) | 344 if (!password_form->action.is_valid()) |
284 return scoped_ptr<PasswordForm>(); | 345 return scoped_ptr<PasswordForm>(); |
285 | 346 |
286 WebFormElementToFormData(web_form, | 347 WebFormElementToFormData(web_form, |
287 blink::WebFormControlElement(), | 348 blink::WebFormControlElement(), |
288 REQUIRE_NONE, | 349 REQUIRE_NONE, |
289 EXTRACT_NONE, | 350 EXTRACT_NONE, |
290 &password_form->form_data, | 351 &password_form->form_data, |
291 NULL /* FormFieldData */); | 352 NULL /* FormFieldData */); |
292 | 353 |
293 return password_form.Pass(); | 354 return password_form.Pass(); |
294 } | 355 } |
295 | 356 |
296 } // namespace autofill | 357 } // namespace autofill |
OLD | NEW |