void findPasswordFormFields(HTMLFormElement* form, PasswordFormFields* fields) { ASSERT(form); ASSERT(fields); HTMLInputElement* latestInputElement = 0; const Vector<FormAssociatedElement*>& formElements = form->associatedElements(); for (size_t i = 0; i < formElements.size(); i++) { if (!formElements[i]->isFormControlElement()) continue; HTMLFormControlElement* control = toHTMLFormControlElement(formElements[i]); if (control->isActivatedSubmit()) fields->submit = control; if (!control->hasTagName(HTMLNames::inputTag)) continue; HTMLInputElement* inputElement = toHTMLInputElement(control); if (inputElement->isDisabledFormControl()) continue; if ((fields->passwords.size() < maxPasswords) && inputElement->isPasswordField()) { // We assume that the username is the input element before the // first password element. if (fields->passwords.isEmpty() && latestInputElement) { fields->userName = latestInputElement; // Remove the selected username from alternateUserNames. if (!fields->alternateUserNames.isEmpty() && !latestInputElement->value().isEmpty()) fields->alternateUserNames.removeLast(); } fields->passwords.append(inputElement); } // Various input types such as text, url, email can be a username field. if (inputElement->isTextField() && !inputElement->isPasswordField()) { latestInputElement = inputElement; // We ignore elements that have no value. Unlike userName, alternateUserNames // is used only for autofill, not for form identification, and blank autofill // entries are not useful. if (!inputElement->value().isEmpty()) fields->alternateUserNames.append(inputElement->value()); } } }