/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_InputType_h__ #define mozilla_dom_InputType_h__ #include #include "mozilla/Decimal.h" #include "mozilla/Maybe.h" #include "mozilla/TextControlState.h" #include "mozilla/UniquePtr.h" #include "nsIConstraintValidation.h" #include "nsString.h" #include "nsError.h" // This must come outside of any namespace, or else it won't overload with the // double based version in nsMathUtils.h inline mozilla::Decimal NS_floorModulo(mozilla::Decimal x, mozilla::Decimal y) { return (x - y * (x / y).floor()); } class nsIFrame; namespace mozilla::dom { class HTMLInputElement; /** * A common superclass for different types of a HTMLInputElement. */ class InputType { public: using ValueSetterOption = TextControlState::ValueSetterOption; using ValueSetterOptions = TextControlState::ValueSetterOptions; // Custom deleter for UniquePtr to avoid freeing memory // pre-allocated for InputType, but we still need to call the destructor // explictly. struct DoNotDelete { void operator()(InputType* p) { p->~InputType(); } }; static UniquePtr Create( HTMLInputElement* aInputElement, FormControlType, void* aMemory); virtual ~InputType() = default; // Float value returned by GetStep() when the step attribute is set to 'any'. static const Decimal kStepAny; /** * Drop the reference to the input element. */ void DropReference(); virtual bool MinAndMaxLengthApply() const { return false; } virtual bool IsTooLong() const; virtual bool IsTooShort() const; virtual bool IsValueMissing() const; virtual bool HasTypeMismatch() const; // May return Nothing() if the JS engine failed to evaluate the regex. virtual Maybe HasPatternMismatch() const; virtual bool IsRangeOverflow() const; virtual bool IsRangeUnderflow() const; virtual bool HasStepMismatch() const; virtual bool HasBadInput() const; nsresult GetValidationMessage( nsAString& aValidationMessage, nsIConstraintValidation::ValidityStateType aType); virtual nsresult GetValueMissingMessage(nsAString& aMessage); virtual nsresult GetTypeMismatchMessage(nsAString& aMessage); virtual nsresult GetRangeOverflowMessage(nsAString& aMessage); virtual nsresult GetRangeUnderflowMessage(nsAString& aMessage); virtual nsresult GetBadInputMessage(nsAString& aMessage); MOZ_CAN_RUN_SCRIPT virtual void MinMaxStepAttrChanged() {} /** * Convert a string to a Decimal number in a type specific way, * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#concept-input-value-string-number * ie parse a date string to a timestamp if type=date, * or parse a number string to its value if type=number. * @param aValue the string to be parsed. * @param aResultValue the number as a Decimal. * @result whether the parsing was successful. */ virtual bool ConvertStringToNumber(nsAString& aValue, Decimal& aResultValue) const; /** * Convert a Decimal to a string in a type specific way, ie convert a * timestamp to a date string if type=date or append the number string * representing the value if type=number. * * @param aValue the Decimal to be converted * @param aResultString [out] the string representing the Decimal * @return whether the function succeeded, it will fail if the current input's * type is not supported or the number can't be converted to a string * as expected by the type. */ virtual bool ConvertNumberToString(Decimal aValue, nsAString& aResultString) const; protected: explicit InputType(HTMLInputElement* aInputElement) : mInputElement(aInputElement) {} /** * Get the mutable state of the element. * When the element isn't mutable (immutable), the value or checkedness * should not be changed by the user. * * See: * https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-fe-mutable */ virtual bool IsMutable() const; /** * Returns whether the input element's current value is the empty string. * This only makes sense for some input types; does NOT make sense for file * inputs. * * @return whether the input element's current value is the empty string. */ bool IsValueEmpty() const; // A getter for callers that know we're not dealing with a file input, so they // don't have to think about the caller type. void GetNonFileValueInternal(nsAString& aValue) const; /** * Setting the input element's value. * * @param aValue String to set. * @param aOptions See TextControlState::ValueSetterOption. */ MOZ_CAN_RUN_SCRIPT nsresult SetValueInternal(const nsAString& aValue, const ValueSetterOptions& aOptions); /** * Get the primary frame for the input element. */ nsIFrame* GetPrimaryFrame() const; /** * Parse a date string of the form yyyy-mm-dd * * @param aValue the string to be parsed. * @return the date in aYear, aMonth, aDay. * @return whether the parsing was successful. */ bool ParseDate(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth, uint32_t* aDay) const; /** * Returns the time expressed in milliseconds of |aValue| being parsed as a * time following the HTML specifications: * https://html.spec.whatwg.org/multipage/infrastructure.html#parse-a-time-string * * Note: |aResult| can be null. * * @param aValue the string to be parsed. * @param aResult the time expressed in milliseconds representing the time * [out] * @return whether the parsing was successful. */ bool ParseTime(const nsAString& aValue, uint32_t* aResult) const; /** * Parse a month string of the form yyyy-mm * * @param the string to be parsed. * @return the year and month in aYear and aMonth. * @return whether the parsing was successful. */ bool ParseMonth(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth) const; /** * Parse a week string of the form yyyy-Www * * @param the string to be parsed. * @return the year and week in aYear and aWeek. * @return whether the parsing was successful. */ bool ParseWeek(const nsAString& aValue, uint32_t* aYear, uint32_t* aWeek) const; /** * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits. * * @param the string to be parsed. * @return the date in aYear, aMonth, aDay and time expressed in milliseconds * in aTime. * @return whether the parsing was successful. */ bool ParseDateTimeLocal(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth, uint32_t* aDay, uint32_t* aTime) const; /** * This methods returns the number of months between January 1970 and the * given year and month. */ int32_t MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const; /** * This methods returns the number of days since epoch for a given year and * week. */ double DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const; /** * This methods returns the day of the week given a date. If @isoWeek is true, * 7=Sunday, otherwise, 0=Sunday. */ uint32_t DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay, bool isoWeek) const; /** * This methods returns the maximum number of week in a given year, the * result is either 52 or 53. */ uint32_t MaximumWeekInYear(uint32_t aYear) const; HTMLInputElement* mInputElement; }; } // namespace mozilla::dom #endif /* mozilla_dom_InputType_h__ */