LCOV - code coverage report
Current view: top level - dom/html/input - InputType.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 22 212 10.4 %
Date: 2017-07-14 16:53:18 Functions: 7 35 20.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 "InputType.h"
       8             : 
       9             : #include "nsIFormControl.h"
      10             : #include "ButtonInputTypes.h"
      11             : #include "CheckableInputTypes.h"
      12             : #include "ColorInputType.h"
      13             : #include "DateTimeInputTypes.h"
      14             : #include "FileInputType.h"
      15             : #include "HiddenInputType.h"
      16             : #include "NumericInputTypes.h"
      17             : #include "SingleLineTextInputTypes.h"
      18             : 
      19             : #include "nsContentUtils.h"
      20             : 
      21           3 : const mozilla::Decimal InputType::kStepAny = mozilla::Decimal(0);
      22             : 
      23             : /* static */ mozilla::UniquePtr<InputType, DoNotDelete>
      24           8 : InputType::Create(mozilla::dom::HTMLInputElement* aInputElement, uint8_t aType,
      25             :                   void* aMemory)
      26             : {
      27           8 :   mozilla::UniquePtr<InputType, DoNotDelete> inputType;
      28           8 :   switch(aType) {
      29             :     // Single line text
      30             :     case NS_FORM_INPUT_TEXT:
      31           7 :       inputType.reset(TextInputType::Create(aInputElement, aMemory));
      32           7 :       break;
      33             :     case NS_FORM_INPUT_TEL:
      34           0 :       inputType.reset(TelInputType::Create(aInputElement, aMemory));
      35           0 :       break;
      36             :     case NS_FORM_INPUT_EMAIL:
      37           0 :       inputType.reset(EmailInputType::Create(aInputElement, aMemory));
      38           0 :       break;
      39             :     case NS_FORM_INPUT_SEARCH:
      40           1 :       inputType.reset(SearchInputType::Create(aInputElement, aMemory));
      41           1 :       break;
      42             :     case NS_FORM_INPUT_PASSWORD:
      43           0 :       inputType.reset(PasswordInputType::Create(aInputElement, aMemory));
      44           0 :       break;
      45             :     case NS_FORM_INPUT_URL:
      46           0 :       inputType.reset(URLInputType::Create(aInputElement, aMemory));
      47           0 :       break;
      48             :     // Button
      49             :     case NS_FORM_INPUT_BUTTON:
      50           0 :       inputType.reset(ButtonInputType::Create(aInputElement, aMemory));
      51           0 :       break;
      52             :     case NS_FORM_INPUT_SUBMIT:
      53           0 :       inputType.reset(SubmitInputType::Create(aInputElement, aMemory));
      54           0 :       break;
      55             :     case NS_FORM_INPUT_IMAGE:
      56           0 :       inputType.reset(ImageInputType::Create(aInputElement, aMemory));
      57           0 :       break;
      58             :     case NS_FORM_INPUT_RESET:
      59           0 :       inputType.reset(ResetInputType::Create(aInputElement, aMemory));
      60           0 :       break;
      61             :     // Checkable
      62             :     case NS_FORM_INPUT_CHECKBOX:
      63           0 :       inputType.reset(CheckboxInputType::Create(aInputElement, aMemory));
      64           0 :       break;
      65             :     case NS_FORM_INPUT_RADIO:
      66           0 :       inputType.reset(RadioInputType::Create(aInputElement, aMemory));
      67           0 :       break;
      68             :     // Numeric
      69             :     case NS_FORM_INPUT_NUMBER:
      70           0 :       inputType.reset(NumberInputType::Create(aInputElement, aMemory));
      71           0 :       break;
      72             :     case NS_FORM_INPUT_RANGE:
      73           0 :       inputType.reset(RangeInputType::Create(aInputElement, aMemory));
      74           0 :       break;
      75             :     // DateTime
      76             :     case NS_FORM_INPUT_DATE:
      77           0 :       inputType.reset(DateInputType::Create(aInputElement, aMemory));
      78           0 :       break;
      79             :     case NS_FORM_INPUT_TIME:
      80           0 :       inputType.reset(TimeInputType::Create(aInputElement, aMemory));
      81           0 :       break;
      82             :     case NS_FORM_INPUT_MONTH:
      83           0 :       inputType.reset(MonthInputType::Create(aInputElement, aMemory));
      84           0 :       break;
      85             :     case NS_FORM_INPUT_WEEK:
      86           0 :       inputType.reset(WeekInputType::Create(aInputElement, aMemory));
      87           0 :       break;
      88             :     case NS_FORM_INPUT_DATETIME_LOCAL:
      89           0 :       inputType.reset(DateTimeLocalInputType::Create(aInputElement, aMemory));
      90           0 :       break;
      91             :     // Others
      92             :     case NS_FORM_INPUT_COLOR:
      93           0 :       inputType.reset(ColorInputType::Create(aInputElement, aMemory));
      94           0 :       break;
      95             :     case NS_FORM_INPUT_FILE:
      96           0 :       inputType.reset(FileInputType::Create(aInputElement, aMemory));
      97           0 :       break;
      98             :     case NS_FORM_INPUT_HIDDEN:
      99           0 :       inputType.reset(HiddenInputType::Create(aInputElement, aMemory));
     100           0 :       break;
     101             :     default:
     102           0 :       inputType.reset(TextInputType::Create(aInputElement, aMemory));
     103             :   }
     104             : 
     105           8 :   return inputType;
     106             : }
     107             : 
     108             : bool
     109           0 : InputType::IsMutable() const
     110             : {
     111           0 :   return !mInputElement->IsDisabled();
     112             : }
     113             : 
     114             : bool
     115           0 : InputType::IsValueEmpty() const
     116             : {
     117           0 :   return mInputElement->IsValueEmpty();
     118             : }
     119             : 
     120             : void
     121           0 : InputType::GetNonFileValueInternal(nsAString& aValue) const
     122             : {
     123           0 :   return mInputElement->GetNonFileValueInternal(aValue);
     124             : }
     125             : 
     126             : nsresult
     127           0 : InputType::SetValueInternal(const nsAString& aValue, uint32_t aFlags)
     128             : {
     129           0 :   return mInputElement->SetValueInternal(aValue, aFlags);
     130             : }
     131             : 
     132             : mozilla::Decimal
     133           0 : InputType::GetStepBase() const
     134             : {
     135           0 :   return mInputElement->GetStepBase();
     136             : }
     137             : 
     138             : nsIFrame*
     139           0 : InputType::GetPrimaryFrame() const
     140             : {
     141           0 :   return mInputElement->GetPrimaryFrame();
     142             : }
     143             : 
     144             : void
     145           1 : InputType::DropReference()
     146             : {
     147             :   // Drop our (non ref-counted) reference.
     148           1 :   mInputElement = nullptr;
     149           1 : }
     150             : 
     151             : bool
     152           0 : InputType::IsTooLong() const
     153             : {
     154           0 :   return false;
     155             : }
     156             : 
     157             : bool
     158           0 : InputType::IsTooShort() const
     159             : {
     160           0 :   return false;
     161             : }
     162             : 
     163             : bool
     164           0 : InputType::IsValueMissing() const
     165             : {
     166           0 :   return false;
     167             : }
     168             : 
     169             : bool
     170           7 : InputType::HasTypeMismatch() const
     171             : {
     172           7 :   return false;
     173             : }
     174             : 
     175             : bool
     176           0 : InputType::HasPatternMismatch() const
     177             : {
     178           0 :   return false;
     179             : }
     180             : 
     181             : bool
     182           7 : InputType::IsRangeOverflow() const
     183             : {
     184           7 :   return false;
     185             : }
     186             : 
     187             : bool
     188           7 : InputType::IsRangeUnderflow() const
     189             : {
     190           7 :   return false;
     191             : }
     192             : 
     193             : bool
     194           7 : InputType::HasStepMismatch(bool aUseZeroIfValueNaN) const
     195             : {
     196           7 :   return false;
     197             : }
     198             : 
     199             : bool
     200           7 : InputType::HasBadInput() const
     201             : {
     202           7 :   return false;
     203             : }
     204             : 
     205             : nsresult
     206           0 : InputType::GetValidationMessage(nsAString& aValidationMessage,
     207             :                                 nsIConstraintValidation::ValidityStateType aType)
     208             : {
     209           0 :   nsresult rv = NS_OK;
     210             : 
     211           0 :   switch (aType)
     212             :   {
     213             :     case nsIConstraintValidation::VALIDITY_STATE_TOO_LONG:
     214             :     {
     215           0 :       nsXPIDLString message;
     216           0 :       int32_t maxLength = mInputElement->MaxLength();
     217             :       int32_t textLength =
     218           0 :         mInputElement->InputTextLength(mozilla::dom::CallerType::System);
     219           0 :       nsAutoString strMaxLength;
     220           0 :       nsAutoString strTextLength;
     221             : 
     222           0 :       strMaxLength.AppendInt(maxLength);
     223           0 :       strTextLength.AppendInt(textLength);
     224             : 
     225           0 :       const char16_t* params[] = { strMaxLength.get(), strTextLength.get() };
     226             :       rv = nsContentUtils::FormatLocalizedString(
     227             :         nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong",
     228           0 :         params, message);
     229           0 :       aValidationMessage = message;
     230           0 :       break;
     231             :     }
     232             :     case nsIConstraintValidation::VALIDITY_STATE_TOO_SHORT:
     233             :     {
     234           0 :       nsXPIDLString message;
     235           0 :       int32_t minLength = mInputElement->MinLength();
     236             :       int32_t textLength =
     237           0 :         mInputElement->InputTextLength(mozilla::dom::CallerType::System);
     238           0 :       nsAutoString strMinLength;
     239           0 :       nsAutoString strTextLength;
     240             : 
     241           0 :       strMinLength.AppendInt(minLength);
     242           0 :       strTextLength.AppendInt(textLength);
     243             : 
     244           0 :       const char16_t* params[] = { strMinLength.get(), strTextLength.get() };
     245             :       rv = nsContentUtils::FormatLocalizedString(
     246             :         nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort",
     247           0 :         params, message);
     248             : 
     249           0 :       aValidationMessage = message;
     250           0 :       break;
     251             :     }
     252             :     case nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING:
     253             :     {
     254           0 :       nsXPIDLString message;
     255           0 :       rv = GetValueMissingMessage(message);
     256           0 :       if (NS_FAILED(rv)) {
     257           0 :         return rv;
     258             :       }
     259             : 
     260           0 :       aValidationMessage = message;
     261           0 :       break;
     262             :     }
     263             :     case nsIConstraintValidation::VALIDITY_STATE_TYPE_MISMATCH:
     264             :     {
     265           0 :       nsXPIDLString message;
     266           0 :       rv = GetTypeMismatchMessage(message);
     267           0 :       if (NS_FAILED(rv)) {
     268           0 :         return rv;
     269             :       }
     270             : 
     271           0 :       aValidationMessage = message;
     272           0 :       break;
     273             :     }
     274             :     case nsIConstraintValidation::VALIDITY_STATE_PATTERN_MISMATCH:
     275             :     {
     276           0 :       nsXPIDLString message;
     277           0 :       nsAutoString title;
     278           0 :       mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
     279           0 :       if (title.IsEmpty()) {
     280             :         rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
     281           0 :           "FormValidationPatternMismatch", message);
     282             :       } else {
     283           0 :         if (title.Length() >
     284             :             nsIConstraintValidation::sContentSpecifiedMaxLengthMessage) {
     285           0 :           title.Truncate(
     286           0 :             nsIConstraintValidation::sContentSpecifiedMaxLengthMessage);
     287             :         }
     288           0 :         const char16_t* params[] = { title.get() };
     289             :         rv = nsContentUtils::FormatLocalizedString(
     290             :           nsContentUtils::eDOM_PROPERTIES,
     291           0 :           "FormValidationPatternMismatchWithTitle", params, message);
     292             :       }
     293           0 :       aValidationMessage = message;
     294           0 :       break;
     295             :     }
     296             :     case nsIConstraintValidation::VALIDITY_STATE_RANGE_OVERFLOW:
     297             :     {
     298           0 :       nsXPIDLString message;
     299           0 :       rv = GetRangeOverflowMessage(message);
     300           0 :       if (NS_FAILED(rv)) {
     301           0 :         return rv;
     302             :       }
     303             : 
     304           0 :       aValidationMessage = message;
     305           0 :       break;
     306             :     }
     307             :     case nsIConstraintValidation::VALIDITY_STATE_RANGE_UNDERFLOW:
     308             :     {
     309           0 :       nsXPIDLString message;
     310           0 :       rv = GetRangeUnderflowMessage(message);
     311           0 :       if (NS_FAILED(rv)) {
     312           0 :         return rv;
     313             :       }
     314             : 
     315           0 :       aValidationMessage = message;
     316           0 :       break;
     317             :     }
     318             :     case nsIConstraintValidation::VALIDITY_STATE_STEP_MISMATCH:
     319             :     {
     320           0 :       nsXPIDLString message;
     321             : 
     322           0 :       mozilla::Decimal value = mInputElement->GetValueAsDecimal();
     323           0 :       MOZ_ASSERT(!value.isNaN());
     324             : 
     325           0 :       mozilla::Decimal step = mInputElement->GetStep();
     326           0 :       MOZ_ASSERT(step != kStepAny && step > mozilla::Decimal(0));
     327             : 
     328           0 :       mozilla::Decimal stepBase = mInputElement->GetStepBase();
     329             : 
     330             :       mozilla::Decimal valueLow =
     331           0 :         value - NS_floorModulo(value - stepBase, step);
     332             :       mozilla::Decimal valueHigh =
     333           0 :         value + step - NS_floorModulo(value - stepBase, step);
     334             : 
     335           0 :       mozilla::Decimal maximum = mInputElement->GetMaximum();
     336             : 
     337           0 :       if (maximum.isNaN() || valueHigh <= maximum) {
     338           0 :         nsAutoString valueLowStr, valueHighStr;
     339           0 :         ConvertNumberToString(valueLow, valueLowStr);
     340           0 :         ConvertNumberToString(valueHigh, valueHighStr);
     341             : 
     342           0 :         if (valueLowStr.Equals(valueHighStr)) {
     343           0 :           const char16_t* params[] = { valueLowStr.get() };
     344             :           rv = nsContentUtils::FormatLocalizedString(
     345             :             nsContentUtils::eDOM_PROPERTIES,
     346           0 :             "FormValidationStepMismatchOneValue", params, message);
     347             :         } else {
     348           0 :           const char16_t* params[] = { valueLowStr.get(), valueHighStr.get() };
     349             :           rv = nsContentUtils::FormatLocalizedString(
     350             :             nsContentUtils::eDOM_PROPERTIES,
     351           0 :             "FormValidationStepMismatch", params, message);
     352             :         }
     353             :       } else {
     354           0 :         nsAutoString valueLowStr;
     355           0 :         ConvertNumberToString(valueLow, valueLowStr);
     356             : 
     357           0 :         const char16_t* params[] = { valueLowStr.get() };
     358             :         rv = nsContentUtils::FormatLocalizedString(
     359             :           nsContentUtils::eDOM_PROPERTIES,
     360           0 :           "FormValidationStepMismatchOneValue", params, message);
     361             :       }
     362             : 
     363           0 :       aValidationMessage = message;
     364           0 :       break;
     365             :     }
     366             :     case nsIConstraintValidation::VALIDITY_STATE_BAD_INPUT:
     367             :     {
     368           0 :       nsXPIDLString message;
     369           0 :       rv = GetBadInputMessage(message);
     370           0 :       if (NS_FAILED(rv)) {
     371           0 :         return rv;
     372             :       }
     373             : 
     374           0 :       aValidationMessage = message;
     375           0 :       break;
     376             :     }
     377             :     default:
     378           0 :       return NS_ERROR_UNEXPECTED;
     379             :   }
     380             : 
     381           0 :   return rv;
     382             : }
     383             : 
     384             : nsresult
     385           0 : InputType::GetValueMissingMessage(nsXPIDLString& aMessage)
     386             : {
     387             :   return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
     388           0 :     "FormValidationValueMissing", aMessage);
     389             : }
     390             : 
     391             : nsresult
     392           0 : InputType::GetTypeMismatchMessage(nsXPIDLString& aMessage)
     393             : {
     394           0 :   return NS_ERROR_UNEXPECTED;
     395             : }
     396             : 
     397             : nsresult
     398           0 : InputType::GetRangeOverflowMessage(nsXPIDLString& aMessage)
     399             : {
     400           0 :   return NS_ERROR_UNEXPECTED;
     401             : }
     402             : 
     403             : nsresult
     404           0 : InputType::GetRangeUnderflowMessage(nsXPIDLString& aMessage)
     405             : {
     406           0 :   return NS_ERROR_UNEXPECTED;
     407             : }
     408             : 
     409             : nsresult
     410           0 : InputType::GetBadInputMessage(nsXPIDLString& aMessage)
     411             : {
     412           0 :   return NS_ERROR_UNEXPECTED;
     413             : }
     414             : 
     415             : nsresult
     416           0 : InputType::MinMaxStepAttrChanged()
     417             : {
     418           0 :   return NS_OK;
     419             : }
     420             : 
     421             : bool
     422           0 : InputType::ConvertStringToNumber(nsAString& aValue,
     423             :                                  mozilla::Decimal& aResultValue) const
     424             : {
     425           0 :   NS_WARNING("InputType::ConvertStringToNumber called");
     426             : 
     427           0 :   return false;
     428             : }
     429             : 
     430             : bool
     431           0 : InputType::ConvertNumberToString(mozilla::Decimal aValue,
     432             :                                  nsAString& aResultString) const
     433             : {
     434           0 :   NS_WARNING("InputType::ConvertNumberToString called");
     435             : 
     436           0 :   return false;
     437             : }
     438             : 
     439             : bool
     440           0 : InputType::ParseDate(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth,
     441             :                      uint32_t* aDay) const
     442             : {
     443             :   // TODO: move this function and implementation to DateTimeInpuTypeBase when
     444             :   // refactoring is completed. Now we can only call HTMLInputElement::ParseDate
     445             :   // from here, since the method is protected and only InputType is a friend
     446             :   // class.
     447           0 :   return mInputElement->ParseDate(aValue, aYear, aMonth, aDay);
     448             : }
     449             : 
     450             : bool
     451           0 : InputType::ParseTime(const nsAString& aValue, uint32_t* aResult) const
     452             : {
     453             :   // see comment in InputType::ParseDate().
     454           0 :   return mInputElement->ParseTime(aValue, aResult);
     455             : }
     456             : 
     457             : bool
     458           0 : InputType::ParseMonth(const nsAString& aValue, uint32_t* aYear,
     459             :                       uint32_t* aMonth) const
     460             : {
     461             :   // see comment in InputType::ParseDate().
     462           0 :   return mInputElement->ParseMonth(aValue, aYear, aMonth);
     463             : }
     464             : 
     465             : bool
     466           0 : InputType::ParseWeek(const nsAString& aValue, uint32_t* aYear,
     467             :                      uint32_t* aWeek) const
     468             : {
     469             :   // see comment in InputType::ParseDate().
     470           0 :   return mInputElement->ParseWeek(aValue, aYear, aWeek);
     471             : }
     472             : 
     473             : bool
     474           0 : InputType::ParseDateTimeLocal(const nsAString& aValue, uint32_t* aYear,
     475             :                               uint32_t* aMonth, uint32_t* aDay, uint32_t* aTime)
     476             :                               const
     477             : {
     478             :   // see comment in InputType::ParseDate().
     479           0 :   return mInputElement->ParseDateTimeLocal(aValue, aYear, aMonth, aDay, aTime);
     480             : }
     481             : 
     482             : int32_t
     483           0 : InputType::MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const
     484             : {
     485             :   // see comment in InputType::ParseDate().
     486           0 :   return mInputElement->MonthsSinceJan1970(aYear, aMonth);
     487             : }
     488             : 
     489             : double
     490           0 : InputType::DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const
     491             : {
     492             :   // see comment in InputType::ParseDate().
     493           0 :   return mInputElement->DaysSinceEpochFromWeek(aYear, aWeek);
     494             : }
     495             : 
     496             : uint32_t
     497           0 : InputType::DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay,
     498             :                      bool isoWeek) const
     499             : {
     500             :   // see comment in InputType::ParseDate().
     501           0 :   return mInputElement->DayOfWeek(aYear, aMonth, aDay, isoWeek);
     502             : }
     503             : 
     504             : uint32_t
     505           0 : InputType::MaximumWeekInYear(uint32_t aYear) const
     506             : {
     507             :   // see comment in InputType::ParseDate().
     508           0 :   return mInputElement->MaximumWeekInYear(aYear);
     509             : }

Generated by: LCOV version 1.13