1/*
2 * Copyright (c) 2010 The Chromium Authors. All rights reserved.
3 * Copyright 2010, The Android Open Source Project
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "FormManagerAndroid.h"
29
30#include "DocumentLoader.h"
31#include "Element.h"
32#include "Frame.h"
33#include "FrameLoader.h"
34#include "HTMLCollection.h"
35#include "HTMLFormControlElement.h"
36#include "HTMLFormElement.h"
37#include "HTMLInputElement.h"
38#include "HTMLLabelElement.h"
39#include "HTMLNames.h"
40#include "HTMLOptionElement.h"
41#include "HTMLSelectElement.h"
42#include "InputElement.h"
43#include "Node.h"
44#include "NodeList.h"
45#include "HTMLCollection.h"
46#include "FormAssociatedElement.h"
47#include "QualifiedName.h"
48#include "StringUtils.h"
49
50// TODO: This file is taken from chromium/chrome/renderer/form_manager.cc and
51// customised to use WebCore types rather than WebKit API types. It would be
52// nice and would ease future merge pain if the two could be combined.
53
54using webkit_glue::FormData;
55using webkit_glue::FormField;
56using WebCore::Element;
57using WebCore::FormAssociatedElement;
58using WebCore::HTMLCollection;
59using WebCore::HTMLElement;
60using WebCore::HTMLFormControlElement;
61using WebCore::HTMLFormElement;
62using WebCore::HTMLInputElement;
63using WebCore::HTMLLabelElement;
64using WebCore::HTMLOptionElement;
65using WebCore::HTMLSelectElement;
66using WebCore::InputElement;
67using WebCore::Node;
68using WebCore::NodeList;
69
70using namespace WebCore::HTMLNames;
71
72namespace {
73
74// Android helper function.
75HTMLInputElement* HTMLFormControlElementToHTMLInputElement(const HTMLFormControlElement& element) {
76    Node* node = const_cast<Node*>(static_cast<const Node*>(&element));
77    InputElement* input_element = node->toInputElement();
78    if (node && node->isHTMLElement())
79        return static_cast<HTMLInputElement*>(input_element);
80
81    return 0;
82}
83
84// The number of fields required by Autofill.  Ideally we could send the forms
85// to Autofill no matter how many fields are in the forms; however, finding the
86// label for each field is a costly operation and we can't spare the cycles if
87// it's not necessary.
88// Note the on ANDROID we reduce this from Chromium's 3 as it allows us to
89// Autofill simple name/email forms for example. This improves the mobile
90// device experience where form filling can be time consuming and frustrating.
91const size_t kRequiredAutofillFields = 2;
92
93// The maximum number of form fields we are willing to parse, due to
94// computational costs. This is a very conservative upper bound.
95const size_t kMaxParseableFields = 1000;
96
97// The maximum length allowed for form data.
98const size_t kMaxDataLength = 1024;
99
100// In HTML5, all text fields except password are text input fields to
101// autocomplete.
102bool IsTextInput(const HTMLInputElement* element) {
103    if (!element)
104        return false;
105
106    return element->isTextField() && !element->isPasswordField();
107}
108
109bool IsSelectElement(const HTMLFormControlElement& element) {
110    return formControlType(element) == kSelectOne;
111}
112
113bool IsOptionElement(Element& element) {
114    return element.hasTagName(optionTag);
115}
116
117bool IsAutofillableElement(const HTMLFormControlElement& element) {
118    HTMLInputElement* html_input_element = HTMLFormControlElementToHTMLInputElement(element);
119    return (html_input_element && IsTextInput(html_input_element)) || IsSelectElement(element);
120}
121
122// This is a helper function for the FindChildText() function (see below).
123// Search depth is limited with the |depth| parameter.
124string16 FindChildTextInner(Node* node, int depth) {
125    string16 element_text;
126    if (!node || depth <= 0)
127        return element_text;
128
129    string16 node_text = WTFStringToString16(node->nodeValue());
130    TrimWhitespace(node_text, TRIM_ALL, &node_text);
131    if (!node_text.empty())
132        element_text = node_text;
133
134    string16 child_text = FindChildTextInner(node->firstChild(), depth-1);
135    if (!child_text.empty())
136        element_text = element_text + child_text;
137
138    string16 sibling_text = FindChildTextInner(node->nextSibling(), depth-1);
139    if (!sibling_text.empty())
140        element_text = element_text + sibling_text;
141
142    return element_text;
143}
144
145// Returns the aggregated values of the decendants or siblings of |element| that
146// are non-empty text nodes. This is a faster alternative to |innerText()| for
147// performance critical operations. It does a full depth-first search so can be
148// used when the structure is not directly known. Whitesapce is trimmed from
149// text accumulated at descendant and sibling. Search is limited to within 10
150// siblings and/or descendants.
151string16 FindChildText(Element* element) {
152    Node* child = element->firstChild();
153
154    const int kChildSearchDepth = 10;
155    return FindChildTextInner(child, kChildSearchDepth);
156}
157
158// Helper for |InferLabelForElement()| that infers a label, if possible, from
159// a previous node of |element|.
160string16 InferLabelFromPrevious(const HTMLFormControlElement& element) {
161    string16 inferred_label;
162    Node* previous = element.previousSibling();
163    if (!previous)
164        return string16();
165
166    if (previous->isTextNode()) {
167        inferred_label = WTFStringToString16(previous->nodeValue());
168        TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label);
169    }
170
171    // If we didn't find text, check for previous paragraph.
172    // Eg. <p>Some Text</p><input ...>
173    // Note the lack of whitespace between <p> and <input> elements.
174    if (inferred_label.empty() && previous->isElementNode()) {
175        Element* element = static_cast<Element*>(previous);
176        if (element->hasTagName(pTag))
177            inferred_label = FindChildText(element);
178    }
179
180    // If we didn't find paragraph, check for previous paragraph to this.
181    // Eg. <p>Some Text</p>   <input ...>
182    // Note the whitespace between <p> and <input> elements.
183    if (inferred_label.empty()) {
184        Node* sibling = previous->previousSibling();
185        if (sibling && sibling->isElementNode()) {
186            Element* element = static_cast<Element*>(sibling);
187            if (element->hasTagName(pTag))
188                inferred_label = FindChildText(element);
189        }
190    }
191
192    // Look for text node prior to <img> tag.
193    // Eg. Some Text<img/><input ...>
194    if (inferred_label.empty()) {
195        while (inferred_label.empty() && previous) {
196            if (previous->isTextNode()) {
197                inferred_label = WTFStringToString16(previous->nodeValue());
198                TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label);
199            } else if (previous->isElementNode()) {
200                Element* element = static_cast<Element*>(previous);
201                if (!element->hasTagName(imgTag))
202                    break;
203            } else
204                break;
205            previous = previous->previousSibling();
206        }
207    }
208
209    // Look for label node prior to <input> tag.
210    // Eg. <label>Some Text</label><input ...>
211    if (inferred_label.empty()) {
212        while (inferred_label.empty() && previous) {
213            if (previous->isTextNode()) {
214                inferred_label = WTFStringToString16(previous->nodeValue());
215                TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label);
216            } else if (previous->isElementNode()) {
217                Element* element = static_cast<Element*>(previous);
218                if (element->hasTagName(labelTag)) {
219                    inferred_label = FindChildText(element);
220                } else {
221                    break;
222                }
223            } else {
224                break;
225            }
226
227            previous = previous->previousSibling();
228         }
229    }
230
231    return inferred_label;
232}
233
234// Helper for |InferLabelForElement()| that infers a label, if possible, from
235// surrounding table structure.
236// Eg. <tr><td>Some Text</td><td><input ...></td></tr>
237// Eg. <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr>
238string16 InferLabelFromTable(const HTMLFormControlElement& element) {
239    string16 inferred_label;
240    Node* parent = element.parentNode();
241    while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(tdTag))
242        parent = parent->parentNode();
243
244    // Check all previous siblings, skipping non-element nodes, until we find a
245    // non-empty text block.
246    Node* previous = parent;
247    while(previous) {
248        if (previous->isElementNode()) {
249            Element* e = static_cast<Element*>(previous);
250            if (e->hasTagName(tdTag)) {
251                inferred_label = FindChildText(e);
252                if (!inferred_label.empty())
253                    break;
254            }
255        }
256        previous = previous->previousSibling();
257    }
258    return inferred_label;
259}
260
261// Helper for |InferLabelForElement()| that infers a label, if possible, from
262// a surrounding div table.
263// Eg. <div>Some Text<span><input ...></span></div>
264string16 InferLabelFromDivTable(const HTMLFormControlElement& element) {
265    Node* parent = element.parentNode();
266    while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(divTag))
267        parent = parent->parentNode();
268
269    if (!parent || !parent->isElementNode())
270        return string16();
271
272    Element* e = static_cast<Element*>(parent);
273    if (!e || !e->hasTagName(divTag))
274        return string16();
275
276    return FindChildText(e);
277}
278
279// Helper for |InferLabelForElement()| that infers a label, if possible, from
280// a surrounding definition list.
281// Eg. <dl><dt>Some Text</dt><dd><input ...></dd></dl>
282// Eg. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl>
283string16 InferLabelFromDefinitionList(const HTMLFormControlElement& element) {
284    string16 inferred_label;
285    Node* parent = element.parentNode();
286    while (parent && parent->isElementNode() && !static_cast<Element*>(parent)->hasTagName(ddTag))
287        parent = parent->parentNode();
288
289    if (parent && parent->isElementNode()) {
290        Element* element = static_cast<Element*>(parent);
291        if (element->hasTagName(ddTag)) {
292            Node* previous = parent->previousSibling();
293
294            // Skip by any intervening text nodes.
295            while (previous && previous->isTextNode())
296                previous = previous->previousSibling();
297
298            if (previous && previous->isElementNode()) {
299                element = static_cast<Element*>(previous);
300                if (element->hasTagName(dtTag))
301                    inferred_label = FindChildText(element);
302            }
303        }
304    }
305    return inferred_label;
306}
307
308// Infers corresponding label for |element| from surrounding context in the DOM.
309// Contents of preceding <p> tag or preceding text element found in the form.
310string16 InferLabelForElement(const HTMLFormControlElement& element) {
311    string16 inferred_label = InferLabelFromPrevious(element);
312
313    // If we didn't find a label, check for table cell case.
314    if (inferred_label.empty())
315        inferred_label = InferLabelFromTable(element);
316
317    // If we didn't find a label, check for div table case.
318    if (inferred_label.empty())
319        inferred_label = InferLabelFromDivTable(element);
320
321    // If we didn't find a label, check for definition list case.
322    if (inferred_label.empty())
323        inferred_label = InferLabelFromDefinitionList(element);
324
325    return inferred_label;
326}
327
328void GetOptionStringsFromElement(const HTMLSelectElement& select_element, std::vector<string16>* option_strings) {
329    DCHECK(option_strings);
330    option_strings->clear();
331    WTF::Vector<Element*> list_items = select_element.listItems();
332    option_strings->reserve(list_items.size());
333    for (size_t i = 0; i < list_items.size(); ++i) {
334        if (IsOptionElement(*list_items[i])) {
335                option_strings->push_back(WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value()));
336        }
337    }
338}
339
340// Returns the form's |name| attribute if non-empty; otherwise the form's |id|
341// attribute.
342const string16 GetFormIdentifier(const HTMLFormElement& form) {
343    string16 identifier = WTFStringToString16(form.name());
344    if (identifier.empty())
345        identifier = WTFStringToString16(form.getIdAttribute());
346    return identifier;
347}
348
349}  // namespace
350
351namespace android {
352
353struct FormManager::FormElement {
354    RefPtr<HTMLFormElement> form_element;
355    std::vector<RefPtr<HTMLFormControlElement> > control_elements;
356    std::vector<string16> control_values;
357};
358
359FormManager::FormManager() {
360}
361
362FormManager::~FormManager() {
363    Reset();
364}
365
366// static
367void FormManager::HTMLFormControlElementToFormField(HTMLFormControlElement* element, ExtractMask extract_mask, FormField* field) {
368    DCHECK(field);
369    DCHECK(element);
370
371    // The label is not officially part of a HTMLFormControlElement; however, the
372    // labels for all form control elements are scraped from the DOM and set in
373    // WebFormElementToFormData.
374    field->name = nameForAutofill(*element);
375    field->form_control_type = formControlType(*element);
376
377    if (!IsAutofillableElement(*element))
378        return;
379
380    HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element);
381
382    if (IsTextInput(input_element)) {
383        field->max_length = input_element->maxLength();
384        field->is_autofilled = input_element->isAutofilled();
385    } else if (extract_mask & EXTRACT_OPTIONS) {
386        // Set option strings on the field is available.
387        DCHECK(IsSelectElement(*element));
388        HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element);
389        std::vector<string16> option_strings;
390        GetOptionStringsFromElement(*select_element, &option_strings);
391        field->option_strings = option_strings;
392    }
393
394    if (!(extract_mask & EXTRACT_VALUE))
395        return;
396
397    string16 value;
398    if (IsTextInput(input_element)) {
399        value = WTFStringToString16(input_element->value());
400    } else {
401        DCHECK(IsSelectElement(*element));
402        HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element);
403        value = WTFStringToString16(select_element->value());
404
405        // Convert the |select_element| value to text if requested.
406        if (extract_mask & EXTRACT_OPTION_TEXT) {
407            Vector<Element*> list_items = select_element->listItems();
408            for (size_t i = 0; i < list_items.size(); ++i) {
409                if (IsOptionElement(*list_items[i]) &&
410                    WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->value()) == value) {
411                    value = WTFStringToString16(static_cast<HTMLOptionElement*>(list_items[i])->text());
412                    break;
413                }
414            }
415        }
416    }
417
418    // TODO: This is a temporary stop-gap measure designed to prevent
419    // a malicious site from DOS'ing the browser with extremely large profile
420    // data.  The correct solution is to parse this data asynchronously.
421    // See http://crbug.com/49332.
422    if (value.size() > kMaxDataLength)
423        value = value.substr(0, kMaxDataLength);
424
425    field->value = value;
426}
427
428// static
429string16 FormManager::LabelForElement(const HTMLFormControlElement& element) {
430    // Don't scrape labels for elements we can't possible autofill anyway.
431    if (!IsAutofillableElement(element))
432        return string16();
433
434    RefPtr<NodeList> labels = element.document()->getElementsByTagName("label");
435    for (unsigned i = 0; i < labels->length(); ++i) {
436        Node* e = labels->item(i);
437        DCHECK(e->hasTagName(labelTag));
438        HTMLLabelElement* label = static_cast<HTMLLabelElement*>(e);
439        if (label->control() == &element)
440            return FindChildText(label);
441    }
442
443    // Infer the label from context if not found in label element.
444    return InferLabelForElement(element);
445}
446
447// static
448bool FormManager::HTMLFormElementToFormData(HTMLFormElement* element, RequirementsMask requirements, ExtractMask extract_mask, FormData* form) {
449    DCHECK(form);
450
451    Frame* frame = element->document()->frame();
452    if (!frame)
453        return false;
454
455    if (requirements & REQUIRE_AUTOCOMPLETE && !element->autoComplete())
456        return false;
457
458    form->name = GetFormIdentifier(*element);
459    form->method = WTFStringToString16(element->method());
460    form->origin = GURL(WTFStringToString16(frame->loader()->documentLoader()->url().string()));
461    form->action = GURL(WTFStringToString16(frame->document()->completeURL(element->action())));
462    form->user_submitted = element->wasUserSubmitted();
463
464    // If the completed URL is not valid, just use the action we get from
465    // WebKit.
466    if (!form->action.is_valid())
467        form->action = GURL(WTFStringToString16(element->action()));
468
469    // A map from a FormField's name to the FormField itself.
470    std::map<string16, FormField*> name_map;
471
472    // The extracted FormFields.  We use pointers so we can store them in
473    // |name_map|.
474    ScopedVector<FormField> form_fields;
475
476    WTF::Vector<WebCore::FormAssociatedElement*> control_elements = element->associatedElements();
477
478    // A vector of bools that indicate whether each field in the form meets the
479    // requirements and thus will be in the resulting |form|.
480    std::vector<bool> fields_extracted(control_elements.size(), false);
481
482    for (size_t i = 0; i < control_elements.size(); ++i) {
483        if (!control_elements[i]->isFormControlElement())
484            continue;
485
486        HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]);
487
488        if(!IsAutofillableElement(*control_element))
489            continue;
490
491        HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*control_element);
492        if (requirements & REQUIRE_AUTOCOMPLETE && IsTextInput(input_element) &&
493                !input_element->autoComplete())
494                continue;
495
496        if (requirements & REQUIRE_ENABLED && !control_element->isEnabledFormControl())
497            continue;
498
499        // Create a new FormField, fill it out and map it to the field's name.
500        FormField* field = new FormField;
501        HTMLFormControlElementToFormField(control_element, extract_mask, field);
502        form_fields.push_back(field);
503        // TODO: A label element is mapped to a form control element's id.
504        // field->name() will contain the id only if the name does not exist.  Add
505        // an id() method to HTMLFormControlElement and use that here.
506        name_map[field->name] = field;
507        fields_extracted[i] = true;
508    }
509
510    // Don't extract field labels if we have no fields.
511    if (form_fields.empty())
512        return false;
513
514    // Loop through the label elements inside the form element.  For each label
515    // element, get the corresponding form control element, use the form control
516    // element's name as a key into the <name, FormField> map to find the
517    // previously created FormField and set the FormField's label to the
518    // label.firstChild().nodeValue() of the label element.
519    RefPtr<WebCore::NodeList> labels = element->getElementsByTagName("label");
520    for (unsigned i = 0; i < labels->length(); ++i) {
521        HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(labels->item(i));
522        HTMLFormControlElement* field_element = label->control();
523        if (!field_element || field_element->type() == "hidden")
524            continue;
525
526        std::map<string16, FormField*>::iterator iter =
527            name_map.find(nameForAutofill(*field_element));
528        // Concatenate labels because some sites might have multiple label
529        // candidates.
530        if (iter != name_map.end())
531            iter->second->label += FindChildText(label);
532    }
533
534    // Loop through the form control elements, extracting the label text from the
535    // DOM.  We use the |fields_extracted| vector to make sure we assign the
536    // extracted label to the correct field, as it's possible |form_fields| will
537    // not contain all of the elements in |control_elements|.
538    for (size_t i = 0, field_idx = 0; i < control_elements.size() && field_idx < form_fields.size(); ++i) {
539        // This field didn't meet the requirements, so don't try to find a label for
540        // it.
541        if (!fields_extracted[i])
542            continue;
543
544        if (!control_elements[i]->isFormControlElement())
545            continue;
546
547        const HTMLFormControlElement* control_element = static_cast<HTMLFormControlElement*>(control_elements[i]);
548        if (form_fields[field_idx]->label.empty())
549            form_fields[field_idx]->label = InferLabelForElement(*control_element);
550
551        ++field_idx;
552
553    }
554    // Copy the created FormFields into the resulting FormData object.
555    for (ScopedVector<FormField>::const_iterator iter = form_fields.begin(); iter != form_fields.end(); ++iter)
556        form->fields.push_back(**iter);
557
558    return true;
559}
560
561void FormManager::ExtractForms(Frame* frame) {
562
563    ResetFrame(frame);
564
565    WTF::RefPtr<HTMLCollection> web_forms = frame->document()->forms();
566
567    for (size_t i = 0; i < web_forms->length(); ++i) {
568        // Owned by |form_elements|.
569        FormElement* form_element = new FormElement;
570        HTMLFormElement* html_form_element = static_cast<HTMLFormElement*>(web_forms->item(i));
571        form_element->form_element = html_form_element;
572
573        WTF::Vector<FormAssociatedElement*> control_elements = html_form_element->associatedElements();
574        for (size_t j = 0; j < control_elements.size(); ++j) {
575            if (!control_elements[j]->isFormControlElement())
576                continue;
577
578            HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(control_elements[j]);
579
580            if (!IsAutofillableElement(*element))
581                continue;
582
583            form_element->control_elements.push_back(element);
584
585            // Save original values of <select> elements so we can restore them
586            // when |ClearFormWithNode()| is invoked.
587            if (IsSelectElement(*element)) {
588                HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element);
589                form_element->control_values.push_back(WTFStringToString16(select_element->value()));
590            } else
591                form_element->control_values.push_back(string16());
592        }
593
594        form_elements_.push_back(form_element);
595    }
596}
597
598void FormManager::GetFormsInFrame(const Frame* frame, RequirementsMask requirements, std::vector<FormData>* forms) {
599    DCHECK(frame);
600    DCHECK(forms);
601
602    size_t num_fields_seen = 0;
603    for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) {
604        FormElement* form_element = *form_iter;
605
606        if (form_element->form_element->document()->frame() != frame)
607            continue;
608
609        // To avoid overly expensive computation, we impose both a minimum and a
610        // maximum number of allowable fields.
611        if (form_element->control_elements.size() < kRequiredAutofillFields ||
612            form_element->control_elements.size() > kMaxParseableFields)
613            continue;
614
615        if (requirements & REQUIRE_AUTOCOMPLETE && !form_element->form_element->autoComplete())
616            continue;
617
618        FormData form;
619        HTMLFormElementToFormData(form_element->form_element.get(), requirements, EXTRACT_VALUE, &form);
620
621        num_fields_seen += form.fields.size();
622        if (num_fields_seen > kMaxParseableFields)
623            break;
624
625        if (form.fields.size() >= kRequiredAutofillFields)
626            forms->push_back(form);
627    }
628}
629
630bool FormManager::FindFormWithFormControlElement(HTMLFormControlElement* element, RequirementsMask requirements, FormData* form) {
631    DCHECK(form);
632
633    const Frame* frame = element->document()->frame();
634    if (!frame)
635        return false;
636
637    for (FormElementList::const_iterator iter = form_elements_.begin(); iter != form_elements_.end(); ++iter) {
638        const FormElement* form_element = *iter;
639
640        if (form_element->form_element->document()->frame() != frame)
641            continue;
642
643        for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = form_element->control_elements.begin(); iter != form_element->control_elements.end(); ++iter) {
644            HTMLFormControlElement* candidate = iter->get();
645            if (nameForAutofill(*candidate) == nameForAutofill(*element)) {
646                ExtractMask extract_mask = static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
647                return HTMLFormElementToFormData(form_element->form_element.get(), requirements, extract_mask, form);
648            }
649        }
650    }
651    return false;
652}
653
654bool FormManager::FillForm(const FormData& form, Node* node) {
655    FormElement* form_element = NULL;
656    if (!FindCachedFormElement(form, &form_element))
657        return false;
658
659    RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY);
660    ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::FillFormField));
661
662    return true;
663}
664
665bool FormManager::PreviewForm(const FormData& form, Node* node) {
666    FormElement* form_element = NULL;
667    if (!FindCachedFormElement(form, &form_element))
668        return false;
669
670    RequirementsMask requirements = static_cast<RequirementsMask>(REQUIRE_AUTOCOMPLETE | REQUIRE_ENABLED | REQUIRE_EMPTY);
671    ForEachMatchingFormField(form_element, node, requirements, form, NewCallback(this, &FormManager::PreviewFormField));
672
673    return true;
674}
675
676bool FormManager::ClearFormWithNode(Node* node) {
677    FormElement* form_element = NULL;
678    if (!FindCachedFormElementWithNode(node, &form_element))
679        return false;
680
681    for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
682        HTMLFormControlElement* element = form_element->control_elements[i].get();
683        HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element);
684        if (IsTextInput(input_element)) {
685
686            // We don't modify the value of disabled fields.
687            if (!input_element->isEnabledFormControl())
688                continue;
689
690            input_element->setValue("");
691            input_element->setAutofilled(false);
692             // Clearing the value in the focused node (above) can cause selection
693             // to be lost. We force selection range to restore the text cursor.
694             if (node == input_element) {
695                 int length = input_element->value().length();
696                 input_element->setSelectionRange(length, length);
697             }
698        } else {
699            DCHECK(IsSelectElement(*element));
700            HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(element);
701            if (WTFStringToString16(select_element->value()) != form_element->control_values[i]) {
702                select_element->setValue(form_element->control_values[i].c_str());
703                select_element->dispatchFormControlChangeEvent();
704            }
705        }
706    }
707
708    return true;
709}
710
711bool FormManager::ClearPreviewedFormWithNode(Node* node, bool was_autofilled) {
712    FormElement* form_element = NULL;
713    if (!FindCachedFormElementWithNode(node, &form_element))
714        return false;
715
716    for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
717        HTMLFormControlElement* element = form_element->control_elements[i].get();
718        HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element);
719
720        // Only input elements can be previewed.
721        if (!IsTextInput(input_element))
722            continue;
723
724        // If the input element has not been auto-filled, FormManager has not
725        // previewed this field, so we have nothing to reset.
726        if (!input_element->isAutofilled())
727            continue;
728
729        // There might be unrelated elements in this form which have already been
730        // auto-filled. For example, the user might have already filled the address
731        // part of a form and now be dealing with the credit card section. We only
732        // want to reset the auto-filled status for fields that were previewed.
733        if (input_element->suggestedValue().isEmpty())
734            continue;
735
736        // Clear the suggested value. For the initiating node, also restore the
737        // original value.
738        input_element->setSuggestedValue("");
739        bool is_initiating_node = (node == input_element);
740        if (is_initiating_node) {
741            input_element->setAutofilled(was_autofilled);
742        } else {
743            input_element->setAutofilled(false);
744        }
745
746        // Clearing the suggested value in the focused node (above) can cause
747        // selection to be lost. We force selection range to restore the text
748        // cursor.
749        if (is_initiating_node) {
750            int length = input_element->value().length();
751            input_element->setSelectionRange(length, length);
752        }
753    }
754
755    return true;
756}
757
758void FormManager::Reset() {
759    form_elements_.reset();
760}
761
762void FormManager::ResetFrame(const Frame* frame) {
763    FormElementList::iterator iter = form_elements_.begin();
764    while (iter != form_elements_.end()) {
765        if ((*iter)->form_element->document()->frame() == frame)
766            iter = form_elements_.erase(iter);
767        else
768            ++iter;
769    }
770}
771
772bool FormManager::FormWithNodeIsAutofilled(Node* node) {
773    FormElement* form_element = NULL;
774    if (!FindCachedFormElementWithNode(node, &form_element))
775        return false;
776
777    for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
778        HTMLFormControlElement* element = form_element->control_elements[i].get();
779        HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element);
780        if (!IsTextInput(input_element))
781            continue;
782
783        if (input_element->isAutofilled())
784            return true;
785    }
786
787    return false;
788}
789
790bool FormManager::FindCachedFormElementWithNode(Node* node, FormElement** form_element) {
791    for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) {
792        for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = (*form_iter)->control_elements.begin(); iter != (*form_iter)->control_elements.end(); ++iter) {
793            if (iter->get() == node) {
794                *form_element = *form_iter;
795                return true;
796            }
797        }
798    }
799
800    return false;
801}
802
803bool FormManager::FindCachedFormElement(const FormData& form, FormElement** form_element) {
804    for (FormElementList::iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) {
805        // TODO: matching on form name here which is not guaranteed to
806        // be unique for the page, nor is it guaranteed to be non-empty.  Need to
807        // find a way to uniquely identify the form cross-process.  For now we'll
808        // check form name and form action for identity.
809        // http://crbug.com/37990 test file sample8.html.
810        // Also note that WebString() == WebString(string16()) does not evaluate to
811        // |true| -- WebKit distinguisges between a "null" string (lhs) and an
812        // "empty" string (rhs). We don't want that distinction, so forcing to
813        // string16.
814        string16 element_name = GetFormIdentifier(*(*form_iter)->form_element);
815        GURL action(WTFStringToString16((*form_iter)->form_element->document()->completeURL((*form_iter)->form_element->action()).string()));
816        if (element_name == form.name && action == form.action) {
817            *form_element = *form_iter;
818            return true;
819        }
820    }
821
822    return false;
823}
824
825
826void FormManager::ForEachMatchingFormField(FormElement* form, Node* node, RequirementsMask requirements, const FormData& data, Callback* callback) {
827    // It's possible that the site has injected fields into the form after the
828    // page has loaded, so we can't assert that the size of the cached control
829    // elements is equal to the size of the fields in |form|.  Fortunately, the
830    // one case in the wild where this happens, paypal.com signup form, the fields
831    // are appended to the end of the form and are not visible.
832    for (size_t i = 0, j = 0; i < form->control_elements.size() && j < data.fields.size(); ++i) {
833        HTMLFormControlElement* element = form->control_elements[i].get();
834        string16 element_name = nameForAutofill(*element);
835
836        // Search forward in the |form| for a corresponding field.
837        size_t k = j;
838        while (k < data.fields.size() && element_name != data.fields[k].name)
839               k++;
840
841        if (k >= data.fields.size())
842            continue;
843
844        DCHECK_EQ(data.fields[k].name, element_name);
845
846        bool is_initiating_node = false;
847
848        HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*element);
849        if (IsTextInput(input_element)) {
850            // TODO: WebKit currently doesn't handle the autocomplete
851            // attribute for select control elements, but it probably should.
852            if (!input_element->autoComplete())
853                continue;
854
855            is_initiating_node = (input_element == node);
856
857            // Only autofill empty fields and the firls that initiated the filling,
858            // i.e. the field the user is currently editing and interacting with.
859            if (!is_initiating_node && !input_element->value().isEmpty())
860               continue;
861        }
862
863        if (!element->isEnabledFormControl() || element->isReadOnlyFormControl() || !element->isFocusable())
864            continue;
865
866        callback->Run(element, &data.fields[k], is_initiating_node);
867
868        // We found a matching form field so move on to the next.
869        ++j;
870    }
871
872    delete callback;
873}
874
875void FormManager::FillFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) {
876    // Nothing to fill.
877    if (data->value.empty())
878        return;
879
880    HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*field);
881
882    if (IsTextInput(input_element)) {
883        // If the maxlength attribute contains a negative value, maxLength()
884        // returns the default maxlength value.
885        input_element->setValue(data->value.substr(0, input_element->maxLength()).c_str(), true);
886        input_element->setAutofilled(true);
887        if (is_initiating_node) {
888            int length = input_element->value().length();
889            input_element->setSelectionRange(length, length);
890        }
891    } else {
892        DCHECK(IsSelectElement(*field));
893        HTMLSelectElement* select_element = static_cast<HTMLSelectElement*>(field);
894        if (WTFStringToString16(select_element->value()) != data->value) {
895            select_element->setValue(data->value.c_str());
896            select_element->dispatchFormControlChangeEvent();
897        }
898    }
899}
900
901void FormManager::PreviewFormField(HTMLFormControlElement* field, const FormField* data, bool is_initiating_node) {
902    // Nothing to preview.
903    if (data->value.empty())
904        return;
905
906    // Only preview input fields.
907    HTMLInputElement* input_element = HTMLFormControlElementToHTMLInputElement(*field);
908    if (!IsTextInput(input_element))
909        return;
910
911    // If the maxlength attribute contains a negative value, maxLength()
912    // returns the default maxlength value.
913    input_element->setSuggestedValue(data->value.substr(0, input_element->maxLength()).c_str());
914    input_element->setAutofilled(true);
915    if (is_initiating_node) {
916        // Select the part of the text that the user didn't type.
917        input_element->setSelectionRange(input_element->value().length(), input_element->suggestedValue().length());
918    }
919}
920
921}
922