summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r--chrome/browser/autofill/address_field.h4
-rw-r--r--chrome/browser/autofill/contact_info.cc357
-rw-r--r--chrome/browser/autofill/contact_info.h105
-rw-r--r--chrome/browser/autofill/credit_card_field.h4
-rw-r--r--chrome/browser/autofill/form_group.h7
5 files changed, 471 insertions, 6 deletions
diff --git a/chrome/browser/autofill/address_field.h b/chrome/browser/autofill/address_field.h
index 58ea0de..bd568d8 100644
--- a/chrome/browser/autofill/address_field.h
+++ b/chrome/browser/autofill/address_field.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,7 +15,7 @@ class AutoFillField;
class AddressField : public FormField {
public:
virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const;
- virtual FormFieldType GetFormFieldType() { return kAddressType; }
+ virtual FormFieldType GetFormFieldType() const { return kAddressType; }
virtual int priority() const { return 3; }
static AddressField* Parse(std::vector<AutoFillField*>::const_iterator* iter,
diff --git a/chrome/browser/autofill/contact_info.cc b/chrome/browser/autofill/contact_info.cc
new file mode 100644
index 0000000..9e31b18
--- /dev/null
+++ b/chrome/browser/autofill/contact_info.cc
@@ -0,0 +1,357 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/autofill/contact_info.h"
+
+#include "base/basictypes.h"
+#include "base/string_util.h"
+#include "chrome/browser/autofill/autofill_type.h"
+#include "chrome/browser/autofill/field_types.h"
+
+static const string16 kNameSplitChars = ASCIIToUTF16("-'. ");
+
+static const AutoFillFieldType kAutoFillContactInfoTypes[] = {
+ NAME_FIRST,
+ NAME_MIDDLE,
+ NAME_LAST,
+ EMAIL_ADDRESS,
+ COMPANY_NAME,
+};
+
+static const size_t kAutoFillContactInfoLength =
+ arraysize(kAutoFillContactInfoTypes);
+
+FormGroup* ContactInfo::Clone() const {
+ return new ContactInfo(*this);
+}
+
+void ContactInfo::GetPossibleFieldTypes(const string16& text,
+ FieldTypeSet* possible_types) const {
+ if (IsFirstName(text))
+ possible_types->insert(NAME_FIRST);
+
+ if (IsMiddleName(text))
+ possible_types->insert(NAME_MIDDLE);
+
+ if (IsLastName(text))
+ possible_types->insert(NAME_LAST);
+
+ if (IsMiddleInitial(text))
+ possible_types->insert(NAME_MIDDLE_INITIAL);
+
+ if (IsSuffix(text))
+ possible_types->insert(NAME_SUFFIX);
+
+ if (IsFullName(text))
+ possible_types->insert(NAME_FULL);
+
+ if (email_ == text)
+ possible_types->insert(EMAIL_ADDRESS);
+
+ if (company_name_ == text)
+ possible_types->insert(COMPANY_NAME);
+}
+
+void ContactInfo::FindInfoMatches(const AutoFillType& type,
+ const string16& info,
+ std::vector<string16>* matched_text) const {
+ if (matched_text == NULL) {
+ DLOG(ERROR) << "NULL matched vector passed in";
+ return;
+ }
+
+ string16 match;
+ if (type.field_type() == UNKNOWN_TYPE) {
+ for (size_t i = 0; i < kAutoFillContactInfoLength; i++) {
+ if (FindInfoMatchesHelper(kAutoFillContactInfoTypes[i], info, &match))
+ matched_text->push_back(match);
+ }
+ } else if (FindInfoMatchesHelper(type.field_type(), info, &match)) {
+ matched_text->push_back(match);
+ }
+}
+
+string16 ContactInfo::GetFieldText(const AutoFillType& type) const {
+ AutoFillFieldType field_type = type.field_type();
+ if (field_type == NAME_FIRST)
+ return first();
+
+ if (field_type == NAME_MIDDLE)
+ return middle();
+
+ if (field_type == NAME_LAST)
+ return last();
+
+ if (field_type == NAME_MIDDLE_INITIAL)
+ MiddleInitial();
+
+ if (field_type == NAME_FULL)
+ return FullName();
+
+ if (field_type == NAME_SUFFIX)
+ return suffix();
+
+ if (field_type == EMAIL_ADDRESS)
+ return email();
+
+ if (field_type == COMPANY_NAME)
+ return company_name();
+
+ return EmptyString16();
+}
+
+void ContactInfo::SetInfo(const AutoFillType& type, const string16& value) {
+ AutoFillFieldType field_type = type.field_type();
+ DCHECK(type.group() == AutoFillType::CONTACT_INFO);
+ if (field_type == NAME_FIRST)
+ SetFirst(value);
+ else if (field_type == NAME_MIDDLE)
+ SetMiddle(value);
+ else if (field_type == NAME_LAST)
+ SetLast(value);
+ else if (field_type == NAME_SUFFIX)
+ set_suffix(value);
+ else if (field_type == EMAIL_ADDRESS)
+ email_ = value;
+ else if (field_type == COMPANY_NAME)
+ company_name_ = value;
+ else
+ NOTREACHED();
+}
+
+string16 ContactInfo::FullName() const {
+ if (first_.empty())
+ return EmptyString16();
+
+ std::vector<string16> full_name;
+ full_name.push_back(first_);
+
+ if (!middle_.empty())
+ full_name.push_back(middle_);
+
+ if (!last_.empty())
+ full_name.push_back(last_);
+
+ if (!suffix_.empty())
+ full_name.push_back(suffix_);
+
+ return JoinString(full_name, ' ');
+}
+
+string16 ContactInfo::MiddleInitial() const {
+ if (middle_.empty())
+ return EmptyString16();
+
+ string16 middle_name(middle());
+ string16 initial;
+ initial.push_back(middle_name[0]);
+ return initial;
+}
+
+ContactInfo::ContactInfo(const ContactInfo& contact_info)
+ : first_tokens_(contact_info.first_tokens_),
+ middle_tokens_(contact_info.middle_tokens_),
+ last_tokens_(contact_info.last_tokens_),
+ first_(contact_info.first_),
+ middle_(contact_info.middle_),
+ last_(contact_info.last_),
+ suffix_(contact_info.suffix_),
+ email_(contact_info.email_),
+ company_name_(contact_info.company_name_) {
+}
+
+bool ContactInfo::FindInfoMatchesHelper(const AutoFillFieldType& field_type,
+ const string16& info,
+ string16* match) const {
+ if (match == NULL) {
+ DLOG(ERROR) << "NULL match string passed in";
+ return false;
+ }
+
+ match->clear();
+ if (field_type == NAME_FIRST &&
+ StartsWith(first(), info, false)) {
+ *match = first();
+ } else if (field_type == NAME_MIDDLE &&
+ StartsWith(middle(), info, false)) {
+ *match = middle();
+ } else if (field_type == NAME_LAST &&
+ StartsWith(last(), info, false)) {
+ *match = last();
+ } else if (field_type == NAME_SUFFIX &&
+ StartsWith(suffix(), info, false)) {
+ *match = suffix();
+ } else if (field_type == NAME_MIDDLE_INITIAL && IsMiddleInitial(info)) {
+ *match = MiddleInitial();
+ } else if (field_type == NAME_FULL &&
+ StartsWith(FullName(), info, false)) {
+ *match = FullName();
+ } else if (field_type == EMAIL_ADDRESS &&
+ StartsWith(email(), info, false)) {
+ *match = email();
+ } else if (field_type == COMPANY_NAME &&
+ StartsWith(company_name(), info, false)) {
+ *match = company_name();
+ }
+
+ return !match->empty();
+}
+
+// If each of the 'words' contained in the text are also present in the first
+// name then we will consider the text to be of type kFirstName. This means
+// that people with multiple first names will be able to enter any one of
+// their first names and have it correctly recognized.
+bool ContactInfo::IsFirstName(const string16& text) const {
+ return IsNameMatch(text, first_tokens_);
+}
+
+// If each of the 'words' contained in the text are also present in the middle
+// name then we will consider the text to be of type kMiddleName.
+bool ContactInfo::IsMiddleName(const string16& text) const {
+ return IsNameMatch(text, middle_tokens_);
+}
+
+// If each of the 'words' contained in the text are also present in the last
+// name then we will consider the text to be of type kLastName.
+bool ContactInfo::IsLastName(const string16& text) const {
+ return IsNameMatch(text, last_tokens_);
+}
+
+bool ContactInfo::IsSuffix(const string16& text) const {
+ string16 lower_suffix = StringToLowerASCII(suffix_);
+ return (lower_suffix == text);
+}
+
+bool ContactInfo::IsMiddleInitial(const string16& text) const {
+ if (text.length() != 1)
+ return false;
+
+ string16 lower_case = StringToLowerASCII(text);
+ // If the text entered was a single character and it matches the first letter
+ // of any of the given middle names then we consider it to be a middle
+ // initial field.
+ size_t middle_tokens_size = middle_tokens_.size();
+ for (size_t i = 0; i < middle_tokens_size; ++i) {
+ if (middle_tokens_[i][0] == lower_case[0])
+ return true;
+ }
+
+ return false;
+}
+
+// A field will be considered to be of type NAME_FULL if:
+// 1) it contains at least one word from the first name.
+// 2) it contains at least one word from the last name.
+// 3) all of the words in the field match a word in either the first,
+// middle, or last name.
+bool ContactInfo::IsFullName(const string16& text) const {
+ size_t first_tokens_size = first_tokens_.size();
+ if (first_tokens_size == 0)
+ return false;
+
+ size_t middle_tokens_size = middle_tokens_.size();
+
+ size_t last_tokens_size = last_tokens_.size();
+ if (last_tokens_size == 0)
+ return false;
+
+ NameTokens text_tokens;
+ Tokenize(text, kNameSplitChars, &text_tokens);
+ size_t text_tokens_size = text_tokens.size();
+ if (text_tokens_size == 0 || text_tokens_size < 2)
+ return false;
+
+ size_t name_tokens_size =
+ first_tokens_size + middle_tokens_size + last_tokens_size;
+ if (text_tokens_size > name_tokens_size)
+ return false;
+
+ bool first_name_match = false;
+ bool last_name_match = false;
+ NameTokens::iterator iter;
+ for (iter = text_tokens.begin(); iter != text_tokens.end(); ++iter) {
+ bool match = false;
+ if (IsWordInName(*iter, first_tokens_)) {
+ match = true;
+ first_name_match = true;
+ }
+
+ if (IsWordInName(*iter, last_tokens_)) {
+ match = true;
+ last_name_match = true;
+ }
+
+ if (IsWordInName(*iter, middle_tokens_))
+ match = true;
+
+ if (!match)
+ return false;
+ }
+
+ return (first_name_match && last_name_match);
+}
+
+bool ContactInfo::IsNameMatch(const string16& text,
+ const NameTokens& name_tokens) const {
+ size_t name_tokens_size = name_tokens.size();
+ if (name_tokens_size == 0)
+ return false;
+
+ NameTokens text_tokens;
+ Tokenize(text, kNameSplitChars, &text_tokens);
+ size_t text_tokens_size = text_tokens.size();
+ if (text_tokens_size == 0)
+ return false;
+
+ if (text_tokens_size > name_tokens_size)
+ return false;
+
+ // If each of the 'words' contained in the text are also present in the name,
+ // then we will consider the text to match the name.
+ NameTokens::iterator iter;
+ for (iter = text_tokens.begin(); iter != text_tokens.end(); ++iter) {
+ if (!IsWordInName(*iter, name_tokens))
+ return false;
+ }
+
+ return true;
+}
+
+bool ContactInfo::IsWordInName(const string16& word,
+ const NameTokens& name_tokens) const {
+ NameTokens::const_iterator iter;
+ for (iter = name_tokens.begin(); iter != name_tokens.end(); ++iter) {
+ if (word == *iter)
+ return true;
+ }
+
+ return false;
+}
+
+void ContactInfo::SetFirst(const string16& first) {
+ first_ = first;
+ first_tokens_.clear();
+ Tokenize(first, kNameSplitChars, &first_tokens_);
+ NameTokens::iterator iter;
+ for (iter = first_tokens_.begin(); iter != first_tokens_.end(); ++iter)
+ *iter = StringToLowerASCII(*iter);
+}
+
+void ContactInfo::SetMiddle(const string16& middle) {
+ middle_ = middle;
+ middle_tokens_.clear();
+ Tokenize(middle, kNameSplitChars, &middle_tokens_);
+ NameTokens::iterator iter;
+ for (iter = middle_tokens_.begin(); iter != middle_tokens_.end(); ++iter)
+ *iter = StringToLowerASCII(*iter);
+}
+
+void ContactInfo::SetLast(const string16& last) {
+ last_ = last;
+ last_tokens_.clear();
+ Tokenize(last, kNameSplitChars, &last_tokens_);
+ NameTokens::iterator iter;
+ for (iter = last_tokens_.begin(); iter != last_tokens_.end(); ++iter)
+ *iter = StringToLowerASCII(*iter);
+}
diff --git a/chrome/browser/autofill/contact_info.h b/chrome/browser/autofill/contact_info.h
new file mode 100644
index 0000000..957e55e
--- /dev/null
+++ b/chrome/browser/autofill/contact_info.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_AUTOFILL_CONTACT_INFO_H_
+#define CHROME_BROWSER_AUTOFILL_CONTACT_INFO_H_
+
+#include <vector>
+
+#include "base/string16.h"
+#include "chrome/browser/autofill/form_group.h"
+
+typedef std::vector<string16> NameTokens;
+
+// A form group that stores contact information.
+class ContactInfo : public FormGroup {
+ public:
+ ContactInfo() {}
+
+ // FormGroup implementation:
+ virtual FormGroup* Clone() const;
+ virtual void GetPossibleFieldTypes(const string16& text,
+ FieldTypeSet* possible_types) const;
+ virtual void FindInfoMatches(const AutoFillType& type,
+ const string16& info,
+ std::vector<string16>* matched_text) const;
+ virtual string16 GetFieldText(const AutoFillType& type) const;
+ virtual void SetInfo(const AutoFillType& type, const string16& value);
+
+ // Returns the full name, which can include up to the first, middle, middle
+ // initial, last name, and suffix.
+ string16 FullName() const;
+
+ string16 first() const { return first_; }
+ string16 middle() const { return middle_; }
+ string16 last() const { return last_; }
+ string16 MiddleInitial() const;
+ string16 suffix() const { return suffix_; }
+ string16 email() const { return email_; }
+ string16 company_name() const { return company_name_; }
+
+ private:
+ explicit ContactInfo(const ContactInfo& contact_info);
+ void operator=(const ContactInfo& info);
+
+ // A helper function for FindInfoMatches that only handles matching the info
+ // with the requested field type.
+ bool FindInfoMatchesHelper(const AutoFillFieldType& field_type,
+ const string16& info,
+ string16* matched_text) const;
+
+ // Returns true if |text| is the first name.
+ bool IsFirstName(const string16& text) const;
+
+ // Returns true if |text| is the middle name.
+ bool IsMiddleName(const string16& text) const;
+
+ // Returns true if |text| is the last name.
+ bool IsLastName(const string16& text) const;
+
+ // Returns true if |text| is the suffix.
+ bool IsSuffix(const string16& text) const;
+
+ // Returns true if |text| is the middle initial.
+ bool IsMiddleInitial(const string16& text) const;
+
+ // Returns true if |text| is the last name.
+ bool IsFullName(const string16& text) const;
+
+ // Returns true if all of the tokens in |text| match the tokens in
+ // |name_tokens|.
+ bool IsNameMatch(const string16& text, const NameTokens& name_tokens) const;
+
+ // Returns true if |word| is one of the tokens in |name_tokens|.
+ bool IsWordInName(const string16& word, const NameTokens& name_tokens) const;
+
+ // Sets |first_| to |first| and |first_tokens_| to the set of tokens in
+ // |first|, made lowercase.
+ void SetFirst(const string16& first);
+
+ // Sets |middle_| to |middle| and |middle_tokens_| to the set of tokens in
+ // |middle|, made lowercase.
+ void SetMiddle(const string16& middle);
+
+ // Sets |last_| to |last| and |last_tokens_| to the set of tokens in |last|,
+ // made lowercase.
+ void SetLast(const string16& last);
+
+ void set_suffix(const string16& suffix) { suffix_ = suffix; }
+
+ // List of tokens in each part of the name.
+ NameTokens first_tokens_;
+ NameTokens middle_tokens_;
+ NameTokens last_tokens_;
+
+ // Contact information data.
+ string16 first_;
+ string16 middle_;
+ string16 last_;
+ string16 suffix_;
+ string16 email_;
+ string16 company_name_;
+};
+
+#endif // CHROME_BROWSER_AUTOFILL_CONTACT_INFO_H_
diff --git a/chrome/browser/autofill/credit_card_field.h b/chrome/browser/autofill/credit_card_field.h
index 4fed417..d870db7 100644
--- a/chrome/browser/autofill/credit_card_field.h
+++ b/chrome/browser/autofill/credit_card_field.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,7 +15,7 @@ class CreditCardField : public FormField {
public:
// FormField implementation:
virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const;
- virtual FormFieldType GetFormFieldType() { return kCreditCardType; }
+ virtual FormFieldType GetFormFieldType() const { return kCreditCardType; }
virtual int priority() const { return 4; }
static CreditCardField* Parse(
diff --git a/chrome/browser/autofill/form_group.h b/chrome/browser/autofill/form_group.h
index 60250da..042ae0d 100644
--- a/chrome/browser/autofill/form_group.h
+++ b/chrome/browser/autofill/form_group.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,9 @@
#include <vector>
#include "base/string16.h"
+#include "base/string_util.h"
+#include "chrome/browser/autofill/autofill_type.h"
+#include "chrome/browser/autofill/field_types.h"
// This class is an interface for collections of form fields, grouped by type.
// The information in objects of this class is managed by the
@@ -46,7 +49,7 @@ class FormGroup {
// Returns the label for this FormGroup item. This should be overridden for
// form group items that implement a label.
- virtual string16 Label() const { return EmptyString(); }
+ virtual string16 Label() const { return EmptyString16(); }
};
#endif // CHROME_BROWSER_AUTOFILL_FORM_GROUP_H_