mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-02 08:41:34 +00:00
#425: M1385478 IsRequired()
This commit is contained in:
parent
faa6eb4c0c
commit
71abc4edc1
|
@ -8382,7 +8382,11 @@ nsDocument::AddToRadioGroup(const nsAString& aName,
|
|||
|
||||
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
|
||||
NS_ASSERTION(element, "radio controls have to be content elements");
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
|
||||
HTMLInputElement* input = HTMLInputElement::FromContent(element);
|
||||
NS_ASSERTION(input, "radio controls have to be input elements!");
|
||||
|
||||
if (input->IsRequired()) {
|
||||
radioGroup->mRequiredRadioCount++;
|
||||
}
|
||||
}
|
||||
|
@ -8396,7 +8400,11 @@ nsDocument::RemoveFromRadioGroup(const nsAString& aName,
|
|||
|
||||
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
|
||||
NS_ASSERTION(element, "radio controls have to be content elements");
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
|
||||
HTMLInputElement* input = HTMLInputElement::FromContent(element);
|
||||
NS_ASSERTION(input, "radio controls have to be input elements!");
|
||||
|
||||
if (input->IsRequired()) {
|
||||
NS_ASSERTION(radioGroup->mRequiredRadioCount != 0,
|
||||
"mRequiredRadioCount about to wrap below 0!");
|
||||
radioGroup->mRequiredRadioCount--;
|
||||
|
|
|
@ -278,11 +278,13 @@ private:
|
|||
|
||||
#define DISABLED_STATES (NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED)
|
||||
|
||||
#define REQUIRED_STATES (NS_EVENT_STATE_REQUIRED | NS_EVENT_STATE_OPTIONAL)
|
||||
|
||||
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
|
||||
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
|
||||
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
|
||||
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | \
|
||||
DISABLED_STATES | \
|
||||
DISABLED_STATES | REQUIRED_STATES | \
|
||||
NS_EVENT_STATE_UNRESOLVED)
|
||||
|
||||
#define INTRINSIC_STATES (~ESM_MANAGED_STATES)
|
||||
|
|
|
@ -2296,7 +2296,10 @@ HTMLFormElement::AddToRadioGroup(const nsAString& aName,
|
|||
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
|
||||
NS_ASSERTION(element, "radio controls have to be content elements!");
|
||||
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
HTMLInputElement* input = HTMLInputElement::FromContent(element);
|
||||
NS_ASSERTION(input, "radio controls have to be input elements!");
|
||||
|
||||
if (input->IsRequired()) {
|
||||
mRequiredRadioButtonCounts.Put(aName,
|
||||
mRequiredRadioButtonCounts.Get(aName)+1);
|
||||
}
|
||||
|
@ -2307,9 +2310,12 @@ HTMLFormElement::RemoveFromRadioGroup(const nsAString& aName,
|
|||
nsIFormControl* aRadio)
|
||||
{
|
||||
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
|
||||
NS_ASSERTION(element, "radio controls have to be content elements!");
|
||||
NS_ASSERTION(element, "radio controls have to be content elements");
|
||||
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
HTMLInputElement* input = HTMLInputElement::FromContent(element);
|
||||
NS_ASSERTION(input, "radio controls have to be input elements!");
|
||||
|
||||
if (input->IsRequired()) {
|
||||
uint32_t requiredNb = mRequiredRadioButtonCounts.Get(aName);
|
||||
NS_ASSERTION(requiredNb >= 1,
|
||||
"At least one radio button has to be required!");
|
||||
|
|
|
@ -1149,6 +1149,13 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::required && DoesRequiredApply()) {
|
||||
// This *has* to be called *before* UpdateValueMissingValidityState
|
||||
// because UpdateValueMissingValidityState depends on our required
|
||||
// state.
|
||||
UpdateRequiredState(!!aValue, aNotify);
|
||||
}
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
|
@ -4371,6 +4378,15 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType)
|
|||
mFocusedValue.Truncate();
|
||||
}
|
||||
|
||||
// Update or clear our required states since we may have changed from a
|
||||
// required input type to a non-required input type or viceversa.
|
||||
if (DoesRequiredApply()) {
|
||||
bool isRequired = HasAttr(kNameSpaceID_None, nsGkAtoms::required);
|
||||
UpdateRequiredState(isRequired, false); // See below for why this is OK.
|
||||
} else {
|
||||
RemoveStatesSilently(REQUIRED_STATES);
|
||||
}
|
||||
|
||||
UpdateHasRange();
|
||||
|
||||
// Do not notify, it will be done after if needed.
|
||||
|
@ -5757,12 +5773,6 @@ HTMLInputElement::IntrinsicState() const
|
|||
state |= nsImageLoadingContent::ImageState();
|
||||
}
|
||||
|
||||
if (DoesRequiredApply() && 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;
|
||||
|
@ -6369,8 +6379,7 @@ HTMLInputElement::IsValueMissing() const
|
|||
// Should use UpdateValueMissingValidityStateForRadio() for type radio.
|
||||
MOZ_ASSERT(mType != NS_FORM_INPUT_RADIO);
|
||||
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) ||
|
||||
!DoesRequiredApply()) {
|
||||
if (!IsRequired() || !DoesRequiredApply()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -6635,7 +6644,7 @@ HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
|||
// If there is no selection, that might mean the radio is not in a group.
|
||||
// In that case, we can look for the checked state of the radio.
|
||||
bool selected = selection || (!aIgnoreSelf && mChecked);
|
||||
bool required = !aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required);
|
||||
bool required = !aIgnoreSelf && IsRequired();
|
||||
bool valueMissing = false;
|
||||
|
||||
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
||||
|
@ -6652,7 +6661,7 @@ HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
|||
// If the current radio is required and not ignored, we can assume the entire
|
||||
// group is required.
|
||||
if (!required) {
|
||||
required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
|
||||
required = (aIgnoreSelf && IsRequired())
|
||||
? container->GetRequiredRadioCount(name) - 1
|
||||
: container->GetRequiredRadioCount(name);
|
||||
}
|
||||
|
|
|
@ -774,6 +774,22 @@ public:
|
|||
*/
|
||||
static Decimal StringToDecimal(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* Returns if the required attribute applies for the current type.
|
||||
*/
|
||||
bool DoesRequiredApply() const;
|
||||
|
||||
/**
|
||||
* Returns the current required state of the element. This function differs
|
||||
* from Required() in that this function only returns true for input types
|
||||
* that @required attribute applies and the attribute is set; in contrast,
|
||||
* Required() returns true whenever @required attribute is set.
|
||||
*/
|
||||
bool IsRequired() const
|
||||
{
|
||||
return State().HasState(NS_EVENT_STATE_REQUIRED);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~HTMLInputElement();
|
||||
|
||||
|
@ -964,11 +980,6 @@ protected:
|
|||
*/
|
||||
bool DoesReadOnlyApply() const;
|
||||
|
||||
/**
|
||||
* Returns if the required attribute applies for the current type.
|
||||
*/
|
||||
bool DoesRequiredApply() const;
|
||||
|
||||
/**
|
||||
* Returns if the pattern attribute applies for the current type.
|
||||
*/
|
||||
|
|
|
@ -1070,7 +1070,7 @@ HTMLSelectElement::IsOptionDisabled(int32_t aIndex, bool* aIsDisabled)
|
|||
}
|
||||
|
||||
bool
|
||||
HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption)
|
||||
HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption) const
|
||||
{
|
||||
MOZ_ASSERT(aOption);
|
||||
if (aOption->Disabled()) {
|
||||
|
@ -1301,6 +1301,11 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateValueMissingValidityState();
|
||||
UpdateBarredFromConstraintValidation();
|
||||
} else if (aName == nsGkAtoms::required) {
|
||||
// This *has* to be called *before* UpdateValueMissingValidityState
|
||||
// because UpdateValueMissingValidityState depends on our required
|
||||
// state.
|
||||
UpdateRequiredState(!!aValue, aNotify);
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
} else if (aName == nsGkAtoms::autocomplete) {
|
||||
// Clear the cached @autocomplete attribute state
|
||||
|
@ -1523,12 +1528,6 @@ HTMLSelectElement::IntrinsicState() const
|
|||
}
|
||||
}
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
|
||||
state |= NS_EVENT_STATE_REQUIRED;
|
||||
} else {
|
||||
state |= NS_EVENT_STATE_OPTIONAL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -1771,7 +1770,7 @@ HTMLSelectElement::RebuildOptionsArray(bool aNotify)
|
|||
}
|
||||
|
||||
bool
|
||||
HTMLSelectElement::IsValueMissing()
|
||||
HTMLSelectElement::IsValueMissing() const
|
||||
{
|
||||
if (!Required()) {
|
||||
return false;
|
||||
|
|
|
@ -198,7 +198,7 @@ public:
|
|||
}
|
||||
bool Required() const
|
||||
{
|
||||
return GetBoolAttr(nsGkAtoms::required);
|
||||
return State().HasState(NS_EVENT_STATE_REQUIRED);
|
||||
}
|
||||
void SetRequired(bool aVal, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -332,7 +332,7 @@ public:
|
|||
*/
|
||||
NS_IMETHOD IsOptionDisabled(int32_t aIndex,
|
||||
bool* aIsDisabled);
|
||||
bool IsOptionDisabled(HTMLOptionElement* aOption);
|
||||
bool IsOptionDisabled(HTMLOptionElement* aOption) const;
|
||||
|
||||
/**
|
||||
* Sets multiple options (or just sets startIndex if select is single)
|
||||
|
@ -505,7 +505,7 @@ protected:
|
|||
|
||||
// nsIConstraintValidation
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
bool IsValueMissing();
|
||||
bool IsValueMissing() const;
|
||||
|
||||
/**
|
||||
* Get the index of the first option at, under or following the content in
|
||||
|
|
|
@ -1136,12 +1136,6 @@ 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;
|
||||
|
@ -1286,6 +1280,13 @@ HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
UpdateDisabledState(aNotify);
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::required) {
|
||||
// This *has* to be called *before* UpdateValueMissingValidityState
|
||||
// because UpdateValueMissingValidityState depends on our required
|
||||
// state.
|
||||
UpdateRequiredState(!!aValue, aNotify);
|
||||
}
|
||||
|
||||
UpdateValueMissingValidityState();
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
|
@ -1368,7 +1369,7 @@ HTMLTextAreaElement::IsTooLong()
|
|||
bool
|
||||
HTMLTextAreaElement::IsValueMissing() const
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) || !IsMutable()) {
|
||||
if (!Required() || !IsMutable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,9 +222,9 @@ public:
|
|||
{
|
||||
SetHTMLBoolAttr(nsGkAtoms::readonly, aReadOnly, aError);
|
||||
}
|
||||
bool Required()
|
||||
bool Required() const
|
||||
{
|
||||
return GetBoolAttr(nsGkAtoms::required);
|
||||
return State().HasState(NS_EVENT_STATE_REQUIRED);
|
||||
}
|
||||
|
||||
void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "mozilla/dom/HTMLInputElement.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -2640,6 +2641,24 @@ void nsGenericHTMLFormElement::UpdateDisabledState(bool aNotify)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::UpdateRequiredState(bool aIsRequired, bool aNotify)
|
||||
{
|
||||
EventStates requiredStates;
|
||||
if (aIsRequired) {
|
||||
requiredStates |= NS_EVENT_STATE_REQUIRED;
|
||||
} else {
|
||||
requiredStates |= NS_EVENT_STATE_OPTIONAL;
|
||||
}
|
||||
|
||||
EventStates oldRequiredStates = State() & REQUIRED_STATES;
|
||||
EventStates changedStates = requiredStates ^ oldRequiredStates;
|
||||
|
||||
if (!changedStates.IsEmpty()) {
|
||||
ToggleStates(changedStates, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::FieldSetDisabledChanged(bool aNotify)
|
||||
{
|
||||
|
|
|
@ -1351,6 +1351,11 @@ public:
|
|||
*/
|
||||
void UpdateDisabledState(bool aNotify);
|
||||
|
||||
/**
|
||||
* Update our required/optional flags to match the given aIsRequired boolean.
|
||||
*/
|
||||
void UpdateRequiredState(bool aIsRequired, bool aNotify);
|
||||
|
||||
void FieldSetFirstLegendChanged(bool aNotify) {
|
||||
UpdateFieldSet(aNotify);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user