| OLD | NEW |
| 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 "components/autofill/renderer/password_autofill_agent.h" | 5 #include "components/autofill/renderer/password_autofill_agent.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 "components/autofill/common/autofill_messages.h" | 10 #include "components/autofill/common/autofill_messages.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 26 #include "ui/base/keycodes/keyboard_codes.h" | 26 #include "ui/base/keycodes/keyboard_codes.h" |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 // The size above which we stop triggering autocomplete. | 30 // The size above which we stop triggering autocomplete. |
| 31 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 31 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
| 32 | 32 |
| 33 // Maps element names to the actual elements to simplify form filling. | 33 // Maps element names to the actual elements to simplify form filling. |
| 34 typedef std::map<string16, WebKit::WebInputElement> | 34 typedef std::map<base::string16, WebKit::WebInputElement> |
| 35 FormInputElementMap; | 35 FormInputElementMap; |
| 36 | 36 |
| 37 // 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 |
| 38 // 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 |
| 39 // 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 |
| 40 // to fill the form, the FindFormElements function stores the pointers | 40 // to fill the form, the FindFormElements function stores the pointers |
| 41 // 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. |
| 42 struct FormElements { | 42 struct FormElements { |
| 43 WebKit::WebFormElement form_element; | 43 WebKit::WebFormElement form_element; |
| 44 FormInputElementMap input_elements; | 44 FormInputElementMap input_elements; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 } | 148 } |
| 149 | 149 |
| 150 bool IsElementEditable(const WebKit::WebInputElement& element) { | 150 bool IsElementEditable(const WebKit::WebInputElement& element) { |
| 151 return element.isEnabled() && !element.isReadOnly(); | 151 return element.isEnabled() && !element.isReadOnly(); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void FillForm(FormElements* fe, const FormData& data) { | 154 void FillForm(FormElements* fe, const FormData& data) { |
| 155 if (!fe->form_element.autoComplete()) | 155 if (!fe->form_element.autoComplete()) |
| 156 return; | 156 return; |
| 157 | 157 |
| 158 std::map<string16, string16> data_map; | 158 std::map<base::string16, base::string16> data_map; |
| 159 for (size_t i = 0; i < data.fields.size(); i++) | 159 for (size_t i = 0; i < data.fields.size(); i++) |
| 160 data_map[data.fields[i].name] = data.fields[i].value; | 160 data_map[data.fields[i].name] = data.fields[i].value; |
| 161 | 161 |
| 162 for (FormInputElementMap::iterator it = fe->input_elements.begin(); | 162 for (FormInputElementMap::iterator it = fe->input_elements.begin(); |
| 163 it != fe->input_elements.end(); ++it) { | 163 it != fe->input_elements.end(); ++it) { |
| 164 WebKit::WebInputElement element = it->second; | 164 WebKit::WebInputElement element = it->second; |
| 165 // Don't fill a form that has pre-filled values distinct from the ones we | 165 // Don't fill a form that has pre-filled values distinct from the ones we |
| 166 // want to fill with. | 166 // want to fill with. |
| 167 if (!element.value().isEmpty() && element.value() != data_map[it->first]) | 167 if (!element.value().isEmpty() && element.value() != data_map[it->first]) |
| 168 return; | 168 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 182 } | 182 } |
| 183 | 183 |
| 184 void SetElementAutofilled(WebKit::WebInputElement* element, bool autofilled) { | 184 void SetElementAutofilled(WebKit::WebInputElement* element, bool autofilled) { |
| 185 if (element->isAutofilled() == autofilled) | 185 if (element->isAutofilled() == autofilled) |
| 186 return; | 186 return; |
| 187 element->setAutofilled(autofilled); | 187 element->setAutofilled(autofilled); |
| 188 // Notify any changeEvent listeners. | 188 // Notify any changeEvent listeners. |
| 189 element->dispatchFormControlChangeEvent(); | 189 element->dispatchFormControlChangeEvent(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 bool DoUsernamesMatch(const string16& username1, | 192 bool DoUsernamesMatch(const base::string16& username1, |
| 193 const string16& username2, | 193 const base::string16& username2, |
| 194 bool exact_match) { | 194 bool exact_match) { |
| 195 if (exact_match) | 195 if (exact_match) |
| 196 return username1 == username2; | 196 return username1 == username2; |
| 197 return StartsWith(username1, username2, true); | 197 return StartsWith(username1, username2, true); |
| 198 } | 198 } |
| 199 | 199 |
| 200 } // namespace | 200 } // namespace |
| 201 | 201 |
| 202 namespace autofill { | 202 namespace autofill { |
| 203 | 203 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 login_to_password_info_.find(element); | 246 login_to_password_info_.find(element); |
| 247 if (iter == login_to_password_info_.end()) | 247 if (iter == login_to_password_info_.end()) |
| 248 return false; | 248 return false; |
| 249 | 249 |
| 250 // The input text is being changed, so any autofilled password is now | 250 // The input text is being changed, so any autofilled password is now |
| 251 // outdated. | 251 // outdated. |
| 252 WebKit::WebInputElement username = element; // We need a non-const. | 252 WebKit::WebInputElement username = element; // We need a non-const. |
| 253 WebKit::WebInputElement password = iter->second.password_field; | 253 WebKit::WebInputElement password = iter->second.password_field; |
| 254 SetElementAutofilled(&username, false); | 254 SetElementAutofilled(&username, false); |
| 255 if (password.isAutofilled()) { | 255 if (password.isAutofilled()) { |
| 256 password.setValue(string16()); | 256 password.setValue(base::string16()); |
| 257 SetElementAutofilled(&password, false); | 257 SetElementAutofilled(&password, false); |
| 258 } | 258 } |
| 259 | 259 |
| 260 // If wait_for_username is true we will fill when the username loses focus. | 260 // If wait_for_username is true we will fill when the username loses focus. |
| 261 if (iter->second.fill_data.wait_for_username) | 261 if (iter->second.fill_data.wait_for_username) |
| 262 return false; | 262 return false; |
| 263 | 263 |
| 264 if (!IsElementEditable(element) || | 264 if (!IsElementEditable(element) || |
| 265 !element.isText() || | 265 !element.isText() || |
| 266 !element.autoComplete()) { | 266 !element.autoComplete()) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 field, | 479 field, |
| 480 form_data)); | 480 form_data)); |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 | 483 |
| 484 //////////////////////////////////////////////////////////////////////////////// | 484 //////////////////////////////////////////////////////////////////////////////// |
| 485 // PasswordAutofillAgent, private: | 485 // PasswordAutofillAgent, private: |
| 486 | 486 |
| 487 void PasswordAutofillAgent::GetSuggestions( | 487 void PasswordAutofillAgent::GetSuggestions( |
| 488 const PasswordFormFillData& fill_data, | 488 const PasswordFormFillData& fill_data, |
| 489 const string16& input, | 489 const base::string16& input, |
| 490 std::vector<string16>* suggestions) { | 490 std::vector<base::string16>* suggestions) { |
| 491 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) | 491 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) |
| 492 suggestions->push_back(fill_data.basic_data.fields[0].value); | 492 suggestions->push_back(fill_data.basic_data.fields[0].value); |
| 493 | 493 |
| 494 PasswordFormFillData::LoginCollection::const_iterator iter; | 494 PasswordFormFillData::LoginCollection::const_iterator iter; |
| 495 for (iter = fill_data.additional_logins.begin(); | 495 for (iter = fill_data.additional_logins.begin(); |
| 496 iter != fill_data.additional_logins.end(); ++iter) { | 496 iter != fill_data.additional_logins.end(); ++iter) { |
| 497 if (StartsWith(iter->first, input, false)) | 497 if (StartsWith(iter->first, input, false)) |
| 498 suggestions->push_back(iter->first); | 498 suggestions->push_back(iter->first); |
| 499 } | 499 } |
| 500 } | 500 } |
| 501 | 501 |
| 502 bool PasswordAutofillAgent::ShowSuggestionPopup( | 502 bool PasswordAutofillAgent::ShowSuggestionPopup( |
| 503 const PasswordFormFillData& fill_data, | 503 const PasswordFormFillData& fill_data, |
| 504 const WebKit::WebInputElement& user_input) { | 504 const WebKit::WebInputElement& user_input) { |
| 505 WebKit::WebFrame* frame = user_input.document().frame(); | 505 WebKit::WebFrame* frame = user_input.document().frame(); |
| 506 if (!frame) | 506 if (!frame) |
| 507 return false; | 507 return false; |
| 508 | 508 |
| 509 WebKit::WebView* webview = frame->view(); | 509 WebKit::WebView* webview = frame->view(); |
| 510 if (!webview) | 510 if (!webview) |
| 511 return false; | 511 return false; |
| 512 | 512 |
| 513 std::vector<string16> suggestions; | 513 std::vector<base::string16> suggestions; |
| 514 GetSuggestions(fill_data, user_input.value(), &suggestions); | 514 GetSuggestions(fill_data, user_input.value(), &suggestions); |
| 515 | 515 |
| 516 if (disable_popup_) { | 516 if (disable_popup_) { |
| 517 FormData form; | 517 FormData form; |
| 518 FormFieldData field; | 518 FormFieldData field; |
| 519 FindFormAndFieldForInputElement( | 519 FindFormAndFieldForInputElement( |
| 520 user_input, &form, &field, REQUIRE_NONE); | 520 user_input, &form, &field, REQUIRE_NONE); |
| 521 | 521 |
| 522 WebKit::WebInputElement selected_element = user_input; | 522 WebKit::WebInputElement selected_element = user_input; |
| 523 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); | 523 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); |
| 524 | 524 |
| 525 float scale = web_view_->pageScaleFactor(); | 525 float scale = web_view_->pageScaleFactor(); |
| 526 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, | 526 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, |
| 527 bounding_box.y() * scale, | 527 bounding_box.y() * scale, |
| 528 bounding_box.width() * scale, | 528 bounding_box.width() * scale, |
| 529 bounding_box.height() * scale); | 529 bounding_box.height() * scale); |
| 530 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), | 530 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), |
| 531 field, | 531 field, |
| 532 bounding_box_scaled, | 532 bounding_box_scaled, |
| 533 suggestions)); | 533 suggestions)); |
| 534 return !suggestions.empty(); | 534 return !suggestions.empty(); |
| 535 } | 535 } |
| 536 | 536 |
| 537 | 537 |
| 538 if (suggestions.empty()) { | 538 if (suggestions.empty()) { |
| 539 webview->hidePopups(); | 539 webview->hidePopups(); |
| 540 return false; | 540 return false; |
| 541 } | 541 } |
| 542 | 542 |
| 543 std::vector<string16> labels(suggestions.size()); | 543 std::vector<base::string16> labels(suggestions.size()); |
| 544 std::vector<string16> icons(suggestions.size()); | 544 std::vector<base::string16> icons(suggestions.size()); |
| 545 std::vector<int> ids(suggestions.size(), | 545 std::vector<int> ids(suggestions.size(), |
| 546 WebKit::WebAutofillClient::MenuItemIDPasswordEntry); | 546 WebKit::WebAutofillClient::MenuItemIDPasswordEntry); |
| 547 webview->applyAutofillSuggestions( | 547 webview->applyAutofillSuggestions( |
| 548 user_input, suggestions, labels, icons, ids); | 548 user_input, suggestions, labels, icons, ids); |
| 549 return true; | 549 return true; |
| 550 } | 550 } |
| 551 | 551 |
| 552 bool PasswordAutofillAgent::FillUserNameAndPassword( | 552 bool PasswordAutofillAgent::FillUserNameAndPassword( |
| 553 WebKit::WebInputElement* username_element, | 553 WebKit::WebInputElement* username_element, |
| 554 WebKit::WebInputElement* password_element, | 554 WebKit::WebInputElement* password_element, |
| 555 const PasswordFormFillData& fill_data, | 555 const PasswordFormFillData& fill_data, |
| 556 bool exact_username_match, | 556 bool exact_username_match, |
| 557 bool set_selection) { | 557 bool set_selection) { |
| 558 string16 current_username = username_element->value(); | 558 base::string16 current_username = username_element->value(); |
| 559 // username and password will contain the match found if any. | 559 // username and password will contain the match found if any. |
| 560 string16 username; | 560 base::string16 username; |
| 561 string16 password; | 561 base::string16 password; |
| 562 | 562 |
| 563 // Look for any suitable matches to current field text. | 563 // Look for any suitable matches to current field text. |
| 564 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, | 564 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, |
| 565 exact_username_match)) { | 565 exact_username_match)) { |
| 566 username = fill_data.basic_data.fields[0].value; | 566 username = fill_data.basic_data.fields[0].value; |
| 567 password = fill_data.basic_data.fields[1].value; | 567 password = fill_data.basic_data.fields[1].value; |
| 568 } else { | 568 } else { |
| 569 // Scan additional logins for a match. | 569 // Scan additional logins for a match. |
| 570 PasswordFormFillData::LoginCollection::const_iterator iter; | 570 PasswordFormFillData::LoginCollection::const_iterator iter; |
| 571 for (iter = fill_data.additional_logins.begin(); | 571 for (iter = fill_data.additional_logins.begin(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 648 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 649 if (iter == login_to_password_info_.end()) | 649 if (iter == login_to_password_info_.end()) |
| 650 return false; | 650 return false; |
| 651 | 651 |
| 652 *found_input = input; | 652 *found_input = input; |
| 653 *found_password = iter->second; | 653 *found_password = iter->second; |
| 654 return true; | 654 return true; |
| 655 } | 655 } |
| 656 | 656 |
| 657 } // namespace autofill | 657 } // namespace autofill |
| OLD | NEW |