LCOV - code coverage report
Current view: top level - dom/html - HTMLFieldSetElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 157 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/BasicEvents.h"
       8             : #include "mozilla/EventDispatcher.h"
       9             : #include "mozilla/EventStates.h"
      10             : #include "mozilla/dom/HTMLFieldSetElement.h"
      11             : #include "mozilla/dom/HTMLFieldSetElementBinding.h"
      12             : #include "nsContentList.h"
      13             : #include "nsQueryObject.h"
      14             : 
      15           0 : NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
      16             : 
      17             : namespace mozilla {
      18             : namespace dom {
      19             : 
      20           0 : HTMLFieldSetElement::HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      21             :   : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_FIELDSET)
      22             :   , mElements(nullptr)
      23             :   , mFirstLegend(nullptr)
      24           0 :   , mInvalidElementsCount(0)
      25             : {
      26             :   // <fieldset> is always barred from constraint validation.
      27           0 :   SetBarredFromConstraintValidation(true);
      28             : 
      29             :   // We start out enabled and valid.
      30           0 :   AddStatesSilently(NS_EVENT_STATE_ENABLED | NS_EVENT_STATE_VALID);
      31           0 : }
      32             : 
      33           0 : HTMLFieldSetElement::~HTMLFieldSetElement()
      34             : {
      35           0 :   uint32_t length = mDependentElements.Length();
      36           0 :   for (uint32_t i = 0; i < length; ++i) {
      37           0 :     mDependentElements[i]->ForgetFieldSet(this);
      38             :   }
      39           0 : }
      40             : 
      41             : // nsISupports
      42             : 
      43           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLFieldSetElement, nsGenericHTMLFormElement,
      44             :                                    mValidity, mElements)
      45             : 
      46           0 : NS_IMPL_ADDREF_INHERITED(HTMLFieldSetElement, Element)
      47           0 : NS_IMPL_RELEASE_INHERITED(HTMLFieldSetElement, Element)
      48             : 
      49             : // QueryInterface implementation for HTMLFieldSetElement
      50           0 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLFieldSetElement)
      51           0 :   NS_INTERFACE_TABLE_INHERITED(HTMLFieldSetElement,
      52             :                                nsIDOMHTMLFieldSetElement,
      53             :                                nsIConstraintValidation)
      54           0 : NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLFormElement)
      55             : 
      56           0 : NS_IMPL_ELEMENT_CLONE(HTMLFieldSetElement)
      57             : 
      58             : 
      59           0 : NS_IMPL_BOOL_ATTR(HTMLFieldSetElement, Disabled, disabled)
      60           0 : NS_IMPL_STRING_ATTR(HTMLFieldSetElement, Name, name)
      61             : 
      62             : // nsIConstraintValidation
      63           0 : NS_IMPL_NSICONSTRAINTVALIDATION(HTMLFieldSetElement)
      64             : 
      65             : bool
      66           0 : HTMLFieldSetElement::IsDisabledForEvents(EventMessage aMessage)
      67             : {
      68           0 :   return IsElementDisabledForEvents(aMessage, nullptr);
      69             : }
      70             : 
      71             : // nsIContent
      72             : nsresult
      73           0 : HTMLFieldSetElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
      74             : {
      75             :   // Do not process any DOM events if the element is disabled.
      76           0 :   aVisitor.mCanHandle = false;
      77           0 :   if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
      78           0 :     return NS_OK;
      79             :   }
      80             : 
      81           0 :   return nsGenericHTMLFormElement::GetEventTargetParent(aVisitor);
      82             : }
      83             : 
      84             : nsresult
      85           0 : HTMLFieldSetElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
      86             :                                   const nsAttrValue* aValue,
      87             :                                   const nsAttrValue* aOldValue, bool aNotify)
      88             : {
      89           0 :   if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled &&
      90           0 :       nsINode::GetFirstChild()) {
      91           0 :     if (!mElements) {
      92             :       mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr,
      93           0 :                                     true);
      94             :     }
      95             : 
      96           0 :     uint32_t length = mElements->Length(true);
      97           0 :     for (uint32_t i=0; i<length; ++i) {
      98           0 :       static_cast<nsGenericHTMLFormElement*>(mElements->Item(i))
      99           0 :         ->FieldSetDisabledChanged(aNotify);
     100             :     }
     101             :   }
     102             : 
     103           0 :   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
     104           0 :                                                 aValue, aOldValue, aNotify);
     105             : }
     106             : 
     107             : // nsIDOMHTMLFieldSetElement
     108             : 
     109             : NS_IMETHODIMP
     110           0 : HTMLFieldSetElement::GetForm(nsIDOMHTMLFormElement** aForm)
     111             : {
     112           0 :   return nsGenericHTMLFormElement::GetForm(aForm);
     113             : }
     114             : 
     115             : NS_IMETHODIMP
     116           0 : HTMLFieldSetElement::GetType(nsAString& aType)
     117             : {
     118           0 :   aType.AssignLiteral("fieldset");
     119           0 :   return NS_OK;
     120             : }
     121             : 
     122             : /* static */
     123             : bool
     124           0 : HTMLFieldSetElement::MatchListedElements(Element* aElement, int32_t aNamespaceID,
     125             :                                          nsIAtom* aAtom, void* aData)
     126             : {
     127           0 :   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aElement);
     128           0 :   return formControl;
     129             : }
     130             : 
     131             : NS_IMETHODIMP
     132           0 : HTMLFieldSetElement::GetElements(nsIDOMHTMLCollection** aElements)
     133             : {
     134           0 :   NS_ADDREF(*aElements = Elements());
     135           0 :   return NS_OK;
     136             : }
     137             : 
     138             : nsIHTMLCollection*
     139           0 : HTMLFieldSetElement::Elements()
     140             : {
     141           0 :   if (!mElements) {
     142             :     mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr,
     143           0 :                                   true);
     144             :   }
     145             : 
     146           0 :   return mElements;
     147             : }
     148             : 
     149             : // nsIFormControl
     150             : 
     151             : nsresult
     152           0 : HTMLFieldSetElement::Reset()
     153             : {
     154           0 :   return NS_OK;
     155             : }
     156             : 
     157             : NS_IMETHODIMP
     158           0 : HTMLFieldSetElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission)
     159             : {
     160           0 :   return NS_OK;
     161             : }
     162             : 
     163             : nsresult
     164           0 : HTMLFieldSetElement::InsertChildAt(nsIContent* aChild, uint32_t aIndex,
     165             :                                    bool aNotify)
     166             : {
     167           0 :   bool firstLegendHasChanged = false;
     168             : 
     169           0 :   if (aChild->IsHTMLElement(nsGkAtoms::legend)) {
     170           0 :     if (!mFirstLegend) {
     171           0 :       mFirstLegend = aChild;
     172             :       // We do not want to notify the first time mFirstElement is set.
     173             :     } else {
     174             :       // If mFirstLegend is before aIndex, we do not change it.
     175             :       // Otherwise, mFirstLegend is now aChild.
     176           0 :       if (int32_t(aIndex) <= IndexOf(mFirstLegend)) {
     177           0 :         mFirstLegend = aChild;
     178           0 :         firstLegendHasChanged = true;
     179             :       }
     180             :     }
     181             :   }
     182             : 
     183           0 :   nsresult rv = nsGenericHTMLFormElement::InsertChildAt(aChild, aIndex, aNotify);
     184           0 :   NS_ENSURE_SUCCESS(rv, rv);
     185             : 
     186           0 :   if (firstLegendHasChanged) {
     187           0 :     NotifyElementsForFirstLegendChange(aNotify);
     188             :   }
     189             : 
     190           0 :   return rv;
     191             : }
     192             : 
     193             : void
     194           0 : HTMLFieldSetElement::RemoveChildAt(uint32_t aIndex, bool aNotify)
     195             : {
     196           0 :   bool firstLegendHasChanged = false;
     197             : 
     198           0 :   if (mFirstLegend && (GetChildAt(aIndex) == mFirstLegend)) {
     199             :     // If we are removing the first legend we have to found another one.
     200           0 :     nsIContent* child = mFirstLegend->GetNextSibling();
     201           0 :     mFirstLegend = nullptr;
     202           0 :     firstLegendHasChanged = true;
     203             : 
     204           0 :     for (; child; child = child->GetNextSibling()) {
     205           0 :       if (child->IsHTMLElement(nsGkAtoms::legend)) {
     206           0 :         mFirstLegend = child;
     207           0 :         break;
     208             :       }
     209             :     }
     210             :   }
     211             : 
     212           0 :   nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify);
     213             : 
     214           0 :   if (firstLegendHasChanged) {
     215           0 :     NotifyElementsForFirstLegendChange(aNotify);
     216             :   }
     217           0 : }
     218             : 
     219             : void
     220           0 : HTMLFieldSetElement::AddElement(nsGenericHTMLFormElement* aElement)
     221             : {
     222           0 :   mDependentElements.AppendElement(aElement);
     223             : 
     224             :   // If the element that we are adding aElement is a fieldset, then all the
     225             :   // invalid elements in aElement are also invalid elements of this.
     226           0 :   HTMLFieldSetElement* fieldSet = FromContent(aElement);
     227           0 :   if (fieldSet) {
     228           0 :     for (int32_t i = 0; i < fieldSet->mInvalidElementsCount; i++) {
     229           0 :       UpdateValidity(false);
     230             :     }
     231           0 :     return;
     232             :   }
     233             : 
     234             :   // We need to update the validity of the fieldset.
     235           0 :   nsCOMPtr<nsIConstraintValidation> cvElmt = do_QueryObject(aElement);
     236           0 :   if (cvElmt &&
     237           0 :       cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
     238           0 :     UpdateValidity(false);
     239             :   }
     240             : 
     241             : #if DEBUG
     242           0 :   int32_t debugInvalidElementsCount = 0;
     243           0 :   for (uint32_t i = 0; i < mDependentElements.Length(); i++) {
     244           0 :     HTMLFieldSetElement* fieldSet = FromContent(mDependentElements[i]);
     245           0 :     if (fieldSet) {
     246           0 :       debugInvalidElementsCount += fieldSet->mInvalidElementsCount;
     247           0 :       continue;
     248             :     }
     249             :     nsCOMPtr<nsIConstraintValidation>
     250           0 :       cvElmt = do_QueryObject(mDependentElements[i]);
     251           0 :     if (cvElmt &&
     252           0 :         cvElmt->IsCandidateForConstraintValidation() &&
     253           0 :         !(cvElmt->IsValid())) {
     254           0 :       debugInvalidElementsCount += 1;
     255             :     }
     256             :   }
     257           0 :   MOZ_ASSERT(debugInvalidElementsCount == mInvalidElementsCount);
     258             : #endif
     259             : }
     260             : 
     261             : void
     262           0 : HTMLFieldSetElement::RemoveElement(nsGenericHTMLFormElement* aElement)
     263             : {
     264           0 :   mDependentElements.RemoveElement(aElement);
     265             : 
     266             :   // If the element that we are removing aElement is a fieldset, then all the
     267             :   // invalid elements in aElement are also removed from this.
     268           0 :   HTMLFieldSetElement* fieldSet = FromContent(aElement);
     269           0 :   if (fieldSet) {
     270           0 :     for (int32_t i = 0; i < fieldSet->mInvalidElementsCount; i++) {
     271           0 :       UpdateValidity(true);
     272             :     }
     273           0 :     return;
     274             :   }
     275             : 
     276             :   // We need to update the validity of the fieldset.
     277           0 :   nsCOMPtr<nsIConstraintValidation> cvElmt = do_QueryObject(aElement);
     278           0 :   if (cvElmt &&
     279           0 :       cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
     280           0 :     UpdateValidity(true);
     281             :   }
     282             : 
     283             : #if DEBUG
     284           0 :   int32_t debugInvalidElementsCount = 0;
     285           0 :   for (uint32_t i = 0; i < mDependentElements.Length(); i++) {
     286           0 :     HTMLFieldSetElement* fieldSet = FromContent(mDependentElements[i]);
     287           0 :     if (fieldSet) {
     288           0 :       debugInvalidElementsCount += fieldSet->mInvalidElementsCount;
     289           0 :       continue;
     290             :     }
     291             :     nsCOMPtr<nsIConstraintValidation>
     292           0 :       cvElmt = do_QueryObject(mDependentElements[i]);
     293           0 :     if (cvElmt &&
     294           0 :         cvElmt->IsCandidateForConstraintValidation() &&
     295           0 :         !(cvElmt->IsValid())) {
     296           0 :       debugInvalidElementsCount += 1;
     297             :     }
     298             :   }
     299           0 :   MOZ_ASSERT(debugInvalidElementsCount == mInvalidElementsCount);
     300             : #endif
     301             : }
     302             : 
     303             : void
     304           0 : HTMLFieldSetElement::NotifyElementsForFirstLegendChange(bool aNotify)
     305             : {
     306             :   /**
     307             :    * NOTE: this could be optimized if only call when the fieldset is currently
     308             :    * disabled.
     309             :    * This should also make sure that mElements is set when we happen to be here.
     310             :    * However, this method shouldn't be called very often in normal use cases.
     311             :    */
     312           0 :   if (!mElements) {
     313             :     mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr,
     314           0 :                                   true);
     315             :   }
     316             : 
     317           0 :   uint32_t length = mElements->Length(true);
     318           0 :   for (uint32_t i = 0; i < length; ++i) {
     319           0 :     static_cast<nsGenericHTMLFormElement*>(mElements->Item(i))
     320           0 :       ->FieldSetFirstLegendChanged(aNotify);
     321             :   }
     322           0 : }
     323             : 
     324             : void
     325           0 : HTMLFieldSetElement::UpdateValidity(bool aElementValidity)
     326             : {
     327           0 :   if (aElementValidity) {
     328           0 :     --mInvalidElementsCount;
     329             :   } else {
     330           0 :     ++mInvalidElementsCount;
     331             :   }
     332             : 
     333           0 :   MOZ_ASSERT(mInvalidElementsCount >= 0);
     334             : 
     335             :   // The fieldset validity has just changed if:
     336             :   // - there are no more invalid elements ;
     337             :   // - or there is one invalid elmement and an element just became invalid.
     338           0 :   if (!mInvalidElementsCount || (mInvalidElementsCount == 1 && !aElementValidity)) {
     339           0 :     UpdateState(true);
     340             :   }
     341             : 
     342             :   // We should propagate the change to the fieldset parent chain.
     343           0 :   if (mFieldSet) {
     344           0 :     mFieldSet->UpdateValidity(aElementValidity);
     345             :   }
     346             : 
     347           0 :   return;
     348             : }
     349             : 
     350             : EventStates
     351           0 : HTMLFieldSetElement::IntrinsicState() const
     352             : {
     353           0 :   EventStates state = nsGenericHTMLFormElement::IntrinsicState();
     354             : 
     355           0 :   if (mInvalidElementsCount) {
     356           0 :     state |= NS_EVENT_STATE_INVALID;
     357             :   } else {
     358           0 :     state |= NS_EVENT_STATE_VALID;
     359             :   }
     360             : 
     361           0 :   return state;
     362             : }
     363             : 
     364             : JSObject*
     365           0 : HTMLFieldSetElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     366             : {
     367           0 :   return HTMLFieldSetElementBinding::Wrap(aCx, this, aGivenProto);
     368             : }
     369             : 
     370             : } // namespace dom
     371             : } // namespace mozilla

Generated by: LCOV version 1.13