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

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

Issue 2148303005: [Password Generation] Sends the flag whether a field has nonempty user input (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changes addressed to reviewer comments Created 4 years, 4 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/form_autofill_util.h" 5 #include "components/autofill/content/renderer/form_autofill_util.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 951
952 // Extracts the fields from |control_elements| with |extract_mask| to 952 // Extracts the fields from |control_elements| with |extract_mask| to
953 // |form_fields|. The extracted fields are also placed in |element_map|. 953 // |form_fields|. The extracted fields are also placed in |element_map|.
954 // |form_fields| and |element_map| should start out empty. 954 // |form_fields| and |element_map| should start out empty.
955 // |fields_extracted| should have as many elements as |control_elements|, 955 // |fields_extracted| should have as many elements as |control_elements|,
956 // initialized to false. 956 // initialized to false.
957 // Returns true if the number of fields extracted is within 957 // Returns true if the number of fields extracted is within
958 // [1, kMaxParseableFields]. 958 // [1, kMaxParseableFields].
959 bool ExtractFieldsFromControlElements( 959 bool ExtractFieldsFromControlElements(
960 const WebVector<WebFormControlElement>& control_elements, 960 const WebVector<WebFormControlElement>& control_elements,
961 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
961 ExtractMask extract_mask, 962 ExtractMask extract_mask,
962 ScopedVector<FormFieldData>* form_fields, 963 ScopedVector<FormFieldData>* form_fields,
963 std::vector<bool>* fields_extracted, 964 std::vector<bool>* fields_extracted,
964 std::map<WebFormControlElement, FormFieldData*>* element_map) { 965 std::map<WebFormControlElement, FormFieldData*>* element_map) {
965 DCHECK(form_fields->empty()); 966 DCHECK(form_fields->empty());
966 DCHECK(element_map->empty()); 967 DCHECK(element_map->empty());
967 DCHECK_EQ(control_elements.size(), fields_extracted->size()); 968 DCHECK_EQ(control_elements.size(), fields_extracted->size());
968 969
969 for (size_t i = 0; i < control_elements.size(); ++i) { 970 for (size_t i = 0; i < control_elements.size(); ++i) {
970 const WebFormControlElement& control_element = control_elements[i]; 971 const WebFormControlElement& control_element = control_elements[i];
971 972
972 if (!IsAutofillableElement(control_element)) 973 if (!IsAutofillableElement(control_element))
973 continue; 974 continue;
974 975
975 // Create a new FormFieldData, fill it out and map it to the field's name. 976 // Create a new FormFieldData, fill it out and map it to the field's name.
976 FormFieldData* form_field = new FormFieldData; 977 FormFieldData* form_field = new FormFieldData;
977 WebFormControlElementToFormField(control_element, extract_mask, form_field); 978 WebFormControlElementToFormField(control_element,
979 field_value_and_properties_map,
980 extract_mask, form_field);
978 form_fields->push_back(form_field); 981 form_fields->push_back(form_field);
979 (*element_map)[control_element] = form_field; 982 (*element_map)[control_element] = form_field;
980 (*fields_extracted)[i] = true; 983 (*fields_extracted)[i] = true;
981 984
982 // To avoid overly expensive computation, we impose a maximum number of 985 // To avoid overly expensive computation, we impose a maximum number of
983 // allowable fields. 986 // allowable fields.
984 if (form_fields->size() > kMaxParseableFields) 987 if (form_fields->size() > kMaxParseableFields)
985 return false; 988 return false;
986 } 989 }
987 990
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 // 1) |form_element| and an empty |fieldsets|. 1057 // 1) |form_element| and an empty |fieldsets|.
1055 // or 1058 // or
1056 // 2) a NULL |form_element|. 1059 // 2) a NULL |form_element|.
1057 // 1060 //
1058 // If |field| is not NULL, then |form_control_element| should be not NULL. 1061 // If |field| is not NULL, then |form_control_element| should be not NULL.
1059 bool FormOrFieldsetsToFormData( 1062 bool FormOrFieldsetsToFormData(
1060 const blink::WebFormElement* form_element, 1063 const blink::WebFormElement* form_element,
1061 const blink::WebFormControlElement* form_control_element, 1064 const blink::WebFormControlElement* form_control_element,
1062 const std::vector<blink::WebElement>& fieldsets, 1065 const std::vector<blink::WebElement>& fieldsets,
1063 const WebVector<WebFormControlElement>& control_elements, 1066 const WebVector<WebFormControlElement>& control_elements,
1067 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
1064 ExtractMask extract_mask, 1068 ExtractMask extract_mask,
1065 FormData* form, 1069 FormData* form,
1066 FormFieldData* field) { 1070 FormFieldData* field) {
1067 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); 1071 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label"));
1068 1072
1069 if (form_element) 1073 if (form_element)
1070 DCHECK(fieldsets.empty()); 1074 DCHECK(fieldsets.empty());
1071 if (field) 1075 if (field)
1072 DCHECK(form_control_element); 1076 DCHECK(form_control_element);
1073 1077
1074 // A map from a FormFieldData's name to the FormFieldData itself. 1078 // A map from a FormFieldData's name to the FormFieldData itself.
1075 std::map<WebFormControlElement, FormFieldData*> element_map; 1079 std::map<WebFormControlElement, FormFieldData*> element_map;
1076 1080
1077 // The extracted FormFields. We use pointers so we can store them in 1081 // The extracted FormFields. We use pointers so we can store them in
1078 // |element_map|. 1082 // |element_map|.
1079 ScopedVector<FormFieldData> form_fields; 1083 ScopedVector<FormFieldData> form_fields;
1080 1084
1081 // A vector of bools that indicate whether each field in the form meets the 1085 // A vector of bools that indicate whether each field in the form meets the
1082 // requirements and thus will be in the resulting |form|. 1086 // requirements and thus will be in the resulting |form|.
1083 std::vector<bool> fields_extracted(control_elements.size(), false); 1087 std::vector<bool> fields_extracted(control_elements.size(), false);
1084 1088
1085 if (!ExtractFieldsFromControlElements(control_elements, extract_mask, 1089 if (!ExtractFieldsFromControlElements(
1086 &form_fields, &fields_extracted, 1090 control_elements, field_value_and_properties_map, extract_mask,
1087 &element_map)) { 1091 &form_fields, &fields_extracted, &element_map)) {
1088 return false; 1092 return false;
1089 } 1093 }
1090 1094
1091 if (form_element) { 1095 if (form_element) {
1092 // Loop through the label elements inside the form element. For each label 1096 // Loop through the label elements inside the form element. For each label
1093 // element, get the corresponding form control element, use the form control 1097 // element, get the corresponding form control element, use the form control
1094 // element's name as a key into the <name, FormFieldData> map to find the 1098 // element's name as a key into the <name, FormFieldData> map to find the
1095 // previously created FormFieldData and set the FormFieldData's label to the 1099 // previously created FormFieldData and set the FormFieldData's label to the
1096 // label.firstChild().nodeValue() of the label element. 1100 // label.firstChild().nodeValue() of the label element.
1097 WebElementCollection labels = 1101 WebElementCollection labels =
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 for (const auto* iter : form_fields) 1152 for (const auto* iter : form_fields)
1149 form->fields.push_back(*iter); 1153 form->fields.push_back(*iter);
1150 return true; 1154 return true;
1151 } 1155 }
1152 1156
1153 bool UnownedFormElementsAndFieldSetsToFormData( 1157 bool UnownedFormElementsAndFieldSetsToFormData(
1154 const std::vector<blink::WebElement>& fieldsets, 1158 const std::vector<blink::WebElement>& fieldsets,
1155 const std::vector<blink::WebFormControlElement>& control_elements, 1159 const std::vector<blink::WebFormControlElement>& control_elements,
1156 const blink::WebFormControlElement* element, 1160 const blink::WebFormControlElement* element,
1157 const blink::WebDocument& document, 1161 const blink::WebDocument& document,
1162 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
1158 ExtractMask extract_mask, 1163 ExtractMask extract_mask,
1159 FormData* form, 1164 FormData* form,
1160 FormFieldData* field) { 1165 FormFieldData* field) {
1161 form->origin = GetCanonicalOriginForDocument(document); 1166 form->origin = GetCanonicalOriginForDocument(document);
1162 form->is_form_tag = false; 1167 form->is_form_tag = false;
1163 1168
1164 return FormOrFieldsetsToFormData(nullptr, element, fieldsets, 1169 return FormOrFieldsetsToFormData(
1165 control_elements, extract_mask, form, field); 1170 nullptr, element, fieldsets, control_elements,
1171 field_value_and_properties_map, extract_mask, form, field);
1166 } 1172 }
1167 1173
1168 GURL StripAuthAndParams(const GURL& gurl) { 1174 GURL StripAuthAndParams(const GURL& gurl) {
1169 // We want to keep the path but strip any authentication data, as well as 1175 // We want to keep the path but strip any authentication data, as well as
1170 // query and ref portions of URL, for the form action and form origin. 1176 // query and ref portions of URL, for the form action and form origin.
1171 GURL::Replacements rep; 1177 GURL::Replacements rep;
1172 rep.ClearUsername(); 1178 rep.ClearUsername();
1173 rep.ClearPassword(); 1179 rep.ClearPassword();
1174 rep.ClearQuery(); 1180 rep.ClearQuery();
1175 rep.ClearRef(); 1181 rep.ClearRef();
1176 return gurl.ReplaceComponents(rep); 1182 return gurl.ReplaceComponents(rep);
1177 } 1183 }
1178 1184
1179 } // namespace 1185 } // namespace
1180 1186
1181 ScopedLayoutPreventer::ScopedLayoutPreventer() { 1187 ScopedLayoutPreventer::ScopedLayoutPreventer() {
1182 DCHECK(!g_prevent_layout) << "Is any other instance of ScopedLayoutPreventer " 1188 DCHECK(!g_prevent_layout) << "Is any other instance of ScopedLayoutPreventer "
1183 "alive in the same process?"; 1189 "alive in the same process?";
1184 g_prevent_layout = true; 1190 g_prevent_layout = true;
1185 } 1191 }
1186 1192
1187 ScopedLayoutPreventer::~ScopedLayoutPreventer() { 1193 ScopedLayoutPreventer::~ScopedLayoutPreventer() {
1188 DCHECK(g_prevent_layout) << "Is any other instance of ScopedLayoutPreventer " 1194 DCHECK(g_prevent_layout) << "Is any other instance of ScopedLayoutPreventer "
1189 "alive in the same process?"; 1195 "alive in the same process?";
1190 g_prevent_layout = false; 1196 g_prevent_layout = false;
1191 } 1197 }
1192 1198
1193 bool ExtractFormData(const WebFormElement& form_element, FormData* data) { 1199 bool ExtractFormData(const WebFormElement& form_element, FormData* data) {
1194 return WebFormElementToFormData( 1200 return WebFormElementToFormData(
1195 form_element, WebFormControlElement(), 1201 form_element, WebFormControlElement(), nullptr,
1196 static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE | 1202 static_cast<form_util::ExtractMask>(form_util::EXTRACT_VALUE |
1197 form_util::EXTRACT_OPTION_TEXT | 1203 form_util::EXTRACT_OPTION_TEXT |
1198 form_util::EXTRACT_OPTIONS), 1204 form_util::EXTRACT_OPTIONS),
1199 data, NULL); 1205 data, NULL);
1200 } 1206 }
1201 1207
1202 bool IsFormVisible(blink::WebFrame* frame, 1208 bool IsFormVisible(blink::WebFrame* frame,
1203 const GURL& canonical_action, 1209 const GURL& canonical_action,
1204 const GURL& canonical_origin, 1210 const GURL& canonical_origin,
1205 const FormData& form_data) { 1211 const FormData& form_data) {
(...skipping 21 matching lines...) Expand all
1227 1233
1228 GURL iter_canonical_action = GetCanonicalActionForForm(form); 1234 GURL iter_canonical_action = GetCanonicalActionForForm(form);
1229 #if !defined(OS_ANDROID) 1235 #if !defined(OS_ANDROID)
1230 bool form_action_is_empty = iter_canonical_action.is_empty() || 1236 bool form_action_is_empty = iter_canonical_action.is_empty() ||
1231 iter_canonical_action == frame_origin; 1237 iter_canonical_action == frame_origin;
1232 if (action_is_empty != form_action_is_empty) 1238 if (action_is_empty != form_action_is_empty)
1233 continue; 1239 continue;
1234 1240
1235 if (action_is_empty) { // Both actions are empty, compare all fields. 1241 if (action_is_empty) { // Both actions are empty, compare all fields.
1236 FormData extracted_form_data; 1242 FormData extracted_form_data;
1237 WebFormElementToFormData(form, WebFormControlElement(), EXTRACT_NONE, 1243 WebFormElementToFormData(form, WebFormControlElement(), nullptr,
1238 &extracted_form_data, nullptr); 1244 EXTRACT_NONE, &extracted_form_data, nullptr);
1239 if (form_data.SameFormAs(extracted_form_data)) { 1245 if (form_data.SameFormAs(extracted_form_data)) {
1240 return true; // Form still exists. 1246 return true; // Form still exists.
1241 } 1247 }
1242 } else { // Both actions are non-empty, compare actions only. 1248 } else { // Both actions are non-empty, compare actions only.
1243 if (canonical_action == iter_canonical_action) { 1249 if (canonical_action == iter_canonical_action) {
1244 return true; // Form still exists. 1250 return true; // Form still exists.
1245 } 1251 }
1246 } 1252 }
1247 #else // OS_ANDROID 1253 #else // OS_ANDROID
1248 if (canonical_action == iter_canonical_action) { 1254 if (canonical_action == iter_canonical_action) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 } 1356 }
1351 1357
1352 std::vector<WebFormControlElement> ExtractAutofillableElementsInForm( 1358 std::vector<WebFormControlElement> ExtractAutofillableElementsInForm(
1353 const WebFormElement& form_element) { 1359 const WebFormElement& form_element) {
1354 WebVector<WebFormControlElement> control_elements; 1360 WebVector<WebFormControlElement> control_elements;
1355 form_element.getFormControlElements(control_elements); 1361 form_element.getFormControlElements(control_elements);
1356 1362
1357 return ExtractAutofillableElementsFromSet(control_elements); 1363 return ExtractAutofillableElementsFromSet(control_elements);
1358 } 1364 }
1359 1365
1360 void WebFormControlElementToFormField(const WebFormControlElement& element, 1366 void WebFormControlElementToFormField(
1361 ExtractMask extract_mask, 1367 const WebFormControlElement& element,
1362 FormFieldData* field) { 1368 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
1369 ExtractMask extract_mask,
1370 FormFieldData* field) {
1363 DCHECK(field); 1371 DCHECK(field);
1364 DCHECK(!element.isNull()); 1372 DCHECK(!element.isNull());
1365 CR_DEFINE_STATIC_LOCAL(WebString, kAutocomplete, ("autocomplete")); 1373 CR_DEFINE_STATIC_LOCAL(WebString, kAutocomplete, ("autocomplete"));
1366 CR_DEFINE_STATIC_LOCAL(WebString, kRole, ("role")); 1374 CR_DEFINE_STATIC_LOCAL(WebString, kRole, ("role"));
1367 CR_DEFINE_STATIC_LOCAL(WebString, kPlaceholder, ("placeholder")); 1375 CR_DEFINE_STATIC_LOCAL(WebString, kPlaceholder, ("placeholder"));
1368 CR_DEFINE_STATIC_LOCAL(WebString, kClass, ("class")); 1376 CR_DEFINE_STATIC_LOCAL(WebString, kClass, ("class"));
1369 1377
1370 // The label is not officially part of a WebFormControlElement; however, the 1378 // The label is not officially part of a WebFormControlElement; however, the
1371 // labels for all form control elements are scraped from the DOM and set in 1379 // labels for all form control elements are scraped from the DOM and set in
1372 // WebFormElementToFormData. 1380 // WebFormElementToFormData.
1373 field->name = element.nameForAutofill(); 1381 field->name = element.nameForAutofill();
1374 field->form_control_type = element.formControlType().utf8(); 1382 field->form_control_type = element.formControlType().utf8();
1375 field->autocomplete_attribute = element.getAttribute(kAutocomplete).utf8(); 1383 field->autocomplete_attribute = element.getAttribute(kAutocomplete).utf8();
1376 if (field->autocomplete_attribute.size() > kMaxDataLength) { 1384 if (field->autocomplete_attribute.size() > kMaxDataLength) {
1377 // Discard overly long attribute values to avoid DOS-ing the browser 1385 // Discard overly long attribute values to avoid DOS-ing the browser
1378 // process. However, send over a default string to indicate that the 1386 // process. However, send over a default string to indicate that the
1379 // attribute was present. 1387 // attribute was present.
1380 field->autocomplete_attribute = "x-max-data-length-exceeded"; 1388 field->autocomplete_attribute = "x-max-data-length-exceeded";
1381 } 1389 }
1382 if (base::LowerCaseEqualsASCII( 1390 if (base::LowerCaseEqualsASCII(
1383 base::StringPiece16(element.getAttribute(kRole)), "presentation")) 1391 base::StringPiece16(element.getAttribute(kRole)), "presentation"))
1384 field->role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION; 1392 field->role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
1385 1393
1386 field->placeholder = element.getAttribute(kPlaceholder); 1394 field->placeholder = element.getAttribute(kPlaceholder);
1387 if (element.hasAttribute(kClass)) 1395 if (element.hasAttribute(kClass))
1388 field->css_classes = element.getAttribute(kClass); 1396 field->css_classes = element.getAttribute(kClass);
1389 1397
1398 if (field_value_and_properties_map) {
1399 FieldValueAndPropertiesMaskMap::const_iterator it =
1400 field_value_and_properties_map->find(element);
1401 if (it != field_value_and_properties_map->end())
1402 field->properties_mask = it->second.second;
1403 }
1404
1390 if (!IsAutofillableElement(element)) 1405 if (!IsAutofillableElement(element))
1391 return; 1406 return;
1392 1407
1393 const WebInputElement* input_element = toWebInputElement(&element); 1408 const WebInputElement* input_element = toWebInputElement(&element);
1394 if (IsAutofillableInputElement(input_element) || 1409 if (IsAutofillableInputElement(input_element) ||
1395 IsTextAreaElement(element) || 1410 IsTextAreaElement(element) ||
1396 IsSelectElement(element)) { 1411 IsSelectElement(element)) {
1397 field->is_autofilled = element.isAutofilled(); 1412 field->is_autofilled = element.isAutofilled();
1398 if (!g_prevent_layout) 1413 if (!g_prevent_layout)
1399 field->is_focusable = element.isFocusable(); 1414 field->is_focusable = element.isFocusable();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 // Constrain the maximum data length to prevent a malicious site from DOS'ing 1465 // Constrain the maximum data length to prevent a malicious site from DOS'ing
1451 // the browser: http://crbug.com/49332 1466 // the browser: http://crbug.com/49332
1452 TruncateString(&value, kMaxDataLength); 1467 TruncateString(&value, kMaxDataLength);
1453 1468
1454 field->value = value; 1469 field->value = value;
1455 } 1470 }
1456 1471
1457 bool WebFormElementToFormData( 1472 bool WebFormElementToFormData(
1458 const blink::WebFormElement& form_element, 1473 const blink::WebFormElement& form_element,
1459 const blink::WebFormControlElement& form_control_element, 1474 const blink::WebFormControlElement& form_control_element,
1475 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
1460 ExtractMask extract_mask, 1476 ExtractMask extract_mask,
1461 FormData* form, 1477 FormData* form,
1462 FormFieldData* field) { 1478 FormFieldData* field) {
1463 const WebFrame* frame = form_element.document().frame(); 1479 const WebFrame* frame = form_element.document().frame();
1464 if (!frame) 1480 if (!frame)
1465 return false; 1481 return false;
1466 1482
1467 form->name = GetFormIdentifier(form_element); 1483 form->name = GetFormIdentifier(form_element);
1468 form->origin = GetCanonicalOriginForDocument(frame->document()); 1484 form->origin = GetCanonicalOriginForDocument(frame->document());
1469 form->action = frame->document().completeURL(form_element.action()); 1485 form->action = frame->document().completeURL(form_element.action());
1470 1486
1471 // If the completed URL is not valid, just use the action we get from 1487 // If the completed URL is not valid, just use the action we get from
1472 // WebKit. 1488 // WebKit.
1473 if (!form->action.is_valid()) 1489 if (!form->action.is_valid())
1474 form->action = GURL(blink::WebStringToGURL(form_element.action())); 1490 form->action = GURL(blink::WebStringToGURL(form_element.action()));
1475 1491
1476 WebVector<WebFormControlElement> control_elements; 1492 WebVector<WebFormControlElement> control_elements;
1477 form_element.getFormControlElements(control_elements); 1493 form_element.getFormControlElements(control_elements);
1478 1494
1479 std::vector<blink::WebElement> dummy_fieldset; 1495 std::vector<blink::WebElement> dummy_fieldset;
1480 return FormOrFieldsetsToFormData(&form_element, &form_control_element, 1496 return FormOrFieldsetsToFormData(
1481 dummy_fieldset, control_elements, 1497 &form_element, &form_control_element, dummy_fieldset, control_elements,
1482 extract_mask, form, field); 1498 field_value_and_properties_map, extract_mask, form, field);
1483 } 1499 }
1484 1500
1485 std::vector<WebFormControlElement> GetUnownedFormFieldElements( 1501 std::vector<WebFormControlElement> GetUnownedFormFieldElements(
1486 const WebElementCollection& elements, 1502 const WebElementCollection& elements,
1487 std::vector<WebElement>* fieldsets) { 1503 std::vector<WebElement>* fieldsets) {
1488 std::vector<WebFormControlElement> unowned_fieldset_children; 1504 std::vector<WebFormControlElement> unowned_fieldset_children;
1489 for (WebElement element = elements.firstItem(); 1505 for (WebElement element = elements.firstItem();
1490 !element.isNull(); 1506 !element.isNull();
1491 element = elements.nextItem()) { 1507 element = elements.nextItem()) {
1492 if (element.isFormControlElement()) { 1508 if (element.isFormControlElement()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 1541
1526 // For now this restriction only applies to English-language pages, because 1542 // For now this restriction only applies to English-language pages, because
1527 // the keywords are not translated. Note that an empty "lang" attribute 1543 // the keywords are not translated. Note that an empty "lang" attribute
1528 // counts as English. 1544 // counts as English.
1529 std::string lang; 1545 std::string lang;
1530 if (!html_element.isNull()) 1546 if (!html_element.isNull())
1531 lang = html_element.getAttribute("lang").utf8(); 1547 lang = html_element.getAttribute("lang").utf8();
1532 if (!lang.empty() && 1548 if (!lang.empty() &&
1533 !base::StartsWith(lang, "en", base::CompareCase::INSENSITIVE_ASCII)) { 1549 !base::StartsWith(lang, "en", base::CompareCase::INSENSITIVE_ASCII)) {
1534 return UnownedFormElementsAndFieldSetsToFormData( 1550 return UnownedFormElementsAndFieldSetsToFormData(
1535 fieldsets, control_elements, element, document, extract_mask, form, 1551 fieldsets, control_elements, element, document, nullptr, extract_mask,
1536 field); 1552 form, field);
1537 } 1553 }
1538 1554
1539 // A potential problem is that this only checks document.title(), but should 1555 // A potential problem is that this only checks document.title(), but should
1540 // actually check the main frame's title. Thus it may make bad decisions for 1556 // actually check the main frame's title. Thus it may make bad decisions for
1541 // iframes. 1557 // iframes.
1542 base::string16 title(base::ToLowerASCII(base::string16(document.title()))); 1558 base::string16 title(base::ToLowerASCII(base::string16(document.title())));
1543 1559
1544 // Don't check the path for url's without a standard format path component, 1560 // Don't check the path for url's without a standard format path component,
1545 // such as data:. 1561 // such as data:.
1546 std::string path; 1562 std::string path;
(...skipping 13 matching lines...) Expand all
1560 for (const auto* keyword : kKeywords) { 1576 for (const auto* keyword : kKeywords) {
1561 // Compare char16 elements of |title| with char elements of |keyword| using 1577 // Compare char16 elements of |title| with char elements of |keyword| using
1562 // operator==. 1578 // operator==.
1563 auto title_pos = std::search(title.begin(), title.end(), 1579 auto title_pos = std::search(title.begin(), title.end(),
1564 keyword, keyword + strlen(keyword)); 1580 keyword, keyword + strlen(keyword));
1565 if (title_pos != title.end() || 1581 if (title_pos != title.end() ||
1566 path.find(keyword) != std::string::npos) { 1582 path.find(keyword) != std::string::npos) {
1567 form->is_formless_checkout = true; 1583 form->is_formless_checkout = true;
1568 // Found a keyword: treat this as an unowned form. 1584 // Found a keyword: treat this as an unowned form.
1569 return UnownedFormElementsAndFieldSetsToFormData( 1585 return UnownedFormElementsAndFieldSetsToFormData(
1570 fieldsets, control_elements, element, document, extract_mask, form, 1586 fieldsets, control_elements, element, document, nullptr, extract_mask,
1571 field); 1587 form, field);
1572 } 1588 }
1573 } 1589 }
1574 1590
1575 // Since it's not a checkout flow, only add fields that have a non-"off" 1591 // Since it's not a checkout flow, only add fields that have a non-"off"
1576 // autocomplete attribute to the formless autofill. 1592 // autocomplete attribute to the formless autofill.
1577 CR_DEFINE_STATIC_LOCAL(WebString, kOffAttribute, ("off")); 1593 CR_DEFINE_STATIC_LOCAL(WebString, kOffAttribute, ("off"));
1578 std::vector<WebFormControlElement> elements_with_autocomplete; 1594 std::vector<WebFormControlElement> elements_with_autocomplete;
1579 for (const WebFormControlElement& element : control_elements) { 1595 for (const WebFormControlElement& element : control_elements) {
1580 blink::WebString autocomplete = element.getAttribute("autocomplete"); 1596 blink::WebString autocomplete = element.getAttribute("autocomplete");
1581 if (autocomplete.length() && autocomplete != kOffAttribute) 1597 if (autocomplete.length() && autocomplete != kOffAttribute)
1582 elements_with_autocomplete.push_back(element); 1598 elements_with_autocomplete.push_back(element);
1583 } 1599 }
1584 1600
1585 if (elements_with_autocomplete.empty()) 1601 if (elements_with_autocomplete.empty())
1586 return false; 1602 return false;
1587 1603
1588 return UnownedFormElementsAndFieldSetsToFormData( 1604 return UnownedFormElementsAndFieldSetsToFormData(
1589 fieldsets, elements_with_autocomplete, element, document, extract_mask, 1605 fieldsets, elements_with_autocomplete, element, document, nullptr,
1590 form, field); 1606 extract_mask, form, field);
1591 } 1607 }
1592 1608
1593 bool UnownedPasswordFormElementsAndFieldSetsToFormData( 1609 bool UnownedPasswordFormElementsAndFieldSetsToFormData(
1594 const std::vector<blink::WebElement>& fieldsets, 1610 const std::vector<blink::WebElement>& fieldsets,
1595 const std::vector<blink::WebFormControlElement>& control_elements, 1611 const std::vector<blink::WebFormControlElement>& control_elements,
1596 const blink::WebFormControlElement* element, 1612 const blink::WebFormControlElement* element,
1597 const blink::WebDocument& document, 1613 const blink::WebDocument& document,
1614 const FieldValueAndPropertiesMaskMap* field_value_and_properties_map,
1598 ExtractMask extract_mask, 1615 ExtractMask extract_mask,
1599 FormData* form, 1616 FormData* form,
1600 FormFieldData* field) { 1617 FormFieldData* field) {
1601 return UnownedFormElementsAndFieldSetsToFormData( 1618 return UnownedFormElementsAndFieldSetsToFormData(
1602 fieldsets, control_elements, element, document, extract_mask, form, 1619 fieldsets, control_elements, element, document,
1603 field); 1620 field_value_and_properties_map, extract_mask, form, field);
1604 } 1621 }
1605 1622
1606 1623
1607 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, 1624 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element,
1608 FormData* form, 1625 FormData* form,
1609 FormFieldData* field) { 1626 FormFieldData* field) {
1610 if (!IsAutofillableElement(element)) 1627 if (!IsAutofillableElement(element))
1611 return false; 1628 return false;
1612 1629
1613 ExtractMask extract_mask = 1630 ExtractMask extract_mask =
1614 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); 1631 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
1615 const WebFormElement form_element = element.form(); 1632 const WebFormElement form_element = element.form();
1616 if (form_element.isNull()) { 1633 if (form_element.isNull()) {
1617 // No associated form, try the synthetic form for unowned form elements. 1634 // No associated form, try the synthetic form for unowned form elements.
1618 WebDocument document = element.document(); 1635 WebDocument document = element.document();
1619 std::vector<WebElement> fieldsets; 1636 std::vector<WebElement> fieldsets;
1620 std::vector<WebFormControlElement> control_elements = 1637 std::vector<WebFormControlElement> control_elements =
1621 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); 1638 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets);
1622 return UnownedCheckoutFormElementsAndFieldSetsToFormData( 1639 return UnownedCheckoutFormElementsAndFieldSetsToFormData(
1623 fieldsets, control_elements, &element, document, extract_mask, 1640 fieldsets, control_elements, &element, document, extract_mask,
1624 form, field); 1641 form, field);
1625 } 1642 }
1626 1643
1627 return WebFormElementToFormData(form_element, 1644 return WebFormElementToFormData(form_element, element, nullptr, extract_mask,
1628 element, 1645 form, field);
1629 extract_mask,
1630 form,
1631 field);
1632 } 1646 }
1633 1647
1634 void FillForm(const FormData& form, const WebFormControlElement& element) { 1648 void FillForm(const FormData& form, const WebFormControlElement& element) {
1635 WebFormElement form_element = element.form(); 1649 WebFormElement form_element = element.form();
1636 if (form_element.isNull()) { 1650 if (form_element.isNull()) {
1637 ForEachMatchingUnownedFormField(element, 1651 ForEachMatchingUnownedFormField(element,
1638 form, 1652 form,
1639 FILTER_ALL_NON_EDITABLE_ELEMENTS, 1653 FILTER_ALL_NON_EDITABLE_ELEMENTS,
1640 false, /* dont force override */ 1654 false, /* dont force override */
1641 &FillFormField); 1655 &FillFormField);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 // Zero selection start is for password manager, which can show usernames 1809 // Zero selection start is for password manager, which can show usernames
1796 // that do not begin with the user input value. 1810 // that do not begin with the user input value.
1797 selection_start = (offset == base::string16::npos) ? 0 : offset; 1811 selection_start = (offset == base::string16::npos) ? 0 : offset;
1798 } 1812 }
1799 1813
1800 input_element->setSelectionRange(selection_start, suggestion.length()); 1814 input_element->setSelectionRange(selection_start, suggestion.length());
1801 } 1815 }
1802 1816
1803 } // namespace form_util 1817 } // namespace form_util
1804 } // namespace autofill 1818 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698