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

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

Issue 1169903007: [NOT FOR REVIEW][Omnibox] Changing protocol scheme from https:// to http:// results in DCHECK. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « chrome/test/data/password/ambiguous_password_form.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 // The size above which we stop triggering autocomplete. 48 // The size above which we stop triggering autocomplete.
49 static const size_t kMaximumTextSizeForAutocomplete = 1000; 49 static const size_t kMaximumTextSizeForAutocomplete = 1000;
50 50
51 // Experiment information 51 // Experiment information
52 const char kFillOnAccountSelectFieldTrialName[] = "FillOnAccountSelect"; 52 const char kFillOnAccountSelectFieldTrialName[] = "FillOnAccountSelect";
53 const char kFillOnAccountSelectFieldTrialEnabledWithHighlightGroup[] = 53 const char kFillOnAccountSelectFieldTrialEnabledWithHighlightGroup[] =
54 "EnableWithHighlight"; 54 "EnableWithHighlight";
55 const char kFillOnAccountSelectFieldTrialEnabledWithNoHighlightGroup[] = 55 const char kFillOnAccountSelectFieldTrialEnabledWithNoHighlightGroup[] =
56 "EnableWithNoHighlight"; 56 "EnableWithNoHighlight";
57 const char kDummyUsernameField[] = "anonymous_username";
58 const char kDummyPasswordField[] = "anonymous_password";
57 59
58 // Maps element names to the actual elements to simplify form filling. 60 // Maps element names to the actual elements to simplify form filling.
59 typedef std::map<base::string16, blink::WebInputElement> FormInputElementMap; 61 typedef std::map<base::string16, blink::WebInputElement> FormInputElementMap;
60 62
61 // Use the shorter name when referencing SavePasswordProgressLogger::StringID 63 // Use the shorter name when referencing SavePasswordProgressLogger::StringID
62 // values to spare line breaks. The code provides enough context for that 64 // values to spare line breaks. The code provides enough context for that
63 // already. 65 // already.
64 typedef SavePasswordProgressLogger Logger; 66 typedef SavePasswordProgressLogger Logger;
65 67
66 typedef std::vector<FormInputElementMap> FormElementsList; 68 typedef std::vector<FormInputElementMap> FormElementsList;
67 69
68 bool FillDataContainsFillableUsername(const PasswordFormFillData& fill_data) { 70 bool FillDataContainsFillableUsername(const PasswordFormFillData& fill_data) {
69 return !fill_data.username_field.name.empty() && 71 return !fill_data.username_field.name.empty() &&
70 (!fill_data.additional_logins.empty() || 72 (!fill_data.additional_logins.empty() ||
71 !fill_data.username_field.value.empty()); 73 !fill_data.username_field.value.empty());
72 } 74 }
73 75
74 // Returns true if |control_elements| contains an element named |name| and is 76 // Returns true if |control_elements| contains an element named |name| and is
75 // visible. 77 // visible.
76 bool IsNamedElementVisible( 78 bool IsNamedElementVisible(
77 const std::vector<blink::WebFormControlElement>& control_elements, 79 const std::vector<blink::WebFormControlElement>& control_elements,
78 const base::string16& name) { 80 const base::string16& name) {
79 for (size_t i = 0; i < control_elements.size(); ++i) { 81 for (const blink::WebFormControlElement& control_element : control_elements) {
80 if (control_elements[i].nameForAutofill() == name) { 82 if (control_element.nameForAutofill() == name) {
81 return IsWebNodeVisible(control_elements[i]); 83 return IsWebNodeVisible(control_element);
82 } 84 }
83 } 85 }
84 return false; 86 return false;
85 } 87 }
86 88
89 // Returns true if password form has username and password fields with either
90 // same or no name and id attributes supplied.
91 bool DoesFormContainAmbiguousOrEmptyNames(
92 const PasswordFormFillData& fill_data) {
93 return (fill_data.username_field.name == fill_data.password_field.name) ||
94 (fill_data.password_field.name ==
95 base::ASCIIToUTF16(kDummyPasswordField) &&
96 (!FillDataContainsFillableUsername(fill_data) ||
97 fill_data.username_field.name ==
98 base::ASCIIToUTF16(kDummyUsernameField)));
99 }
100
101 bool IsPasswordField(const FormFieldData& field) {
102 return (field.form_control_type == "password");
103 }
104
105 bool HasMultiplePasswordFields(
106 const std::vector<blink::WebFormControlElement>& control_elements) {
107 size_t password_elements = 0;
108 for (const blink::WebFormControlElement& control_element : control_elements) {
109 if (!control_element.hasHTMLTagName("input"))
110 continue;
111
112 const blink::WebInputElement input_element =
113 control_element.toConst<blink::WebInputElement>();
114 if (input_element.isPasswordField())
115 ++password_elements;
116 }
117
118 return password_elements > 1;
119 }
120
121 bool HasAutocompleteCurrentPasswordAttribute(
122 const blink::WebInputElement& password_element) {
123 return password_element.hasAttribute("autocomplete") &&
124 password_element.getAttribute("autocomplete") == "current-password";
125 }
126
127 // Returns the |field|'s autofillable name. If |ambiguous_or_empty_names| is set
128 // to true returns a dummy name instead.
129 base::string16 FieldName(const FormFieldData& field,
130 bool ambiguous_or_empty_names) {
131 return ambiguous_or_empty_names
132 ? IsPasswordField(field) ? base::ASCIIToUTF16(kDummyPasswordField)
133 : base::ASCIIToUTF16(kDummyUsernameField)
134 : field.name;
135 }
136
87 // Utility function to find the unique entry of |control_elements| for the 137 // Utility function to find the unique entry of |control_elements| for the
88 // specified input |field|. On successful find, adds it to |result| and returns 138 // specified input |field|. On successful find, adds it to |result| and returns
89 // |true|. Otherwise clears the references from each |HTMLInputElement| from 139 // |true|. Otherwise clears the references from each |HTMLInputElement| from
90 // |result| and returns |false|. 140 // |result| and returns |false|.
91 bool FindFormInputElement( 141 bool FindFormInputElement(
92 const std::vector<blink::WebFormControlElement>& control_elements, 142 const std::vector<blink::WebFormControlElement>& control_elements,
93 const FormFieldData& field, 143 const FormFieldData& field,
144 bool ambiguous_or_empty_names,
94 FormInputElementMap* result) { 145 FormInputElementMap* result) {
95 // Match the first input element, if any. 146 // Match the first input element, if any.
96 // If more than one match is made, then we have ambiguity (due to misuse
97 // of "name" attribute) so is it considered not found.
98 bool found_input = false; 147 bool found_input = false;
99 for (size_t i = 0; i < control_elements.size(); ++i) { 148 bool has_multiple_password_fields =
100 if (control_elements[i].nameForAutofill() != field.name) 149 HasMultiplePasswordFields(control_elements);
150 base::string16 field_name = FieldName(field, ambiguous_or_empty_names);
151 for (const blink::WebFormControlElement& control_element : control_elements) {
152 if (!ambiguous_or_empty_names &&
153 control_element.nameForAutofill() != field_name) {
154 continue;
155 }
156
157 if (!control_element.hasHTMLTagName("input"))
101 continue; 158 continue;
102 159
103 if (!control_elements[i].hasHTMLTagName("input")) 160 // Only fill saved passwords into password fields and usernames into text
161 // fields.
162 const blink::WebInputElement input_element =
163 control_element.toConst<blink::WebInputElement>();
164 bool is_password_field = IsPasswordField(field);
165 if (input_element.isPasswordField() != is_password_field)
166 continue;
167
168 // For change password form with ambiguous or empty names keep only the
169 // first password field having |autocomplete='current-password'| attribute
170 // set.
171 if (ambiguous_or_empty_names && has_multiple_password_fields &&
172 is_password_field &&
173 !HasAutocompleteCurrentPasswordAttribute(input_element))
104 continue; 174 continue;
105 175
106 // Check for a non-unique match. 176 // Check for a non-unique match.
107 if (found_input) { 177 if (found_input) {
108 found_input = false; 178 found_input = false;
109 break; 179 break;
110 } 180 }
111 181
112 // Only fill saved passwords into password fields and usernames into 182 (*result)[field_name] = input_element;
113 // text fields.
114 const blink::WebInputElement input_element =
115 control_elements[i].toConst<blink::WebInputElement>();
116 if (input_element.isPasswordField() !=
117 (field.form_control_type == "password"))
118 continue;
119
120 (*result)[field.name] = input_element;
121 found_input = true; 183 found_input = true;
122 } 184 }
123 185
124 // A required element was not found. This is not the right form. 186 // A required element was not found. This is not the right form.
125 // Make sure no input elements from a partially matched form in this 187 // Make sure no input elements from a partially matched form in this
126 // iteration remain in the result set. 188 // iteration remain in the result set.
127 // Note: clear will remove a reference from each InputElement. 189 // Note: clear will remove a reference from each InputElement.
128 if (!found_input) { 190 if (!found_input) {
129 result->clear(); 191 result->clear();
130 return false; 192 return false;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 234
173 return group_name != 235 return group_name !=
174 kFillOnAccountSelectFieldTrialEnabledWithNoHighlightGroup; 236 kFillOnAccountSelectFieldTrialEnabledWithNoHighlightGroup;
175 } 237 }
176 238
177 // Helper to search through |control_elements| for the specified input elements 239 // Helper to search through |control_elements| for the specified input elements
178 // in |data|, and add results to |result|. 240 // in |data|, and add results to |result|.
179 bool FindFormInputElements( 241 bool FindFormInputElements(
180 const std::vector<blink::WebFormControlElement>& control_elements, 242 const std::vector<blink::WebFormControlElement>& control_elements,
181 const PasswordFormFillData& data, 243 const PasswordFormFillData& data,
244 bool ambiguous_or_empty_names,
182 FormInputElementMap* result) { 245 FormInputElementMap* result) {
183 return FindFormInputElement(control_elements, data.password_field, result) && 246 return FindFormInputElement(control_elements, data.password_field,
247 ambiguous_or_empty_names, result) &&
184 (!FillDataContainsFillableUsername(data) || 248 (!FillDataContainsFillableUsername(data) ||
185 FindFormInputElement(control_elements, data.username_field, result)); 249 FindFormInputElement(control_elements, data.username_field,
250 ambiguous_or_empty_names, result));
186 } 251 }
187 252
188 // Helper to locate form elements identified by |data|. 253 // Helper to locate form elements identified by |data|.
189 void FindFormElements(content::RenderFrame* render_frame, 254 void FindFormElements(content::RenderFrame* render_frame,
190 const PasswordFormFillData& data, 255 const PasswordFormFillData& data,
256 bool ambiguous_or_empty_names,
191 FormElementsList* results) { 257 FormElementsList* results) {
192 DCHECK(results); 258 DCHECK(results);
193 259
194 blink::WebDocument doc = render_frame->GetWebFrame()->document(); 260 blink::WebDocument doc = render_frame->GetWebFrame()->document();
195 if (!doc.isHTMLDocument()) 261 if (!doc.isHTMLDocument())
196 return; 262 return;
197 263
198 if (data.origin != GetCanonicalOriginForDocument(doc)) 264 if (data.origin != GetCanonicalOriginForDocument(doc))
199 return; 265 return;
200 266
201 blink::WebVector<blink::WebFormElement> forms; 267 blink::WebVector<blink::WebFormElement> forms;
202 doc.forms(forms); 268 doc.forms(forms);
203 269
204 for (size_t i = 0; i < forms.size(); ++i) { 270 for (size_t i = 0; i < forms.size(); ++i) {
205 blink::WebFormElement fe = forms[i]; 271 blink::WebFormElement fe = forms[i];
206 272
207 // Action URL must match. 273 // Action URL must match.
208 if (data.action != GetCanonicalActionForForm(fe)) 274 if (data.action != GetCanonicalActionForForm(fe))
209 continue; 275 continue;
210 276
211 std::vector<blink::WebFormControlElement> control_elements = 277 std::vector<blink::WebFormControlElement> control_elements =
212 ExtractAutofillableElementsInForm(fe); 278 ExtractAutofillableElementsInForm(fe);
213 FormInputElementMap cur_map; 279 FormInputElementMap cur_map;
214 if (FindFormInputElements(control_elements, data, &cur_map)) 280 if (FindFormInputElements(control_elements, data, ambiguous_or_empty_names,
281 &cur_map))
215 results->push_back(cur_map); 282 results->push_back(cur_map);
216 } 283 }
217 // If the element to be filled are not in a <form> element, the "action" and 284 // If the element to be filled are not in a <form> element, the "action" and
218 // origin should be the same. 285 // origin should be the same.
219 if (data.action != data.origin) 286 if (data.action != data.origin)
220 return; 287 return;
221 288
222 std::vector<blink::WebFormControlElement> control_elements = 289 std::vector<blink::WebFormControlElement> control_elements =
223 GetUnownedAutofillableFormFieldElements(doc.all(), nullptr); 290 GetUnownedAutofillableFormFieldElements(doc.all(), nullptr);
224 FormInputElementMap unowned_elements_map; 291 FormInputElementMap unowned_elements_map;
225 if (FindFormInputElements(control_elements, data, &unowned_elements_map)) 292 if (FindFormInputElements(control_elements, data, ambiguous_or_empty_names,
293 &unowned_elements_map))
226 results->push_back(unowned_elements_map); 294 results->push_back(unowned_elements_map);
227 } 295 }
228 296
229 bool IsElementEditable(const blink::WebInputElement& element) { 297 bool IsElementEditable(const blink::WebInputElement& element) {
230 return element.isEnabled() && !element.isReadOnly(); 298 return element.isEnabled() && !element.isReadOnly();
231 } 299 }
232 300
233 bool DoUsernamesMatch(const base::string16& username1, 301 bool DoUsernamesMatch(const base::string16& username1,
234 const base::string16& username2, 302 const base::string16& username2,
235 bool exact_match) { 303 bool exact_match) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 if (!bottom_frame_origin.equals(cur_frame->securityOrigin().toString())) 514 if (!bottom_frame_origin.equals(cur_frame->securityOrigin().toString()))
447 return false; 515 return false;
448 } 516 }
449 517
450 // If we can't modify the password, don't try to set the username 518 // If we can't modify the password, don't try to set the username
451 if (!IsElementAutocompletable(password_element)) 519 if (!IsElementAutocompletable(password_element))
452 return false; 520 return false;
453 521
454 bool form_contains_fillable_username_field = 522 bool form_contains_fillable_username_field =
455 FillDataContainsFillableUsername(fill_data); 523 FillDataContainsFillableUsername(fill_data);
524 bool ambiguous_or_empty_names =
525 DoesFormContainAmbiguousOrEmptyNames(fill_data);
526 base::string16 username_field_name;
527 if (form_contains_fillable_username_field)
528 username_field_name =
529 FieldName(fill_data.username_field, ambiguous_or_empty_names);
530
456 // If the form contains an autocompletable username field, try to set the 531 // If the form contains an autocompletable username field, try to set the
457 // username to the preferred name, but only if: 532 // username to the preferred name, but only if:
458 // (a) The fill-on-account-select flag is not set, and 533 // (a) The fill-on-account-select flag is not set, and
459 // (b) The username element isn't prefilled 534 // (b) The username element isn't prefilled
460 // 535 //
461 // If (a) is false, then just mark the username element as autofilled if the 536 // If (a) is false, then just mark the username element as autofilled if the
462 // user is not in the "no highlighting" group and return so the fill step is 537 // user is not in the "no highlighting" group and return so the fill step is
463 // skipped. 538 // skipped.
464 // 539 //
465 // If there is no autocompletable username field, and (a) is false, then the 540 // If there is no autocompletable username field, and (a) is false, then the
466 // username element cannot be autofilled, but the user should still be able to 541 // username element cannot be autofilled, but the user should still be able to
467 // select to fill the password element, so the password element must be marked 542 // select to fill the password element, so the password element must be marked
468 // as autofilled and the fill step should also be skipped if the user is not 543 // as autofilled and the fill step should also be skipped if the user is not
469 // in the "no highlighting" group. 544 // in the "no highlighting" group.
470 // 545 //
471 // In all other cases, do nothing. 546 // In all other cases, do nothing.
472 bool form_has_fillable_username = form_contains_fillable_username_field && 547 bool form_has_fillable_username = !username_field_name.empty() &&
473 IsElementAutocompletable(username_element); 548 IsElementAutocompletable(username_element);
474 549
475 if (ShouldFillOnAccountSelect()) { 550 if (ShouldFillOnAccountSelect()) {
476 if (!ShouldHighlightFields()) { 551 if (!ShouldHighlightFields()) {
477 return false; 552 return false;
478 } 553 }
479 554
480 if (form_has_fillable_username) { 555 if (form_has_fillable_username) {
481 username_element.setAutofilled(true); 556 username_element.setAutofilled(true);
482 } else if (username_element.isNull() || 557 } else if (username_element.isNull() ||
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 return false; 883 return false;
809 884
810 // If autocomplete='off' is set on the form elements, no suggestion dialog 885 // If autocomplete='off' is set on the form elements, no suggestion dialog
811 // should be shown. However, return |true| to indicate that this is a known 886 // should be shown. However, return |true| to indicate that this is a known
812 // password form and that the request to show suggestions has been handled (as 887 // password form and that the request to show suggestions has been handled (as
813 // a no-op). 888 // a no-op).
814 if (!element.isTextField() || !IsElementAutocompletable(element) || 889 if (!element.isTextField() || !IsElementAutocompletable(element) ||
815 !IsElementAutocompletable(password_info->password_field)) 890 !IsElementAutocompletable(password_info->password_field))
816 return true; 891 return true;
817 892
818 if (element.nameForAutofill().isEmpty()) 893 if (element.nameForAutofill().isEmpty() &&
894 !DoesFormContainAmbiguousOrEmptyNames(password_info->fill_data)) {
819 return false; // If the field has no name, then we won't have values. 895 return false; // If the field has no name, then we won't have values.
896 }
820 897
821 // Don't attempt to autofill with values that are too large. 898 // Don't attempt to autofill with values that are too large.
822 if (element.value().length() > kMaximumTextSizeForAutocomplete) 899 if (element.value().length() > kMaximumTextSizeForAutocomplete)
823 return false; 900 return false;
824 901
825 bool username_is_available = 902 bool username_is_available =
826 !username_element->isNull() && IsElementEditable(*username_element); 903 !username_element->isNull() && IsElementEditable(*username_element);
827 // If the element is a password field, a popup should only be shown if there 904 // If the element is a password field, a popup should only be shown if there
828 // is no username or the corresponding username element is not editable since 905 // is no username or the corresponding username element is not editable since
829 // it is only in that case that the username element does not have a 906 // it is only in that case that the username element does not have a
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 } 1265 }
1189 1266
1190 // This is a new navigation, so require a new user gesture before filling in 1267 // This is a new navigation, so require a new user gesture before filling in
1191 // passwords. 1268 // passwords.
1192 gatekeeper_.Reset(); 1269 gatekeeper_.Reset();
1193 } 1270 }
1194 1271
1195 void PasswordAutofillAgent::OnFillPasswordForm( 1272 void PasswordAutofillAgent::OnFillPasswordForm(
1196 int key, 1273 int key,
1197 const PasswordFormFillData& form_data) { 1274 const PasswordFormFillData& form_data) {
1198 1275 bool ambiguous_or_empty_names =
1276 DoesFormContainAmbiguousOrEmptyNames(form_data);
1199 FormElementsList forms; 1277 FormElementsList forms;
1200 FindFormElements(render_frame(), form_data, &forms); 1278 FindFormElements(render_frame(), form_data, ambiguous_or_empty_names, &forms);
1201 FormElementsList::iterator iter; 1279 FormElementsList::iterator iter;
1202 for (iter = forms.begin(); iter != forms.end(); ++iter) { 1280 for (iter = forms.begin(); iter != forms.end(); ++iter) {
1203 // Attach autocomplete listener to enable selecting alternate logins. 1281 // Attach autocomplete listener to enable selecting alternate logins.
1204 blink::WebInputElement username_element, password_element; 1282 blink::WebInputElement username_element, password_element;
1205 1283
1206 // Check whether the password form has a username input field. 1284 base::string16 username_field_name, password_field_name;
1285 password_field_name =
1286 FieldName(form_data.password_field, ambiguous_or_empty_names);
1207 bool form_contains_fillable_username_field = 1287 bool form_contains_fillable_username_field =
1208 FillDataContainsFillableUsername(form_data); 1288 FillDataContainsFillableUsername(form_data);
1209 if (form_contains_fillable_username_field) { 1289 if (form_contains_fillable_username_field)
1210 username_element = 1290 username_field_name =
1211 (*iter)[form_data.username_field.name]; 1291 FieldName(form_data.username_field, ambiguous_or_empty_names);
1292
1293 // Check whether the password form has a username input field.
1294 if (!username_field_name.empty()) {
1295 username_element = (*iter)[username_field_name];
1212 } 1296 }
1213 1297
1214 // No password field, bail out. 1298 // No password field, bail out.
1215 if (form_data.password_field.name.empty()) 1299 if (password_field_name.empty())
1216 break; 1300 break;
1217 1301
1218 // We might have already filled this form if there are two <form> elements 1302 // We might have already filled this form if there are two <form> elements
1219 // with identical markup. 1303 // with identical markup.
1220 if (login_to_password_info_.find(username_element) != 1304 if (login_to_password_info_.find(username_element) !=
1221 login_to_password_info_.end()) 1305 login_to_password_info_.end())
1222 continue; 1306 continue;
1223 1307
1224 // Get pointer to password element. (We currently only support single 1308 // Get pointer to password element. (We currently only support single
1225 // password forms). 1309 // password forms).
1226 password_element = (*iter)[form_data.password_field.name]; 1310 password_element = (*iter)[password_field_name];
1227 1311
1228 // If wait_for_username is true, we don't want to initially fill the form 1312 // If wait_for_username is true, we don't want to initially fill the form
1229 // until the user types in a valid username. 1313 // until the user types in a valid username.
1230 if (!form_data.wait_for_username) { 1314 if (!form_data.wait_for_username) {
1231 FillFormOnPasswordReceived( 1315 FillFormOnPasswordReceived(
1232 form_data, 1316 form_data,
1233 username_element, 1317 username_element,
1234 password_element, 1318 password_element,
1235 &nonscript_modified_values_, 1319 &nonscript_modified_values_,
1236 base::Bind(&PasswordValueGatekeeper::RegisterElement, 1320 base::Bind(&PasswordValueGatekeeper::RegisterElement,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::DidStopLoading() { 1521 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::DidStopLoading() {
1438 agent_->DidStopLoading(); 1522 agent_->DidStopLoading();
1439 } 1523 }
1440 1524
1441 void PasswordAutofillAgent::LegacyPasswordAutofillAgent:: 1525 void PasswordAutofillAgent::LegacyPasswordAutofillAgent::
1442 DidStartProvisionalLoad(blink::WebLocalFrame* navigated_frame) { 1526 DidStartProvisionalLoad(blink::WebLocalFrame* navigated_frame) {
1443 agent_->LegacyDidStartProvisionalLoad(navigated_frame); 1527 agent_->LegacyDidStartProvisionalLoad(navigated_frame);
1444 } 1528 }
1445 1529
1446 } // namespace autofill 1530 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/test/data/password/ambiguous_password_form.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698