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

Side by Side Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 962673004: [Autofill/Autocomplete Feature] Substring matching instead of prefix matching. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated Vaclav's review comments. Created 5 years, 5 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 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_autofill_agent.h" 5 #include "components/autofill/content/renderer/password_autofill_agent.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "components/autofill/content/common/autofill_messages.h" 15 #include "components/autofill/content/common/autofill_messages.h"
16 #include "components/autofill/content/renderer/form_autofill_util.h" 16 #include "components/autofill/content/renderer/form_autofill_util.h"
17 #include "components/autofill/content/renderer/password_form_conversion_utils.h" 17 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
18 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h" 18 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h"
19 #include "components/autofill/core/common/autofill_constants.h" 19 #include "components/autofill/core/common/autofill_constants.h"
20 #include "components/autofill/core/common/autofill_switches.h" 20 #include "components/autofill/core/common/autofill_switches.h"
21 #include "components/autofill/core/common/autofill_util.h"
21 #include "components/autofill/core/common/form_field_data.h" 22 #include "components/autofill/core/common/form_field_data.h"
22 #include "components/autofill/core/common/password_form.h" 23 #include "components/autofill/core/common/password_form.h"
23 #include "components/autofill/core/common/password_form_fill_data.h" 24 #include "components/autofill/core/common/password_form_fill_data.h"
24 #include "content/public/renderer/document_state.h" 25 #include "content/public/renderer/document_state.h"
25 #include "content/public/renderer/navigation_state.h" 26 #include "content/public/renderer/navigation_state.h"
26 #include "content/public/renderer/render_frame.h" 27 #include "content/public/renderer/render_frame.h"
27 #include "content/public/renderer/render_view.h" 28 #include "content/public/renderer/render_view.h"
28 #include "third_party/WebKit/public/platform/WebVector.h" 29 #include "third_party/WebKit/public/platform/WebVector.h"
29 #include "third_party/WebKit/public/web/WebAutofillClient.h" 30 #include "third_party/WebKit/public/web/WebAutofillClient.h"
30 #include "third_party/WebKit/public/web/WebDocument.h" 31 #include "third_party/WebKit/public/web/WebDocument.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 220
220 bool IsElementEditable(const blink::WebInputElement& element) { 221 bool IsElementEditable(const blink::WebInputElement& element) {
221 return element.isEnabled() && !element.isReadOnly(); 222 return element.isEnabled() && !element.isReadOnly();
222 } 223 }
223 224
224 bool DoUsernamesMatch(const base::string16& username1, 225 bool DoUsernamesMatch(const base::string16& username1,
225 const base::string16& username2, 226 const base::string16& username2,
226 bool exact_match) { 227 bool exact_match) {
227 if (exact_match) 228 if (exact_match)
228 return username1 == username2; 229 return username1 == username2;
229 return base::StartsWith(username1, username2, base::CompareCase::SENSITIVE); 230 return FieldIsSuggestionSubstringStartingOnTokenBoundary(username1, username2,
231 true);
230 } 232 }
231 233
232 // Returns |true| if the given element is editable. Otherwise, returns |false|. 234 // Returns |true| if the given element is editable. Otherwise, returns |false|.
233 bool IsElementAutocompletable(const blink::WebInputElement& element) { 235 bool IsElementAutocompletable(const blink::WebInputElement& element) {
234 return IsElementEditable(element); 236 return IsElementEditable(element);
235 } 237 }
236 238
237 // Returns true if the password specified in |form| is a default value. 239 // Returns true if the password specified in |form| is a default value.
238 bool PasswordValueIsDefault(const base::string16& password_element, 240 bool PasswordValueIsDefault(const base::string16& password_element,
239 const base::string16& password_value, 241 const base::string16& password_value,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 403 }
402 if (password.empty()) 404 if (password.empty())
403 return false; 405 return false;
404 406
405 // TODO(tkent): Check maxlength and pattern for both username and password 407 // TODO(tkent): Check maxlength and pattern for both username and password
406 // fields. 408 // fields.
407 409
408 // Input matches the username, fill in required values. 410 // Input matches the username, fill in required values.
409 if (!username_element->isNull() && 411 if (!username_element->isNull() &&
410 IsElementAutocompletable(*username_element)) { 412 IsElementAutocompletable(*username_element)) {
413 // TODO(vabr): Why not setSuggestedValue? http://crbug.com/507714
411 username_element->setValue(username, true); 414 username_element->setValue(username, true);
412 (*nonscript_modified_values)[*username_element] = username; 415 (*nonscript_modified_values)[*username_element] = username;
413 username_element->setAutofilled(true); 416 username_element->setAutofilled(true);
414 417 if (set_selection)
415 if (set_selection) { 418 PreviewSuggestion(username, current_username, username_element);
416 username_element->setSelectionRange(current_username.length(),
417 username.length());
418 }
419 } else if (current_username != username) { 419 } else if (current_username != username) {
420 // If the username can't be filled and it doesn't match a saved password 420 // If the username can't be filled and it doesn't match a saved password
421 // as is, don't autofill a password. 421 // as is, don't autofill a password.
422 return false; 422 return false;
423 } 423 }
424 424
425 // Wait to fill in the password until a user gesture occurs. This is to make 425 // Wait to fill in the password until a user gesture occurs. This is to make
426 // sure that we do not fill in the DOM with a password until we believe the 426 // sure that we do not fill in the DOM with a password until we believe the
427 // user is intentionally interacting with the page. 427 // user is intentionally interacting with the page.
428 password_element->setSuggestedValue(password); 428 password_element->setSuggestedValue(password);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 554
555 //////////////////////////////////////////////////////////////////////////////// 555 ////////////////////////////////////////////////////////////////////////////////
556 // PasswordAutofillAgent, public: 556 // PasswordAutofillAgent, public:
557 557
558 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame) 558 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame)
559 : content::RenderFrameObserver(render_frame), 559 : content::RenderFrameObserver(render_frame),
560 legacy_(render_frame->GetRenderView(), this), 560 legacy_(render_frame->GetRenderView(), this),
561 logging_state_active_(false), 561 logging_state_active_(false),
562 was_username_autofilled_(false), 562 was_username_autofilled_(false),
563 was_password_autofilled_(false), 563 was_password_autofilled_(false),
564 username_selection_start_(0),
565 did_stop_loading_(false), 564 did_stop_loading_(false),
566 weak_ptr_factory_(this) { 565 weak_ptr_factory_(this) {
567 Send(new AutofillHostMsg_PasswordAutofillAgentConstructed(routing_id())); 566 Send(new AutofillHostMsg_PasswordAutofillAgentConstructed(routing_id()));
568 } 567 }
569 568
570 PasswordAutofillAgent::~PasswordAutofillAgent() { 569 PasswordAutofillAgent::~PasswordAutofillAgent() {
571 } 570 }
572 571
573 PasswordAutofillAgent::PasswordValueGatekeeper::PasswordValueGatekeeper() 572 PasswordAutofillAgent::PasswordValueGatekeeper::PasswordValueGatekeeper()
574 : was_user_gesture_seen_(false) { 573 : was_user_gesture_seen_(false) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 const blink::WebString& password) { 744 const blink::WebString& password) {
746 blink::WebInputElement username_element; 745 blink::WebInputElement username_element;
747 PasswordInfo* password_info; 746 PasswordInfo* password_info;
748 747
749 if (!FindLoginInfo(node, &username_element, &password_info) || 748 if (!FindLoginInfo(node, &username_element, &password_info) ||
750 !IsElementAutocompletable(username_element) || 749 !IsElementAutocompletable(username_element) ||
751 !IsElementAutocompletable(password_info->password_field)) { 750 !IsElementAutocompletable(password_info->password_field)) {
752 return false; 751 return false;
753 } 752 }
754 753
754 if (username_query_prefix_.empty())
755 username_query_prefix_ = username_element.value();
756
755 was_username_autofilled_ = username_element.isAutofilled(); 757 was_username_autofilled_ = username_element.isAutofilled();
756 username_selection_start_ = username_element.selectionStart();
757 username_element.setSuggestedValue(username); 758 username_element.setSuggestedValue(username);
758 username_element.setAutofilled(true); 759 username_element.setAutofilled(true);
759 username_element.setSelectionRange( 760 ::autofill::PreviewSuggestion(username_element.suggestedValue(),
760 username_selection_start_, 761 username_query_prefix_, &username_element);
761 username_element.suggestedValue().length());
762
763 was_password_autofilled_ = password_info->password_field.isAutofilled(); 762 was_password_autofilled_ = password_info->password_field.isAutofilled();
764 password_info->password_field.setSuggestedValue(password); 763 password_info->password_field.setSuggestedValue(password);
765 password_info->password_field.setAutofilled(true); 764 password_info->password_field.setAutofilled(true);
766 765
767 return true; 766 return true;
768 } 767 }
769 768
770 bool PasswordAutofillAgent::DidClearAutofillSelection( 769 bool PasswordAutofillAgent::DidClearAutofillSelection(
771 const blink::WebNode& node) { 770 const blink::WebNode& node) {
772 blink::WebInputElement username_element; 771 blink::WebInputElement username_element;
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 if (show_all) 1296 if (show_all)
1298 options |= SHOW_ALL; 1297 options |= SHOW_ALL;
1299 if (show_on_password_field) 1298 if (show_on_password_field)
1300 options |= IS_PASSWORD_FIELD; 1299 options |= IS_PASSWORD_FIELD;
1301 base::string16 username_string( 1300 base::string16 username_string(
1302 username.isNull() ? base::string16() 1301 username.isNull() ? base::string16()
1303 : static_cast<base::string16>(user_input.value())); 1302 : static_cast<base::string16>(user_input.value()));
1304 Send(new AutofillHostMsg_ShowPasswordSuggestions( 1303 Send(new AutofillHostMsg_ShowPasswordSuggestions(
1305 routing_id(), key_it->second, field.text_direction, username_string, 1304 routing_id(), key_it->second, field.text_direction, username_string,
1306 options, bounding_box_scaled)); 1305 options, bounding_box_scaled));
1306 username_query_prefix_ = username_string;
1307 return CanShowSuggestion(fill_data, username_string, show_all); 1307 return CanShowSuggestion(fill_data, username_string, show_all);
1308 } 1308 }
1309 1309
1310 void PasswordAutofillAgent::FrameClosing() { 1310 void PasswordAutofillAgent::FrameClosing() {
1311 for (auto const& iter : login_to_password_info_) { 1311 for (auto const& iter : login_to_password_info_) {
1312 login_to_password_info_key_.erase(iter.first); 1312 login_to_password_info_key_.erase(iter.first);
1313 password_to_username_.erase(iter.second.password_field); 1313 password_to_username_.erase(iter.second.password_field);
1314 } 1314 }
1315 login_to_password_info_.clear(); 1315 login_to_password_info_.clear();
1316 provisionally_saved_form_.reset(); 1316 provisionally_saved_form_.reset();
(...skipping 15 matching lines...) Expand all
1332 return FindPasswordInfoForElement(*found_input, &username_element, 1332 return FindPasswordInfoForElement(*found_input, &username_element,
1333 found_password); 1333 found_password);
1334 } 1334 }
1335 1335
1336 void PasswordAutofillAgent::ClearPreview( 1336 void PasswordAutofillAgent::ClearPreview(
1337 blink::WebInputElement* username, 1337 blink::WebInputElement* username,
1338 blink::WebInputElement* password) { 1338 blink::WebInputElement* password) {
1339 if (!username->suggestedValue().isEmpty()) { 1339 if (!username->suggestedValue().isEmpty()) {
1340 username->setSuggestedValue(blink::WebString()); 1340 username->setSuggestedValue(blink::WebString());
1341 username->setAutofilled(was_username_autofilled_); 1341 username->setAutofilled(was_username_autofilled_);
1342 username->setSelectionRange(username_selection_start_, 1342 username->setSelectionRange(username_query_prefix_.length(),
1343 username->value().length()); 1343 username->value().length());
1344 } 1344 }
1345 if (!password->suggestedValue().isEmpty()) { 1345 if (!password->suggestedValue().isEmpty()) {
1346 password->setSuggestedValue(blink::WebString()); 1346 password->setSuggestedValue(blink::WebString());
1347 password->setAutofilled(was_password_autofilled_); 1347 password->setAutofilled(was_password_autofilled_);
1348 } 1348 }
1349 } 1349 }
1350 1350
1351 void PasswordAutofillAgent::ProvisionallySavePassword( 1351 void PasswordAutofillAgent::ProvisionallySavePassword(
1352 const blink::WebFormElement& form, 1352 const blink::WebFormElement& form,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::DidStopLoading() { 1391 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::DidStopLoading() {
1392 agent_->DidStopLoading(); 1392 agent_->DidStopLoading();
1393 } 1393 }
1394 1394
1395 void PasswordAutofillAgent::LegacyPasswordAutofillAgent:: 1395 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::
1396 DidStartProvisionalLoad(blink::WebLocalFrame* navigated_frame) { 1396 DidStartProvisionalLoad(blink::WebLocalFrame* navigated_frame) {
1397 agent_->LegacyDidStartProvisionalLoad(navigated_frame); 1397 agent_->LegacyDidStartProvisionalLoad(navigated_frame);
1398 } 1398 }
1399 1399
1400 } // namespace autofill 1400 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698