summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill/form_structure.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/autofill/form_structure.cc')
-rw-r--r--chrome/browser/autofill/form_structure.cc128
1 files changed, 85 insertions, 43 deletions
diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc
index dd9cfaa..f96e5272 100644
--- a/chrome/browser/autofill/form_structure.cc
+++ b/chrome/browser/autofill/form_structure.cc
@@ -36,6 +36,8 @@ const char* const kAttributeAutoFillType = "autofilltype";
// The only form control type we handle currently.
const char* const kControlTypeText = "text";
+// This type is required for AutoFill servers.
+const char* const kControlTypeSingleSelect = "select-one";
// The number of fillable fields necessary for a form to be fillable.
const size_t kRequiredFillableFields = 3;
@@ -66,9 +68,18 @@ FormStructure::FormStructure(const FormFieldValues& values)
std::vector<webkit_glue::FormField>::const_iterator field;
for (field = values.elements.begin();
field != values.elements.end(); field++) {
+ // Add all form fields (including with empty names) to signature.
+ // This is requirement for AutoFill servers.
+ bool is_text_control = LowerCaseEqualsASCII(field->form_control_type(),
+ kControlTypeText);
+ if (is_text_control || LowerCaseEqualsASCII(field->form_control_type(),
+ kControlTypeSingleSelect)) {
+ form_signature_field_names_.append("&");
+ form_signature_field_names_.append(UTF16ToUTF8(field->name()));
+ }
// We currently only handle text fields. This prevents us from thinking we
// can autofill other types of controls, e.g., select, password, hidden.
- if (!LowerCaseEqualsASCII(field->form_control_type(), kControlTypeText))
+ if (!is_text_control)
continue;
// Generate a unique name for this field by appending a counter to the name.
@@ -90,65 +101,61 @@ FormStructure::FormStructure(const FormFieldValues& values)
}
bool FormStructure::EncodeUploadRequest(bool auto_fill_used,
- bool query,
std::string* encoded_xml) const {
bool auto_fillable = IsAutoFillable();
DCHECK(auto_fillable); // Caller should've checked for search pages.
if (!auto_fillable)
return false;
- buzz::XmlElement autofil_request_xml(query ? buzz::QName("autofillquery") :
- buzz::QName("autofillupload"));
- buzz::XmlElement *encompassing_xml_element = &autofil_request_xml;
- if (query)
- encompassing_xml_element = new buzz::XmlElement(buzz::QName("form"));
+ buzz::XmlElement autofil_request_xml(buzz::QName("autofillupload"));
- // Attributes for the <autofillupload>/<autofillquery> element.
+ // Attributes for the <autofillupload> element.
//
// TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients.
// For now these values are hacked from the toolbar code.
autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion),
"6.1.1715.1442/en (GGLL)");
- encompassing_xml_element->SetAttr(query ? buzz::QName(kAttributeSignature) :
- buzz::QName(kAttributeFormSignature),
- FormSignature());
+ autofil_request_xml.SetAttr(buzz::QName(kAttributeFormSignature),
+ FormSignature());
- if (!query) {
- autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed),
- auto_fill_used ? "true" : "false");
+ autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed),
+ auto_fill_used ? "true" : "false");
- // TODO(jhawkins): Hook this up to the personal data manager.
- // personaldata_manager_->GetDataPresent();
- autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), "");
- }
+ // TODO(jhawkins): Hook this up to the personal data manager.
+ // personaldata_manager_->GetDataPresent();
+ autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), "");
- // Add the child nodes for the form fields.
- for (size_t index = 0; index < field_count(); index++) {
- const AutoFillField* field = fields_[index];
- if (!query) {
- FieldTypeSet types = field->possible_types();
- for (FieldTypeSet::const_iterator type = types.begin();
- type != types.end(); type++) {
- buzz::XmlElement *field_element = new buzz::XmlElement(
- buzz::QName(kXMLElementField));
+ EncodeFormRequest(FormStructure::UPLOAD, &autofil_request_xml);
+
+ // Obtain the XML structure as a string.
+ *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ *encoded_xml += autofil_request_xml.Str().c_str();
+
+ return true;
+}
+
+bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms,
+ std::string* encoded_xml) {
+ buzz::XmlElement autofil_request_xml(buzz::QName("autofillquery"));
+ // Attributes for the <autofillquery> element.
+ //
+ // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients.
+ // For now these values are hacked from the toolbar code.
+ autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion),
+ "6.1.1715.1442/en (GGLL)");
+ for (ScopedVector<FormStructure>::const_iterator it = forms.begin();
+ it != forms.end();
+ ++it) {
+ buzz::XmlElement* encompassing_xml_element =
+ new buzz::XmlElement(buzz::QName("form"));
+ encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature),
+ (*it)->FormSignature());
+
+ (*it)->EncodeFormRequest(FormStructure::QUERY, encompassing_xml_element);
- field_element->SetAttr(buzz::QName(kAttributeSignature),
- field->FieldSignature());
- field_element->SetAttr(buzz::QName(kAttributeAutoFillType),
- IntToString(*type));
- encompassing_xml_element->AddElement(field_element);
- }
- } else {
- buzz::XmlElement *field_element = new buzz::XmlElement(
- buzz::QName(kXMLElementField));
- field_element->SetAttr(buzz::QName(kAttributeSignature),
- field->FieldSignature());
- encompassing_xml_element->AddElement(field_element);
- }
- }
- if (query)
autofil_request_xml.AddElement(encompassing_xml_element);
+ }
// Obtain the XML structure as a string.
*encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
@@ -185,7 +192,9 @@ void FormStructure::GetHeuristicAutoFillTypes() {
}
std::string FormStructure::FormSignature() const {
- std::string form_string = target_url_.host() +
+ std::string form_string = target_url_.scheme() +
+ "://" +
+ target_url_.host() +
"&" +
form_name_ +
form_signature_field_names_;
@@ -253,3 +262,36 @@ void FormStructure::GetHeuristicFieldInfo(FieldTypeMap* field_type_map) {
DCHECK(ok);
}
}
+
+bool FormStructure::EncodeFormRequest(
+ FormStructure::EncodeRequestType request_type,
+ buzz::XmlElement* encompassing_xml_element) const {
+ if (!field_count()) // Nothing to add.
+ return false;
+ // Add the child nodes for the form fields.
+ for (size_t index = 0; index < field_count(); index++) {
+ const AutoFillField* field = fields_[index];
+ if (request_type == FormStructure::UPLOAD) {
+ FieldTypeSet types = field->possible_types();
+ for (FieldTypeSet::const_iterator type = types.begin();
+ type != types.end(); type++) {
+ buzz::XmlElement *field_element = new buzz::XmlElement(
+ buzz::QName(kXMLElementField));
+
+ field_element->SetAttr(buzz::QName(kAttributeSignature),
+ field->FieldSignature());
+ field_element->SetAttr(buzz::QName(kAttributeAutoFillType),
+ IntToString(*type));
+ encompassing_xml_element->AddElement(field_element);
+ }
+ } else {
+ buzz::XmlElement *field_element = new buzz::XmlElement(
+ buzz::QName(kXMLElementField));
+ field_element->SetAttr(buzz::QName(kAttributeSignature),
+ field->FieldSignature());
+ encompassing_xml_element->AddElement(field_element);
+ }
+ }
+ return true;
+}
+