tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NumericInputTypes.cpp (5640B)


      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/dom/NumericInputTypes.h"
      8 
      9 #include "ICUUtils.h"
     10 #include "mozilla/TextControlState.h"
     11 #include "mozilla/dom/HTMLInputElement.h"
     12 
     13 using namespace mozilla;
     14 using namespace mozilla::dom;
     15 
     16 bool NumericInputTypeBase::IsRangeOverflow() const {
     17  Decimal maximum = mInputElement->GetMaximum();
     18  if (maximum.isNaN()) {
     19    return false;
     20  }
     21 
     22  Decimal value = mInputElement->GetValueAsDecimal();
     23  if (value.isNaN()) {
     24    return false;
     25  }
     26 
     27  return value > maximum;
     28 }
     29 
     30 bool NumericInputTypeBase::IsRangeUnderflow() const {
     31  Decimal minimum = mInputElement->GetMinimum();
     32  if (minimum.isNaN()) {
     33    return false;
     34  }
     35 
     36  Decimal value = mInputElement->GetValueAsDecimal();
     37  if (value.isNaN()) {
     38    return false;
     39  }
     40 
     41  return value < minimum;
     42 }
     43 
     44 bool NumericInputTypeBase::HasStepMismatch() const {
     45  Decimal value = mInputElement->GetValueAsDecimal();
     46  return mInputElement->ValueIsStepMismatch(value);
     47 }
     48 
     49 nsresult NumericInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
     50  // We want to show the value as parsed when it's a number
     51  Decimal maximum = mInputElement->GetMaximum();
     52  MOZ_ASSERT(!maximum.isNaN());
     53 
     54  nsAutoString maxStr;
     55  ConvertNumberToString(maximum, Localized::Yes, maxStr);
     56  return nsContentUtils::FormatMaybeLocalizedString(
     57      aMessage, nsContentUtils::eDOM_PROPERTIES,
     58      "FormValidationNumberRangeOverflow", mInputElement->OwnerDoc(), maxStr);
     59 }
     60 
     61 nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
     62  Decimal minimum = mInputElement->GetMinimum();
     63  MOZ_ASSERT(!minimum.isNaN());
     64 
     65  nsAutoString minStr;
     66  ConvertNumberToString(minimum, Localized::Yes, minStr);
     67  return nsContentUtils::FormatMaybeLocalizedString(
     68      aMessage, nsContentUtils::eDOM_PROPERTIES,
     69      "FormValidationNumberRangeUnderflow", mInputElement->OwnerDoc(), minStr);
     70 }
     71 
     72 auto NumericInputTypeBase::ConvertStringToNumber(const nsAString& aValue) const
     73    -> StringToNumberResult {
     74  return {HTMLInputElement::StringToDecimal(aValue)};
     75 }
     76 
     77 bool NumericInputTypeBase::ConvertNumberToString(
     78    Decimal aValue, Localized, nsAString& aResultString) const {
     79  MOZ_ASSERT(aValue.isFinite(), "aValue must be a valid non-Infinite number.");
     80  aResultString.Truncate();
     81  aResultString.AssignASCII(aValue.toString().c_str());
     82  return true;
     83 }
     84 
     85 /* input type=number */
     86 
     87 bool NumberInputType::IsValueMissing() const {
     88  if (!mInputElement->IsRequired()) {
     89    return false;
     90  }
     91 
     92  if (!IsMutable()) {
     93    return false;
     94  }
     95 
     96  return IsValueEmpty();
     97 }
     98 
     99 bool NumberInputType::HasBadInput() const {
    100  nsAutoString value;
    101  GetNonFileValueInternal(value);
    102  return !value.IsEmpty() && mInputElement->GetValueAsDecimal().isNaN();
    103 }
    104 
    105 auto NumberInputType::ConvertStringToNumber(const nsAString& aValue) const
    106    -> StringToNumberResult {
    107  auto result = NumericInputTypeBase::ConvertStringToNumber(aValue);
    108  if (result.mResult.isFinite()) {
    109    return result;
    110  }
    111  // Try to read the localized value from the user.
    112  ICUUtils::LanguageTagIterForContent langTagIter(mInputElement);
    113  result.mLocalized = true;
    114  result.mResult =
    115      Decimal::fromDouble(ICUUtils::ParseNumber(aValue, langTagIter));
    116  return result;
    117 }
    118 
    119 bool NumberInputType::ConvertNumberToString(Decimal aValue,
    120                                            Localized aLocalized,
    121                                            nsAString& aResultString) const {
    122  MOZ_ASSERT(aValue.isFinite(), "aValue must be a valid non-Infinite number.");
    123 
    124  if (aLocalized == Localized::No) {
    125    return NumericInputTypeBase::ConvertNumberToString(aValue, aLocalized,
    126                                                       aResultString);
    127  }
    128  aResultString.Truncate();
    129  ICUUtils::LanguageTagIterForContent langTagIter(mInputElement);
    130  ICUUtils::LocalizeNumber(aValue.toDouble(), langTagIter, aResultString);
    131  return true;
    132 }
    133 
    134 nsresult NumberInputType::GetValueMissingMessage(nsAString& aMessage) {
    135  return nsContentUtils::GetMaybeLocalizedString(
    136      nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
    137      mInputElement->OwnerDoc(), aMessage);
    138 }
    139 
    140 nsresult NumberInputType::GetBadInputMessage(nsAString& aMessage) {
    141  return nsContentUtils::GetMaybeLocalizedString(
    142      nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
    143      mInputElement->OwnerDoc(), aMessage);
    144 }
    145 
    146 bool NumberInputType::IsMutable() const {
    147  return !mInputElement->IsDisabledOrReadOnly();
    148 }
    149 
    150 /* input type=range */
    151 void RangeInputType::MinMaxStepAttrChanged() {
    152  // The value may need to change when @min/max/step changes since the value may
    153  // have been invalid and can now change to a valid value, or vice versa. For
    154  // example, consider: <input type=range value=-1 max=1 step=3>. The valid
    155  // range is 0 to 1 while the nearest valid steps are -1 and 2 (the max value
    156  // having prevented there being a valid step in range). Changing @max to/from
    157  // 1 and a number greater than on equal to 3 should change whether we have a
    158  // step mismatch or not.
    159  // The value may also need to change between a value that results in a step
    160  // mismatch and a value that results in overflow. For example, if @max in the
    161  // example above were to change from 1 to -1.
    162  nsAutoString value;
    163  GetNonFileValueInternal(value);
    164  SetValueInternal(value, TextControlState::ValueSetterOption::ByInternalAPI);
    165 }