diff options
Diffstat (limited to 'dom/html/input/InputType.h')
-rw-r--r-- | dom/html/input/InputType.h | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/dom/html/input/InputType.h b/dom/html/input/InputType.h new file mode 100644 index 0000000000..a4853e09b2 --- /dev/null +++ b/dom/html/input/InputType.h @@ -0,0 +1,235 @@ +/* -*- 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 <stdint.h> +#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<InputType> 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<InputType, DoNotDelete> 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<bool> 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__ */ |