1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/*
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Google Inc. All rights reserved.
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions are
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * met:
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions of source code must retain the above copyright
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer.
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions in binary form must reproduce the above
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * copyright notice, this list of conditions and the following disclaimer
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * in the documentation and/or other materials provided with the
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * distribution.
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Neither the name of Google Inc. nor the names of its
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * contributors may be used to endorse or promote products derived from
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * this software without specific prior written permission.
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebSearchableFormData.h"
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "Document.h"
3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "DocumentLoader.h"
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "FormDataBuilder.h"
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "FormDataList.h"
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "Frame.h"
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLFormControlElement.h"
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLFormElement.h"
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLInputElement.h"
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLNames.h"
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLOptionElement.h"
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLOptionsCollection.h"
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLSelectElement.h"
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "TextEncoding.h"
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebFormElement.h"
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore;
50cad810f21b803229eb11403f9209855525a25d57Steve Blockusing namespace HTMLNames;
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace {
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Gets the encoding for the form.
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid GetFormEncoding(const HTMLFormElement* form, TextEncoding* encoding)
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String str(form->getAttribute(HTMLNames::accept_charsetAttr));
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    str.replace(',', ' ');
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Vector<String> charsets;
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    str.split(' ', charsets);
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (Vector<String>::const_iterator i(charsets.begin()); i != charsets.end(); ++i) {
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        *encoding = TextEncoding(*i);
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (encoding->isValid())
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return;
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    *encoding = TextEncoding(form->document()->loader()->writer()->encoding());
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Returns true if the submit request results in an HTTP URL.
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool IsHTTPFormSubmit(const HTMLFormElement* form)
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String action(form->action());
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return form->document()->frame()->loader()->completeURL(action.isNull() ? "" : action).protocol() == "http";
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// If the form does not have an activated submit button, the first submit
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// button is returned.
78643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockHTMLFormControlElement* GetButtonToActivate(HTMLFormElement* form)
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    HTMLFormControlElement* firstSubmitButton = 0;
815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice.
82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Vector<FormAssociatedElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) {
83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch      if (!(*i)->isFormControlElement())
84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch          continue;
85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch      HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(*i);
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      if (formElement->isActivatedSubmit())
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          // There's a button that is already activated for submit, return 0.
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          return 0;
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      if (!firstSubmitButton && formElement->isSuccessfulSubmitButton())
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          firstSubmitButton = formElement;
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return firstSubmitButton;
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Returns true if the selected state of all the options matches the default
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// selected state.
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool IsSelectInDefaultState(const HTMLSelectElement* select)
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    const Vector<Element*>& listItems = select->listItems();
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (select->multiple() || select->size() > 1) {
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (Vector<Element*>::const_iterator i(listItems.begin()); i != listItems.end(); ++i) {
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!(*i)->hasLocalName(HTMLNames::optionTag))
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                continue;
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            const HTMLOptionElement* optionElement = static_cast<const HTMLOptionElement*>(*i);
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (optionElement->selected() != optionElement->defaultSelected())
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return false;
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return true;
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // The select is rendered as a combobox (called menulist in WebKit). At
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // least one item is selected, determine which one.
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    const HTMLOptionElement* initialSelected = 0;
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (Vector<Element*>::const_iterator i(listItems.begin()); i != listItems.end(); ++i) {
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!(*i)->hasLocalName(HTMLNames::optionTag))
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            continue;
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        const HTMLOptionElement* optionElement = static_cast<const HTMLOptionElement*>(*i);
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (optionElement->defaultSelected()) {
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // The page specified the option to select.
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            initialSelected = optionElement;
121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!initialSelected)
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            initialSelected = optionElement;
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return initialSelected ? initialSelected->selected() : true;
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Returns true if the form element is in its default state, false otherwise.
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// The default state is the state of the form element on initial load of the
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// page, and varies depending upon the form element. For example, a checkbox is
132cad810f21b803229eb11403f9209855525a25d57Steve Block// in its default state if the checked state matches the state of the checked attribute.
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool IsInDefaultState(const HTMLFormControlElement* formElement)
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (formElement->hasTagName(HTMLNames::inputTag)) {
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        const HTMLInputElement* inputElement = static_cast<const HTMLInputElement*>(formElement);
13768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (inputElement->isCheckbox() || inputElement->isRadioButton())
138cad810f21b803229eb11403f9209855525a25d57Steve Block            return inputElement->checked() == inputElement->hasAttribute(checkedAttr);
139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else if (formElement->hasTagName(HTMLNames::selectTag))
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return IsSelectInDefaultState(static_cast<const HTMLSelectElement*>(formElement));
141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return true;
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// If form has only one text input element, return true. If a valid input
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// element is not found, return false. Additionally, the form data for all
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// elements is added to enc_string and the encoding used is set in
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// encoding_name.
148643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool HasSuitableTextElement(const HTMLFormElement* form, Vector<char>* encodedString, String* encodingName)
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    TextEncoding encoding;
151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    GetFormEncoding(form, &encoding);
152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!encoding.isValid()) {
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Need a valid encoding to encode the form elements.
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // If the encoding isn't found webkit ends up replacing the params with
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // empty strings. So, we don't try to do anything here.
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    *encodingName = encoding.name();
159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    HTMLInputElement* textElement = 0;
1615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice.
162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (Vector<FormAssociatedElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) {
163f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!(*i)->isFormControlElement())
164f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            continue;
165f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(*i);
166643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (formElement->disabled() || formElement->name().isNull())
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            continue;
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!IsInDefaultState(formElement) || formElement->hasTagName(HTMLNames::textareaTag))
170643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return 0;
171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        bool isTextElement = false;
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (formElement->hasTagName(HTMLNames::inputTag)) {
174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            const HTMLInputElement* input = static_cast<const HTMLInputElement*>(formElement);
175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (input->isFileUpload()) {
17668513a70bcd92384395513322f1b801e7bf9c729Steve Block                // Too big, don't try to index this.
17768513a70bcd92384395513322f1b801e7bf9c729Steve Block                return 0;
17868513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
17968513a70bcd92384395513322f1b801e7bf9c729Steve Block
180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (input->isPasswordField()) {
18168513a70bcd92384395513322f1b801e7bf9c729Steve Block                // Don't store passwords! This is most likely an https anyway.
18268513a70bcd92384395513322f1b801e7bf9c729Steve Block                return 0;
18368513a70bcd92384395513322f1b801e7bf9c729Steve Block            }
18468513a70bcd92384395513322f1b801e7bf9c729Steve Block
185a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (input->isTextField())
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                isTextElement = true;
187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      }
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      FormDataList dataList(encoding);
190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      if (!formElement->appendFormData(dataList, false))
191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          continue;
192643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen      const Vector<FormDataList::Item>& items = dataList.items();
194545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch      if (isTextElement && !items.isEmpty()) {
195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          if (textElement) {
196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              // The auto-complete bar only knows how to fill in one value.
197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              // This form has multiple fields; don't treat it as searchable.
198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              return false;
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          }
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          textElement = static_cast<HTMLInputElement*>(formElement);
201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      }
2025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen      for (Vector<FormDataList::Item>::const_iterator j(items.begin()); j != items.end(); ++j) {
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          // Handle ISINDEX / <input name=isindex> specially, but only if it's
204643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          // the first entry.
2055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen          if (!encodedString->isEmpty() || j->data() != "isindex") {
206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              if (!encodedString->isEmpty())
207643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                  encodedString->append('&');
2085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen              FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());
209643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              encodedString->append('=');
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          }
211643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          ++j;
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          if (formElement == textElement)
213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block              encodedString->append("{searchTerms}", 13);
214643ca7872b450ea4efacab6188849e5aac2ba161Steve Block          else
2155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen              FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());
216643ca7872b450ea4efacab6188849e5aac2ba161Steve Block      }
217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
218643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return textElement;
220643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
221643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace
223643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
224643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebKit {
225643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
226643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebSearchableFormData::WebSearchableFormData(const WebFormElement& form)
227643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RefPtr<HTMLFormElement> formElement = form.operator PassRefPtr<HTMLFormElement>();
229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    const Frame* frame = formElement->document()->frame();
230643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!frame)
231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Only consider forms that GET data and the action targets an http page.
234643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (equalIgnoringCase(formElement->getAttribute(HTMLNames::methodAttr), "post") || !IsHTTPFormSubmit(formElement.get()))
235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
236643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
237643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    HTMLFormControlElement* firstSubmitButton = GetButtonToActivate(formElement.get());
238643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (firstSubmitButton) {
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // The form does not have an active submit button, make the first button
240643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // active. We need to do this, otherwise the URL will not contain the
241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // name of the submit button.
242643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        firstSubmitButton->setActivatedSubmit(true);
243643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
244643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Vector<char> encodedString;
245643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String encoding;
246643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool hasElement = HasSuitableTextElement(formElement.get(), &encodedString, &encoding);
247643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (firstSubmitButton)
248643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        firstSubmitButton->setActivatedSubmit(false);
249643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!hasElement) {
250643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Not a searchable form.
251643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
252643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
253643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
254643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    String action(formElement->action());
255643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    KURL url(frame->loader()->completeURL(action.isNull() ? "" : action));
256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RefPtr<FormData> formData = FormData::create(encodedString);
257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    url.setQuery(formData->flattenToString());
258643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_url = url;
259643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_encoding = encoding;
260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
261643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
262643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebKit
263