| OLD | NEW |
| 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 Loading... |
| 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 WebInputElement* input_element = |
| 210 toWebInputElement(&autofillable_elements[i]); |
| 211 if (input_element) { |
| 212 *predicted_username_element = *input_element; |
| 213 } |
| 214 break; |
| 215 } |
| 216 } |
| 217 } |
| 218 |
| 180 // Get information about a login form encapsulated in a PasswordForm struct. | 219 // 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 | 220 // 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 | 221 // associated string is used instead of the element's value to create |
| 183 // the PasswordForm. | 222 // the PasswordForm. |
| 184 void GetPasswordForm( | 223 void GetPasswordForm( |
| 185 const WebFormElement& form, | 224 const WebFormElement& form, |
| 186 PasswordForm* password_form, | 225 PasswordForm* password_form, |
| 187 const std::map<const blink::WebInputElement, blink::WebString>* | 226 const std::map<const blink::WebInputElement, blink::WebString>* |
| 188 nonscript_modified_values) { | 227 nonscript_modified_values, |
| 228 const std::map<autofill::FormData, autofill::FormFieldData>* |
| 229 form_predictions) { |
| 189 WebInputElement latest_input_element; | 230 WebInputElement latest_input_element; |
| 190 WebInputElement username_element; | 231 WebInputElement username_element; |
| 191 password_form->username_marked_by_site = false; | 232 password_form->username_marked_by_site = false; |
| 192 std::vector<WebInputElement> passwords; | 233 std::vector<WebInputElement> passwords; |
| 193 std::vector<base::string16> other_possible_usernames; | 234 std::vector<base::string16> other_possible_usernames; |
| 194 | 235 |
| 195 WebVector<WebFormControlElement> control_elements; | 236 WebVector<WebFormControlElement> control_elements; |
| 196 form.getFormControlElements(control_elements); | 237 form.getFormControlElements(control_elements); |
| 197 | 238 |
| 198 std::string layout_sequence; | 239 std::string layout_sequence; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 if (username_element.isNull()) | 309 if (username_element.isNull()) |
| 269 latest_input_element = *input_element; | 310 latest_input_element = *input_element; |
| 270 if (!input_element->value().isEmpty()) | 311 if (!input_element->value().isEmpty()) |
| 271 other_possible_usernames.push_back(input_element->value()); | 312 other_possible_usernames.push_back(input_element->value()); |
| 272 } | 313 } |
| 273 } | 314 } |
| 274 } | 315 } |
| 275 } | 316 } |
| 276 password_form->layout = SequenceToLayout(layout_sequence); | 317 password_form->layout = SequenceToLayout(layout_sequence); |
| 277 | 318 |
| 319 WebInputElement predicted_username_element; |
| 320 if (form_predictions) { |
| 321 FindPredictedUsernameElement(form, *form_predictions, &control_elements, |
| 322 &predicted_username_element); |
| 323 } |
| 324 // Let server predictions override the selection of the username field. This |
| 325 // allows instant adjusting without changing Chromium code. |
| 326 if (!predicted_username_element.isNull() && |
| 327 username_element != predicted_username_element) { |
| 328 auto it = |
| 329 find(other_possible_usernames.begin(), other_possible_usernames.end(), |
| 330 predicted_username_element.value()); |
| 331 if (it != other_possible_usernames.end()) |
| 332 other_possible_usernames.erase(it); |
| 333 if (!username_element.isNull()) { |
| 334 other_possible_usernames.push_back(username_element.value()); |
| 335 } |
| 336 username_element = predicted_username_element; |
| 337 password_form->was_parsed_using_autofill_predictions = true; |
| 338 } |
| 339 |
| 278 if (!username_element.isNull()) { | 340 if (!username_element.isNull()) { |
| 279 password_form->username_element = username_element.nameForAutofill(); | 341 password_form->username_element = username_element.nameForAutofill(); |
| 280 base::string16 username_value = username_element.value(); | 342 base::string16 username_value = username_element.value(); |
| 281 if (nonscript_modified_values != nullptr) { | 343 if (nonscript_modified_values != nullptr) { |
| 282 auto username_iterator = | 344 auto username_iterator = |
| 283 nonscript_modified_values->find(username_element); | 345 nonscript_modified_values->find(username_element); |
| 284 if (username_iterator != nonscript_modified_values->end()) { | 346 if (username_iterator != nonscript_modified_values->end()) { |
| 285 base::string16 typed_username_value = username_iterator->second; | 347 base::string16 typed_username_value = username_iterator->second; |
| 286 if (!StartsWith(username_value, typed_username_value, false)) { | 348 if (!StartsWith(username_value, typed_username_value, false)) { |
| 287 // We check that |username_value| was not obtained by autofilling | 349 // We check that |username_value| was not obtained by autofilling |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 password_form->preferred = false; | 408 password_form->preferred = false; |
| 347 password_form->blacklisted_by_user = false; | 409 password_form->blacklisted_by_user = false; |
| 348 password_form->type = PasswordForm::TYPE_MANUAL; | 410 password_form->type = PasswordForm::TYPE_MANUAL; |
| 349 } | 411 } |
| 350 | 412 |
| 351 } // namespace | 413 } // namespace |
| 352 | 414 |
| 353 scoped_ptr<PasswordForm> CreatePasswordForm( | 415 scoped_ptr<PasswordForm> CreatePasswordForm( |
| 354 const WebFormElement& web_form, | 416 const WebFormElement& web_form, |
| 355 const std::map<const blink::WebInputElement, blink::WebString>* | 417 const std::map<const blink::WebInputElement, blink::WebString>* |
| 356 nonscript_modified_values) { | 418 nonscript_modified_values, |
| 419 const std::map<autofill::FormData, autofill::FormFieldData>* |
| 420 form_predictions) { |
| 357 if (web_form.isNull()) | 421 if (web_form.isNull()) |
| 358 return scoped_ptr<PasswordForm>(); | 422 return scoped_ptr<PasswordForm>(); |
| 359 | 423 |
| 360 scoped_ptr<PasswordForm> password_form(new PasswordForm()); | 424 scoped_ptr<PasswordForm> password_form(new PasswordForm()); |
| 361 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values); | 425 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, |
| 426 form_predictions); |
| 362 | 427 |
| 363 if (!password_form->action.is_valid()) | 428 if (!password_form->action.is_valid()) |
| 364 return scoped_ptr<PasswordForm>(); | 429 return scoped_ptr<PasswordForm>(); |
| 365 | 430 |
| 366 WebFormElementToFormData(web_form, | 431 WebFormElementToFormData(web_form, |
| 367 blink::WebFormControlElement(), | 432 blink::WebFormControlElement(), |
| 368 REQUIRE_NONE, | 433 REQUIRE_NONE, |
| 369 EXTRACT_NONE, | 434 EXTRACT_NONE, |
| 370 &password_form->form_data, | 435 &password_form->form_data, |
| 371 NULL /* FormFieldData */); | 436 NULL /* FormFieldData */); |
| 372 | 437 |
| 373 return password_form.Pass(); | 438 return password_form.Pass(); |
| 374 } | 439 } |
| 375 | 440 |
| 376 } // namespace autofill | 441 } // namespace autofill |
| OLD | NEW |