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 |