| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/renderer/autofill/password_autofill_manager.h" | 5 #include "chrome/renderer/autofill/password_autofill_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "chrome/common/autofill_messages.h" | 10 #include "chrome/common/autofill_messages.h" |
| 11 #include "content/public/renderer/render_view.h" | 11 #include "content/public/renderer/render_view.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" | 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
| 20 #include "ui/base/keycodes/keyboard_codes.h" | 20 #include "ui/base/keycodes/keyboard_codes.h" |
| 21 #include "webkit/glue/form_field.h" | 21 #include "webkit/forms/form_field.h" |
| 22 #include "webkit/glue/password_form.h" | 22 #include "webkit/forms/password_form.h" |
| 23 #include "webkit/glue/password_form_dom_manager.h" | 23 #include "webkit/forms/password_form_dom_manager.h" |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // The size above which we stop triggering autocomplete. | 27 // The size above which we stop triggering autocomplete. |
| 28 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 28 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
| 29 | 29 |
| 30 // Maps element names to the actual elements to simplify form filling. | 30 // Maps element names to the actual elements to simplify form filling. |
| 31 typedef std::map<string16, WebKit::WebInputElement> | 31 typedef std::map<string16, WebKit::WebInputElement> |
| 32 FormInputElementMap; | 32 FormInputElementMap; |
| 33 | 33 |
| 34 // Utility struct for form lookup and autofill. When we parse the DOM to look up | 34 // Utility struct for form lookup and autofill. When we parse the DOM to look up |
| 35 // a form, in addition to action and origin URL's we have to compare all | 35 // a form, in addition to action and origin URL's we have to compare all |
| 36 // necessary form elements. To avoid having to look these up again when we want | 36 // necessary form elements. To avoid having to look these up again when we want |
| 37 // to fill the form, the FindFormElements function stores the pointers | 37 // to fill the form, the FindFormElements function stores the pointers |
| 38 // in a FormElements* result, referenced to ensure they are safe to use. | 38 // in a FormElements* result, referenced to ensure they are safe to use. |
| 39 struct FormElements { | 39 struct FormElements { |
| 40 WebKit::WebFormElement form_element; | 40 WebKit::WebFormElement form_element; |
| 41 FormInputElementMap input_elements; | 41 FormInputElementMap input_elements; |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 typedef std::vector<FormElements*> FormElementsList; | 44 typedef std::vector<FormElements*> FormElementsList; |
| 45 | 45 |
| 46 // Helper to search the given form element for the specified input elements | 46 // Helper to search the given form element for the specified input elements |
| 47 // in |data|, and add results to |result|. | 47 // in |data|, and add results to |result|. |
| 48 static bool FindFormInputElements(WebKit::WebFormElement* fe, | 48 static bool FindFormInputElements(WebKit::WebFormElement* fe, |
| 49 const webkit_glue::FormData& data, | 49 const webkit::forms::FormData& data, |
| 50 FormElements* result) { | 50 FormElements* result) { |
| 51 // Loop through the list of elements we need to find on the form in order to | 51 // Loop through the list of elements we need to find on the form in order to |
| 52 // autofill it. If we don't find any one of them, abort processing this | 52 // autofill it. If we don't find any one of them, abort processing this |
| 53 // form; it can't be the right one. | 53 // form; it can't be the right one. |
| 54 for (size_t j = 0; j < data.fields.size(); j++) { | 54 for (size_t j = 0; j < data.fields.size(); j++) { |
| 55 WebKit::WebVector<WebKit::WebNode> temp_elements; | 55 WebKit::WebVector<WebKit::WebNode> temp_elements; |
| 56 fe->getNamedElements(data.fields[j].name, temp_elements); | 56 fe->getNamedElements(data.fields[j].name, temp_elements); |
| 57 | 57 |
| 58 // Match the first input element, if any. | 58 // Match the first input element, if any. |
| 59 // |getNamedElements| may return non-input elements where the names match, | 59 // |getNamedElements| may return non-input elements where the names match, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 87 if (!found_input) { | 87 if (!found_input) { |
| 88 result->input_elements.clear(); | 88 result->input_elements.clear(); |
| 89 return false; | 89 return false; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 return true; | 92 return true; |
| 93 } | 93 } |
| 94 | 94 |
| 95 // Helper to locate form elements identified by |data|. | 95 // Helper to locate form elements identified by |data|. |
| 96 void FindFormElements(WebKit::WebView* view, | 96 void FindFormElements(WebKit::WebView* view, |
| 97 const webkit_glue::FormData& data, | 97 const webkit::forms::FormData& data, |
| 98 FormElementsList* results) { | 98 FormElementsList* results) { |
| 99 DCHECK(view); | 99 DCHECK(view); |
| 100 DCHECK(results); | 100 DCHECK(results); |
| 101 WebKit::WebFrame* main_frame = view->mainFrame(); | 101 WebKit::WebFrame* main_frame = view->mainFrame(); |
| 102 if (!main_frame) | 102 if (!main_frame) |
| 103 return; | 103 return; |
| 104 | 104 |
| 105 GURL::Replacements rep; | 105 GURL::Replacements rep; |
| 106 rep.ClearQuery(); | 106 rep.ClearQuery(); |
| 107 rep.ClearRef(); | 107 rep.ClearRef(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 curr_elements->form_element = fe; | 141 curr_elements->form_element = fe; |
| 142 results->push_back(curr_elements.release()); | 142 results->push_back(curr_elements.release()); |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 } | 145 } |
| 146 | 146 |
| 147 bool IsElementEditable(const WebKit::WebInputElement& element) { | 147 bool IsElementEditable(const WebKit::WebInputElement& element) { |
| 148 return element.isEnabled() && !element.isReadOnly(); | 148 return element.isEnabled() && !element.isReadOnly(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void FillForm(FormElements* fe, const webkit_glue::FormData& data) { | 151 void FillForm(FormElements* fe, const webkit::forms::FormData& data) { |
| 152 if (!fe->form_element.autoComplete()) | 152 if (!fe->form_element.autoComplete()) |
| 153 return; | 153 return; |
| 154 | 154 |
| 155 std::map<string16, string16> data_map; | 155 std::map<string16, string16> data_map; |
| 156 for (size_t i = 0; i < data.fields.size(); i++) | 156 for (size_t i = 0; i < data.fields.size(); i++) |
| 157 data_map[data.fields[i].name] = data.fields[i].value; | 157 data_map[data.fields[i].name] = data.fields[i].value; |
| 158 | 158 |
| 159 for (FormInputElementMap::iterator it = fe->input_elements.begin(); | 159 for (FormInputElementMap::iterator it = fe->input_elements.begin(); |
| 160 it != fe->input_elements.end(); ++it) { | 160 it != fe->input_elements.end(); ++it) { |
| 161 WebKit::WebInputElement element = it->second; | 161 WebKit::WebInputElement element = it->second; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 PasswordAutofillManager::~PasswordAutofillManager() { | 210 PasswordAutofillManager::~PasswordAutofillManager() { |
| 211 } | 211 } |
| 212 | 212 |
| 213 bool PasswordAutofillManager::TextFieldDidEndEditing( | 213 bool PasswordAutofillManager::TextFieldDidEndEditing( |
| 214 const WebKit::WebInputElement& element) { | 214 const WebKit::WebInputElement& element) { |
| 215 LoginToPasswordInfoMap::const_iterator iter = | 215 LoginToPasswordInfoMap::const_iterator iter = |
| 216 login_to_password_info_.find(element); | 216 login_to_password_info_.find(element); |
| 217 if (iter == login_to_password_info_.end()) | 217 if (iter == login_to_password_info_.end()) |
| 218 return false; | 218 return false; |
| 219 | 219 |
| 220 const webkit_glue::PasswordFormFillData& fill_data = | 220 const webkit::forms::PasswordFormFillData& fill_data = |
| 221 iter->second.fill_data; | 221 iter->second.fill_data; |
| 222 | 222 |
| 223 // If wait_for_username is false, we should have filled when the text changed. | 223 // If wait_for_username is false, we should have filled when the text changed. |
| 224 if (!fill_data.wait_for_username) | 224 if (!fill_data.wait_for_username) |
| 225 return false; | 225 return false; |
| 226 | 226 |
| 227 WebKit::WebInputElement password = iter->second.password_field; | 227 WebKit::WebInputElement password = iter->second.password_field; |
| 228 if (!IsElementEditable(password)) | 228 if (!IsElementEditable(password)) |
| 229 return false; | 229 return false; |
| 230 | 230 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 void PasswordAutofillManager::SendPasswordForms(WebKit::WebFrame* frame, | 335 void PasswordAutofillManager::SendPasswordForms(WebKit::WebFrame* frame, |
| 336 bool only_visible) { | 336 bool only_visible) { |
| 337 // Make sure that this security origin is allowed to use password manager. | 337 // Make sure that this security origin is allowed to use password manager. |
| 338 WebKit::WebSecurityOrigin origin = frame->document().securityOrigin(); | 338 WebKit::WebSecurityOrigin origin = frame->document().securityOrigin(); |
| 339 if (!origin.canAccessPasswordManager()) | 339 if (!origin.canAccessPasswordManager()) |
| 340 return; | 340 return; |
| 341 | 341 |
| 342 WebKit::WebVector<WebKit::WebFormElement> forms; | 342 WebKit::WebVector<WebKit::WebFormElement> forms; |
| 343 frame->document().forms(forms); | 343 frame->document().forms(forms); |
| 344 | 344 |
| 345 std::vector<webkit_glue::PasswordForm> password_forms; | 345 std::vector<webkit::forms::PasswordForm> password_forms; |
| 346 for (size_t i = 0; i < forms.size(); ++i) { | 346 for (size_t i = 0; i < forms.size(); ++i) { |
| 347 const WebKit::WebFormElement& form = forms[i]; | 347 const WebKit::WebFormElement& form = forms[i]; |
| 348 | 348 |
| 349 // Respect autocomplete=off. | 349 // Respect autocomplete=off. |
| 350 if (!form.autoComplete()) | 350 if (!form.autoComplete()) |
| 351 continue; | 351 continue; |
| 352 if (only_visible && !form.hasNonEmptyBoundingBox()) | 352 if (only_visible && !form.hasNonEmptyBoundingBox()) |
| 353 continue; | 353 continue; |
| 354 scoped_ptr<webkit_glue::PasswordForm> password_form( | 354 scoped_ptr<webkit::forms::PasswordForm> password_form( |
| 355 webkit_glue::PasswordFormDomManager::CreatePasswordForm(form)); | 355 webkit::forms::PasswordFormDomManager::CreatePasswordForm(form)); |
| 356 if (password_form.get()) | 356 if (password_form.get()) |
| 357 password_forms.push_back(*password_form); | 357 password_forms.push_back(*password_form); |
| 358 } | 358 } |
| 359 | 359 |
| 360 if (password_forms.empty()) | 360 if (password_forms.empty()) |
| 361 return; | 361 return; |
| 362 | 362 |
| 363 if (only_visible) { | 363 if (only_visible) { |
| 364 Send(new AutofillHostMsg_PasswordFormsVisible( | 364 Send(new AutofillHostMsg_PasswordFormsVisible( |
| 365 routing_id(), password_forms)); | 365 routing_id(), password_forms)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 bool is_focused) { | 403 bool is_focused) { |
| 404 // TODO(jcivelli): http://crbug.com/51644 Implement behavior. | 404 // TODO(jcivelli): http://crbug.com/51644 Implement behavior. |
| 405 return false; | 405 return false; |
| 406 } | 406 } |
| 407 | 407 |
| 408 bool PasswordAutofillManager::InputElementLostFocus() { | 408 bool PasswordAutofillManager::InputElementLostFocus() { |
| 409 return false; | 409 return false; |
| 410 } | 410 } |
| 411 | 411 |
| 412 void PasswordAutofillManager::OnFillPasswordForm( | 412 void PasswordAutofillManager::OnFillPasswordForm( |
| 413 const webkit_glue::PasswordFormFillData& form_data) { | 413 const webkit::forms::PasswordFormFillData& form_data) { |
| 414 FormElementsList forms; | 414 FormElementsList forms; |
| 415 // We own the FormElements* in forms. | 415 // We own the FormElements* in forms. |
| 416 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); | 416 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); |
| 417 FormElementsList::iterator iter; | 417 FormElementsList::iterator iter; |
| 418 for (iter = forms.begin(); iter != forms.end(); ++iter) { | 418 for (iter = forms.begin(); iter != forms.end(); ++iter) { |
| 419 scoped_ptr<FormElements> form_elements(*iter); | 419 scoped_ptr<FormElements> form_elements(*iter); |
| 420 | 420 |
| 421 // If wait_for_username is true, we don't want to initially fill the form | 421 // If wait_for_username is true, we don't want to initially fill the form |
| 422 // until the user types in a valid username. | 422 // until the user types in a valid username. |
| 423 if (!form_data.wait_for_username) | 423 if (!form_data.wait_for_username) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 443 password_info.fill_data = form_data; | 443 password_info.fill_data = form_data; |
| 444 password_info.password_field = password_element; | 444 password_info.password_field = password_element; |
| 445 login_to_password_info_[username_element] = password_info; | 445 login_to_password_info_[username_element] = password_info; |
| 446 } | 446 } |
| 447 } | 447 } |
| 448 | 448 |
| 449 //////////////////////////////////////////////////////////////////////////////// | 449 //////////////////////////////////////////////////////////////////////////////// |
| 450 // PasswordAutofillManager, private: | 450 // PasswordAutofillManager, private: |
| 451 | 451 |
| 452 void PasswordAutofillManager::GetSuggestions( | 452 void PasswordAutofillManager::GetSuggestions( |
| 453 const webkit_glue::PasswordFormFillData& fill_data, | 453 const webkit::forms::PasswordFormFillData& fill_data, |
| 454 const string16& input, | 454 const string16& input, |
| 455 std::vector<string16>* suggestions) { | 455 std::vector<string16>* suggestions) { |
| 456 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) | 456 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) |
| 457 suggestions->push_back(fill_data.basic_data.fields[0].value); | 457 suggestions->push_back(fill_data.basic_data.fields[0].value); |
| 458 | 458 |
| 459 webkit_glue::PasswordFormFillData::LoginCollection::const_iterator iter; | 459 webkit::forms::PasswordFormFillData::LoginCollection::const_iterator iter; |
| 460 for (iter = fill_data.additional_logins.begin(); | 460 for (iter = fill_data.additional_logins.begin(); |
| 461 iter != fill_data.additional_logins.end(); ++iter) { | 461 iter != fill_data.additional_logins.end(); ++iter) { |
| 462 if (StartsWith(iter->first, input, false)) | 462 if (StartsWith(iter->first, input, false)) |
| 463 suggestions->push_back(iter->first); | 463 suggestions->push_back(iter->first); |
| 464 } | 464 } |
| 465 } | 465 } |
| 466 | 466 |
| 467 bool PasswordAutofillManager::ShowSuggestionPopup( | 467 bool PasswordAutofillManager::ShowSuggestionPopup( |
| 468 const webkit_glue::PasswordFormFillData& fill_data, | 468 const webkit::forms::PasswordFormFillData& fill_data, |
| 469 const WebKit::WebInputElement& user_input) { | 469 const WebKit::WebInputElement& user_input) { |
| 470 WebKit::WebFrame* frame = user_input.document().frame(); | 470 WebKit::WebFrame* frame = user_input.document().frame(); |
| 471 if (!frame) | 471 if (!frame) |
| 472 return false; | 472 return false; |
| 473 | 473 |
| 474 WebKit::WebView* webview = frame->view(); | 474 WebKit::WebView* webview = frame->view(); |
| 475 if (!webview) | 475 if (!webview) |
| 476 return false; | 476 return false; |
| 477 | 477 |
| 478 std::vector<string16> suggestions; | 478 std::vector<string16> suggestions; |
| 479 GetSuggestions(fill_data, user_input.value(), &suggestions); | 479 GetSuggestions(fill_data, user_input.value(), &suggestions); |
| 480 if (suggestions.empty()) { | 480 if (suggestions.empty()) { |
| 481 webview->hidePopups(); | 481 webview->hidePopups(); |
| 482 return false; | 482 return false; |
| 483 } | 483 } |
| 484 | 484 |
| 485 std::vector<string16> labels(suggestions.size()); | 485 std::vector<string16> labels(suggestions.size()); |
| 486 std::vector<string16> icons(suggestions.size()); | 486 std::vector<string16> icons(suggestions.size()); |
| 487 std::vector<int> ids(suggestions.size(), 0); | 487 std::vector<int> ids(suggestions.size(), 0); |
| 488 webview->applyAutofillSuggestions( | 488 webview->applyAutofillSuggestions( |
| 489 user_input, suggestions, labels, icons, ids, -1); | 489 user_input, suggestions, labels, icons, ids, -1); |
| 490 return true; | 490 return true; |
| 491 } | 491 } |
| 492 | 492 |
| 493 bool PasswordAutofillManager::FillUserNameAndPassword( | 493 bool PasswordAutofillManager::FillUserNameAndPassword( |
| 494 WebKit::WebInputElement* username_element, | 494 WebKit::WebInputElement* username_element, |
| 495 WebKit::WebInputElement* password_element, | 495 WebKit::WebInputElement* password_element, |
| 496 const webkit_glue::PasswordFormFillData& fill_data, | 496 const webkit::forms::PasswordFormFillData& fill_data, |
| 497 bool exact_username_match, | 497 bool exact_username_match, |
| 498 bool set_selection) { | 498 bool set_selection) { |
| 499 string16 current_username = username_element->value(); | 499 string16 current_username = username_element->value(); |
| 500 // username and password will contain the match found if any. | 500 // username and password will contain the match found if any. |
| 501 string16 username; | 501 string16 username; |
| 502 string16 password; | 502 string16 password; |
| 503 | 503 |
| 504 // Look for any suitable matches to current field text. | 504 // Look for any suitable matches to current field text. |
| 505 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, | 505 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, |
| 506 exact_username_match)) { | 506 exact_username_match)) { |
| 507 username = fill_data.basic_data.fields[0].value; | 507 username = fill_data.basic_data.fields[0].value; |
| 508 password = fill_data.basic_data.fields[1].value; | 508 password = fill_data.basic_data.fields[1].value; |
| 509 } else { | 509 } else { |
| 510 // Scan additional logins for a match. | 510 // Scan additional logins for a match. |
| 511 webkit_glue::PasswordFormFillData::LoginCollection::const_iterator iter; | 511 webkit::forms::PasswordFormFillData::LoginCollection::const_iterator iter; |
| 512 for (iter = fill_data.additional_logins.begin(); | 512 for (iter = fill_data.additional_logins.begin(); |
| 513 iter != fill_data.additional_logins.end(); ++iter) { | 513 iter != fill_data.additional_logins.end(); ++iter) { |
| 514 if (DoUsernamesMatch(iter->first, current_username, | 514 if (DoUsernamesMatch(iter->first, current_username, |
| 515 exact_username_match)) { | 515 exact_username_match)) { |
| 516 username = iter->first; | 516 username = iter->first; |
| 517 password = iter->second; | 517 password = iter->second; |
| 518 break; | 518 break; |
| 519 } | 519 } |
| 520 } | 520 } |
| 521 } | 521 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 533 SetElementAutofilled(username_element, true); | 533 SetElementAutofilled(username_element, true); |
| 534 if (IsElementEditable(*password_element)) | 534 if (IsElementEditable(*password_element)) |
| 535 password_element->setValue(password); | 535 password_element->setValue(password); |
| 536 SetElementAutofilled(password_element, true); | 536 SetElementAutofilled(password_element, true); |
| 537 return true; | 537 return true; |
| 538 } | 538 } |
| 539 | 539 |
| 540 void PasswordAutofillManager::PerformInlineAutocomplete( | 540 void PasswordAutofillManager::PerformInlineAutocomplete( |
| 541 const WebKit::WebInputElement& username_input, | 541 const WebKit::WebInputElement& username_input, |
| 542 const WebKit::WebInputElement& password_input, | 542 const WebKit::WebInputElement& password_input, |
| 543 const webkit_glue::PasswordFormFillData& fill_data) { | 543 const webkit::forms::PasswordFormFillData& fill_data) { |
| 544 DCHECK(!fill_data.wait_for_username); | 544 DCHECK(!fill_data.wait_for_username); |
| 545 | 545 |
| 546 // We need non-const versions of the username and password inputs. | 546 // We need non-const versions of the username and password inputs. |
| 547 WebKit::WebInputElement username = username_input; | 547 WebKit::WebInputElement username = username_input; |
| 548 WebKit::WebInputElement password = password_input; | 548 WebKit::WebInputElement password = password_input; |
| 549 | 549 |
| 550 // Don't inline autocomplete if the caret is not at the end. | 550 // Don't inline autocomplete if the caret is not at the end. |
| 551 // TODO(jcivelli): is there a better way to test the caret location? | 551 // TODO(jcivelli): is there a better way to test the caret location? |
| 552 if (username.selectionStart() != username.selectionEnd() || | 552 if (username.selectionStart() != username.selectionEnd() || |
| 553 username.selectionEnd() != static_cast<int>(username.value().length())) { | 553 username.selectionEnd() != static_cast<int>(username.value().length())) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 586 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 587 if (iter == login_to_password_info_.end()) | 587 if (iter == login_to_password_info_.end()) |
| 588 return false; | 588 return false; |
| 589 | 589 |
| 590 *found_input = input; | 590 *found_input = input; |
| 591 *found_password = iter->second; | 591 *found_password = iter->second; |
| 592 return true; | 592 return true; |
| 593 } | 593 } |
| 594 | 594 |
| 595 } // namespace autofill | 595 } // namespace autofill |
| OLD | NEW |