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

Side by Side Diff: chrome/browser/autofill/credit_card_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/credit_card_field.h" 5 #include "chrome/browser/autofill/credit_card_field.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/string16.h" 11 #include "base/string16.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/autofill/autofill_ecml.h"
14 #include "chrome/browser/autofill/autofill_field.h" 15 #include "chrome/browser/autofill/autofill_field.h"
15 #include "chrome/browser/autofill/autofill_scanner.h" 16 #include "chrome/browser/autofill/autofill_scanner.h"
16 #include "chrome/browser/autofill/field_types.h" 17 #include "chrome/browser/autofill/field_types.h"
17 #include "grit/autofill_resources.h" 18 #include "grit/autofill_resources.h"
18 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
19 20
20 bool CreditCardField::GetFieldInfo(FieldTypeMap* field_type_map) const { 21 using autofill::GetEcmlPattern;
21 bool ok = Add(field_type_map, number_, CREDIT_CARD_NUMBER);
22
23 // If the heuristics detected first and last name in separate fields,
24 // then ignore both fields. Putting them into separate fields is probably
25 // wrong, because the credit card can also contain a middle name or middle
26 // initial.
27 if (cardholder_last_ == NULL)
28 ok = ok && Add(field_type_map, cardholder_, CREDIT_CARD_NAME);
29
30 ok = ok && Add(field_type_map, type_, CREDIT_CARD_TYPE);
31 ok = ok && Add(field_type_map, expiration_month_, CREDIT_CARD_EXP_MONTH);
32 ok = ok && Add(field_type_map, expiration_year_,
33 CREDIT_CARD_EXP_4_DIGIT_YEAR);
34 return ok;
35 }
36 22
37 // static 23 // static
38 CreditCardField* CreditCardField::Parse(AutofillScanner* scanner, 24 CreditCardField* CreditCardField::Parse(AutofillScanner* scanner,
39 bool is_ecml) { 25 bool is_ecml) {
40 if (scanner->IsEnd()) 26 if (scanner->IsEnd())
41 return NULL; 27 return NULL;
42 28
43 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField); 29 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField);
44 scanner->SaveCursor(); 30 scanner->SaveCursor();
45 31
(...skipping 15 matching lines...) Expand all
61 if (fields == 0 || credit_card_field->expiration_month_) { 47 if (fields == 0 || credit_card_field->expiration_month_) {
62 // at beginning or end 48 // at beginning or end
63 name_pattern = l10n_util::GetStringUTF16( 49 name_pattern = l10n_util::GetStringUTF16(
64 IDS_AUTOFILL_NAME_ON_CARD_RE); 50 IDS_AUTOFILL_NAME_ON_CARD_RE);
65 } else { 51 } else {
66 name_pattern = l10n_util::GetStringUTF16( 52 name_pattern = l10n_util::GetStringUTF16(
67 IDS_AUTOFILL_NAME_ON_CARD_CONTEXTUAL_RE); 53 IDS_AUTOFILL_NAME_ON_CARD_CONTEXTUAL_RE);
68 } 54 }
69 } 55 }
70 56
71 if (ParseText(scanner, name_pattern, &credit_card_field->cardholder_)) 57 if (ParseField(scanner, name_pattern, &credit_card_field->cardholder_))
72 continue; 58 continue;
73 59
74 // As a hard-coded hack for Expedia's billing pages (expedia_checkout.html 60 // As a hard-coded hack for Expedia's billing pages (expedia_checkout.html
75 // and ExpediaBilling.html in our test suite), recognize separate fields 61 // and ExpediaBilling.html in our test suite), recognize separate fields
76 // for the cardholder's first and last name if they have the labels "cfnm" 62 // for the cardholder's first and last name if they have the labels "cfnm"
77 // and "clnm". 63 // and "clnm".
78 scanner->SaveCursor(); 64 scanner->SaveCursor();
79 const AutofillField* first; 65 const AutofillField* first;
80 if (!is_ecml && ParseText(scanner, ASCIIToUTF16("^cfnm"), &first) && 66 if (!is_ecml && ParseField(scanner, ASCIIToUTF16("^cfnm"), &first) &&
81 ParseText(scanner, ASCIIToUTF16("^clnm"), 67 ParseField(scanner, ASCIIToUTF16("^clnm"),
82 &credit_card_field->cardholder_last_)) { 68 &credit_card_field->cardholder_last_)) {
83 credit_card_field->cardholder_ = first; 69 credit_card_field->cardholder_ = first;
84 continue; 70 continue;
85 } 71 }
86 scanner->Rewind(); 72 scanner->Rewind();
87 } 73 }
88 74
89 // We look for a card security code before we look for a credit 75 // We look for a card security code before we look for a credit
90 // card number and match the general term "number". The security code 76 // card number and match the general term "number". The security code
91 // has a plethora of names; we've seen "verification #", 77 // has a plethora of names; we've seen "verification #",
92 // "verification number", "card identification number" and others listed 78 // "verification number", "card identification number" and others listed
93 // in the |pattern| below. 79 // in the |pattern| below.
94 string16 pattern; 80 string16 pattern;
95 if (is_ecml) 81 if (is_ecml)
96 pattern = GetEcmlPattern(kEcmlCardVerification); 82 pattern = GetEcmlPattern(kEcmlCardVerification);
97 else 83 else
98 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_CVC_RE); 84 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_CVC_RE);
99 85
100 if (!credit_card_field->verification_ && 86 if (!credit_card_field->verification_ &&
101 ParseText(scanner, pattern, &credit_card_field->verification_)) 87 ParseField(scanner, pattern, &credit_card_field->verification_)) {
102 continue; 88 continue;
103 89 }
104 // TODO(jhawkins): Parse the type select control. 90 // TODO(jhawkins): Parse the type select control.
105 91
106 if (is_ecml) 92 if (is_ecml)
107 pattern = GetEcmlPattern(kEcmlCardNumber); 93 pattern = GetEcmlPattern(kEcmlCardNumber);
108 else 94 else
109 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_NUMBER_RE); 95 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_NUMBER_RE);
110 96
111 if (!credit_card_field->number_ && 97 if (!credit_card_field->number_ &&
112 ParseText(scanner, pattern, &credit_card_field->number_)) 98 ParseField(scanner, pattern, &credit_card_field->number_)) {
113 continue; 99 continue;
100 }
114 101
115 if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) { 102 if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) {
116 credit_card_field->expiration_month_ = scanner->Cursor(); 103 credit_card_field->expiration_month_ = scanner->Cursor();
117 scanner->Advance(); 104 scanner->Advance();
118 } else { 105 } else {
119 // "Expiration date" is the most common label here, but some pages have 106 // "Expiration date" is the most common label here, but some pages have
120 // "Expires", "exp. date" or "exp. month" and "exp. year". We also look 107 // "Expires", "exp. date" or "exp. month" and "exp. year". We also look
121 // for the field names ccmonth and ccyear, which appear on at least 4 of 108 // for the field names ccmonth and ccyear, which appear on at least 4 of
122 // our test pages. 109 // our test pages.
123 // 110 //
124 // -> On at least one page (The China Shop2.html) we find only the labels 111 // -> On at least one page (The China Shop2.html) we find only the labels
125 // "month" and "year". So for now we match these words directly; we'll 112 // "month" and "year". So for now we match these words directly; we'll
126 // see if this turns out to be too general. 113 // see if this turns out to be too general.
127 // 114 //
128 // Toolbar Bug 51451: indeed, simply matching "month" is too general for 115 // Toolbar Bug 51451: indeed, simply matching "month" is too general for
129 // https://rps.fidelity.com/ftgw/rps/RtlCust/CreatePIN/Init. 116 // https://rps.fidelity.com/ftgw/rps/RtlCust/CreatePIN/Init.
130 // Instead, we match only words beginning with "month". 117 // Instead, we match only words beginning with "month".
131 if (is_ecml) 118 if (is_ecml)
132 pattern = GetEcmlPattern(kEcmlCardExpireMonth); 119 pattern = GetEcmlPattern(kEcmlCardExpireMonth);
133 else 120 else
134 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_EXPIRATION_MONTH_RE); 121 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_EXPIRATION_MONTH_RE);
135 122
136 if ((!credit_card_field->expiration_month_ || 123 if ((!credit_card_field->expiration_month_ ||
137 credit_card_field->expiration_month_->IsEmpty()) && 124 credit_card_field->expiration_month_->IsEmpty()) &&
138 ParseText(scanner, pattern, &credit_card_field->expiration_month_)) { 125 ParseField(scanner, pattern, &credit_card_field->expiration_month_)) {
139 if (is_ecml) 126 if (is_ecml)
140 pattern = GetEcmlPattern(kEcmlCardExpireYear); 127 pattern = GetEcmlPattern(kEcmlCardExpireYear);
141 else 128 else
142 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_EXPIRATION_DATE_RE); 129 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_EXPIRATION_DATE_RE);
143 130
144 if (!ParseText(scanner, pattern, 131 if (!ParseField(scanner, pattern,
145 &credit_card_field->expiration_year_)) { 132 &credit_card_field->expiration_year_)) {
146 scanner->Rewind(); 133 scanner->Rewind();
147 return NULL; 134 return NULL;
148 } 135 }
149 continue; 136 continue;
150 } 137 }
151 } 138 }
152 139
153 if (ParseText(scanner, GetEcmlPattern(kEcmlCardExpireDay))) 140 if (ParseField(scanner, GetEcmlPattern(kEcmlCardExpireDay), NULL))
154 continue; 141 continue;
155 142
156 // Some pages (e.g. ExpediaBilling.html) have a "card description" 143 // Some pages (e.g. ExpediaBilling.html) have a "card description"
157 // field; we parse this field but ignore it. 144 // field; we parse this field but ignore it.
158 // We also ignore any other fields within a credit card block that 145 // We also ignore any other fields within a credit card block that
159 // start with "card", under the assumption that they are related to 146 // start with "card", under the assumption that they are related to
160 // the credit card section being processed but are uninteresting to us. 147 // the credit card section being processed but are uninteresting to us.
161 if (ParseText(scanner, 148 if (ParseField(scanner,
162 l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_IGNORED_RE))) 149 l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_IGNORED_RE),
150 NULL)) {
163 continue; 151 continue;
152 }
164 153
165 break; 154 break;
166 } 155 }
167 156
168 // Some pages have a billing address field after the cardholder name field. 157 // Some pages have a billing address field after the cardholder name field.
169 // For that case, allow only just the cardholder name field. The remaining 158 // For that case, allow only just the cardholder name field. The remaining
170 // CC fields will be picked up in a following CreditCardField. 159 // CC fields will be picked up in a following CreditCardField.
171 if (credit_card_field->cardholder_) 160 if (credit_card_field->cardholder_)
172 return credit_card_field.release(); 161 return credit_card_field.release();
173 162
(...skipping 19 matching lines...) Expand all
193 182
194 CreditCardField::CreditCardField() 183 CreditCardField::CreditCardField()
195 : cardholder_(NULL), 184 : cardholder_(NULL),
196 cardholder_last_(NULL), 185 cardholder_last_(NULL),
197 type_(NULL), 186 type_(NULL),
198 number_(NULL), 187 number_(NULL),
199 verification_(NULL), 188 verification_(NULL),
200 expiration_month_(NULL), 189 expiration_month_(NULL),
201 expiration_year_(NULL) { 190 expiration_year_(NULL) {
202 } 191 }
192
193 bool CreditCardField::ClassifyField(FieldTypeMap* map) const {
194 bool ok = AddClassification(number_, CREDIT_CARD_NUMBER, map);
195
196 // If the heuristics detected first and last name in separate fields,
197 // then ignore both fields. Putting them into separate fields is probably
198 // wrong, because the credit card can also contain a middle name or middle
199 // initial.
200 if (cardholder_last_ == NULL)
201 ok = ok && AddClassification(cardholder_, CREDIT_CARD_NAME, map);
202
203 ok = ok && AddClassification(type_, CREDIT_CARD_TYPE, map);
204 ok = ok && AddClassification(expiration_month_, CREDIT_CARD_EXP_MONTH, map);
205 ok = ok && AddClassification(expiration_year_,
206 CREDIT_CARD_EXP_4_DIGIT_YEAR,
207 map);
208 return ok;
209 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698