Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: chrome/renderer/autofill/password_autofill_manager.cc

Issue 11000016: Move forms/ out of webkit/. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Response to review Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/common/form_field_data.h"
12 #include "chrome/common/password_form_fill_data.h"
11 #include "chrome/renderer/autofill/form_autofill_util.h" 13 #include "chrome/renderer/autofill/form_autofill_util.h"
14 #include "content/public/common/password_form.h"
15 #include "content/public/renderer/password_form_conversion_utils.h"
12 #include "content/public/renderer/render_view.h" 16 #include "content/public/renderer/render_view.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
22 #include "ui/base/keycodes/keyboard_codes.h" 26 #include "ui/base/keycodes/keyboard_codes.h"
23 #include "webkit/forms/form_field.h"
24 #include "webkit/forms/password_form.h"
25 #include "webkit/forms/password_form_dom_manager.h"
26 27
27 namespace { 28 namespace {
28 29
29 // The size above which we stop triggering autocomplete. 30 // The size above which we stop triggering autocomplete.
30 static const size_t kMaximumTextSizeForAutocomplete = 1000; 31 static const size_t kMaximumTextSizeForAutocomplete = 1000;
31 32
32 // Maps element names to the actual elements to simplify form filling. 33 // Maps element names to the actual elements to simplify form filling.
33 typedef std::map<string16, WebKit::WebInputElement> 34 typedef std::map<string16, WebKit::WebInputElement>
34 FormInputElementMap; 35 FormInputElementMap;
35 36
36 // Utility struct for form lookup and autofill. When we parse the DOM to look up 37 // Utility struct for form lookup and autofill. When we parse the DOM to look up
37 // a form, in addition to action and origin URL's we have to compare all 38 // a form, in addition to action and origin URL's we have to compare all
38 // necessary form elements. To avoid having to look these up again when we want 39 // necessary form elements. To avoid having to look these up again when we want
39 // to fill the form, the FindFormElements function stores the pointers 40 // to fill the form, the FindFormElements function stores the pointers
40 // in a FormElements* result, referenced to ensure they are safe to use. 41 // in a FormElements* result, referenced to ensure they are safe to use.
41 struct FormElements { 42 struct FormElements {
42 WebKit::WebFormElement form_element; 43 WebKit::WebFormElement form_element;
43 FormInputElementMap input_elements; 44 FormInputElementMap input_elements;
44 }; 45 };
45 46
46 typedef std::vector<FormElements*> FormElementsList; 47 typedef std::vector<FormElements*> FormElementsList;
47 48
48 // Helper to search the given form element for the specified input elements 49 // Helper to search the given form element for the specified input elements
49 // in |data|, and add results to |result|. 50 // in |data|, and add results to |result|.
50 static bool FindFormInputElements(WebKit::WebFormElement* fe, 51 static bool FindFormInputElements(WebKit::WebFormElement* fe,
51 const webkit::forms::FormData& data, 52 const FormData& data,
52 FormElements* result) { 53 FormElements* result) {
53 // Loop through the list of elements we need to find on the form in order to 54 // Loop through the list of elements we need to find on the form in order to
54 // autofill it. If we don't find any one of them, abort processing this 55 // autofill it. If we don't find any one of them, abort processing this
55 // form; it can't be the right one. 56 // form; it can't be the right one.
56 for (size_t j = 0; j < data.fields.size(); j++) { 57 for (size_t j = 0; j < data.fields.size(); j++) {
57 WebKit::WebVector<WebKit::WebNode> temp_elements; 58 WebKit::WebVector<WebKit::WebNode> temp_elements;
58 fe->getNamedElements(data.fields[j].name, temp_elements); 59 fe->getNamedElements(data.fields[j].name, temp_elements);
59 60
60 // Match the first input element, if any. 61 // Match the first input element, if any.
61 // |getNamedElements| may return non-input elements where the names match, 62 // |getNamedElements| may return non-input elements where the names match,
(...skipping 27 matching lines...) Expand all
89 if (!found_input) { 90 if (!found_input) {
90 result->input_elements.clear(); 91 result->input_elements.clear();
91 return false; 92 return false;
92 } 93 }
93 } 94 }
94 return true; 95 return true;
95 } 96 }
96 97
97 // Helper to locate form elements identified by |data|. 98 // Helper to locate form elements identified by |data|.
98 void FindFormElements(WebKit::WebView* view, 99 void FindFormElements(WebKit::WebView* view,
99 const webkit::forms::FormData& data, 100 const FormData& data,
100 FormElementsList* results) { 101 FormElementsList* results) {
101 DCHECK(view); 102 DCHECK(view);
102 DCHECK(results); 103 DCHECK(results);
103 WebKit::WebFrame* main_frame = view->mainFrame(); 104 WebKit::WebFrame* main_frame = view->mainFrame();
104 if (!main_frame) 105 if (!main_frame)
105 return; 106 return;
106 107
107 GURL::Replacements rep; 108 GURL::Replacements rep;
108 rep.ClearQuery(); 109 rep.ClearQuery();
109 rep.ClearRef(); 110 rep.ClearRef();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 curr_elements->form_element = fe; 144 curr_elements->form_element = fe;
144 results->push_back(curr_elements.release()); 145 results->push_back(curr_elements.release());
145 } 146 }
146 } 147 }
147 } 148 }
148 149
149 bool IsElementEditable(const WebKit::WebInputElement& element) { 150 bool IsElementEditable(const WebKit::WebInputElement& element) {
150 return element.isEnabled() && !element.isReadOnly(); 151 return element.isEnabled() && !element.isReadOnly();
151 } 152 }
152 153
153 void FillForm(FormElements* fe, const webkit::forms::FormData& data) { 154 void FillForm(FormElements* fe, const FormData& data) {
154 if (!fe->form_element.autoComplete()) 155 if (!fe->form_element.autoComplete())
155 return; 156 return;
156 157
157 std::map<string16, string16> data_map; 158 std::map<string16, string16> data_map;
158 for (size_t i = 0; i < data.fields.size(); i++) 159 for (size_t i = 0; i < data.fields.size(); i++)
159 data_map[data.fields[i].name] = data.fields[i].value; 160 data_map[data.fields[i].name] = data.fields[i].value;
160 161
161 for (FormInputElementMap::iterator it = fe->input_elements.begin(); 162 for (FormInputElementMap::iterator it = fe->input_elements.begin();
162 it != fe->input_elements.end(); ++it) { 163 it != fe->input_elements.end(); ++it) {
163 WebKit::WebInputElement element = it->second; 164 WebKit::WebInputElement element = it->second;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 PasswordAutofillManager::~PasswordAutofillManager() { 214 PasswordAutofillManager::~PasswordAutofillManager() {
214 } 215 }
215 216
216 bool PasswordAutofillManager::TextFieldDidEndEditing( 217 bool PasswordAutofillManager::TextFieldDidEndEditing(
217 const WebKit::WebInputElement& element) { 218 const WebKit::WebInputElement& element) {
218 LoginToPasswordInfoMap::const_iterator iter = 219 LoginToPasswordInfoMap::const_iterator iter =
219 login_to_password_info_.find(element); 220 login_to_password_info_.find(element);
220 if (iter == login_to_password_info_.end()) 221 if (iter == login_to_password_info_.end())
221 return false; 222 return false;
222 223
223 const webkit::forms::PasswordFormFillData& fill_data = 224 const PasswordFormFillData& fill_data =
224 iter->second.fill_data; 225 iter->second.fill_data;
225 226
226 // If wait_for_username is false, we should have filled when the text changed. 227 // If wait_for_username is false, we should have filled when the text changed.
227 if (!fill_data.wait_for_username) 228 if (!fill_data.wait_for_username)
228 return false; 229 return false;
229 230
230 WebKit::WebInputElement password = iter->second.password_field; 231 WebKit::WebInputElement password = iter->second.password_field;
231 if (!IsElementEditable(password)) 232 if (!IsElementEditable(password))
232 return false; 233 return false;
233 234
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 void PasswordAutofillManager::SendPasswordForms(WebKit::WebFrame* frame, 337 void PasswordAutofillManager::SendPasswordForms(WebKit::WebFrame* frame,
337 bool only_visible) { 338 bool only_visible) {
338 // Make sure that this security origin is allowed to use password manager. 339 // Make sure that this security origin is allowed to use password manager.
339 WebKit::WebSecurityOrigin origin = frame->document().securityOrigin(); 340 WebKit::WebSecurityOrigin origin = frame->document().securityOrigin();
340 if (!origin.canAccessPasswordManager()) 341 if (!origin.canAccessPasswordManager())
341 return; 342 return;
342 343
343 WebKit::WebVector<WebKit::WebFormElement> forms; 344 WebKit::WebVector<WebKit::WebFormElement> forms;
344 frame->document().forms(forms); 345 frame->document().forms(forms);
345 346
346 std::vector<webkit::forms::PasswordForm> password_forms; 347 std::vector<content::PasswordForm> password_forms;
347 for (size_t i = 0; i < forms.size(); ++i) { 348 for (size_t i = 0; i < forms.size(); ++i) {
348 const WebKit::WebFormElement& form = forms[i]; 349 const WebKit::WebFormElement& form = forms[i];
349 350
350 // Respect autocomplete=off. 351 // Respect autocomplete=off.
351 if (!form.autoComplete()) 352 if (!form.autoComplete())
352 continue; 353 continue;
353 354
354 // If requested, ignore non-rendered forms, e.g. those styled with 355 // If requested, ignore non-rendered forms, e.g. those styled with
355 // display:none. 356 // display:none.
356 if (only_visible && !form.hasNonEmptyBoundingBox()) 357 if (only_visible && !form.hasNonEmptyBoundingBox())
357 continue; 358 continue;
358 359
359 scoped_ptr<webkit::forms::PasswordForm> password_form( 360 scoped_ptr<content::PasswordForm> password_form(
360 webkit::forms::PasswordFormDomManager::CreatePasswordForm(form)); 361 content::CreatePasswordForm(form));
361 if (password_form.get()) 362 if (password_form.get())
362 password_forms.push_back(*password_form); 363 password_forms.push_back(*password_form);
363 } 364 }
364 365
365 if (password_forms.empty() && !only_visible) { 366 if (password_forms.empty() && !only_visible) {
366 // We need to send the PasswordFormsRendered message regardless of whether 367 // We need to send the PasswordFormsRendered message regardless of whether
367 // there are any forms visible, as this is also the code path that triggers 368 // there are any forms visible, as this is also the code path that triggers
368 // showing the infobar. 369 // showing the infobar.
369 return; 370 return;
370 } 371 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 bool is_focused) { 420 bool is_focused) {
420 // TODO(jcivelli): http://crbug.com/51644 Implement behavior. 421 // TODO(jcivelli): http://crbug.com/51644 Implement behavior.
421 return false; 422 return false;
422 } 423 }
423 424
424 bool PasswordAutofillManager::InputElementLostFocus() { 425 bool PasswordAutofillManager::InputElementLostFocus() {
425 return false; 426 return false;
426 } 427 }
427 428
428 void PasswordAutofillManager::OnFillPasswordForm( 429 void PasswordAutofillManager::OnFillPasswordForm(
429 const webkit::forms::PasswordFormFillData& form_data, 430 const PasswordFormFillData& form_data,
430 bool disable_popup) { 431 bool disable_popup) {
431 disable_popup_ = disable_popup; 432 disable_popup_ = disable_popup;
432 433
433 FormElementsList forms; 434 FormElementsList forms;
434 // We own the FormElements* in forms. 435 // We own the FormElements* in forms.
435 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); 436 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms);
436 FormElementsList::iterator iter; 437 FormElementsList::iterator iter;
437 for (iter = forms.begin(); iter != forms.end(); ++iter) { 438 for (iter = forms.begin(); iter != forms.end(); ++iter) {
438 scoped_ptr<FormElements> form_elements(*iter); 439 scoped_ptr<FormElements> form_elements(*iter);
439 440
(...skipping 16 matching lines...) Expand all
456 // with identical markup. 457 // with identical markup.
457 if (login_to_password_info_.find(username_element) != 458 if (login_to_password_info_.find(username_element) !=
458 login_to_password_info_.end()) 459 login_to_password_info_.end())
459 continue; 460 continue;
460 461
461 PasswordInfo password_info; 462 PasswordInfo password_info;
462 password_info.fill_data = form_data; 463 password_info.fill_data = form_data;
463 password_info.password_field = password_element; 464 password_info.password_field = password_element;
464 login_to_password_info_[username_element] = password_info; 465 login_to_password_info_[username_element] = password_info;
465 466
466 webkit::forms::FormData form; 467 FormData form;
467 webkit::forms::FormField field; 468 FormFieldData field;
468 FindFormAndFieldForInputElement( 469 FindFormAndFieldForInputElement(
469 username_element, &form, &field, REQUIRE_NONE); 470 username_element, &form, &field, REQUIRE_NONE);
470 Send(new AutofillHostMsg_AddPasswordFormMapping( 471 Send(new AutofillHostMsg_AddPasswordFormMapping(
471 routing_id(), 472 routing_id(),
472 field, 473 field,
473 form_data)); 474 form_data));
474 } 475 }
475 } 476 }
476 477
477 //////////////////////////////////////////////////////////////////////////////// 478 ////////////////////////////////////////////////////////////////////////////////
478 // PasswordAutofillManager, private: 479 // PasswordAutofillManager, private:
479 480
480 void PasswordAutofillManager::GetSuggestions( 481 void PasswordAutofillManager::GetSuggestions(
481 const webkit::forms::PasswordFormFillData& fill_data, 482 const PasswordFormFillData& fill_data,
482 const string16& input, 483 const string16& input,
483 std::vector<string16>* suggestions) { 484 std::vector<string16>* suggestions) {
484 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) 485 if (StartsWith(fill_data.basic_data.fields[0].value, input, false))
485 suggestions->push_back(fill_data.basic_data.fields[0].value); 486 suggestions->push_back(fill_data.basic_data.fields[0].value);
486 487
487 webkit::forms::PasswordFormFillData::LoginCollection::const_iterator iter; 488 PasswordFormFillData::LoginCollection::const_iterator iter;
488 for (iter = fill_data.additional_logins.begin(); 489 for (iter = fill_data.additional_logins.begin();
489 iter != fill_data.additional_logins.end(); ++iter) { 490 iter != fill_data.additional_logins.end(); ++iter) {
490 if (StartsWith(iter->first, input, false)) 491 if (StartsWith(iter->first, input, false))
491 suggestions->push_back(iter->first); 492 suggestions->push_back(iter->first);
492 } 493 }
493 } 494 }
494 495
495 bool PasswordAutofillManager::ShowSuggestionPopup( 496 bool PasswordAutofillManager::ShowSuggestionPopup(
496 const webkit::forms::PasswordFormFillData& fill_data, 497 const PasswordFormFillData& fill_data,
497 const WebKit::WebInputElement& user_input) { 498 const WebKit::WebInputElement& user_input) {
498 WebKit::WebFrame* frame = user_input.document().frame(); 499 WebKit::WebFrame* frame = user_input.document().frame();
499 if (!frame) 500 if (!frame)
500 return false; 501 return false;
501 502
502 WebKit::WebView* webview = frame->view(); 503 WebKit::WebView* webview = frame->view();
503 if (!webview) 504 if (!webview)
504 return false; 505 return false;
505 506
506 std::vector<string16> suggestions; 507 std::vector<string16> suggestions;
507 GetSuggestions(fill_data, user_input.value(), &suggestions); 508 GetSuggestions(fill_data, user_input.value(), &suggestions);
508 509
509 if (disable_popup_) { 510 if (disable_popup_) {
510 webkit::forms::FormData form; 511 FormData form;
511 webkit::forms::FormField field; 512 FormFieldData field;
512 FindFormAndFieldForInputElement( 513 FindFormAndFieldForInputElement(
513 user_input, &form, &field, REQUIRE_NONE); 514 user_input, &form, &field, REQUIRE_NONE);
514 515
515 WebKit::WebInputElement selected_element = user_input; 516 WebKit::WebInputElement selected_element = user_input;
516 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); 517 gfx::Rect bounding_box(selected_element.boundsInViewportSpace());
517 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), 518 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(),
518 field, 519 field,
519 bounding_box, 520 bounding_box,
520 suggestions)); 521 suggestions));
521 return !suggestions.empty(); 522 return !suggestions.empty();
(...skipping 10 matching lines...) Expand all
532 std::vector<int> ids(suggestions.size(), 533 std::vector<int> ids(suggestions.size(),
533 WebKit::WebAutofillClient::MenuItemIDPasswordEntry); 534 WebKit::WebAutofillClient::MenuItemIDPasswordEntry);
534 webview->applyAutofillSuggestions( 535 webview->applyAutofillSuggestions(
535 user_input, suggestions, labels, icons, ids); 536 user_input, suggestions, labels, icons, ids);
536 return true; 537 return true;
537 } 538 }
538 539
539 bool PasswordAutofillManager::FillUserNameAndPassword( 540 bool PasswordAutofillManager::FillUserNameAndPassword(
540 WebKit::WebInputElement* username_element, 541 WebKit::WebInputElement* username_element,
541 WebKit::WebInputElement* password_element, 542 WebKit::WebInputElement* password_element,
542 const webkit::forms::PasswordFormFillData& fill_data, 543 const PasswordFormFillData& fill_data,
543 bool exact_username_match, 544 bool exact_username_match,
544 bool set_selection) { 545 bool set_selection) {
545 string16 current_username = username_element->value(); 546 string16 current_username = username_element->value();
546 // username and password will contain the match found if any. 547 // username and password will contain the match found if any.
547 string16 username; 548 string16 username;
548 string16 password; 549 string16 password;
549 550
550 // Look for any suitable matches to current field text. 551 // Look for any suitable matches to current field text.
551 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, 552 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username,
552 exact_username_match)) { 553 exact_username_match)) {
553 username = fill_data.basic_data.fields[0].value; 554 username = fill_data.basic_data.fields[0].value;
554 password = fill_data.basic_data.fields[1].value; 555 password = fill_data.basic_data.fields[1].value;
555 } else { 556 } else {
556 // Scan additional logins for a match. 557 // Scan additional logins for a match.
557 webkit::forms::PasswordFormFillData::LoginCollection::const_iterator iter; 558 PasswordFormFillData::LoginCollection::const_iterator iter;
558 for (iter = fill_data.additional_logins.begin(); 559 for (iter = fill_data.additional_logins.begin();
559 iter != fill_data.additional_logins.end(); ++iter) { 560 iter != fill_data.additional_logins.end(); ++iter) {
560 if (DoUsernamesMatch(iter->first, current_username, 561 if (DoUsernamesMatch(iter->first, current_username,
561 exact_username_match)) { 562 exact_username_match)) {
562 username = iter->first; 563 username = iter->first;
563 password = iter->second; 564 password = iter->second;
564 break; 565 break;
565 } 566 }
566 } 567 }
567 } 568 }
(...skipping 11 matching lines...) Expand all
579 SetElementAutofilled(username_element, true); 580 SetElementAutofilled(username_element, true);
580 if (IsElementEditable(*password_element)) 581 if (IsElementEditable(*password_element))
581 password_element->setValue(password); 582 password_element->setValue(password);
582 SetElementAutofilled(password_element, true); 583 SetElementAutofilled(password_element, true);
583 return true; 584 return true;
584 } 585 }
585 586
586 void PasswordAutofillManager::PerformInlineAutocomplete( 587 void PasswordAutofillManager::PerformInlineAutocomplete(
587 const WebKit::WebInputElement& username_input, 588 const WebKit::WebInputElement& username_input,
588 const WebKit::WebInputElement& password_input, 589 const WebKit::WebInputElement& password_input,
589 const webkit::forms::PasswordFormFillData& fill_data) { 590 const PasswordFormFillData& fill_data) {
590 DCHECK(!fill_data.wait_for_username); 591 DCHECK(!fill_data.wait_for_username);
591 592
592 // We need non-const versions of the username and password inputs. 593 // We need non-const versions of the username and password inputs.
593 WebKit::WebInputElement username = username_input; 594 WebKit::WebInputElement username = username_input;
594 WebKit::WebInputElement password = password_input; 595 WebKit::WebInputElement password = password_input;
595 596
596 // Don't inline autocomplete if the caret is not at the end. 597 // Don't inline autocomplete if the caret is not at the end.
597 // TODO(jcivelli): is there a better way to test the caret location? 598 // TODO(jcivelli): is there a better way to test the caret location?
598 if (username.selectionStart() != username.selectionEnd() || 599 if (username.selectionStart() != username.selectionEnd() ||
599 username.selectionEnd() != static_cast<int>(username.value().length())) { 600 username.selectionEnd() != static_cast<int>(username.value().length())) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); 633 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input);
633 if (iter == login_to_password_info_.end()) 634 if (iter == login_to_password_info_.end())
634 return false; 635 return false;
635 636
636 *found_input = input; 637 *found_input = input;
637 *found_password = iter->second; 638 *found_password = iter->second;
638 return true; 639 return true;
639 } 640 }
640 641
641 } // namespace autofill 642 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698