Chromium Code Reviews| 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 "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
| 8 #include "components/autofill/content/renderer/form_autofill_util.h" | 8 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 9 #include "components/autofill/core/common/form_data_predictions.h" | |
| 9 #include "components/autofill/core/common/password_form.h" | 10 #include "components/autofill/core/common/password_form.h" |
| 10 #include "third_party/WebKit/public/platform/WebString.h" | 11 #include "third_party/WebKit/public/platform/WebString.h" |
| 11 #include "third_party/WebKit/public/web/WebDocument.h" | 12 #include "third_party/WebKit/public/web/WebDocument.h" |
| 12 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 13 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
| 13 #include "third_party/WebKit/public/web/WebInputElement.h" | 14 #include "third_party/WebKit/public/web/WebInputElement.h" |
| 14 | 15 |
| 15 using blink::WebDocument; | 16 using blink::WebDocument; |
| 16 using blink::WebFormControlElement; | 17 using blink::WebFormControlElement; |
| 17 using blink::WebFormElement; | 18 using blink::WebFormElement; |
| 18 using blink::WebInputElement; | 19 using blink::WebInputElement; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 *new_password = passwords[0]; | 101 *new_password = passwords[0]; |
| 101 } else { | 102 } else { |
| 102 // Three different passwords, or first and last match with middle | 103 // Three different passwords, or first and last match with middle |
| 103 // different. No idea which is which, so no luck. | 104 // different. No idea which is which, so no luck. |
| 104 return false; | 105 return false; |
| 105 } | 106 } |
| 106 } | 107 } |
| 107 return true; | 108 return true; |
| 108 } | 109 } |
| 109 | 110 |
| 111 void FindPredictedUsernameElement( | |
| 112 const WebFormElement& form, | |
| 113 const std::vector<autofill::FormDataPredictions>* form_predictions, | |
| 114 WebVector<WebFormControlElement>* control_elements, | |
| 115 WebInputElement& predicted_username_element) { | |
| 116 if (!form_predictions) | |
| 117 return; | |
|
Garrett Casto
2015/03/24 01:31:12
Nit: Generally we give a line of whitespace after
dvadym
2015/03/24 16:38:49
Done.
| |
| 118 FormData form_data; | |
| 119 if (!WebFormElementToFormData( | |
| 120 form, WebFormControlElement(), REQUIRE_AUTOCOMPLETE, | |
|
Garrett Casto
2015/03/24 01:31:12
Why REQUIRE_AUTOCOMPLETE and these particular Extr
dvadym
2015/03/24 16:38:49
Thanks, it makes sense, I didn't dig into details
| |
| 121 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTION_TEXT | | |
| 122 EXTRACT_OPTIONS), | |
| 123 &form_data, nullptr)) | |
| 124 return; | |
|
Garrett Casto
2015/03/24 01:31:12
Nit: Newline.
dvadym
2015/03/24 16:38:49
Done.
| |
| 125 // Prediction forms are not user submitted, but |form| can be user submitted. | |
| 126 // We don't care about this flag for finding predictions, so set it to false. | |
| 127 form_data.user_submitted = false; | |
|
Garrett Casto
2015/03/24 01:31:12
It's a little strange to me that user_submitted is
dvadym
2015/03/24 16:38:49
Yeah, for me it also seems strange. Anyway we need
| |
| 128 const autofill::FormDataPredictions* prediction = nullptr; | |
| 129 for (auto& form_prediction : *form_predictions) { | |
| 130 if (form_prediction.data.SameFormAs(form_data)) { | |
| 131 prediction = &form_prediction; | |
| 132 break; | |
| 133 } | |
| 134 } | |
| 135 if (!prediction) | |
| 136 return; | |
|
Garrett Casto
2015/03/24 01:31:12
Nit: Newline.
dvadym
2015/03/24 16:38:49
Done.
| |
| 137 std::vector<blink::WebFormControlElement> autofillable_elements = | |
| 138 ExtractAutofillableElementsFromSet(*control_elements, REQUIRE_NONE); | |
|
Garrett Casto
2015/03/24 01:31:12
What do you think about changing this so that inst
dvadym
2015/03/24 16:38:49
Yeah, I also think it's more clear. I'm surprised
| |
| 139 if (autofillable_elements.size() != prediction->fields.size()) { | |
| 140 // Keep things simple. Don't use predictions for forms that were modified | |
| 141 // between page load and the server's response to our query. | |
| 142 return; | |
| 143 } | |
| 144 | |
| 145 for (size_t i = 0; i < autofillable_elements.size(); ++i) { | |
| 146 if (prediction->fields[i].server_type != "USERNAME" && | |
| 147 prediction->fields[i].server_type != "USERNAME_AND_EMAIL_ADDRESS") | |
| 148 continue; | |
| 149 WebFormControlElement& element = autofillable_elements[i]; | |
|
Garrett Casto
2015/03/24 01:31:12
Nit: Move the whitespace up a line. |element| logi
dvadym
2015/03/24 16:38:49
Done.
| |
| 150 | |
| 151 if (base::string16(element.nameForAutofill()) != | |
| 152 prediction->data.fields[i].name) { | |
| 153 // Keep things simple. Don't show predictions for elements whose names | |
| 154 // were modified between page load and the server's response to our query. | |
| 155 continue; | |
| 156 } | |
| 157 predicted_username_element = *toWebInputElement(&element); | |
| 158 break; | |
| 159 } | |
| 160 } | |
| 161 | |
| 110 // Get information about a login form encapsulated in a PasswordForm struct. | 162 // Get information about a login form encapsulated in a PasswordForm struct. |
| 111 // If an element of |form| has an entry in |nonscript_modified_values|, the | 163 // If an element of |form| has an entry in |nonscript_modified_values|, the |
| 112 // associated string is used instead of the element's value to create | 164 // associated string is used instead of the element's value to create |
| 113 // the PasswordForm. | 165 // the PasswordForm. |
| 114 void GetPasswordForm( | 166 void GetPasswordForm( |
| 115 const WebFormElement& form, | 167 const WebFormElement& form, |
| 116 PasswordForm* password_form, | 168 PasswordForm* password_form, |
| 117 const std::map<const blink::WebInputElement, blink::WebString>* | 169 const std::map<const blink::WebInputElement, blink::WebString>* |
| 118 nonscript_modified_values) { | 170 nonscript_modified_values, |
| 171 const std::vector<autofill::FormDataPredictions>* form_predictions) { | |
| 119 WebInputElement latest_input_element; | 172 WebInputElement latest_input_element; |
| 120 WebInputElement username_element; | 173 WebInputElement username_element; |
| 121 password_form->username_marked_by_site = false; | 174 password_form->username_marked_by_site = false; |
| 122 std::vector<WebInputElement> passwords; | 175 std::vector<WebInputElement> passwords; |
| 123 std::vector<base::string16> other_possible_usernames; | 176 std::vector<base::string16> other_possible_usernames; |
| 124 | 177 |
| 125 WebVector<WebFormControlElement> control_elements; | 178 WebVector<WebFormControlElement> control_elements; |
| 126 form.getFormControlElements(control_elements); | 179 form.getFormControlElements(control_elements); |
| 127 | 180 |
| 128 for (size_t i = 0; i < control_elements.size(); ++i) { | 181 for (size_t i = 0; i < control_elements.size(); ++i) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 // alternative, at least for now. | 241 // alternative, at least for now. |
| 189 if (username_element.isNull()) | 242 if (username_element.isNull()) |
| 190 latest_input_element = *input_element; | 243 latest_input_element = *input_element; |
| 191 if (!input_element->value().isEmpty()) | 244 if (!input_element->value().isEmpty()) |
| 192 other_possible_usernames.push_back(input_element->value()); | 245 other_possible_usernames.push_back(input_element->value()); |
| 193 } | 246 } |
| 194 } | 247 } |
| 195 } | 248 } |
| 196 } | 249 } |
| 197 | 250 |
| 251 WebInputElement predicted_username_element; | |
| 252 FindPredictedUsernameElement(form, form_predictions, &control_elements, | |
| 253 predicted_username_element); | |
| 254 if (!predicted_username_element.isNull()) { | |
| 255 username_element = predicted_username_element; | |
| 256 password_form->parsed_using_autofill_predictions = true; | |
| 257 } | |
| 258 | |
| 198 if (!username_element.isNull()) { | 259 if (!username_element.isNull()) { |
| 199 password_form->username_element = username_element.nameForAutofill(); | 260 password_form->username_element = username_element.nameForAutofill(); |
| 200 base::string16 username_value = username_element.value(); | 261 base::string16 username_value = username_element.value(); |
| 201 if (nonscript_modified_values != nullptr) { | 262 if (nonscript_modified_values != nullptr) { |
| 202 auto username_iterator = | 263 auto username_iterator = |
| 203 nonscript_modified_values->find(username_element); | 264 nonscript_modified_values->find(username_element); |
| 204 if (username_iterator != nonscript_modified_values->end()) { | 265 if (username_iterator != nonscript_modified_values->end()) { |
| 205 base::string16 typed_username_value = username_iterator->second; | 266 base::string16 typed_username_value = username_iterator->second; |
| 206 if (!StartsWith(username_value, typed_username_value, false)) { | 267 if (!StartsWith(username_value, typed_username_value, false)) { |
| 207 // We check that |username_value| was not obtained by autofilling | 268 // We check that |username_value| was not obtained by autofilling |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 password_form->preferred = false; | 327 password_form->preferred = false; |
| 267 password_form->blacklisted_by_user = false; | 328 password_form->blacklisted_by_user = false; |
| 268 password_form->type = PasswordForm::TYPE_MANUAL; | 329 password_form->type = PasswordForm::TYPE_MANUAL; |
| 269 } | 330 } |
| 270 | 331 |
| 271 } // namespace | 332 } // namespace |
| 272 | 333 |
| 273 scoped_ptr<PasswordForm> CreatePasswordForm( | 334 scoped_ptr<PasswordForm> CreatePasswordForm( |
| 274 const WebFormElement& web_form, | 335 const WebFormElement& web_form, |
| 275 const std::map<const blink::WebInputElement, blink::WebString>* | 336 const std::map<const blink::WebInputElement, blink::WebString>* |
| 276 nonscript_modified_values) { | 337 nonscript_modified_values, |
| 338 const std::vector<autofill::FormDataPredictions>* form_predictions) { | |
| 277 if (web_form.isNull()) | 339 if (web_form.isNull()) |
| 278 return scoped_ptr<PasswordForm>(); | 340 return scoped_ptr<PasswordForm>(); |
| 279 | 341 |
| 280 scoped_ptr<PasswordForm> password_form(new PasswordForm()); | 342 scoped_ptr<PasswordForm> password_form(new PasswordForm()); |
| 281 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values); | 343 GetPasswordForm(web_form, password_form.get(), nonscript_modified_values, |
| 344 form_predictions); | |
| 282 | 345 |
| 283 if (!password_form->action.is_valid()) | 346 if (!password_form->action.is_valid()) |
| 284 return scoped_ptr<PasswordForm>(); | 347 return scoped_ptr<PasswordForm>(); |
| 285 | 348 |
| 286 WebFormElementToFormData(web_form, | 349 WebFormElementToFormData(web_form, |
| 287 blink::WebFormControlElement(), | 350 blink::WebFormControlElement(), |
| 288 REQUIRE_NONE, | 351 REQUIRE_NONE, |
| 289 EXTRACT_NONE, | 352 EXTRACT_NONE, |
| 290 &password_form->form_data, | 353 &password_form->form_data, |
| 291 NULL /* FormFieldData */); | 354 NULL /* FormFieldData */); |
| 292 | 355 |
| 293 return password_form.Pass(); | 356 return password_form.Pass(); |
| 294 } | 357 } |
| 295 | 358 |
| 296 } // namespace autofill | 359 } // namespace autofill |
| OLD | NEW |