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

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: Test and comment improvements Created 6 years, 11 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 // Returns |true| if the given element is both editable and has permission to be
186 // autocompleted. The latter can be either because there is no
187 // autocomplete='off' set for the element, or because the flag is set to ignore
188 // autocomplete='off'. Otherwise, returns |false|.
189 bool IsElementAutocompletable(const blink::WebInputElement& element) {
190 return IsElementEditable(element) &&
191 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
192 element.autoComplete());
193 }
194
184 } // namespace 195 } // namespace
185 196
186 //////////////////////////////////////////////////////////////////////////////// 197 ////////////////////////////////////////////////////////////////////////////////
187 // PasswordAutofillAgent, public: 198 // PasswordAutofillAgent, public:
188 199
189 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view) 200 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view)
190 : content::RenderViewObserver(render_view), 201 : content::RenderViewObserver(render_view),
191 usernames_usage_(NOTHING_TO_AUTOFILL), 202 usernames_usage_(NOTHING_TO_AUTOFILL),
192 web_view_(render_view->GetWebView()), 203 web_view_(render_view->GetWebView()),
193 gesture_handler_(new AutofillWebUserGestureHandler(this)), 204 gesture_handler_(new AutofillWebUserGestureHandler(this)),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 SetElementAutofilled(&username, false); 254 SetElementAutofilled(&username, false);
244 if (password.isAutofilled()) { 255 if (password.isAutofilled()) {
245 password.setValue(base::string16()); 256 password.setValue(base::string16());
246 SetElementAutofilled(&password, false); 257 SetElementAutofilled(&password, false);
247 } 258 }
248 259
249 // 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.
250 if (iter->second.fill_data.wait_for_username) 261 if (iter->second.fill_data.wait_for_username)
251 return false; 262 return false;
252 263
253 if (!IsElementEditable(element) || !element.isText() || 264 if (!element.isText() || !IsElementAutocompletable(element) ||
254 (!ShouldIgnoreAutocompleteOffForPasswordFields() && 265 !IsElementAutocompletable(password)) {
255 !element.autoComplete())) {
256 return false; 266 return false;
257 } 267 }
258 268
259 // Don't inline autocomplete if the user is deleting, that would be confusing. 269 // 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 270 // But refresh the popup. Note, since this is ours, return true to signal
261 // no further processing is required. 271 // no further processing is required.
262 if (iter->second.backspace_pressed_last) { 272 if (iter->second.backspace_pressed_last) {
263 ShowSuggestionPopup(iter->second.fill_data, username); 273 ShowSuggestionPopup(iter->second.fill_data, username);
264 return true; 274 return true;
265 } 275 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 return FindLoginInfo(node, &input, &password); 328 return FindLoginInfo(node, &input, &password);
319 } 329 }
320 330
321 bool PasswordAutofillAgent::ShowSuggestions( 331 bool PasswordAutofillAgent::ShowSuggestions(
322 const blink::WebInputElement& element) { 332 const blink::WebInputElement& element) {
323 LoginToPasswordInfoMap::const_iterator iter = 333 LoginToPasswordInfoMap::const_iterator iter =
324 login_to_password_info_.find(element); 334 login_to_password_info_.find(element);
325 if (iter == login_to_password_info_.end()) 335 if (iter == login_to_password_info_.end())
326 return false; 336 return false;
327 337
338 // If autocomplete='off' is set on the form elements, no suggestion dialog
339 // should be shown. However, return |true| to indicate that this is a known
340 // password form and that the request to show suggestions has been handled (as
341 // a no-op).
342 if (!IsElementAutocompletable(element) ||
343 !IsElementAutocompletable(iter->second.password_field))
344 return true;
345
328 return ShowSuggestionPopup(iter->second.fill_data, element); 346 return ShowSuggestionPopup(iter->second.fill_data, element);
329 } 347 }
330 348
331 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( 349 bool PasswordAutofillAgent::OriginCanAccessPasswordManager(
332 const blink::WebSecurityOrigin& origin) { 350 const blink::WebSecurityOrigin& origin) {
333 return origin.canAccessPasswordManager(); 351 return origin.canAccessPasswordManager();
334 } 352 }
335 353
336 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { 354 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) {
337 SendPasswordForms(frame, false /* only_visible */); 355 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. 656 // Do not fill if the password field is in an iframe.
639 DCHECK(password_element.document().frame()); 657 DCHECK(password_element.document().frame());
640 if (password_element.document().frame()->parent()) 658 if (password_element.document().frame()->parent())
641 return; 659 return;
642 660
643 if (!ShouldIgnoreAutocompleteOffForPasswordFields() && 661 if (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
644 !username_element.form().autoComplete()) 662 !username_element.form().autoComplete())
645 return; 663 return;
646 664
647 // If we can't modify the password, don't try to set the username 665 // If we can't modify the password, don't try to set the username
648 if (!IsElementEditable(password_element) || 666 if (!IsElementAutocompletable(password_element))
649 (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
650 !password_element.autoComplete()))
651 return; 667 return;
652 668
653 // Try to set the username to the preferred name, but only if the field 669 // Try to set the username to the preferred name, but only if the field
654 // can be set and isn't prefilled. 670 // can be set and isn't prefilled.
655 if (IsElementEditable(username_element) && 671 if (IsElementAutocompletable(username_element) &&
656 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
657 username_element.autoComplete()) &&
658 username_element.value().isEmpty()) { 672 username_element.value().isEmpty()) {
659 // TODO(tkent): Check maxlength and pattern. 673 // TODO(tkent): Check maxlength and pattern.
660 username_element.setValue(fill_data.basic_data.fields[0].value); 674 username_element.setValue(fill_data.basic_data.fields[0].value);
661 } 675 }
662 676
663 // Fill if we have an exact match for the username. Note that this sets 677 // Fill if we have an exact match for the username. Note that this sets
664 // username to autofilled. 678 // username to autofilled.
665 FillUserNameAndPassword(&username_element, &password_element, fill_data, 679 FillUserNameAndPassword(&username_element, &password_element, fill_data,
666 true /* exact_username_match */, 680 true /* exact_username_match */,
667 false /* set_selection */); 681 false /* set_selection */);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } 729 }
716 } 730 }
717 } 731 }
718 if (password.empty()) 732 if (password.empty())
719 return false; // No match was found. 733 return false; // No match was found.
720 734
721 // TODO(tkent): Check maxlength and pattern for both username and password 735 // TODO(tkent): Check maxlength and pattern for both username and password
722 // fields. 736 // fields.
723 737
724 // Don't fill username if password can't be set. 738 // Don't fill username if password can't be set.
725 if (!IsElementEditable(*password_element) || 739 if (!IsElementAutocompletable(*password_element)) {
726 (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
727 !password_element->autoComplete())) {
728 return false; 740 return false;
729 } 741 }
730 742
731 // Input matches the username, fill in required values. 743 // Input matches the username, fill in required values.
732 if (IsElementEditable(*username_element) && 744 if (IsElementAutocompletable(*username_element)) {
733 (ShouldIgnoreAutocompleteOffForPasswordFields() ||
734 username_element->autoComplete())) {
735 username_element->setValue(username); 745 username_element->setValue(username);
736 SetElementAutofilled(username_element, true); 746 SetElementAutofilled(username_element, true);
737 747
738 if (set_selection) { 748 if (set_selection) {
739 username_element->setSelectionRange(current_username.length(), 749 username_element->setSelectionRange(current_username.length(),
740 username.length()); 750 username.length());
741 } 751 }
742 } else if (current_username != username) { 752 } else if (current_username != username) {
743 // If the username can't be filled and it doesn't match a saved password 753 // If the username can't be filled and it doesn't match a saved password
744 // as is, don't autofill a password. 754 // as is, don't autofill a password.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 } 850 }
841 851
842 PasswordAutofillAgent::AutofillWebUserGestureHandler:: 852 PasswordAutofillAgent::AutofillWebUserGestureHandler::
843 AutofillWebUserGestureHandler(PasswordAutofillAgent* agent) 853 AutofillWebUserGestureHandler(PasswordAutofillAgent* agent)
844 : agent_(agent) {} 854 : agent_(agent) {}
845 855
846 PasswordAutofillAgent::AutofillWebUserGestureHandler:: 856 PasswordAutofillAgent::AutofillWebUserGestureHandler::
847 ~AutofillWebUserGestureHandler() {} 857 ~AutofillWebUserGestureHandler() {}
848 858
849 } // namespace autofill 859 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698