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 : #ifndef InputType_h__
8 : #define InputType_h__
9 :
10 : #include <stdint.h>
11 : #include "mozilla/Decimal.h"
12 : #include "mozilla/UniquePtr.h"
13 : #include "nsIConstraintValidation.h"
14 : #include "nsString.h"
15 : #include "nsError.h"
16 :
17 : // This must come outside of any namespace, or else it won't overload with the
18 : // double based version in nsMathUtils.h
19 : inline mozilla::Decimal
20 0 : NS_floorModulo(mozilla::Decimal x, mozilla::Decimal y)
21 : {
22 0 : return (x - y * (x / y).floor());
23 : }
24 :
25 : namespace mozilla {
26 : namespace dom {
27 : class HTMLInputElement;
28 : } // namespace dom
29 : } // namespace mozilla
30 :
31 : struct DoNotDelete;
32 : class nsIFrame;
33 :
34 : /**
35 : * A common superclass for different types of a HTMLInputElement.
36 : */
37 : class InputType
38 : {
39 : public:
40 : static mozilla::UniquePtr<InputType, DoNotDelete>
41 : Create(mozilla::dom::HTMLInputElement* aInputElement, uint8_t aType,
42 : void* aMemory);
43 :
44 1 : virtual ~InputType() {}
45 :
46 : // Float value returned by GetStep() when the step attribute is set to 'any'.
47 : static const mozilla::Decimal kStepAny;
48 :
49 : /**
50 : * Drop the reference to the input element.
51 : */
52 : void DropReference();
53 :
54 : virtual bool IsTooLong() const;
55 : virtual bool IsTooShort() const;
56 : virtual bool IsValueMissing() const;
57 : virtual bool HasTypeMismatch() const;
58 : virtual bool HasPatternMismatch() const;
59 : virtual bool IsRangeOverflow() const;
60 : virtual bool IsRangeUnderflow() const;
61 : virtual bool HasStepMismatch(bool aUseZeroIfValueNaN) const;
62 : virtual bool HasBadInput() const;
63 :
64 : nsresult GetValidationMessage(nsAString& aValidationMessage,
65 : nsIConstraintValidation::ValidityStateType aType);
66 : virtual nsresult GetValueMissingMessage(nsXPIDLString& aMessage);
67 : virtual nsresult GetTypeMismatchMessage(nsXPIDLString& aMessage);
68 : virtual nsresult GetRangeOverflowMessage(nsXPIDLString& aMessage);
69 : virtual nsresult GetRangeUnderflowMessage(nsXPIDLString& aMessage);
70 : virtual nsresult GetBadInputMessage(nsXPIDLString& aMessage);
71 :
72 : virtual nsresult MinMaxStepAttrChanged();
73 :
74 : /**
75 : * Convert a string to a Decimal number in a type specific way,
76 : * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#concept-input-value-string-number
77 : * ie parse a date string to a timestamp if type=date,
78 : * or parse a number string to its value if type=number.
79 : * @param aValue the string to be parsed.
80 : * @param aResultValue the number as a Decimal.
81 : * @result whether the parsing was successful.
82 : */
83 : virtual bool ConvertStringToNumber(nsAString& aValue,
84 : mozilla::Decimal& aResultValue) const;
85 :
86 : /**
87 : * Convert a Decimal to a string in a type specific way, ie convert a timestamp
88 : * to a date string if type=date or append the number string representing the
89 : * value if type=number.
90 : *
91 : * @param aValue the Decimal to be converted
92 : * @param aResultString [out] the string representing the Decimal
93 : * @return whether the function succeeded, it will fail if the current input's
94 : * type is not supported or the number can't be converted to a string
95 : * as expected by the type.
96 : */
97 : virtual bool ConvertNumberToString(mozilla::Decimal aValue,
98 : nsAString& aResultString) const;
99 :
100 : protected:
101 8 : explicit InputType(mozilla::dom::HTMLInputElement* aInputElement)
102 8 : : mInputElement(aInputElement)
103 8 : {}
104 :
105 : /**
106 : * Get the mutable state of the element.
107 : * When the element isn't mutable (immutable), the value or checkedness
108 : * should not be changed by the user.
109 : *
110 : * See: https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-fe-mutable
111 : */
112 : virtual bool IsMutable() const;
113 :
114 : /**
115 : * Returns whether the input element's current value is the empty string.
116 : * This only makes sense for some input types; does NOT make sense for file
117 : * inputs.
118 : *
119 : * @return whether the input element's current value is the empty string.
120 : */
121 : bool IsValueEmpty() const;
122 :
123 : // A getter for callers that know we're not dealing with a file input, so they
124 : // don't have to think about the caller type.
125 : void GetNonFileValueInternal(nsAString& aValue) const;
126 :
127 : /**
128 : * Setting the input element's value.
129 : *
130 : * @param aValue String to set.
131 : * @param aFlags See nsTextEditorState::SetValueFlags.
132 : */
133 : nsresult SetValueInternal(const nsAString& aValue, uint32_t aFlags);
134 :
135 : /**
136 : * Return the base used to compute if a value matches step.
137 : * Basically, it's the min attribute if present and a default value otherwise.
138 : *
139 : * @return The step base.
140 : */
141 : mozilla::Decimal GetStepBase() const;
142 :
143 : /**
144 : * Get the primary frame for the input element.
145 : */
146 : nsIFrame* GetPrimaryFrame() const;
147 :
148 : /**
149 : * Parse a date string of the form yyyy-mm-dd
150 : *
151 : * @param aValue the string to be parsed.
152 : * @return the date in aYear, aMonth, aDay.
153 : * @return whether the parsing was successful.
154 : */
155 : bool ParseDate(const nsAString& aValue,
156 : uint32_t* aYear,
157 : uint32_t* aMonth,
158 : uint32_t* aDay) const;
159 :
160 : /**
161 : * Returns the time expressed in milliseconds of |aValue| being parsed as a
162 : * time following the HTML specifications:
163 : * https://html.spec.whatwg.org/multipage/infrastructure.html#parse-a-time-string
164 : *
165 : * Note: |aResult| can be null.
166 : *
167 : * @param aValue the string to be parsed.
168 : * @param aResult the time expressed in milliseconds representing the time [out]
169 : * @return whether the parsing was successful.
170 : */
171 : bool ParseTime(const nsAString& aValue, uint32_t* aResult) const;
172 :
173 : /**
174 : * Parse a month string of the form yyyy-mm
175 : *
176 : * @param the string to be parsed.
177 : * @return the year and month in aYear and aMonth.
178 : * @return whether the parsing was successful.
179 : */
180 : bool ParseMonth(const nsAString& aValue,
181 : uint32_t* aYear,
182 : uint32_t* aMonth) const;
183 :
184 : /**
185 : * Parse a week string of the form yyyy-Www
186 : *
187 : * @param the string to be parsed.
188 : * @return the year and week in aYear and aWeek.
189 : * @return whether the parsing was successful.
190 : */
191 : bool ParseWeek(const nsAString& aValue,
192 : uint32_t* aYear,
193 : uint32_t* aWeek) const;
194 :
195 : /**
196 : * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or
197 : * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits.
198 : *
199 : * @param the string to be parsed.
200 : * @return the date in aYear, aMonth, aDay and time expressed in milliseconds
201 : * in aTime.
202 : * @return whether the parsing was successful.
203 : */
204 : bool ParseDateTimeLocal(const nsAString& aValue,
205 : uint32_t* aYear,
206 : uint32_t* aMonth,
207 : uint32_t* aDay,
208 : uint32_t* aTime) const;
209 :
210 : /**
211 : * This methods returns the number of months between January 1970 and the
212 : * given year and month.
213 : */
214 : int32_t MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const;
215 :
216 : /**
217 : * This methods returns the number of days since epoch for a given year and
218 : * week.
219 : */
220 : double DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const;
221 :
222 : /**
223 : * This methods returns the day of the week given a date. If @isoWeek is true,
224 : * 7=Sunday, otherwise, 0=Sunday.
225 : */
226 : uint32_t DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay,
227 : bool isoWeek) const;
228 :
229 : /**
230 : * This methods returns the maximum number of week in a given year, the
231 : * result is either 52 or 53.
232 : */
233 : uint32_t MaximumWeekInYear(uint32_t aYear) const;
234 :
235 : mozilla::dom::HTMLInputElement* mInputElement;
236 : };
237 :
238 : // Custom deleter for UniquePtr<InputType> to avoid freeing memory pre-allocated
239 : // for InputType, but we still need to call the destructor explictly.
240 1 : struct DoNotDelete { void operator()(::InputType* p) { p->~InputType(); } };
241 :
242 : #endif /* InputType_h__ */
|