1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/* ***** BEGIN LICENSE BLOCK *****
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Version: MPL 1.1/GPL 2.0/LGPL 2.1
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* The contents of this file are subject to the Mozilla Public License Version
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* 1.1 (the "License"); you may not use this file except in compliance with
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* the License. You may obtain a copy of the License at
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* http://www.mozilla.org/MPL/
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Software distributed under the License is distributed on an "AS IS" basis,
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* for the specific language governing rights and limitations under the
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* License.
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* The Original Code is Mozilla Password Manager.
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* The Initial Developer of the Original Code is
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Brian Ryner.
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Portions created by the Initial Developer are Copyright (C) 2003
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* the Initial Developer. All Rights Reserved.
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Contributor(s):
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*  Brian Ryner <bryner@brianryner.com>
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* Alternatively, the contents of this file may be used under the terms of
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* either the GNU General Public License Version 2 or later (the "GPL"), or
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* in which case the provisions of the GPL or the LGPL are applicable instead
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* of those above. If you wish to allow use of your version of this file only
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* under the terms of either the GPL or the LGPL, and not to allow others to
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* use your version of this file under the terms of the MPL, indicate your
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* decision by deleting the provisions above and replace them with the notice
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* and other provisions required by the GPL or the LGPL. If you do not delete
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* the provisions above, a recipient may use your version of this file under
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* the terms of any one of the MPL, the GPL or the LGPL.
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block*
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block* ***** END LICENSE BLOCK ***** */
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Helper to WebPasswordFormData to do the locating of username/password
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// fields.
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// This method based on Firefox2 code in
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block//   toolkit/components/passwordmgr/base/nsPasswordManager.cpp
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebPasswordFormUtils.h"
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLFormElement.h"
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLInputElement.h"
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "HTMLNames.h"
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "KURL.h"
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "DOMUtilitiesPrivate.h"
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore;
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebKit {
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Maximum number of password fields we will observe before throwing our
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// hands in the air and giving up with a given form.
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const size_t maxPasswords = 3;
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid findPasswordFormFields(HTMLFormElement* form, PasswordFormFields* fields)
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(form);
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(fields);
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int firstPasswordIndex = 0;
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // First, find the password fields and activated submit button
68f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    const Vector<FormAssociatedElement*>& formElements = form->associatedElements();
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for (size_t i = 0; i < formElements.size(); i++) {
70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!formElements[i]->isFormControlElement())
71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            continue;
72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]);
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (formElement->isActivatedSubmit())
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            fields->submit = formElement;
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!formElement->hasLocalName(HTMLNames::inputTag))
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            continue;
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        HTMLInputElement* inputElement = toHTMLInputElement(formElement);
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!inputElement->isEnabledFormControl())
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            continue;
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if ((fields->passwords.size() < maxPasswords)
8468513a70bcd92384395513322f1b801e7bf9c729Steve Block            && inputElement->isPasswordField()
8568513a70bcd92384395513322f1b801e7bf9c729Steve Block            && inputElement->autoComplete()) {
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (fields->passwords.isEmpty())
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                firstPasswordIndex = i;
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            fields->passwords.append(inputElement);
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!fields->passwords.isEmpty()) {
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Then, search backwards for the username field
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (int i = firstPasswordIndex - 1; i >= 0; i--) {
95f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!formElements[i]->isFormControlElement())
96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                continue;
97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]);
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!formElement->hasLocalName(HTMLNames::inputTag))
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                continue;
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            HTMLInputElement* inputElement = toHTMLInputElement(formElement);
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!inputElement->isEnabledFormControl())
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                continue;
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            // Various input types such as text, url, email can be a username field.
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if ((inputElement->isTextField() && !inputElement->isPasswordField())
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                && (inputElement->autoComplete())) {
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                fields->userName = inputElement;
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                break;
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebKit
116