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