EventStates HTMLButtonElement::IntrinsicState() const { EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState(); if (IsCandidateForConstraintValidation()) { if (IsValid()) { state |= NS_EVENT_STATE_VALID; if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) { state |= NS_EVENT_STATE_MOZ_UI_VALID; } } else { state |= NS_EVENT_STATE_INVALID; if (!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) { state |= NS_EVENT_STATE_MOZ_UI_INVALID; } } } if (mForm && !mForm->GetValidity() && IsSubmitControl()) { state |= NS_EVENT_STATE_MOZ_SUBMITINVALID; } return state; }
EventStates HTMLTextAreaElement::IntrinsicState() const { EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState(); if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) { state |= NS_EVENT_STATE_REQUIRED; } else { state |= NS_EVENT_STATE_OPTIONAL; } if (IsCandidateForConstraintValidation()) { if (IsValid()) { state |= NS_EVENT_STATE_VALID; } else { state |= NS_EVENT_STATE_INVALID; // :-moz-ui-invalid always apply if the element suffers from a custom // error and never applies if novalidate is set on the form owner. if ((!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) && (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR) || (mCanShowInvalidUI && ShouldShowValidityUI()))) { state |= NS_EVENT_STATE_MOZ_UI_INVALID; } } // :-moz-ui-valid applies if all the following are true: // 1. The element is not focused, or had either :-moz-ui-valid or // :-moz-ui-invalid applying before it was focused ; // 2. The element is either valid or isn't allowed to have // :-moz-ui-invalid applying ; // 3. The element has no form owner or its form owner doesn't have the // novalidate attribute set ; // 4. The element has already been modified or the user tried to submit the // form owner while invalid. if ((!mForm || !mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate)) && (mCanShowValidUI && ShouldShowValidityUI() && (IsValid() || (state.HasState(NS_EVENT_STATE_MOZ_UI_INVALID) && !mCanShowInvalidUI)))) { state |= NS_EVENT_STATE_MOZ_UI_VALID; } } if (HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder) && IsValueEmpty()) { state |= NS_EVENT_STATE_PLACEHOLDERSHOWN; } return state; }
bool nsIConstraintValidation::CheckValidity() { if (!IsCandidateForConstraintValidation() || IsValid()) { return true; } nsCOMPtr<nsIContent> content = do_QueryInterface(this); NS_ASSERTION(content, "This class should be inherited by HTML elements only!"); nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, NS_LITERAL_STRING("invalid"), false, true); return false; }
NS_IMETHODIMP nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage) { aValidationMessage.Truncate(); if (IsCandidateForConstraintValidation() && !IsValid()) { nsCOMPtr<nsIContent> content = do_QueryInterface(this); NS_ASSERTION(content, "This class should be inherited by HTML elements only!"); nsAutoString authorMessage; content->GetAttr(kNameSpaceID_None, nsGkAtoms::x_moz_errormessage, authorMessage); if (!authorMessage.IsEmpty()) { aValidationMessage.Assign(authorMessage); if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) { aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage); } } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) { aValidationMessage.Assign(mCustomValidity); if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) { aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage); } } else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG); } else if (GetValidityState(VALIDITY_STATE_VALUE_MISSING)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_VALUE_MISSING); } else if (GetValidityState(VALIDITY_STATE_TYPE_MISMATCH)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_TYPE_MISMATCH); } else if (GetValidityState(VALIDITY_STATE_PATTERN_MISMATCH)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_PATTERN_MISMATCH); } else if (GetValidityState(VALIDITY_STATE_RANGE_OVERFLOW)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_RANGE_OVERFLOW); } else if (GetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_RANGE_UNDERFLOW); } else if (GetValidityState(VALIDITY_STATE_STEP_MISMATCH)) { GetValidationMessage(aValidationMessage, VALIDITY_STATE_STEP_MISMATCH); } else { // There should not be other validity states. return NS_ERROR_UNEXPECTED; } } else { aValidationMessage.Truncate(); } return NS_OK; }
void nsIConstraintValidation::SetValidityState(ValidityStateType aState, bool aValue) { bool previousValidity = IsValid(); if (aValue) { mValidityBitField |= aState; } else { mValidityBitField &= ~aState; } // Inform the form element if our validity has changed. if (previousValidity != IsValid() && IsCandidateForConstraintValidation()) { nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this); NS_ASSERTION(formCtrl, "This interface should be used by form elements!"); nsHTMLFormElement* form = static_cast<nsHTMLFormElement*>(formCtrl->GetFormElement()); if (form) { form->UpdateValidity(IsValid()); } } }