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

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

Issue 1028163002: Processing USERNAME reply from Autofill server in Password Manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Small nit Created 5 years, 9 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_form_conversion_utils.h" 5 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
6 6
7 #include <vector>
8
7 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
10 #include "components/autofill/content/renderer/form_autofill_util.h" 12 #include "components/autofill/content/renderer/form_autofill_util.h"
13 #include "components/autofill/core/common/form_data_predictions.h"
11 #include "components/autofill/core/common/password_form.h" 14 #include "components/autofill/core/common/password_form.h"
12 #include "third_party/WebKit/public/platform/WebString.h" 15 #include "third_party/WebKit/public/platform/WebString.h"
13 #include "third_party/WebKit/public/web/WebDocument.h" 16 #include "third_party/WebKit/public/web/WebDocument.h"
14 #include "third_party/WebKit/public/web/WebFormControlElement.h" 17 #include "third_party/WebKit/public/web/WebFormControlElement.h"
15 #include "third_party/WebKit/public/web/WebInputElement.h" 18 #include "third_party/WebKit/public/web/WebInputElement.h"
16 #include "third_party/icu/source/i18n/unicode/regex.h" 19 #include "third_party/icu/source/i18n/unicode/regex.h"
17 20
18 using blink::WebDocument; 21 using blink::WebDocument;
19 using blink::WebFormControlElement; 22 using blink::WebFormControlElement;
20 using blink::WebFormElement; 23 using blink::WebFormElement;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 *new_password = passwords[0]; 173 *new_password = passwords[0];
171 } else { 174 } else {
172 // Three different passwords, or first and last match with middle 175 // Three different passwords, or first and last match with middle
173 // different. No idea which is which, so no luck. 176 // different. No idea which is which, so no luck.
174 return false; 177 return false;
175 } 178 }
176 } 179 }
177 return true; 180 return true;
178 } 181 }
179 182
183 void FindPredictedUsernameElement(
184 const WebFormElement& form,
185 const std::map<autofill::FormData, autofill::FormFieldData>&
186 form_predictions,
187 WebVector<WebFormControlElement>* control_elements,
188 WebInputElement* predicted_username_element) {
189 FormData form_data;
190 if (!WebFormElementToFormData(form, WebFormControlElement(), REQUIRE_NONE,
191 EXTRACT_NONE, &form_data, nullptr))
192 return;
193
194 // Prediction forms are not user submitted, but |form| can be user submitted.
195 // We don't care about this flag for finding predictions, so set it to false.
196 form_data.user_submitted = false;
197 auto predictions_iterator = form_predictions.find(form_data);
198 if (predictions_iterator == form_predictions.end())
199 return;
200
201 std::vector<blink::WebFormControlElement> autofillable_elements =
202 ExtractAutofillableElementsFromSet(*control_elements, REQUIRE_NONE);
203 DCHECK_EQ(autofillable_elements.size(), form_data.fields.size());
204
205 const autofill::FormFieldData& username_field = predictions_iterator->second;
206 autofill::FormFieldData form_field;
207 for (size_t i = 0; i < autofillable_elements.size(); ++i) {
208 if (form_data.fields[i].SameFieldAs(username_field)) {
209 *predicted_username_element =
210 *toWebInputElement(&autofillable_elements[i]);
Ilya Sherman 2015/03/31 00:45:04 Note that toWebInputElement() can return a null po
dvadym 2015/03/31 09:54:03 Thanks, it makes sense. Done
211 break;
212 }
213 }
214 }
215
180 // Get information about a login form encapsulated in a PasswordForm struct. 216 // Get information about a login form encapsulated in a PasswordForm struct.
181 // If an element of |form| has an entry in |nonscript_modified_values|, the 217 // If an element of |form| has an entry in |nonscript_modified_values|, the
182 // associated string is used instead of the element's value to create 218 // associated string is used instead of the element's value to create
183 // the PasswordForm. 219 // the PasswordForm.
184 void GetPasswordForm( 220 void GetPasswordForm(
185 const WebFormElement& form, 221 const WebFormElement& form,
186 PasswordForm* password_form, 222 PasswordForm* password_form,
187 const std::map<const blink::WebInputElement, blink::WebString>* 223 const std::map<const blink::WebInputElement, blink::WebString>*
188 nonscript_modified_values) { 224 nonscript_modified_values,
225 const std::map<autofill::FormData, autofill::FormFieldData>*
226 form_predictions) {
189 WebInputElement latest_input_element; 227 WebInputElement latest_input_element;
190 WebInputElement username_element; 228 WebInputElement username_element;
191 password_form->username_marked_by_site = false; 229 password_form->username_marked_by_site = false;
192 std::vector<WebInputElement> passwords; 230 std::vector<WebInputElement> passwords;
193 std::vector<base::string16> other_possible_usernames; 231 std::vector<base::string16> other_possible_usernames;
194 232
195 WebVector<WebFormControlElement> control_elements; 233 WebVector<WebFormControlElement> control_elements;
196 form.getFormControlElements(control_elements); 234 form.getFormControlElements(control_elements);
197 235
198 std::string layout_sequence; 236 std::string layout_sequence;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 if (username_element.isNull()) 306 if (username_element.isNull())
269 latest_input_element = *input_element; 307 latest_input_element = *input_element;
270 if (!input_element->value().isEmpty()) 308 if (!input_element->value().isEmpty())
271 other_possible_usernames.push_back(input_element->value()); 309 other_possible_usernames.push_back(input_element->value());
272 } 310 }
273 } 311 }
274 } 312 }
275 } 313 }
276 password_form->layout = SequenceToLayout(layout_sequence); 314 password_form->layout = SequenceToLayout(layout_sequence);
277 315
316 WebInputElement predicted_username_element;
317 if (form_predictions) {
318 FindPredictedUsernameElement(form, *form_predictions, &control_elements,
319 &predicted_username_element);
320 }
321 // Let server predictions override the selection of the username field. This
322 // allows instant adjusting without changing Chromium code.
323 if (!predicted_username_element.isNull() &&
324 username_element != predicted_username_element) {
325 auto it =
326 find(other_possible_usernames.begin(), other_possible_usernames.end(),
327 predicted_username_element.value());
328 if (it != other_possible_usernames.end())
329 other_possible_usernames.erase(it);
330 if (!username_element.isNull()) {
331 other_possible_usernames.push_back(username_element.value());
332 }
333 username_element = predicted_username_element;
334 password_form->parsed_using_autofill_predictions = true;
335 }
336
278 if (!username_element.isNull()) { 337 if (!username_element.isNull()) {
279 password_form->username_element = username_element.nameForAutofill(); 338 password_form->username_element = username_element.nameForAutofill();
280 base::string16 username_value = username_element.value(); 339 base::string16 username_value = username_element.value();
281 if (nonscript_modified_values != nullptr) { 340 if (nonscript_modified_values != nullptr) {
282 auto username_iterator = 341 auto username_iterator =
283 nonscript_modified_values->find(username_element); 342 nonscript_modified_values->find(username_element);
284 if (username_iterator != nonscript_modified_values->end()) { 343 if (username_iterator != nonscript_modified_values->end()) {
285 base::string16 typed_username_value = username_iterator->second; 344 base::string16 typed_username_value = username_iterator->second;
286 if (!StartsWith(username_value, typed_username_value, false)) { 345 if (!StartsWith(username_value, typed_username_value, false)) {
287 // We check that |username_value| was not obtained by autofilling 346 // We check that |username_value| was not obtained by autofilling
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 password_form->preferred = false; 405 password_form->preferred = false;
347 password_form->blacklisted_by_user = false; 406 password_form->blacklisted_by_user = false;
348 password_form->type = PasswordForm::TYPE_MANUAL; 407 password_form->type = PasswordForm::TYPE_MANUAL;
349 } 408 }
350 409
351 } // namespace 410 } // namespace
352 411
353 scoped_ptr<PasswordForm> CreatePasswordForm( 412 scoped_ptr<PasswordForm> CreatePasswordForm(
354 const WebFormElement& web_form, 413 const WebFormElement& web_form,
355 const std::map<const blink::WebInputElement, blink::WebString>* 414 const std::map<const blink::WebInputElement, blink::WebString>*
356 nonscript_modified_values) { 415 nonscript_modified_values,
416 const std::map<autofill::FormData, autofill::FormFieldData>*
417 form_predictions) {
357 if (web_form.isNull()) 418 if (web_form.isNull())
358 return scoped_ptr<PasswordForm>(); 419 return scoped_ptr<PasswordForm>();
359 420
360 scoped_ptr<PasswordForm> password_form(new PasswordForm()); 421 scoped_ptr<PasswordForm> password_form(new PasswordForm());
361 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values); 422 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values,
423 form_predictions);
362 424
363 if (!password_form->action.is_valid()) 425 if (!password_form->action.is_valid())
364 return scoped_ptr<PasswordForm>(); 426 return scoped_ptr<PasswordForm>();
365 427
366 WebFormElementToFormData(web_form, 428 WebFormElementToFormData(web_form,
367 blink::WebFormControlElement(), 429 blink::WebFormControlElement(),
368 REQUIRE_NONE, 430 REQUIRE_NONE,
369 EXTRACT_NONE, 431 EXTRACT_NONE,
370 &password_form->form_data, 432 &password_form->form_data,
371 NULL /* FormFieldData */); 433 NULL /* FormFieldData */);
372 434
373 return password_form.Pass(); 435 return password_form.Pass();
374 } 436 }
375 437
376 } // namespace autofill 438 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698