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

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

Issue 1153023004: Prepare the infrastructure for password overrides. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed the test. Created 5 years, 6 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> 7 #include <vector>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.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/core/common/form_data_predictions.h"
15 #include "components/autofill/core/common/password_form.h" 14 #include "components/autofill/core/common/password_form.h"
15 #include "components/autofill/core/common/password_form_field_prediction_map.h"
16 #include "third_party/WebKit/public/platform/WebString.h" 16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/web/WebDocument.h" 17 #include "third_party/WebKit/public/web/WebDocument.h"
18 #include "third_party/WebKit/public/web/WebFormControlElement.h" 18 #include "third_party/WebKit/public/web/WebFormControlElement.h"
19 #include "third_party/WebKit/public/web/WebInputElement.h" 19 #include "third_party/WebKit/public/web/WebInputElement.h"
20 #include "third_party/icu/source/i18n/unicode/regex.h" 20 #include "third_party/icu/source/i18n/unicode/regex.h"
21 21
22 using blink::WebDocument; 22 using blink::WebDocument;
23 using blink::WebFormControlElement; 23 using blink::WebFormControlElement;
24 using blink::WebFormElement; 24 using blink::WebFormElement;
25 using blink::WebInputElement; 25 using blink::WebInputElement;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 *new_password = passwords[0]; 174 *new_password = passwords[0];
175 } else { 175 } else {
176 // Three different passwords, or first and last match with middle 176 // Three different passwords, or first and last match with middle
177 // different. No idea which is which, so no luck. 177 // different. No idea which is which, so no luck.
178 return false; 178 return false;
179 } 179 }
180 } 180 }
181 return true; 181 return true;
182 } 182 }
183 183
184 void FindPredictedUsernameElement( 184 void FindPredictedElements(
185 const WebFormElement& form, 185 const WebFormElement& form,
186 const std::map<autofill::FormData, autofill::FormFieldData>& 186 const std::map<autofill::FormData,
187 form_predictions, 187 autofill::PasswordFormFieldPredictionMap>& form_predictions,
188 WebVector<WebFormControlElement>* control_elements, 188 WebVector<WebFormControlElement>* control_elements,
189 WebInputElement* predicted_username_element) { 189 std::map<autofill::PasswordFormFieldPredictionType, WebInputElement>*
190 predicted_elements) {
190 FormData form_data; 191 FormData form_data;
191 if (!WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE, 192 if (!WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE,
192 &form_data, nullptr)) { 193 &form_data, nullptr)) {
193 return; 194 return;
194 } 195 }
195 196
196 // Matching only requires that action and name of the form match to allow 197 // Matching only requires that action and name of the form match to allow
197 // the username to be updated even if the form is changed after page load. 198 // the username to be updated even if the form is changed after page load.
198 // See https://crbug.com/476092 for more details. 199 // See https://crbug.com/476092 for more details.
199 auto predictions_iterator = form_predictions.begin(); 200 auto predictions_iterator = form_predictions.begin();
200 for (;predictions_iterator != form_predictions.end(); 201 for (;predictions_iterator != form_predictions.end();
201 ++predictions_iterator) { 202 ++predictions_iterator) {
202 if (predictions_iterator->first.action == form_data.action && 203 if (predictions_iterator->first.action == form_data.action &&
203 predictions_iterator->first.name == form_data.name) { 204 predictions_iterator->first.name == form_data.name) {
204 break; 205 break;
205 } 206 }
206 } 207 }
207 208
208 if (predictions_iterator == form_predictions.end()) 209 if (predictions_iterator == form_predictions.end())
209 return; 210 return;
210 211
211 std::vector<blink::WebFormControlElement> autofillable_elements = 212 std::vector<blink::WebFormControlElement> autofillable_elements =
212 ExtractAutofillableElementsFromSet(*control_elements); 213 ExtractAutofillableElementsFromSet(*control_elements);
213 214
214 const autofill::FormFieldData& username_field = predictions_iterator->second; 215 const autofill::PasswordFormFieldPredictionMap& field_predictions =
215 for (size_t i = 0; i < autofillable_elements.size(); ++i) { 216 predictions_iterator->second;
216 if (autofillable_elements[i].nameForAutofill() == username_field.name) { 217 for (autofill::PasswordFormFieldPredictionMap::const_iterator prediction =
217 WebInputElement* input_element = 218 field_predictions.begin();
218 toWebInputElement(&autofillable_elements[i]); 219 prediction != field_predictions.end(); ++prediction) {
219 if (input_element) { 220 const autofill::PasswordFormFieldPredictionType& type = prediction->first;
220 *predicted_username_element = *input_element; 221 const autofill::FormFieldData& target_field = prediction->second;
222
223 for (size_t i = 0; i < autofillable_elements.size(); ++i) {
224 if (autofillable_elements[i].nameForAutofill() == target_field.name) {
225 WebInputElement* input_element =
226 toWebInputElement(&autofillable_elements[i]);
227 if (input_element) {
228 (*predicted_elements)[type] = *input_element;
229 }
230 break;
221 } 231 }
222 break;
223 } 232 }
224 } 233 }
225 } 234 }
226 235
227 // Get information about a login form encapsulated in a PasswordForm struct. 236 // Get information about a login form encapsulated in a PasswordForm struct.
228 // If an element of |form| has an entry in |nonscript_modified_values|, the 237 // If an element of |form| has an entry in |nonscript_modified_values|, the
229 // associated string is used instead of the element's value to create 238 // associated string is used instead of the element's value to create
230 // the PasswordForm. 239 // the PasswordForm.
231 void GetPasswordForm( 240 void GetPasswordForm(
232 const WebFormElement& form, 241 const WebFormElement& form,
233 PasswordForm* password_form, 242 PasswordForm* password_form,
234 const std::map<const blink::WebInputElement, blink::WebString>* 243 const std::map<const blink::WebInputElement, blink::WebString>*
235 nonscript_modified_values, 244 nonscript_modified_values,
236 const std::map<autofill::FormData, autofill::FormFieldData>* 245 const std::map<autofill::FormData,
246 autofill::PasswordFormFieldPredictionMap>*
237 form_predictions) { 247 form_predictions) {
238 WebInputElement latest_input_element; 248 WebInputElement latest_input_element;
239 WebInputElement username_element; 249 WebInputElement username_element;
240 password_form->username_marked_by_site = false; 250 password_form->username_marked_by_site = false;
241 std::vector<WebInputElement> passwords; 251 std::vector<WebInputElement> passwords;
242 std::vector<base::string16> other_possible_usernames; 252 std::vector<base::string16> other_possible_usernames;
243 253
244 WebVector<WebFormControlElement> control_elements; 254 WebVector<WebFormControlElement> control_elements;
245 form.getFormControlElements(control_elements); 255 form.getFormControlElements(control_elements);
246 256
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 if (username_element.isNull()) 339 if (username_element.isNull())
330 latest_input_element = *input_element; 340 latest_input_element = *input_element;
331 if (!input_element->value().isEmpty()) 341 if (!input_element->value().isEmpty())
332 other_possible_usernames.push_back(input_element->value()); 342 other_possible_usernames.push_back(input_element->value());
333 } 343 }
334 } 344 }
335 } 345 }
336 } 346 }
337 password_form->layout = SequenceToLayout(layout_sequence); 347 password_form->layout = SequenceToLayout(layout_sequence);
338 348
339 WebInputElement predicted_username_element; 349 std::map<autofill::PasswordFormFieldPredictionType, WebInputElement>
350 predicted_elements;
340 if (form_predictions) { 351 if (form_predictions) {
341 FindPredictedUsernameElement(form, *form_predictions, &control_elements, 352 FindPredictedElements(form, *form_predictions, &control_elements,
342 &predicted_username_element); 353 &predicted_elements);
343 } 354 }
344 // Let server predictions override the selection of the username field. This 355 // Let server predictions override the selection of the username field. This
345 // allows instant adjusting without changing Chromium code. 356 // allows instant adjusting without changing Chromium code.
346 if (!predicted_username_element.isNull() && 357 if (!predicted_elements[autofill::PREDICTION_USERNAME].isNull() &&
347 username_element != predicted_username_element) { 358 username_element != predicted_elements[autofill::PREDICTION_USERNAME]) {
348 auto it = 359 auto it =
349 find(other_possible_usernames.begin(), other_possible_usernames.end(), 360 find(other_possible_usernames.begin(), other_possible_usernames.end(),
350 predicted_username_element.value()); 361 predicted_elements[autofill::PREDICTION_USERNAME].value());
351 if (it != other_possible_usernames.end()) 362 if (it != other_possible_usernames.end())
352 other_possible_usernames.erase(it); 363 other_possible_usernames.erase(it);
353 if (!username_element.isNull()) { 364 if (!username_element.isNull()) {
354 other_possible_usernames.push_back(username_element.value()); 365 other_possible_usernames.push_back(username_element.value());
355 } 366 }
356 username_element = predicted_username_element; 367 username_element = predicted_elements[autofill::PREDICTION_USERNAME];
357 password_form->was_parsed_using_autofill_predictions = true; 368 password_form->was_parsed_using_autofill_predictions = true;
358 } 369 }
359 370
360 if (!username_element.isNull()) { 371 if (!username_element.isNull()) {
361 password_form->username_element = username_element.nameForAutofill(); 372 password_form->username_element = username_element.nameForAutofill();
362 base::string16 username_value = username_element.value(); 373 base::string16 username_value = username_element.value();
363 if (nonscript_modified_values != nullptr) { 374 if (nonscript_modified_values != nullptr) {
364 auto username_iterator = 375 auto username_iterator =
365 nonscript_modified_values->find(username_element); 376 nonscript_modified_values->find(username_element);
366 if (username_iterator != nonscript_modified_values->end()) { 377 if (username_iterator != nonscript_modified_values->end()) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 459
449 GURL GetCanonicalOriginForDocument(const WebDocument& document) { 460 GURL GetCanonicalOriginForDocument(const WebDocument& document) {
450 GURL full_origin(document.url()); 461 GURL full_origin(document.url());
451 return StripAuthAndParams(full_origin); 462 return StripAuthAndParams(full_origin);
452 } 463 }
453 464
454 scoped_ptr<PasswordForm> CreatePasswordForm( 465 scoped_ptr<PasswordForm> CreatePasswordForm(
455 const WebFormElement& web_form, 466 const WebFormElement& web_form,
456 const std::map<const blink::WebInputElement, blink::WebString>* 467 const std::map<const blink::WebInputElement, blink::WebString>*
457 nonscript_modified_values, 468 nonscript_modified_values,
458 const std::map<autofill::FormData, autofill::FormFieldData>* 469 const std::map<autofill::FormData,
470 autofill::PasswordFormFieldPredictionMap>*
459 form_predictions) { 471 form_predictions) {
460 if (web_form.isNull()) 472 if (web_form.isNull())
461 return scoped_ptr<PasswordForm>(); 473 return scoped_ptr<PasswordForm>();
462 474
463 scoped_ptr<PasswordForm> password_form(new PasswordForm()); 475 scoped_ptr<PasswordForm> password_form(new PasswordForm());
464 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, 476 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values,
465 form_predictions); 477 form_predictions);
466 478
467 if (!password_form->action.is_valid()) 479 if (!password_form->action.is_valid())
468 return scoped_ptr<PasswordForm>(); 480 return scoped_ptr<PasswordForm>();
469 481
470 WebFormElementToFormData(web_form, 482 WebFormElementToFormData(web_form,
471 blink::WebFormControlElement(), 483 blink::WebFormControlElement(),
472 EXTRACT_NONE, 484 EXTRACT_NONE,
473 &password_form->form_data, 485 &password_form->form_data,
474 NULL /* FormFieldData */); 486 NULL /* FormFieldData */);
475 487
476 return password_form.Pass(); 488 return password_form.Pass();
477 } 489 }
478 490
479 } // namespace autofill 491 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698