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/core/common/form_field_data.h" | 5 #include "components/autofill/core/common/form_field_data.h" |
| 6 | 6 |
| 7 #include "base/pickle.h" | 7 #include "base/pickle.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 | 10 |
| 11 namespace autofill { | 11 namespace autofill { |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // Increment this anytime pickle format is modified as well as provide | 15 // Increment this anytime pickle format is modified as well as provide |
| 16 // deserialization routine from previous kPickleVersion format. | 16 // deserialization routine from previous kPickleVersion format. |
| 17 const int kPickleVersion = 3; | 17 const int kPickleVersion = 4; |
| 18 | 18 |
| 19 void AddVectorToPickle(std::vector<base::string16> strings, | 19 void AddVectorToPickle(std::vector<base::string16> strings, |
| 20 base::Pickle* pickle) { | 20 base::Pickle* pickle) { |
| 21 pickle->WriteInt(static_cast<int>(strings.size())); | 21 pickle->WriteInt(static_cast<int>(strings.size())); |
| 22 for (size_t i = 0; i < strings.size(); ++i) { | 22 for (size_t i = 0; i < strings.size(); ++i) { |
| 23 pickle->WriteString16(strings[i]); | 23 pickle->WriteString16(strings[i]); |
| 24 } | 24 } |
| 25 } | 25 } |
| 26 | 26 |
| 27 bool ReadStringVector(base::PickleIterator* iter, | 27 bool ReadStringVector(base::PickleIterator* iter, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 43 template <typename T> | 43 template <typename T> |
| 44 bool ReadAsInt(base::PickleIterator* iter, T* target_value) { | 44 bool ReadAsInt(base::PickleIterator* iter, T* target_value) { |
| 45 int pickle_data; | 45 int pickle_data; |
| 46 if (!iter->ReadInt(&pickle_data)) | 46 if (!iter->ReadInt(&pickle_data)) |
| 47 return false; | 47 return false; |
| 48 | 48 |
| 49 *target_value = static_cast<T>(pickle_data); | 49 *target_value = static_cast<T>(pickle_data); |
| 50 return true; | 50 return true; |
| 51 } | 51 } |
| 52 | 52 |
| 53 bool DeserializeCommonSection1(base::PickleIterator* iter, | 53 bool DeserializeCommonSection1(base::PickleIterator* iter, |
|
vabr (Chromium)
2016/06/06 12:39:30
This is not a fault of your CL, but I'm afraid the
| |
| 54 FormFieldData* field_data) { | 54 FormFieldData* field_data) { |
| 55 return iter->ReadString16(&field_data->label) && | 55 bool ret = true; |
|
vabr (Chromium)
2016/06/06 12:39:30
nit: Please avoid abbreviations [1]. My suggestion
| |
| 56 iter->ReadString16(&field_data->name) && | 56 bool is_checkable = false; |
| 57 iter->ReadString16(&field_data->value) && | 57 bool is_checked = false; |
| 58 iter->ReadString(&field_data->form_control_type) && | 58 ret = ret && iter->ReadString16(&field_data->label); |
|
vabr (Chromium)
2016/06/06 12:39:30
nit: Repeating |ret| clutters the code. Please ini
| |
| 59 iter->ReadString(&field_data->autocomplete_attribute) && | 59 ret = ret && iter->ReadString16(&field_data->name); |
| 60 iter->ReadUInt64(&field_data->max_length) && | 60 ret = ret && iter->ReadString16(&field_data->value); |
| 61 iter->ReadBool(&field_data->is_autofilled) && | 61 ret = ret && iter->ReadString(&field_data->form_control_type); |
| 62 iter->ReadBool(&field_data->is_checked) && | 62 ret = ret && iter->ReadString(&field_data->autocomplete_attribute); |
| 63 iter->ReadBool(&field_data->is_checkable) && | 63 ret = ret && iter->ReadUInt64(&field_data->max_length); |
| 64 iter->ReadBool(&field_data->is_focusable) && | 64 ret = ret && iter->ReadBool(&field_data->is_autofilled); |
| 65 iter->ReadBool(&field_data->should_autocomplete); | 65 ret = ret && iter->ReadBool(&is_checked); |
| 66 ret = ret && iter->ReadBool(&is_checkable); | |
| 67 SetCheckStatus(field_data, is_checkable, is_checked); | |
| 68 ret = ret && iter->ReadBool(&field_data->is_focusable); | |
| 69 ret = ret && iter->ReadBool(&field_data->should_autocomplete); | |
| 70 return ret; | |
| 66 } | 71 } |
| 67 | 72 |
| 68 bool DeserializeCommonSection2(base::PickleIterator* iter, | 73 bool DeserializeCommonSection2(base::PickleIterator* iter, |
| 69 FormFieldData* field_data) { | 74 FormFieldData* field_data) { |
| 70 return ReadAsInt(iter, &field_data->text_direction) && | 75 return ReadAsInt(iter, &field_data->text_direction) && |
| 71 ReadStringVector(iter, &field_data->option_values) && | 76 ReadStringVector(iter, &field_data->option_values) && |
| 72 ReadStringVector(iter, &field_data->option_contents); | 77 ReadStringVector(iter, &field_data->option_contents); |
| 73 } | 78 } |
| 74 | 79 |
| 75 bool DeserializeVersion2Specific(base::PickleIterator* iter, | 80 bool DeserializeVersion2Specific(base::PickleIterator* iter, |
| 76 FormFieldData* field_data) { | 81 FormFieldData* field_data) { |
| 77 return ReadAsInt(iter, &field_data->role); | 82 return ReadAsInt(iter, &field_data->role); |
| 78 } | 83 } |
| 79 | 84 |
| 80 bool DeserializeVersion3Specific(base::PickleIterator* iter, | 85 bool DeserializeVersion3Specific(base::PickleIterator* iter, |
| 81 FormFieldData* field_data) { | 86 FormFieldData* field_data) { |
| 82 return iter->ReadString16(&field_data->placeholder); | 87 return iter->ReadString16(&field_data->placeholder); |
| 83 } | 88 } |
| 84 | 89 |
| 90 bool DeserializeCommonSection1Version4Specific(base::PickleIterator* iter, | |
| 91 FormFieldData* field_data) { | |
| 92 return iter->ReadString16(&field_data->label) && | |
| 93 iter->ReadString16(&field_data->name) && | |
| 94 iter->ReadString16(&field_data->value) && | |
| 95 iter->ReadString(&field_data->form_control_type) && | |
| 96 iter->ReadString(&field_data->autocomplete_attribute) && | |
| 97 iter->ReadUInt64(&field_data->max_length) && | |
| 98 iter->ReadBool(&field_data->is_autofilled) && | |
| 99 ReadAsInt(iter, &field_data->check_status) && | |
| 100 iter->ReadBool(&field_data->is_focusable) && | |
| 101 iter->ReadBool(&field_data->should_autocomplete); | |
| 102 } | |
| 103 | |
| 85 } // namespace | 104 } // namespace |
| 86 | 105 |
| 87 FormFieldData::FormFieldData() | 106 FormFieldData::FormFieldData() |
| 88 : max_length(0), | 107 : max_length(0), |
| 89 is_autofilled(false), | 108 is_autofilled(false), |
| 90 is_checked(false), | 109 check_status(CheckStatus::NOT_CHECKABLE), |
|
vabr (Chromium)
2016/06/06 12:39:30
No need for CheckStatus:: because you are not usin
| |
| 91 is_checkable(false), | |
| 92 is_focusable(false), | 110 is_focusable(false), |
| 93 should_autocomplete(true), | 111 should_autocomplete(true), |
| 94 role(ROLE_ATTRIBUTE_OTHER), | 112 role(ROLE_ATTRIBUTE_OTHER), |
| 95 text_direction(base::i18n::UNKNOWN_DIRECTION) { | 113 text_direction(base::i18n::UNKNOWN_DIRECTION) { |
| 96 } | 114 } |
| 97 | 115 |
| 98 FormFieldData::FormFieldData(const FormFieldData& other) = default; | 116 FormFieldData::FormFieldData(const FormFieldData& other) = default; |
| 99 | 117 |
| 100 FormFieldData::~FormFieldData() { | 118 FormFieldData::~FormFieldData() { |
| 101 } | 119 } |
| 102 | 120 |
| 103 bool FormFieldData::SameFieldAs(const FormFieldData& field) const { | 121 bool FormFieldData::SameFieldAs(const FormFieldData& field) const { |
| 104 // A FormFieldData stores a value, but the value is not part of the identity | 122 // A FormFieldData stores a value, but the value is not part of the identity |
| 105 // of the field, so we don't want to compare the values. | 123 // of the field, so we don't want to compare the values. |
| 106 return label == field.label && name == field.name && | 124 return label == field.label && name == field.name && |
| 107 form_control_type == field.form_control_type && | 125 form_control_type == field.form_control_type && |
| 108 autocomplete_attribute == field.autocomplete_attribute && | 126 autocomplete_attribute == field.autocomplete_attribute && |
| 109 placeholder == field.placeholder && max_length == field.max_length && | 127 placeholder == field.placeholder && max_length == field.max_length && |
| 110 // is_checked and is_autofilled counts as "value" since these change | 128 // is_checked and is_autofilled counts as "value" since these change |
| 111 // when we fill things in. | 129 // when we fill things in. |
| 112 is_checkable == field.is_checkable && | 130 IsCheckable(check_status) == IsCheckable(field.check_status) && |
| 113 is_focusable == field.is_focusable && | 131 is_focusable == field.is_focusable && |
| 114 should_autocomplete == field.should_autocomplete && | 132 should_autocomplete == field.should_autocomplete && |
| 115 role == field.role && text_direction == field.text_direction; | 133 role == field.role && text_direction == field.text_direction; |
| 116 // The option values/contents which are the list of items in the list | 134 // The option values/contents which are the list of items in the list |
| 117 // of a drop-down are currently not considered part of the identity of | 135 // of a drop-down are currently not considered part of the identity of |
| 118 // a form element. This is debatable, since one might base heuristics | 136 // a form element. This is debatable, since one might base heuristics |
| 119 // on the types of elements that are available. Alternatively, one | 137 // on the types of elements that are available. Alternatively, one |
| 120 // could imagine some forms that dynamically change the element | 138 // could imagine some forms that dynamically change the element |
| 121 // contents (say, insert years starting from the current year) that | 139 // contents (say, insert years starting from the current year) that |
| 122 // should not be considered changes in the structure of the form. | 140 // should not be considered changes in the structure of the form. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 135 if (name > field.name) return false; | 153 if (name > field.name) return false; |
| 136 if (form_control_type < field.form_control_type) return true; | 154 if (form_control_type < field.form_control_type) return true; |
| 137 if (form_control_type > field.form_control_type) return false; | 155 if (form_control_type > field.form_control_type) return false; |
| 138 if (autocomplete_attribute < field.autocomplete_attribute) return true; | 156 if (autocomplete_attribute < field.autocomplete_attribute) return true; |
| 139 if (autocomplete_attribute > field.autocomplete_attribute) return false; | 157 if (autocomplete_attribute > field.autocomplete_attribute) return false; |
| 140 if (placeholder < field.placeholder) return true; | 158 if (placeholder < field.placeholder) return true; |
| 141 if (placeholder > field.placeholder) return false; | 159 if (placeholder > field.placeholder) return false; |
| 142 if (max_length < field.max_length) return true; | 160 if (max_length < field.max_length) return true; |
| 143 if (max_length > field.max_length) return false; | 161 if (max_length > field.max_length) return false; |
| 144 // Skip |is_checked| and |is_autofilled| as in SameFieldAs. | 162 // Skip |is_checked| and |is_autofilled| as in SameFieldAs. |
| 145 if (is_checkable < field.is_checkable) return true; | 163 if (IsCheckable(check_status) < IsCheckable(field.check_status)) return true; |
| 146 if (is_checkable > field.is_checkable) return false; | 164 if (IsCheckable(check_status) > IsCheckable(field.check_status)) return false; |
| 147 if (is_focusable < field.is_focusable) return true; | 165 if (is_focusable < field.is_focusable) return true; |
| 148 if (is_focusable > field.is_focusable) return false; | 166 if (is_focusable > field.is_focusable) return false; |
| 149 if (should_autocomplete < field.should_autocomplete) return true; | 167 if (should_autocomplete < field.should_autocomplete) return true; |
| 150 if (should_autocomplete > field.should_autocomplete) return false; | 168 if (should_autocomplete > field.should_autocomplete) return false; |
| 151 if (role < field.role) return true; | 169 if (role < field.role) return true; |
| 152 if (role > field.role) return false; | 170 if (role > field.role) return false; |
| 153 if (text_direction < field.text_direction) return true; | 171 if (text_direction < field.text_direction) return true; |
| 154 if (text_direction > field.text_direction) return false; | 172 if (text_direction > field.text_direction) return false; |
| 155 // See operator== above for why we don't check option_values/contents. | 173 // See operator== above for why we don't check option_values/contents. |
| 156 return false; | 174 return false; |
| 157 } | 175 } |
| 158 | 176 |
| 159 void SerializeFormFieldData(const FormFieldData& field_data, | 177 void SerializeFormFieldData(const FormFieldData& field_data, |
| 160 base::Pickle* pickle) { | 178 base::Pickle* pickle) { |
| 161 pickle->WriteInt(kPickleVersion); | 179 pickle->WriteInt(kPickleVersion); |
| 162 pickle->WriteString16(field_data.label); | 180 pickle->WriteString16(field_data.label); |
| 163 pickle->WriteString16(field_data.name); | 181 pickle->WriteString16(field_data.name); |
| 164 pickle->WriteString16(field_data.value); | 182 pickle->WriteString16(field_data.value); |
| 165 pickle->WriteString(field_data.form_control_type); | 183 pickle->WriteString(field_data.form_control_type); |
| 166 pickle->WriteString(field_data.autocomplete_attribute); | 184 pickle->WriteString(field_data.autocomplete_attribute); |
| 167 pickle->WriteUInt64(field_data.max_length); | 185 pickle->WriteUInt64(field_data.max_length); |
| 168 pickle->WriteBool(field_data.is_autofilled); | 186 pickle->WriteBool(field_data.is_autofilled); |
| 169 pickle->WriteBool(field_data.is_checked); | 187 pickle->WriteInt(field_data.check_status); |
| 170 pickle->WriteBool(field_data.is_checkable); | |
| 171 pickle->WriteBool(field_data.is_focusable); | 188 pickle->WriteBool(field_data.is_focusable); |
| 172 pickle->WriteBool(field_data.should_autocomplete); | 189 pickle->WriteBool(field_data.should_autocomplete); |
| 173 pickle->WriteInt(field_data.role); | 190 pickle->WriteInt(field_data.role); |
| 174 pickle->WriteInt(field_data.text_direction); | 191 pickle->WriteInt(field_data.text_direction); |
| 175 AddVectorToPickle(field_data.option_values, pickle); | 192 AddVectorToPickle(field_data.option_values, pickle); |
| 176 AddVectorToPickle(field_data.option_contents, pickle); | 193 AddVectorToPickle(field_data.option_contents, pickle); |
| 177 pickle->WriteString16(field_data.placeholder); | 194 pickle->WriteString16(field_data.placeholder); |
| 178 } | 195 } |
| 179 | 196 |
| 180 bool DeserializeFormFieldData(base::PickleIterator* iter, | 197 bool DeserializeFormFieldData(base::PickleIterator* iter, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 207 case 3: { | 224 case 3: { |
| 208 if (!DeserializeCommonSection1(iter, &temp_form_field_data) || | 225 if (!DeserializeCommonSection1(iter, &temp_form_field_data) || |
| 209 !DeserializeVersion2Specific(iter, &temp_form_field_data) || | 226 !DeserializeVersion2Specific(iter, &temp_form_field_data) || |
| 210 !DeserializeCommonSection2(iter, &temp_form_field_data) || | 227 !DeserializeCommonSection2(iter, &temp_form_field_data) || |
| 211 !DeserializeVersion3Specific(iter, &temp_form_field_data)) { | 228 !DeserializeVersion3Specific(iter, &temp_form_field_data)) { |
| 212 LOG(ERROR) << "Could not deserialize FormFieldData from pickle"; | 229 LOG(ERROR) << "Could not deserialize FormFieldData from pickle"; |
| 213 return false; | 230 return false; |
| 214 } | 231 } |
| 215 break; | 232 break; |
| 216 } | 233 } |
| 234 case 4: { | |
| 235 if (!DeserializeCommonSection1Version4Specific(iter, | |
| 236 &temp_form_field_data) || | |
| 237 !DeserializeVersion2Specific(iter, &temp_form_field_data) || | |
| 238 !DeserializeCommonSection2(iter, &temp_form_field_data) || | |
| 239 !DeserializeVersion3Specific(iter, &temp_form_field_data)) { | |
| 240 LOG(ERROR) << "Could not deserialize FormFieldData from pickle"; | |
| 241 return false; | |
| 242 } | |
| 243 break; | |
| 244 } | |
| 217 default: { | 245 default: { |
| 218 LOG(ERROR) << "Unknown FormFieldData pickle version " << version; | 246 LOG(ERROR) << "Unknown FormFieldData pickle version " << version; |
| 219 return false; | 247 return false; |
| 220 } | 248 } |
| 221 } | 249 } |
| 222 *field_data = temp_form_field_data; | 250 *field_data = temp_form_field_data; |
| 223 return true; | 251 return true; |
| 224 } | 252 } |
| 225 | 253 |
| 226 std::ostream& operator<<(std::ostream& os, const FormFieldData& field) { | 254 std::ostream& operator<<(std::ostream& os, const FormFieldData& field) { |
| 255 std::string checkStatusStr; | |
|
vabr (Chromium)
2016/06/06 12:39:30
nit: Please use all-lower-case and underscores for
| |
| 256 switch (field.check_status) { | |
| 257 case FormFieldData::CheckStatus::NOT_CHECKABLE: | |
| 258 checkStatusStr = "NOT_CHECKABLE"; | |
| 259 break; | |
| 260 case FormFieldData::CheckStatus::CHECKABLE_BUT_UNCHECKED: | |
| 261 checkStatusStr = "CHECKABLE_BUT_UNCHECKED"; | |
| 262 break; | |
| 263 case FormFieldData::CheckStatus::CHECKED: | |
| 264 checkStatusStr = "CHECKED"; | |
| 265 break; | |
| 266 } | |
| 267 | |
| 268 std::string roleStr; | |
| 269 switch (field.role) { | |
| 270 case FormFieldData::RoleAttribute::ROLE_ATTRIBUTE_PRESENTATION: | |
| 271 roleStr = "ROLE_ATTRIBUTE_PRESENTATION"; | |
| 272 break; | |
| 273 case FormFieldData::RoleAttribute::ROLE_ATTRIBUTE_OTHER: | |
| 274 roleStr = "ROLE_ATTRIBUTE_OTHER"; | |
| 275 break; | |
| 276 } | |
| 277 | |
| 227 return os << base::UTF16ToUTF8(field.label) << " " | 278 return os << base::UTF16ToUTF8(field.label) << " " |
| 228 << base::UTF16ToUTF8(field.name) << " " | 279 << base::UTF16ToUTF8(field.name) << " " |
| 229 << base::UTF16ToUTF8(field.value) << " " << field.form_control_type | 280 << base::UTF16ToUTF8(field.value) << " " << field.form_control_type |
| 230 << " " << field.autocomplete_attribute << " " << field.placeholder | 281 << " " << field.autocomplete_attribute << " " << field.placeholder |
| 231 << " " << field.max_length << " " | 282 << " " << field.max_length << " " |
| 232 << (field.is_autofilled ? "true" : "false") << " " | 283 << (field.is_autofilled ? "true" : "false") << " " |
| 233 << (field.is_checked ? "true" : "false") << " " | 284 << checkStatusStr |
| 234 << (field.is_checkable ? "true" : "false") << " " | |
| 235 << (field.is_focusable ? "true" : "false") << " " | 285 << (field.is_focusable ? "true" : "false") << " " |
| 236 << (field.should_autocomplete ? "true" : "false") << " " | 286 << (field.should_autocomplete ? "true" : "false") << " " |
| 237 << field.role << " " << field.text_direction; | 287 << roleStr << " " << field.text_direction; |
| 288 } | |
| 289 | |
| 290 bool IsCheckable(const FormFieldData::CheckStatus& check_status){ | |
| 291 return check_status == FormFieldData::CheckStatus::NOT_CHECKABLE | |
|
vabr (Chromium)
2016/06/06 12:39:30
No need for the ternary operator:
X == Y ? false :
| |
| 292 ? false : true; | |
| 293 } | |
| 294 | |
| 295 bool IsChecked(const FormFieldData::CheckStatus& check_status){ | |
| 296 return check_status == FormFieldData::CheckStatus::CHECKED ? false : true; | |
|
vabr (Chromium)
2016/06/06 12:39:30
This returns the opposite of what it should return
| |
| 297 } | |
| 298 | |
| 299 void SetCheckStatus(FormFieldData* form_field_data, bool isCheckable, | |
| 300 bool isChecked){ | |
| 301 if(isChecked == true){ | |
|
vabr (Chromium)
2016/06/06 12:39:30
nit: Formatting is off, please make sure to run gi
vabr (Chromium)
2016/06/06 12:39:30
Drop " == true" (also below).
| |
| 302 form_field_data->check_status = FormFieldData::CheckStatus::CHECKED; | |
| 303 }else{ | |
| 304 if(isCheckable == true){ | |
| 305 form_field_data->check_status = | |
| 306 FormFieldData::CheckStatus::CHECKABLE_BUT_UNCHECKED; | |
| 307 }else{ | |
| 308 form_field_data->check_status = FormFieldData::CheckStatus::NOT_CHECKABLE; | |
| 309 } | |
| 310 } | |
| 238 } | 311 } |
| 239 | 312 |
| 240 } // namespace autofill | 313 } // namespace autofill |
| OLD | NEW |