Bug 1385478 - Part 1: Use IsRequired/Required() to get the current required state. r=bz
authorJessica Jong <jjong@mozilla.com>
Thu, 03 Aug 2017 01:23:00 -0400
changeset 372739 00412d7d8f38
parent 372738 dd577e997eb3
child 372740 2aa4fe1bb445
push id32283
push userkwierso@gmail.com
push dateFri, 04 Aug 2017 01:07:14 +0000
treeherdermozilla-central@32083f24a1bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1385478
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1385478 - Part 1: Use IsRequired/Required() to get the current required state. r=bz IsRequired() helper function returns the current 'required' state of the element, that is, whether its required attribute is set or not. This will be used only for input elements that @required applies.
dom/base/nsDocument.cpp
dom/html/HTMLFormElement.cpp
dom/html/HTMLInputElement.cpp
dom/html/HTMLInputElement.h
dom/html/HTMLSelectElement.cpp
dom/html/HTMLSelectElement.h
dom/html/HTMLTextAreaElement.cpp
dom/html/HTMLTextAreaElement.h
dom/html/input/CheckableInputTypes.cpp
dom/html/input/DateTimeInputTypes.cpp
dom/html/input/FileInputType.cpp
dom/html/input/NumericInputTypes.cpp
dom/html/input/SingleLineTextInputTypes.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -8299,31 +8299,39 @@ void
 nsDocument::AddToRadioGroup(const nsAString& aName,
                             nsIFormControl* aRadio)
 {
   nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
   radioGroup->mRadioButtons.AppendObject(aRadio);
 
   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++;
   }
 }
 
 void
 nsDocument::RemoveFromRadioGroup(const nsAString& aName,
                                  nsIFormControl* aRadio)
 {
   nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
   radioGroup->mRadioButtons.RemoveObject(aRadio);
 
   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--;
   }
 }
 
 NS_IMETHODIMP
 nsDocument::WalkRadioGroup(const nsAString& aName,
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -2309,34 +2309,40 @@ HTMLFormElement::WalkRadioGroup(const ns
 
 void
 HTMLFormElement::AddToRadioGroup(const nsAString& aName,
                                  nsIFormControl* aRadio)
 {
   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()) {
     auto entry = mRequiredRadioButtonCounts.LookupForAdd(aName);
     if (!entry) {
       entry.OrInsert([]() { return 1; });
     } else {
       ++entry.Data();
     }
   }
 }
 
 void
 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()) {
     auto entry = mRequiredRadioButtonCounts.Lookup(aName);
     if (!entry) {
       MOZ_ASSERT_UNREACHABLE("At least one radio button has to be required!");
     } else {
       MOZ_ASSERT(entry.Data() >= 1,
                  "At least one radio button has to be required!");
       if (entry.Data() <= 1) {
         entry.Remove();
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -6549,17 +6549,17 @@ HTMLInputElement::IntrinsicState() const
     // Check whether we are the default checked element (:default)
     if (DefaultChecked()) {
       state |= NS_EVENT_STATE_DEFAULT;
     }
   } else if (mType == NS_FORM_INPUT_IMAGE) {
     state |= nsImageLoadingContent::ImageState();
   }
 
-  if (DoesRequiredApply() && HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (DoesRequiredApply() && IsRequired()) {
     state |= NS_EVENT_STATE_REQUIRED;
   } else {
     state |= NS_EVENT_STATE_OPTIONAL;
   }
 
   if (IsCandidateForConstraintValidation()) {
     if (IsValid()) {
       state |= NS_EVENT_STATE_VALID;
@@ -7227,42 +7227,45 @@ void
 HTMLInputElement::UpdateTooShortValidityState()
 {
   SetValidityState(VALIDITY_STATE_TOO_SHORT, IsTooShort());
 }
 
 void
 HTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
 {
+  MOZ_ASSERT(mType == NS_FORM_INPUT_RADIO,
+             "This should be called only for radio input types");
+
   bool notify = mDoneCreating;
   nsCOMPtr<nsIDOMHTMLInputElement> selection = GetSelectedRadioButton();
 
   aIgnoreSelf = aIgnoreSelf || !IsMutable();
 
   // 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();
 
   if (!container) {
     SetValidityState(VALIDITY_STATE_VALUE_MISSING,
                      IsMutable() && required && !selected);
     return;
   }
 
   nsAutoString name;
   GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
 
   // 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);
   }
 
   valueMissing = required && !selected;
 
   if (container->GetValueMissingState(name) != valueMissing) {
     container->SetValueMissingState(name, valueMissing);
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -936,16 +936,24 @@ public:
    * it will return a Decimal for which Decimal::isFinite() will return false.
    */
   static Decimal StringToDecimal(const nsAString& aValue);
 
   void UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories);
 
   static void Shutdown();
 
+  /**
+   * Returns the current required state of the element.
+   */
+  bool IsRequired() const
+  {
+    return HasAttr(kNameSpaceID_None, nsGkAtoms::required);
+  }
+
 protected:
   virtual ~HTMLInputElement();
 
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   // Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
   // by the nsITextControlElement version.
   using nsGenericHTMLFormElementWithState::IsSingleLineTextControl;
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1083,17 +1083,17 @@ HTMLSelectElement::IsOptionDisabled(int3
   RefPtr<HTMLOptionElement> option = Item(aIndex);
   NS_ENSURE_TRUE(option, NS_ERROR_FAILURE);
 
   *aIsDisabled = IsOptionDisabled(option);
   return NS_OK;
 }
 
 bool
-HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption)
+HTMLSelectElement::IsOptionDisabled(HTMLOptionElement* aOption) const
 {
   MOZ_ASSERT(aOption);
   if (aOption->Disabled()) {
     return true;
   }
 
   // Check for disabled optgroups
   // If there are no artifacts, there are no optgroups
@@ -1525,17 +1525,17 @@ HTMLSelectElement::IntrinsicState() cons
     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::required)) {
+  if (Required()) {
     state |= NS_EVENT_STATE_REQUIRED;
   } else {
     state |= NS_EVENT_STATE_OPTIONAL;
   }
 
   return state;
 }
 
@@ -1776,17 +1776,17 @@ void
 HTMLSelectElement::RebuildOptionsArray(bool aNotify)
 {
   mOptions->Clear();
   AddOptions(this, mOptions);
   FindSelectedIndex(0, aNotify);
 }
 
 bool
-HTMLSelectElement::IsValueMissing()
+HTMLSelectElement::IsValueMissing() const
 {
   if (!Required()) {
     return false;
   }
 
   uint32_t length = Length();
 
   for (uint32_t i = 0; i < length; ++i) {
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -336,17 +336,17 @@ public:
   /**
    * Checks whether an option is disabled (even if it's part of an optgroup)
    *
    * @param aIndex the index of the option to check
    * @return whether the option is disabled
    */
   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)
    * and handles notifications and cleanup and everything under the sun.
    * When this method exits, the select will be in a consistent state.  i.e.
    * if you set the last option to false, it will select an option anyway.
    *
    * @param aStartIndex the first index to set
@@ -516,17 +516,17 @@ protected:
    */
   nsresult RemoveOptionsFromList(nsIContent* aOptions,
                                  int32_t aListIndex,
                                  int32_t aDepth,
                                  bool aNotify);
 
   // nsIConstraintValidation
   void UpdateBarredFromConstraintValidation();
-  bool IsValueMissing();
+  bool IsValueMissing() const;
 
   /**
    * Get the index of the first option at, under or following the content in
    * the select, or length of options[] if none are found
    * @param aOptions the content
    * @return the index of the first option
    */
   int32_t GetOptionIndexAt(nsIContent* aOptions);
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -953,17 +953,17 @@ HTMLTextAreaElement::RestoreState(nsPres
   return false;
 }
 
 EventStates
 HTMLTextAreaElement::IntrinsicState() const
 {
   EventStates state = nsGenericHTMLFormElementWithState::IntrinsicState();
 
-  if (HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (Required()) {
     state |= NS_EVENT_STATE_REQUIRED;
   } else {
     state |= NS_EVENT_STATE_OPTIONAL;
   }
 
   if (IsCandidateForConstraintValidation()) {
     if (IsValid()) {
       state |= NS_EVENT_STATE_VALID;
@@ -1213,17 +1213,17 @@ HTMLTextAreaElement::IsTooShort()
   GetTextLength(&textLength);
 
   return textLength && textLength < minLength;
 }
 
 bool
 HTMLTextAreaElement::IsValueMissing() const
 {
-  if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) || !IsMutable()) {
+  if (!Required() || !IsMutable()) {
     return false;
   }
 
   return IsValueEmpty();
 }
 
 void
 HTMLTextAreaElement::UpdateTooLongValidityState()
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -247,17 +247,17 @@ public:
   bool ReadOnly()
   {
     return GetBoolAttr(nsGkAtoms::readonly);
   }
   void SetReadOnly(bool aReadOnly, ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::readonly, aReadOnly, aError);
   }
-  bool Required()
+  bool Required() const
   {
     return GetBoolAttr(nsGkAtoms::required);
   }
 
   void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
 
   void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
                     uint32_t aEnd, SelectionMode aSelectMode,
--- a/dom/html/input/CheckableInputTypes.cpp
+++ b/dom/html/input/CheckableInputTypes.cpp
@@ -8,17 +8,17 @@
 
 #include "mozilla/dom/HTMLInputElement.h"
 
 /* input type=checkbox */
 
 bool
 CheckboxInputType::IsValueMissing() const
 {
-  if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (!mInputElement->IsRequired()) {
     return false;
   }
 
   if (!IsMutable()) {
     return false;
   }
 
   return !mInputElement->Checked();
--- a/dom/html/input/DateTimeInputTypes.cpp
+++ b/dom/html/input/DateTimeInputTypes.cpp
@@ -36,17 +36,17 @@ DateTimeInputTypeBase::IsMutable() const
 {
   return !mInputElement->IsDisabled() &&
          !mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
 }
 
 bool
 DateTimeInputTypeBase::IsValueMissing() const
 {
-  if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (!mInputElement->IsRequired()) {
     return false;
   }
 
   if (!IsMutable()) {
     return false;
   }
 
   return IsValueEmpty();
--- a/dom/html/input/FileInputType.cpp
+++ b/dom/html/input/FileInputType.cpp
@@ -6,17 +6,17 @@
 
 #include "FileInputType.h"
 
 #include "mozilla/dom/HTMLInputElement.h"
 
 bool
 FileInputType::IsValueMissing() const
 {
-  if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (!mInputElement->IsRequired()) {
     return false;
   }
 
   if (!IsMutable()) {
     return false;
   }
 
   return mInputElement->GetFilesOrDirectoriesInternal().IsEmpty();
--- a/dom/html/input/NumericInputTypes.cpp
+++ b/dom/html/input/NumericInputTypes.cpp
@@ -128,17 +128,17 @@ NumericInputTypeBase::ConvertNumberToStr
   return ok;
 }
 
 /* input type=numer */
 
 bool
 NumberInputType::IsValueMissing() const
 {
-  if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (!mInputElement->IsRequired()) {
     return false;
   }
 
   if (!IsMutable()) {
     return false;
   }
 
   return IsValueEmpty();
--- a/dom/html/input/SingleLineTextInputTypes.cpp
+++ b/dom/html/input/SingleLineTextInputTypes.cpp
@@ -53,17 +53,17 @@ SingleLineTextInputTypeBase::IsTooShort(
     mInputElement->InputTextLength(mozilla::dom::CallerType::System);
 
   return textLength && textLength < minLength;
 }
 
 bool
 SingleLineTextInputTypeBase::IsValueMissing() const
 {
-  if (!mInputElement->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
+  if (!mInputElement->IsRequired()) {
     return false;
   }
 
   if (!IsMutable()) {
     return false;
   }
 
   return IsValueEmpty();