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 <vector> | |
8 | |
7 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
8 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
9 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
10 #include "components/autofill/content/renderer/form_autofill_util.h" | 12 #include "components/autofill/content/renderer/form_autofill_util.h" |
13 #include "components/autofill/core/common/form_data_predictions.h" | |
11 #include "components/autofill/core/common/password_form.h" | 14 #include "components/autofill/core/common/password_form.h" |
12 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
13 #include "third_party/WebKit/public/web/WebDocument.h" | 16 #include "third_party/WebKit/public/web/WebDocument.h" |
14 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 17 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
15 #include "third_party/WebKit/public/web/WebInputElement.h" | 18 #include "third_party/WebKit/public/web/WebInputElement.h" |
16 #include "third_party/icu/source/i18n/unicode/regex.h" | 19 #include "third_party/icu/source/i18n/unicode/regex.h" |
17 | 20 |
18 using blink::WebDocument; | 21 using blink::WebDocument; |
19 using blink::WebFormControlElement; | 22 using blink::WebFormControlElement; |
20 using blink::WebFormElement; | 23 using blink::WebFormElement; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 *new_password = passwords[0]; | 173 *new_password = passwords[0]; |
171 } else { | 174 } else { |
172 // Three different passwords, or first and last match with middle | 175 // Three different passwords, or first and last match with middle |
173 // different. No idea which is which, so no luck. | 176 // different. No idea which is which, so no luck. |
174 return false; | 177 return false; |
175 } | 178 } |
176 } | 179 } |
177 return true; | 180 return true; |
178 } | 181 } |
179 | 182 |
183 void FindPredictedUsernameElement( | |
184 const WebFormElement& form, | |
185 const std::map<autofill::FormData, autofill::FormFieldData>& | |
186 form_predictions, | |
187 WebVector<WebFormControlElement>* control_elements, | |
188 WebInputElement* predicted_username_element) { | |
189 FormData form_data; | |
190 if (!WebFormElementToFormData(form, WebFormControlElement(), REQUIRE_NONE, | |
191 EXTRACT_NONE, &form_data, nullptr)) | |
192 return; | |
193 | |
194 // Prediction forms are not user submitted, but |form| can be user submitted. | |
195 // We don't care about this flag for finding predictions, so set it to false. | |
196 form_data.user_submitted = false; | |
197 auto predictions_iterator = form_predictions.find(form_data); | |
198 if (predictions_iterator == form_predictions.end()) | |
199 return; | |
200 | |
201 std::vector<blink::WebFormControlElement> autofillable_elements = | |
202 ExtractAutofillableElementsFromSet(*control_elements, REQUIRE_NONE); | |
203 DCHECK_EQ(autofillable_elements.size(), form_data.fields.size()); | |
204 | |
205 const autofill::FormFieldData& username_field = predictions_iterator->second; | |
206 autofill::FormFieldData form_field; | |
207 for (size_t i = 0; i < autofillable_elements.size(); ++i) { | |
208 if (form_data.fields[i].SameFieldAs(username_field)) { | |
209 *predicted_username_element = | |
210 *toWebInputElement(&autofillable_elements[i]); | |
Ilya Sherman
2015/03/31 00:45:04
Note that toWebInputElement() can return a null po
dvadym
2015/03/31 09:54:03
Thanks, it makes sense. Done
| |
211 break; | |
212 } | |
213 } | |
214 } | |
215 | |
180 // Get information about a login form encapsulated in a PasswordForm struct. | 216 // Get information about a login form encapsulated in a PasswordForm struct. |
181 // If an element of |form| has an entry in |nonscript_modified_values|, the | 217 // If an element of |form| has an entry in |nonscript_modified_values|, the |
182 // associated string is used instead of the element's value to create | 218 // associated string is used instead of the element's value to create |
183 // the PasswordForm. | 219 // the PasswordForm. |
184 void GetPasswordForm( | 220 void GetPasswordForm( |
185 const WebFormElement& form, | 221 const WebFormElement& form, |
186 PasswordForm* password_form, | 222 PasswordForm* password_form, |
187 const std::map<const blink::WebInputElement, blink::WebString>* | 223 const std::map<const blink::WebInputElement, blink::WebString>* |
188 nonscript_modified_values) { | 224 nonscript_modified_values, |
225 const std::map<autofill::FormData, autofill::FormFieldData>* | |
226 form_predictions) { | |
189 WebInputElement latest_input_element; | 227 WebInputElement latest_input_element; |
190 WebInputElement username_element; | 228 WebInputElement username_element; |
191 password_form->username_marked_by_site = false; | 229 password_form->username_marked_by_site = false; |
192 std::vector<WebInputElement> passwords; | 230 std::vector<WebInputElement> passwords; |
193 std::vector<base::string16> other_possible_usernames; | 231 std::vector<base::string16> other_possible_usernames; |
194 | 232 |
195 WebVector<WebFormControlElement> control_elements; | 233 WebVector<WebFormControlElement> control_elements; |
196 form.getFormControlElements(control_elements); | 234 form.getFormControlElements(control_elements); |
197 | 235 |
198 std::string layout_sequence; | 236 std::string layout_sequence; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 if (username_element.isNull()) | 306 if (username_element.isNull()) |
269 latest_input_element = *input_element; | 307 latest_input_element = *input_element; |
270 if (!input_element->value().isEmpty()) | 308 if (!input_element->value().isEmpty()) |
271 other_possible_usernames.push_back(input_element->value()); | 309 other_possible_usernames.push_back(input_element->value()); |
272 } | 310 } |
273 } | 311 } |
274 } | 312 } |
275 } | 313 } |
276 password_form->layout = SequenceToLayout(layout_sequence); | 314 password_form->layout = SequenceToLayout(layout_sequence); |
277 | 315 |
316 WebInputElement predicted_username_element; | |
317 if (form_predictions) { | |
318 FindPredictedUsernameElement(form, *form_predictions, &control_elements, | |
319 &predicted_username_element); | |
320 } | |
321 // Let server predictions override the selection of the username field. This | |
322 // allows instant adjusting without changing Chromium code. | |
323 if (!predicted_username_element.isNull() && | |
324 username_element != predicted_username_element) { | |
325 auto it = | |
326 find(other_possible_usernames.begin(), other_possible_usernames.end(), | |
327 predicted_username_element.value()); | |
328 if (it != other_possible_usernames.end()) | |
329 other_possible_usernames.erase(it); | |
330 if (!username_element.isNull()) { | |
331 other_possible_usernames.push_back(username_element.value()); | |
332 } | |
333 username_element = predicted_username_element; | |
334 password_form->parsed_using_autofill_predictions = true; | |
335 } | |
336 | |
278 if (!username_element.isNull()) { | 337 if (!username_element.isNull()) { |
279 password_form->username_element = username_element.nameForAutofill(); | 338 password_form->username_element = username_element.nameForAutofill(); |
280 base::string16 username_value = username_element.value(); | 339 base::string16 username_value = username_element.value(); |
281 if (nonscript_modified_values != nullptr) { | 340 if (nonscript_modified_values != nullptr) { |
282 auto username_iterator = | 341 auto username_iterator = |
283 nonscript_modified_values->find(username_element); | 342 nonscript_modified_values->find(username_element); |
284 if (username_iterator != nonscript_modified_values->end()) { | 343 if (username_iterator != nonscript_modified_values->end()) { |
285 base::string16 typed_username_value = username_iterator->second; | 344 base::string16 typed_username_value = username_iterator->second; |
286 if (!StartsWith(username_value, typed_username_value, false)) { | 345 if (!StartsWith(username_value, typed_username_value, false)) { |
287 // We check that |username_value| was not obtained by autofilling | 346 // We check that |username_value| was not obtained by autofilling |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 password_form->preferred = false; | 405 password_form->preferred = false; |
347 password_form->blacklisted_by_user = false; | 406 password_form->blacklisted_by_user = false; |
348 password_form->type = PasswordForm::TYPE_MANUAL; | 407 password_form->type = PasswordForm::TYPE_MANUAL; |
349 } | 408 } |
350 | 409 |
351 } // namespace | 410 } // namespace |
352 | 411 |
353 scoped_ptr<PasswordForm> CreatePasswordForm( | 412 scoped_ptr<PasswordForm> CreatePasswordForm( |
354 const WebFormElement& web_form, | 413 const WebFormElement& web_form, |
355 const std::map<const blink::WebInputElement, blink::WebString>* | 414 const std::map<const blink::WebInputElement, blink::WebString>* |
356 nonscript_modified_values) { | 415 nonscript_modified_values, |
416 const std::map<autofill::FormData, autofill::FormFieldData>* | |
417 form_predictions) { | |
357 if (web_form.isNull()) | 418 if (web_form.isNull()) |
358 return scoped_ptr<PasswordForm>(); | 419 return scoped_ptr<PasswordForm>(); |
359 | 420 |
360 scoped_ptr<PasswordForm> password_form(new PasswordForm()); | 421 scoped_ptr<PasswordForm> password_form(new PasswordForm()); |
361 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values); | 422 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, |
423 form_predictions); | |
362 | 424 |
363 if (!password_form->action.is_valid()) | 425 if (!password_form->action.is_valid()) |
364 return scoped_ptr<PasswordForm>(); | 426 return scoped_ptr<PasswordForm>(); |
365 | 427 |
366 WebFormElementToFormData(web_form, | 428 WebFormElementToFormData(web_form, |
367 blink::WebFormControlElement(), | 429 blink::WebFormControlElement(), |
368 REQUIRE_NONE, | 430 REQUIRE_NONE, |
369 EXTRACT_NONE, | 431 EXTRACT_NONE, |
370 &password_form->form_data, | 432 &password_form->form_data, |
371 NULL /* FormFieldData */); | 433 NULL /* FormFieldData */); |
372 | 434 |
373 return password_form.Pass(); | 435 return password_form.Pass(); |
374 } | 436 } |
375 | 437 |
376 } // namespace autofill | 438 } // namespace autofill |
OLD | NEW |