LCOV - code coverage report
Current view: top level - dom/html - nsIConstraintValidation.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 14 134 10.4 %
Date: 2017-07-14 16:53:18 Functions: 3 12 25.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 "nsIConstraintValidation.h"
       8             : 
       9             : #include "nsAString.h"
      10             : #include "nsGenericHTMLElement.h"
      11             : #include "mozilla/dom/HTMLFormElement.h"
      12             : #include "mozilla/dom/HTMLFieldSetElement.h"
      13             : #include "mozilla/dom/HTMLInputElement.h"
      14             : #include "mozilla/dom/ValidityState.h"
      15             : #include "nsIFormControl.h"
      16             : #include "nsContentUtils.h"
      17             : 
      18             : #include "nsIFormSubmitObserver.h"
      19             : #include "nsIObserverService.h"
      20             : 
      21             : const uint16_t nsIConstraintValidation::sContentSpecifiedMaxLengthMessage = 256;
      22             : 
      23             : using namespace mozilla;
      24             : using namespace mozilla::dom;
      25             : 
      26           9 : nsIConstraintValidation::nsIConstraintValidation()
      27             :   : mValidityBitField(0)
      28             :   // By default, all elements are subjects to constraint validation.
      29           9 :   , mBarredFromConstraintValidation(false)
      30             : {
      31           9 : }
      32             : 
      33           0 : nsIConstraintValidation::~nsIConstraintValidation()
      34             : {
      35           0 : }
      36             : 
      37             : mozilla::dom::ValidityState*
      38           0 : nsIConstraintValidation::Validity()
      39             : {
      40           0 :   if (!mValidity) {
      41           0 :     mValidity = new mozilla::dom::ValidityState(this);
      42             :   }
      43             : 
      44           0 :   return mValidity;
      45             : }
      46             : 
      47             : nsresult
      48           0 : nsIConstraintValidation::GetValidity(nsIDOMValidityState** aValidity)
      49             : {
      50           0 :   NS_ENSURE_ARG_POINTER(aValidity);
      51             : 
      52           0 :   NS_ADDREF(*aValidity = Validity());
      53             : 
      54           0 :   return NS_OK;
      55             : }
      56             : 
      57             : NS_IMETHODIMP
      58           0 : nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage)
      59             : {
      60           0 :   aValidationMessage.Truncate();
      61             : 
      62           0 :   if (IsCandidateForConstraintValidation() && !IsValid()) {
      63           0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(this);
      64           0 :     NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
      65             : 
      66           0 :     nsAutoString authorMessage;
      67           0 :     content->GetAttr(kNameSpaceID_None, nsGkAtoms::x_moz_errormessage,
      68           0 :                      authorMessage);
      69             : 
      70           0 :     if (!authorMessage.IsEmpty()) {
      71           0 :       aValidationMessage.Assign(authorMessage);
      72           0 :       if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
      73           0 :         aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
      74             :       }
      75           0 :     } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
      76           0 :       aValidationMessage.Assign(mCustomValidity);
      77           0 :       if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
      78           0 :         aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
      79             :       }
      80           0 :     } else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) {
      81           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG);
      82           0 :     } else if (GetValidityState(VALIDITY_STATE_TOO_SHORT)) {
      83           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_SHORT);
      84           0 :     } else if (GetValidityState(VALIDITY_STATE_VALUE_MISSING)) {
      85           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_VALUE_MISSING);
      86           0 :     } else if (GetValidityState(VALIDITY_STATE_TYPE_MISMATCH)) {
      87           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TYPE_MISMATCH);
      88           0 :     } else if (GetValidityState(VALIDITY_STATE_PATTERN_MISMATCH)) {
      89           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_PATTERN_MISMATCH);
      90           0 :     } else if (GetValidityState(VALIDITY_STATE_RANGE_OVERFLOW)) {
      91           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_RANGE_OVERFLOW);
      92           0 :     } else if (GetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW)) {
      93           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_RANGE_UNDERFLOW);
      94           0 :     } else if (GetValidityState(VALIDITY_STATE_STEP_MISMATCH)) {
      95           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_STEP_MISMATCH);
      96           0 :     } else if (GetValidityState(VALIDITY_STATE_BAD_INPUT)) {
      97           0 :       GetValidationMessage(aValidationMessage, VALIDITY_STATE_BAD_INPUT);
      98             :     } else {
      99             :       // There should not be other validity states.
     100           0 :       return NS_ERROR_UNEXPECTED;
     101             :     }
     102             :   } else {
     103           0 :     aValidationMessage.Truncate();
     104             :   }
     105             : 
     106           0 :   return NS_OK;
     107             : }
     108             : 
     109             : bool
     110           0 : nsIConstraintValidation::CheckValidity()
     111             : {
     112           0 :   if (!IsCandidateForConstraintValidation() || IsValid()) {
     113           0 :     return true;
     114             :   }
     115             : 
     116           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(this);
     117           0 :   NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
     118             : 
     119           0 :   nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content,
     120           0 :                                        NS_LITERAL_STRING("invalid"),
     121           0 :                                        false, true);
     122           0 :   return false;
     123             : }
     124             : 
     125             : nsresult
     126           0 : nsIConstraintValidation::CheckValidity(bool* aValidity)
     127             : {
     128           0 :   NS_ENSURE_ARG_POINTER(aValidity);
     129             : 
     130           0 :   *aValidity = CheckValidity();
     131             : 
     132           0 :   return NS_OK;
     133             : }
     134             : 
     135             : bool
     136           0 : nsIConstraintValidation::ReportValidity()
     137             : {
     138           0 :   if (!IsCandidateForConstraintValidation() || IsValid()) {
     139           0 :     return true;
     140             :   }
     141             : 
     142           0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(this);
     143           0 :   MOZ_ASSERT(content, "This class should be inherited by HTML elements only!");
     144             : 
     145           0 :   bool defaultAction = true;
     146           0 :   nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content,
     147           0 :                                        NS_LITERAL_STRING("invalid"),
     148           0 :                                        false, true, &defaultAction);
     149           0 :   if (!defaultAction) {
     150           0 :     return false;
     151             :   }
     152             : 
     153             :   nsCOMPtr<nsIObserverService> service =
     154           0 :     mozilla::services::GetObserverService();
     155           0 :   if (!service) {
     156           0 :     NS_WARNING("No observer service available!");
     157           0 :     return true;
     158             :   }
     159             : 
     160           0 :   nsCOMPtr<nsISimpleEnumerator> theEnum;
     161           0 :   nsresult rv = service->EnumerateObservers(NS_INVALIDFORMSUBMIT_SUBJECT,
     162           0 :                                             getter_AddRefs(theEnum));
     163             : 
     164             :   // Return true on error here because that's what we always did
     165           0 :   NS_ENSURE_SUCCESS(rv, true);
     166             : 
     167           0 :   bool hasObserver = false;
     168           0 :   rv = theEnum->HasMoreElements(&hasObserver);
     169             : 
     170             :   nsCOMPtr<nsIMutableArray> invalidElements =
     171           0 :     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
     172           0 :   invalidElements->AppendElement(content, false);
     173             : 
     174           0 :   NS_ENSURE_SUCCESS(rv, true);
     175           0 :   nsCOMPtr<nsISupports> inst;
     176           0 :   nsCOMPtr<nsIFormSubmitObserver> observer;
     177           0 :   bool more = true;
     178           0 :   while (NS_SUCCEEDED(theEnum->HasMoreElements(&more)) && more) {
     179           0 :     theEnum->GetNext(getter_AddRefs(inst));
     180           0 :     observer = do_QueryInterface(inst);
     181             : 
     182           0 :     if (observer) {
     183           0 :       observer->NotifyInvalidSubmit(nullptr, invalidElements);
     184             :     }
     185             :   }
     186             : 
     187           0 :   if (content->IsHTMLElement(nsGkAtoms::input) &&
     188           0 :       nsContentUtils::IsFocusedContent(content)) {
     189             :     HTMLInputElement* inputElement =
     190           0 :     HTMLInputElement::FromContentOrNull(content);
     191             : 
     192           0 :     inputElement->UpdateValidityUIBits(true);
     193             :   }
     194             : 
     195           0 :   dom::Element* element = content->AsElement();
     196           0 :   element->UpdateState(true);
     197           0 :   return false;
     198             : }
     199             : 
     200             : void
     201          89 : nsIConstraintValidation::SetValidityState(ValidityStateType aState,
     202             :                                           bool aValue)
     203             : {
     204          89 :   bool previousValidity = IsValid();
     205             : 
     206          89 :   if (aValue) {
     207           0 :     mValidityBitField |= aState;
     208             :   } else {
     209          89 :     mValidityBitField &= ~aState;
     210             :   }
     211             : 
     212             :   // Inform the form and fieldset elements if our validity has changed.
     213          89 :   if (previousValidity != IsValid() && IsCandidateForConstraintValidation()) {
     214           0 :     nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
     215           0 :     NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
     216             : 
     217             :     HTMLFormElement* form =
     218           0 :       static_cast<HTMLFormElement*>(formCtrl->GetFormElement());
     219           0 :     if (form) {
     220           0 :       form->UpdateValidity(IsValid());
     221             :     }
     222           0 :     HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
     223           0 :       if (fieldSet) {
     224           0 :       fieldSet->UpdateValidity(IsValid());
     225             :     }
     226             :   }
     227          89 : }
     228             : 
     229             : void
     230           0 : nsIConstraintValidation::SetCustomValidity(const nsAString& aError)
     231             : {
     232           0 :   mCustomValidity.Assign(aError);
     233           0 :   SetValidityState(VALIDITY_STATE_CUSTOM_ERROR, !mCustomValidity.IsEmpty());
     234           0 : }
     235             : 
     236             : void
     237          27 : nsIConstraintValidation::SetBarredFromConstraintValidation(bool aBarred)
     238             : {
     239          27 :   bool previousBarred = mBarredFromConstraintValidation;
     240             : 
     241          27 :   mBarredFromConstraintValidation = aBarred;
     242             : 
     243             :   // Inform the form and fieldset elements if our status regarding constraint
     244             :   // validation is going to change.
     245          27 :   if (!IsValid() && previousBarred != mBarredFromConstraintValidation) {
     246           0 :     nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
     247           0 :     NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
     248             : 
     249             :     // If the element is going to be barred from constraint validation, we can
     250             :     // inform the form and fieldset that we are now valid. Otherwise, we are now
     251             :     // invalid.
     252             :     HTMLFormElement* form =
     253           0 :       static_cast<HTMLFormElement*>(formCtrl->GetFormElement());
     254           0 :     if (form) {
     255           0 :       form->UpdateValidity(aBarred);
     256             :     }
     257           0 :     HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
     258           0 :     if (fieldSet) {
     259           0 :       fieldSet->UpdateValidity(aBarred);
     260             :     }
     261             :   }
     262          27 : }
     263             : 

Generated by: LCOV version 1.13