Chromium Code Reviews| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 base::LazyInstance<re2::RE2, PasswordSiteUrlLazyInstanceTraits> | 306 base::LazyInstance<re2::RE2, PasswordSiteUrlLazyInstanceTraits> |
| 307 g_password_site_matcher = LAZY_INSTANCE_INITIALIZER; | 307 g_password_site_matcher = LAZY_INSTANCE_INITIALIZER; |
| 308 | 308 |
| 309 // Returns the |input_field| name if its non-empty; otherwise a |dummy_name|. | 309 // Returns the |input_field| name if its non-empty; otherwise a |dummy_name|. |
| 310 base::string16 FieldName(const WebInputElement& input_field, | 310 base::string16 FieldName(const WebInputElement& input_field, |
| 311 const char dummy_name[]) { | 311 const char dummy_name[]) { |
| 312 base::string16 field_name = input_field.nameForAutofill(); | 312 base::string16 field_name = input_field.nameForAutofill(); |
| 313 return field_name.empty() ? base::ASCIIToUTF16(dummy_name) : field_name; | 313 return field_name.empty() ? base::ASCIIToUTF16(dummy_name) : field_name; |
| 314 } | 314 } |
| 315 | 315 |
| 316 bool FormContainsVisiblePasswordFields(const SyntheticForm& form) { | 316 // Helper function that checks the presence of visible password and username |
| 317 // fields in |form.control_elements|. | |
| 318 // Iff a visible password found, then |*found_visible_password| is set to true. | |
| 319 // Iff a visible password found AND there is a visible username before it, then | |
| 320 // |*found_visible_username_before_visible_password| is set to true. | |
| 321 void FoundVisiblePasswordAndVisibleUsernameBeforePassword( | |
| 322 const SyntheticForm& form, | |
| 323 bool* found_visible_password, | |
| 324 bool* found_visible_username_before_visible_password) { | |
| 325 DCHECK(found_visible_password != nullptr); | |
|
dvadym
2016/01/27 14:05:51
You don't need to write != nullptr,
DCHECK(found_v
kolos1
2016/01/27 15:14:24
Thanks. Fixed
| |
| 326 DCHECK(found_visible_username_before_visible_password != nullptr); | |
| 327 *found_visible_password = false; | |
| 328 *found_visible_username_before_visible_password = false; | |
| 329 | |
| 330 bool found_visible_username = false; | |
| 317 for (auto& control_element : form.control_elements) { | 331 for (auto& control_element : form.control_elements) { |
| 318 const WebInputElement* input_element = toWebInputElement(&control_element); | 332 const WebInputElement* input_element = toWebInputElement(&control_element); |
| 319 if (!input_element || !input_element->isEnabled()) | 333 if (!input_element || !input_element->isEnabled() || |
| 334 !input_element->isTextField()) | |
| 320 continue; | 335 continue; |
| 321 | 336 |
| 322 if (input_element->isPasswordField() && | 337 if (!form_util::IsWebNodeVisible(*input_element)) |
| 323 form_util::IsWebNodeVisible(*input_element)) | 338 continue; |
| 324 return true; | 339 |
| 340 if (input_element->isPasswordField()) { | |
| 341 *found_visible_password = true; | |
| 342 *found_visible_username_before_visible_password = found_visible_username; | |
| 343 break; | |
| 344 } else { | |
| 345 found_visible_username = true; | |
| 346 } | |
| 325 } | 347 } |
| 326 return false; | |
| 327 } | 348 } |
| 328 | 349 |
| 329 // Get information about a login form encapsulated in a PasswordForm struct. | 350 // Get information about a login form encapsulated in a PasswordForm struct. |
| 330 // If an element of |form| has an entry in |nonscript_modified_values|, the | 351 // If an element of |form| has an entry in |nonscript_modified_values|, the |
| 331 // associated string is used instead of the element's value to create | 352 // associated string is used instead of the element's value to create |
| 332 // the PasswordForm. | 353 // the PasswordForm. |
| 333 bool GetPasswordForm(const SyntheticForm& form, | 354 bool GetPasswordForm(const SyntheticForm& form, |
| 334 PasswordForm* password_form, | 355 PasswordForm* password_form, |
| 335 const ModifiedValues* nonscript_modified_values, | 356 const ModifiedValues* nonscript_modified_values, |
| 336 const FormsPredictionsMap* form_predictions) { | 357 const FormsPredictionsMap* form_predictions) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 350 form.control_elements)) { | 371 form.control_elements)) { |
| 351 return false; | 372 return false; |
| 352 } | 373 } |
| 353 | 374 |
| 354 std::map<WebInputElement, PasswordFormFieldPredictionType> predicted_elements; | 375 std::map<WebInputElement, PasswordFormFieldPredictionType> predicted_elements; |
| 355 if (form_predictions) { | 376 if (form_predictions) { |
| 356 FindPredictedElements(form, password_form->form_data, *form_predictions, | 377 FindPredictedElements(form, password_form->form_data, *form_predictions, |
| 357 &predicted_elements); | 378 &predicted_elements); |
| 358 } | 379 } |
| 359 | 380 |
| 381 // Check the presence of visible password and username fields. | |
| 382 // If there is a visible password field, then ignore invisible password | |
| 383 // fields. If there is a visible username before visible password, then ignore | |
| 384 // invisible username fields. | |
| 385 // If there is no visible password field, don't ignore any elements (i.e. use | |
| 386 // the latest username field just before selected password field). | |
| 387 bool ignore_invisible_passwords = false; | |
| 388 bool ignore_invisible_usernames = false; | |
| 389 FoundVisiblePasswordAndVisibleUsernameBeforePassword( | |
| 390 form, &ignore_invisible_passwords, &ignore_invisible_usernames); | |
| 360 std::string layout_sequence; | 391 std::string layout_sequence; |
| 361 layout_sequence.reserve(form.control_elements.size()); | 392 layout_sequence.reserve(form.control_elements.size()); |
| 362 bool ignore_invisible_fields = FormContainsVisiblePasswordFields(form); | |
| 363 for (size_t i = 0; i < form.control_elements.size(); ++i) { | 393 for (size_t i = 0; i < form.control_elements.size(); ++i) { |
| 364 WebFormControlElement control_element = form.control_elements[i]; | 394 WebFormControlElement control_element = form.control_elements[i]; |
| 365 | 395 |
| 366 WebInputElement* input_element = toWebInputElement(&control_element); | 396 WebInputElement* input_element = toWebInputElement(&control_element); |
| 367 if (!input_element || !input_element->isEnabled()) | 397 if (!input_element || !input_element->isEnabled()) |
| 368 continue; | 398 continue; |
| 369 if (ignore_invisible_fields && !form_util::IsWebNodeVisible(*input_element)) | 399 |
| 370 continue; | 400 bool element_is_invisible = !form_util::IsWebNodeVisible(*input_element); |
| 371 if (input_element->isTextField()) { | 401 if (input_element->isTextField()) { |
| 372 if (input_element->isPasswordField()) | 402 if (input_element->isPasswordField()) { |
| 403 if (element_is_invisible && ignore_invisible_passwords) | |
| 404 continue; | |
| 373 layout_sequence.push_back('P'); | 405 layout_sequence.push_back('P'); |
| 374 else | 406 } else { |
| 407 if (element_is_invisible && ignore_invisible_usernames) | |
| 408 continue; | |
| 375 layout_sequence.push_back('N'); | 409 layout_sequence.push_back('N'); |
| 410 } | |
| 376 } | 411 } |
| 377 | 412 |
| 378 bool password_marked_by_autocomplete_attribute = | 413 bool password_marked_by_autocomplete_attribute = |
| 379 HasAutocompleteAttributeValue(*input_element, | 414 HasAutocompleteAttributeValue(*input_element, |
| 380 kAutocompleteCurrentPassword) || | 415 kAutocompleteCurrentPassword) || |
| 381 HasAutocompleteAttributeValue(*input_element, kAutocompleteNewPassword); | 416 HasAutocompleteAttributeValue(*input_element, kAutocompleteNewPassword); |
| 382 | 417 |
| 383 // If the password field is readonly, the page is likely using a virtual | 418 // If the password field is readonly, the page is likely using a virtual |
| 384 // keyboard and bypassing the password field value (see | 419 // keyboard and bypassing the password field value (see |
| 385 // http://crbug.com/475488). There is nothing Chrome can do to fill | 420 // http://crbug.com/475488). There is nothing Chrome can do to fill |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 } | 687 } |
| 653 | 688 |
| 654 bool HasAutocompleteAttributeValue(const blink::WebInputElement& element, | 689 bool HasAutocompleteAttributeValue(const blink::WebInputElement& element, |
| 655 const char* value_in_lowercase) { | 690 const char* value_in_lowercase) { |
| 656 return base::LowerCaseEqualsASCII( | 691 return base::LowerCaseEqualsASCII( |
| 657 base::StringPiece16(element.getAttribute("autocomplete")), | 692 base::StringPiece16(element.getAttribute("autocomplete")), |
| 658 value_in_lowercase); | 693 value_in_lowercase); |
| 659 } | 694 } |
| 660 | 695 |
| 661 } // namespace autofill | 696 } // namespace autofill |
| OLD | NEW |