bool CredentialTransformData::findPasswordFormFields(HTMLFormElement* form) { ASSERT(form); int firstPasswordIndex = 0; // First, find the password fields and activated submit button. const Vector<FormAssociatedElement*>& formElements = form->associatedElements(); Vector<HTMLInputElement*> passwords; for (size_t i = 0; i < formElements.size(); i++) { if (!formElements[i]->isFormControlElement()) continue; HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]); if (!formElement->hasLocalName(HTMLNames::inputTag)) continue; HTMLInputElement* inputElement = formElement->toInputElement(); if (!inputElement->isEnabledFormControl()) continue; if ((passwords.size() < maxPasswords) && inputElement->isPasswordField() && inputElement->shouldAutocomplete()) { if (passwords.isEmpty()) firstPasswordIndex = i; passwords.append(inputElement); } } if (!passwords.isEmpty()) { // Then, search backwards for the username field. for (int i = firstPasswordIndex - 1; i >= 0; i--) { if (!formElements[i]->isFormControlElement()) continue; HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]); if (!formElement->hasLocalName(HTMLNames::inputTag)) continue; HTMLInputElement* inputElement = formElement->toInputElement(); if (!inputElement->isEnabledFormControl()) continue; // Various input types such as text, url, email can be a username field. if ((inputElement->isTextField() && !inputElement->isPasswordField()) && (inputElement->shouldAutocomplete())) { m_userNameElement = inputElement; break; } } } if (!m_userNameElement) return false; if (!locateSpecificPasswords(passwords, &(m_passwordElement))) return false; return true; }