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

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

Issue 120343003: Autofill popup should not be presented when autocomplete='off', even if (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refactoring and fixes as per comments Created 6 years, 12 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 | Annotate | Revision Log
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/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "components/autofill/content/common/autofill_messages.h" 12 #include "components/autofill/content/common/autofill_messages.h"
13 #include "components/autofill/content/renderer/form_autofill_util.h" 13 #include "components/autofill/content/renderer/form_autofill_util.h"
14 #include "components/autofill/content/renderer/password_form_conversion_utils.h" 14 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
15 #include "components/autofill/core/common/form_field_data.h" 15 #include "components/autofill/core/common/form_field_data.h"
16 #include "components/autofill/core/common/password_autofill_util.h" 16 #include "components/autofill/core/common/password_autofill_util.h"
17 #include "components/autofill/core/common/password_form.h" 17 #include "components/autofill/core/common/password_form.h"
18 #include "components/autofill/core/common/password_form_fill_data.h" 18 #include "components/autofill/core/common/password_form_fill_data.h"
19 #include "content/public/renderer/render_view.h" 19 #include "content/public/renderer/render_view.h"
20 #include "third_party/WebKit/public/platform/WebVector.h" 20 #include "third_party/WebKit/public/platform/WebVector.h"
21 #include "third_party/WebKit/public/web/WebAutofillClient.h" 21 #include "third_party/WebKit/public/web/WebAutofillClient.h"
22 #include "third_party/WebKit/public/web/WebDocument.h" 22 #include "third_party/WebKit/public/web/WebDocument.h"
23 #include "third_party/WebKit/public/web/WebElement.h" 23 #include "third_party/WebKit/public/web/WebElement.h"
24 #include "third_party/WebKit/public/web/WebFormElement.h" 24 #include "third_party/WebKit/public/web/WebFormElement.h"
25 #include "third_party/WebKit/public/web/WebFrame.h" 25 #include "third_party/WebKit/public/web/WebFrame.h"
26 #include "third_party/WebKit/public/web/WebInputEvent.h" 26 #include "third_party/WebKit/public/web/WebInputEvent.h"
27 #include "third_party/WebKit/public/web/WebNode.h" 27 #include "third_party/WebKit/public/web/WebNode.h"
28 #include "third_party/WebKit/public/web/WebNodeList.h" 28 #include "third_party/WebKit/public/web/WebNodeList.h"
29 #include "third_party/WebKit/public/web/WebPasswordFormData.h"
29 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" 30 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
30 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 31 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
31 #include "third_party/WebKit/public/web/WebView.h" 32 #include "third_party/WebKit/public/web/WebView.h"
32 #include "ui/events/keycodes/keyboard_codes.h" 33 #include "ui/events/keycodes/keyboard_codes.h"
33 34
34 namespace autofill { 35 namespace autofill {
35 namespace { 36 namespace {
36 37
37 // The size above which we stop triggering autocomplete. 38 // The size above which we stop triggering autocomplete.
38 static const size_t kMaximumTextSizeForAutocomplete = 1000; 39 static const size_t kMaximumTextSizeForAutocomplete = 1000;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 175 }
175 176
176 bool DoUsernamesMatch(const base::string16& username1, 177 bool DoUsernamesMatch(const base::string16& username1,
177 const base::string16& username2, 178 const base::string16& username2,
178 bool exact_match) { 179 bool exact_match) {
179 if (exact_match) 180 if (exact_match)
180 return username1 == username2; 181 return username1 == username2;
181 return StartsWith(username1, username2, true); 182 return StartsWith(username1, username2, true);
182 } 183 }
183 184
185 bool IsElementAutocompletable(const blink::WebInputElement& element) {
Ilya Sherman 2013/12/27 23:17:09 nit: Docs, please.
jww 2013/12/31 00:33:05 Done.
186 return IsElementEditable(element) &&
187 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
188 element.autoComplete());
189 }
190
184 } // namespace 191 } // namespace
185 192
186 //////////////////////////////////////////////////////////////////////////////// 193 ////////////////////////////////////////////////////////////////////////////////
187 // PasswordAutofillAgent, public: 194 // PasswordAutofillAgent, public:
188 195
189 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view) 196 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view)
190 : content::RenderViewObserver(render_view), 197 : content::RenderViewObserver(render_view),
191 usernames_usage_(NOTHING_TO_AUTOFILL), 198 usernames_usage_(NOTHING_TO_AUTOFILL),
192 web_view_(render_view->GetWebView()), 199 web_view_(render_view->GetWebView()),
193 gesture_handler_(new AutofillWebUserGestureHandler(this)), 200 gesture_handler_(new AutofillWebUserGestureHandler(this)),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 SetElementAutofilled(&username, false); 250 SetElementAutofilled(&username, false);
244 if (password.isAutofilled()) { 251 if (password.isAutofilled()) {
245 password.setValue(base::string16()); 252 password.setValue(base::string16());
246 SetElementAutofilled(&password, false); 253 SetElementAutofilled(&password, false);
247 } 254 }
248 255
249 // If wait_for_username is true we will fill when the username loses focus. 256 // If wait_for_username is true we will fill when the username loses focus.
250 if (iter->second.fill_data.wait_for_username) 257 if (iter->second.fill_data.wait_for_username)
251 return false; 258 return false;
252 259
253 if (!IsElementEditable(element) || !element.isText() || 260 if (!element.isText() || !IsElementAutocompletable(element)) {
254 (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
255 !element.autoComplete())) {
256 return false; 261 return false;
257 } 262 }
258 263
259 // Don't inline autocomplete if the user is deleting, that would be confusing. 264 // Don't inline autocomplete if the user is deleting, that would be confusing.
260 // But refresh the popup. Note, since this is ours, return true to signal 265 // But refresh the popup. Note, since this is ours, return true to signal
261 // no further processing is required. 266 // no further processing is required.
262 if (iter->second.backspace_pressed_last) { 267 if (iter->second.backspace_pressed_last) {
263 ShowSuggestionPopup(iter->second.fill_data, username); 268 ShowSuggestionPopup(iter->second.fill_data, username);
264 return true; 269 return true;
265 } 270 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 return FindLoginInfo(node, &input, &password); 323 return FindLoginInfo(node, &input, &password);
319 } 324 }
320 325
321 bool PasswordAutofillAgent::ShowSuggestions( 326 bool PasswordAutofillAgent::ShowSuggestions(
322 const blink::WebInputElement& element) { 327 const blink::WebInputElement& element) {
323 LoginToPasswordInfoMap::const_iterator iter = 328 LoginToPasswordInfoMap::const_iterator iter =
324 login_to_password_info_.find(element); 329 login_to_password_info_.find(element);
325 if (iter == login_to_password_info_.end()) 330 if (iter == login_to_password_info_.end())
326 return false; 331 return false;
327 332
333 // If autocomplete='off' is set on the form, we don't want to actually show a
334 // suggestion dialog, so we return "true," prentending we've done so.
Ilya Sherman 2013/12/27 23:17:09 nit: "prentending" -> "pretending"
Ilya Sherman 2013/12/27 23:17:09 nit: Please avoid the pronoun "we" in comments (ac
jww 2013/12/31 00:33:05 Done.
335 if (!IsElementAutocompletable(element) ||
336 !IsElementAutocompletable(iter->second.password_field))
337 return true;
338
328 return ShowSuggestionPopup(iter->second.fill_data, element); 339 return ShowSuggestionPopup(iter->second.fill_data, element);
329 } 340 }
330 341
331 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( 342 bool PasswordAutofillAgent::OriginCanAccessPasswordManager(
332 const blink::WebSecurityOrigin& origin) { 343 const blink::WebSecurityOrigin& origin) {
333 return origin.canAccessPasswordManager(); 344 return origin.canAccessPasswordManager();
334 } 345 }
335 346
336 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { 347 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) {
337 SendPasswordForms(frame, false /* only_visible */); 348 SendPasswordForms(frame, false /* only_visible */);
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // Do not fill if the password field is in an iframe. 649 // Do not fill if the password field is in an iframe.
639 DCHECK(password_element.document().frame()); 650 DCHECK(password_element.document().frame());
640 if (password_element.document().frame()->parent()) 651 if (password_element.document().frame()->parent())
641 return; 652 return;
642 653
643 if (!ShouldIgnoreAutocompleteOffForPasswordFields() && 654 if (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
644 !username_element.form().autoComplete()) 655 !username_element.form().autoComplete())
645 return; 656 return;
646 657
647 // If we can't modify the password, don't try to set the username 658 // If we can't modify the password, don't try to set the username
648 if (!IsElementEditable(password_element) || 659 if (!IsElementAutocompletable(password_element))
649 (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
650 !password_element.autoComplete()))
651 return; 660 return;
652 661
653 // Try to set the username to the preferred name, but only if the field 662 // Try to set the username to the preferred name, but only if the field
654 // can be set and isn't prefilled. 663 // can be set and isn't prefilled.
655 if (IsElementEditable(username_element) && 664 if (IsElementAutocompletable(username_element) &&
656 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
657 username_element.autoComplete()) &&
658 username_element.value().isEmpty()) { 665 username_element.value().isEmpty()) {
659 // TODO(tkent): Check maxlength and pattern. 666 // TODO(tkent): Check maxlength and pattern.
660 username_element.setValue(fill_data.basic_data.fields[0].value); 667 username_element.setValue(fill_data.basic_data.fields[0].value);
661 } 668 }
662 669
663 // Fill if we have an exact match for the username. Note that this sets 670 // Fill if we have an exact match for the username. Note that this sets
664 // username to autofilled. 671 // username to autofilled.
665 FillUserNameAndPassword(&username_element, &password_element, fill_data, 672 FillUserNameAndPassword(&username_element, &password_element, fill_data,
666 true /* exact_username_match */, 673 true /* exact_username_match */,
667 false /* set_selection */); 674 false /* set_selection */);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } 722 }
716 } 723 }
717 } 724 }
718 if (password.empty()) 725 if (password.empty())
719 return false; // No match was found. 726 return false; // No match was found.
720 727
721 // TODO(tkent): Check maxlength and pattern for both username and password 728 // TODO(tkent): Check maxlength and pattern for both username and password
722 // fields. 729 // fields.
723 730
724 // Don't fill username if password can't be set. 731 // Don't fill username if password can't be set.
725 if (!IsElementEditable(*password_element) || 732 if (!IsElementAutocompletable(*password_element)) {
726 (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
727 !password_element->autoComplete())) {
728 return false; 733 return false;
729 } 734 }
730 735
731 // Input matches the username, fill in required values. 736 // Input matches the username, fill in required values.
732 if (IsElementEditable(*username_element) && 737 if (IsElementAutocompletable(*username_element)) {
733 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
734 username_element->autoComplete())) {
735 username_element->setValue(username); 738 username_element->setValue(username);
736 SetElementAutofilled(username_element, true); 739 SetElementAutofilled(username_element, true);
737 740
738 if (set_selection) { 741 if (set_selection) {
739 username_element->setSelectionRange(current_username.length(), 742 username_element->setSelectionRange(current_username.length(),
740 username.length()); 743 username.length());
741 } 744 }
742 } else if (current_username != username) { 745 } else if (current_username != username) {
743 // If the username can't be filled and it doesn't match a saved password 746 // If the username can't be filled and it doesn't match a saved password
744 // as is, don't autofill a password. 747 // as is, don't autofill a password.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 } 843 }
841 844
842 PasswordAutofillAgent::AutofillWebUserGestureHandler:: 845 PasswordAutofillAgent::AutofillWebUserGestureHandler::
843 AutofillWebUserGestureHandler(PasswordAutofillAgent* agent) 846 AutofillWebUserGestureHandler(PasswordAutofillAgent* agent)
844 : agent_(agent) {} 847 : agent_(agent) {}
845 848
846 PasswordAutofillAgent::AutofillWebUserGestureHandler:: 849 PasswordAutofillAgent::AutofillWebUserGestureHandler::
847 ~AutofillWebUserGestureHandler() {} 850 ~AutofillWebUserGestureHandler() {}
848 851
849 } // namespace autofill 852 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698