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

Side by Side Diff: chrome/browser/autofill/name_field.cc

Issue 7043027: Autofill refactor form_field.h/cc. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/autofill/name_field.h" 5 #include "chrome/browser/autofill/name_field.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/autofill/autofill_ecml.h"
11 #include "chrome/browser/autofill/autofill_scanner.h" 12 #include "chrome/browser/autofill/autofill_scanner.h"
12 #include "chrome/browser/autofill/autofill_type.h" 13 #include "chrome/browser/autofill/autofill_type.h"
13 #include "grit/autofill_resources.h" 14 #include "grit/autofill_resources.h"
14 #include "ui/base/l10n/l10n_util.h" 15 #include "ui/base/l10n/l10n_util.h"
15 16
17 using autofill::GetEcmlPattern;
18
16 NameField* NameField::Parse(AutofillScanner* scanner, bool is_ecml) { 19 NameField* NameField::Parse(AutofillScanner* scanner, bool is_ecml) {
17 if (scanner->IsEnd()) 20 if (scanner->IsEnd())
18 return NULL; 21 return NULL;
19 22
20 // Try FirstLastNameField first since it's more specific. 23 // Try FirstLastNameField first since it's more specific.
21 NameField* field = FirstLastNameField::Parse(scanner, is_ecml); 24 NameField* field = FirstLastNameField::Parse(scanner, is_ecml);
22 if (!field && !is_ecml) 25 if (!field && !is_ecml)
23 field = FullNameField::Parse(scanner); 26 field = FullNameField::Parse(scanner);
24 return field; 27 return field;
25 } 28 }
26 29
27 bool FullNameField::GetFieldInfo(FieldTypeMap* field_type_map) const { 30 bool FullNameField::ClassifyField(FieldTypeMap* map) const {
28 return Add(field_type_map, field_, NAME_FULL); 31 return AddClassification(field_, NAME_FULL, map);
29 } 32 }
Ilya Sherman 2011/05/19 05:44:16 nit: Please move this to be below Parse()
dhollowa 2011/05/19 17:53:08 Done.
30 33
31 FullNameField* FullNameField::Parse(AutofillScanner* scanner) { 34 FullNameField* FullNameField::Parse(AutofillScanner* scanner) {
32 // Exclude labels containing the string "username", which typically 35 // Exclude labels containing the string "username", which typically
33 // denotes a login ID rather than the user's actual name. 36 // denotes a login ID rather than the user's actual name.
34 const AutofillField* field = scanner->Cursor(); 37 scanner->SaveCursor();
35 if (Match(field, l10n_util::GetStringUTF16(IDS_AUTOFILL_USERNAME_RE), false)) 38 bool username = ParseField(
Ilya Sherman 2011/05/19 05:44:16 nit: Perhaps "is_username"?
dhollowa 2011/05/19 17:53:08 Done.
39 scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_USERNAME_RE), NULL);
40 scanner->Rewind();
41 if (username)
36 return NULL; 42 return NULL;
37 43
38 // Searching for any label containing the word "name" is too general; 44 // Searching for any label containing the word "name" is too general;
39 // for example, Travelocity_Edit travel profile.html contains a field 45 // for example, Travelocity_Edit travel profile.html contains a field
40 // "Travel Profile Name". 46 // "Travel Profile Name".
41 if (ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_RE), 47 const AutofillField* field = NULL;
48 if (ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_RE),
42 &field)) 49 &field))
Ilya Sherman 2011/05/19 05:44:16 nit: indentation
dhollowa 2011/05/19 17:53:08 Done.
43 return new FullNameField(field); 50 return new FullNameField(field);
44 51
45 return NULL; 52 return NULL;
46 } 53 }
47 54
48 FullNameField::FullNameField(const AutofillField* field) 55 FullNameField::FullNameField(const AutofillField* field)
49 : field_(field) { 56 : field_(field) {
50 } 57 }
51 58
52 bool FirstLastNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
53 bool ok = Add(field_type_map, first_name_, NAME_FIRST);
54 ok = ok && Add(field_type_map, last_name_, NAME_LAST);
55 AutofillFieldType type = middle_initial_ ? NAME_MIDDLE_INITIAL : NAME_MIDDLE;
56 ok = ok && Add(field_type_map, middle_name_, type);
57 return ok;
58 }
59
60 FirstLastNameField* FirstLastNameField::ParseSpecificName( 59 FirstLastNameField* FirstLastNameField::ParseSpecificName(
61 AutofillScanner* scanner) { 60 AutofillScanner* scanner) {
62 // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html) 61 // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html)
63 // have the label "Name" followed by two or three text fields. 62 // have the label "Name" followed by two or three text fields.
64 scoped_ptr<FirstLastNameField> v(new FirstLastNameField); 63 scoped_ptr<FirstLastNameField> v(new FirstLastNameField);
65 scanner->SaveCursor(); 64 scanner->SaveCursor();
66 65
67 const AutofillField* next; 66 const AutofillField* next;
68 if (ParseText(scanner, 67 if (ParseField(scanner,
69 l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_SPECIFIC_RE), 68 l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_SPECIFIC_RE),
70 &v->first_name_) && 69 &v->first_name_) &&
Ilya Sherman 2011/05/19 05:44:16 nit: indentation
dhollowa 2011/05/19 17:53:08 Done.
71 ParseEmptyText(scanner, &next)) { 70 ParseEmptyLabel(scanner, &next)) {
72 if (ParseEmptyText(scanner, &v->last_name_)) { 71 if (ParseEmptyLabel(scanner, &v->last_name_)) {
73 // There are three name fields; assume that the middle one is a 72 // There are three name fields; assume that the middle one is a
74 // middle initial (it is, at least, on SmithsonianCheckout.html). 73 // middle initial (it is, at least, on SmithsonianCheckout.html).
75 v->middle_name_ = next; 74 v->middle_name_ = next;
76 v->middle_initial_ = true; 75 v->middle_initial_ = true;
77 } else { // only two name fields 76 } else { // only two name fields
78 v->last_name_ = next; 77 v->last_name_ = next;
79 } 78 }
80 79
81 return v.release(); 80 return v.release();
82 } 81 }
83 82
84 scanner->Rewind(); 83 scanner->Rewind();
85 return NULL; 84 return NULL;
86 } 85 }
87 86
88 FirstLastNameField* FirstLastNameField::ParseComponentNames( 87 FirstLastNameField* FirstLastNameField::ParseComponentNames(
89 AutofillScanner* scanner) { 88 AutofillScanner* scanner) {
90 scoped_ptr<FirstLastNameField> v(new FirstLastNameField); 89 scoped_ptr<FirstLastNameField> v(new FirstLastNameField);
91 scanner->SaveCursor(); 90 scanner->SaveCursor();
92 91
93 // A fair number of pages use the names "fname" and "lname" for naming 92 // A fair number of pages use the names "fname" and "lname" for naming
94 // first and last name fields (examples from the test suite: 93 // first and last name fields (examples from the test suite:
95 // BESTBUY_COM - Sign In2.html; Crate and Barrel Check Out.html; 94 // BESTBUY_COM - Sign In2.html; Crate and Barrel Check Out.html;
96 // dell_checkout1.html). At least one UK page (The China Shop2.html) 95 // dell_checkout1.html). At least one UK page (The China Shop2.html)
97 // asks, in stuffy English style, for just initials and a surname, 96 // asks, in stuffy English style, for just initials and a surname,
98 // so we match "initials" here (and just fill in a first name there, 97 // so we match "initials" here (and just fill in a first name there,
99 // American-style). 98 // American-style).
100 // The ".*first$" matches fields ending in "first" (example in sample8.html). 99 // The ".*first$" matches fields ending in "first" (example in sample8.html).
101 if (!ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_FIRST_NAME_RE), 100 if (!ParseField(scanner,
102 &v->first_name_)) 101 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIRST_NAME_RE),
102 &v->first_name_)) {
103 return NULL; 103 return NULL;
104 }
104 105
105 // We check for a middle initial before checking for a middle name 106 // We check for a middle initial before checking for a middle name
106 // because at least one page (PC Connection.html) has a field marked 107 // because at least one page (PC Connection.html) has a field marked
107 // as both (the label text is "MI" and the element name is 108 // as both (the label text is "MI" and the element name is
108 // "txtmiddlename"); such a field probably actually represents a 109 // "txtmiddlename"); such a field probably actually represents a
109 // middle initial. 110 // middle initial.
110 if (ParseText(scanner, 111 if (ParseField(scanner,
111 l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_INITIAL_RE), 112 l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_INITIAL_RE),
112 &v->middle_name_)) { 113 &v->middle_name_)) {
113 v->middle_initial_ = true; 114 v->middle_initial_ = true;
114 } else { 115 } else {
115 ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_NAME_RE), 116 ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_NAME_RE),
116 &v->middle_name_); 117 &v->middle_name_);
117 } 118 }
118 119
119 // The ".*last$" matches fields ending in "last" (example in sample8.html). 120 // The ".*last$" matches fields ending in "last" (example in sample8.html).
120 if (ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_LAST_NAME_RE), 121 if (ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_LAST_NAME_RE),
121 &v->last_name_)) { 122 &v->last_name_)) {
122 return v.release(); 123 return v.release();
123 } 124 }
124 125
125 scanner->Rewind(); 126 scanner->Rewind();
126 return NULL; 127 return NULL;
127 } 128 }
128 129
129 FirstLastNameField* FirstLastNameField::ParseEcmlName( 130 FirstLastNameField* FirstLastNameField::ParseEcmlName(
130 AutofillScanner* scanner) { 131 AutofillScanner* scanner) {
131 scoped_ptr<FirstLastNameField> field(new FirstLastNameField); 132 scoped_ptr<FirstLastNameField> field(new FirstLastNameField);
132 scanner->SaveCursor(); 133 scanner->SaveCursor();
133 134
134 string16 pattern = GetEcmlPattern(kEcmlShipToFirstName, 135 string16 pattern = GetEcmlPattern(kEcmlShipToFirstName,
135 kEcmlBillToFirstName, '|'); 136 kEcmlBillToFirstName, '|');
136 if (!ParseText(scanner, pattern, &field->first_name_)) 137 if (!ParseField(scanner, pattern, &field->first_name_))
137 return NULL; 138 return NULL;
138 139
139 pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|'); 140 pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|');
140 ParseText(scanner, pattern, &field->middle_name_); 141 ParseField(scanner, pattern, &field->middle_name_);
141 142
142 pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|'); 143 pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|');
143 if (ParseText(scanner, pattern, &field->last_name_)) 144 if (ParseField(scanner, pattern, &field->last_name_))
144 return field.release(); 145 return field.release();
145 146
146 scanner->Rewind(); 147 scanner->Rewind();
147 return NULL; 148 return NULL;
148 } 149 }
149 150
150 FirstLastNameField* FirstLastNameField::Parse(AutofillScanner* scanner, 151 FirstLastNameField* FirstLastNameField::Parse(AutofillScanner* scanner,
151 bool is_ecml) { 152 bool is_ecml) {
152 if (is_ecml) 153 if (is_ecml)
153 return ParseEcmlName(scanner); 154 return ParseEcmlName(scanner);
154 155
155 FirstLastNameField* field = ParseSpecificName(scanner); 156 FirstLastNameField* field = ParseSpecificName(scanner);
156 if (!field) 157 if (!field)
157 field = ParseComponentNames(scanner); 158 field = ParseComponentNames(scanner);
158 return field; 159 return field;
159 } 160 }
160 161
161 FirstLastNameField::FirstLastNameField() 162 FirstLastNameField::FirstLastNameField()
162 : first_name_(NULL), 163 : first_name_(NULL),
163 middle_name_(NULL), 164 middle_name_(NULL),
164 last_name_(NULL), 165 last_name_(NULL),
165 middle_initial_(false) { 166 middle_initial_(false) {
166 } 167 }
168
169 bool FirstLastNameField::ClassifyField(FieldTypeMap* map) const {
170 bool ok = AddClassification(first_name_, NAME_FIRST, map);
171 ok = ok && AddClassification(last_name_, NAME_LAST, map);
172 AutofillFieldType type = middle_initial_ ? NAME_MIDDLE_INITIAL : NAME_MIDDLE;
173 ok = ok && AddClassification(middle_name_, type, map);
174 return ok;
175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698