summaryrefslogtreecommitdiffstats
path: root/dom/html/input/DateTimeInputTypes.h
blob: a34f0bfca8825fb4c3af574f6fe26e9c2665bee8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* -*- 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_DateTimeInputTypes_h__
#define mozilla_dom_DateTimeInputTypes_h__

#include "mozilla/dom/InputType.h"

namespace mozilla {
namespace dom {

class DateTimeInputTypeBase : public InputType {
 public:
  ~DateTimeInputTypeBase() override = default;

  bool IsValueMissing() const override;
  bool IsRangeOverflow() const override;
  bool IsRangeUnderflow() const override;
  bool HasStepMismatch(bool aUseZeroIfValueNaN) const override;
  bool HasBadInput() const override;

  nsresult GetRangeOverflowMessage(nsAString& aMessage) override;
  nsresult GetRangeUnderflowMessage(nsAString& aMessage) override;

  nsresult MinMaxStepAttrChanged() override;

 protected:
  explicit DateTimeInputTypeBase(HTMLInputElement* aInputElement)
      : InputType(aInputElement) {}

  bool IsMutable() const override;

  /**
   * This method converts aValue (milliseconds within a day) to hours, minutes,
   * seconds and milliseconds.
   */
  bool GetTimeFromMs(double aValue, uint16_t* aHours, uint16_t* aMinutes,
                     uint16_t* aSeconds, uint16_t* aMilliseconds) const;

  // Minimum year limited by HTML standard, year >= 1.
  static const double kMinimumYear;
  // Maximum year limited by ECMAScript date object range, year <= 275760.
  static const double kMaximumYear;
  // Maximum valid month is 275760-09.
  static const double kMaximumMonthInMaximumYear;
  // Maximum valid week is 275760-W37.
  static const double kMaximumWeekInMaximumYear;
  // Milliseconds in a day.
  static const double kMsPerDay;
};

// input type=date
class DateInputType : public DateTimeInputTypeBase {
 public:
  static InputType* Create(HTMLInputElement* aInputElement, void* aMemory) {
    return new (aMemory) DateInputType(aInputElement);
  }

  // Currently, for input date and time, only date can have an invalid value, as
  // we forbid or autocorrect values that are not in the valid range for time.
  // For example, in 12hr format, if user enters '2' in the hour field, it will
  // be treated as '02' and automatically advance to the next field.
  nsresult GetBadInputMessage(nsAString& aMessage) override;

  bool ConvertStringToNumber(nsAString& aValue,
                             Decimal& aResultValue) const override;
  bool ConvertNumberToString(Decimal aValue,
                             nsAString& aResultString) const override;

 private:
  explicit DateInputType(HTMLInputElement* aInputElement)
      : DateTimeInputTypeBase(aInputElement) {}
};

// input type=time
class TimeInputType : public DateTimeInputTypeBase {
 public:
  static InputType* Create(HTMLInputElement* aInputElement, void* aMemory) {
    return new (aMemory) TimeInputType(aInputElement);
  }

  bool ConvertStringToNumber(nsAString& aValue,
                             Decimal& aResultValue) const override;
  bool ConvertNumberToString(Decimal aValue,
                             nsAString& aResultString) const override;
  bool IsRangeOverflow() const override;
  bool IsRangeUnderflow() const override;
  nsresult GetRangeOverflowMessage(nsAString& aMessage) override;
  nsresult GetRangeUnderflowMessage(nsAString& aMessage) override;

 private:
  explicit TimeInputType(HTMLInputElement* aInputElement)
      : DateTimeInputTypeBase(aInputElement) {}

  // https://html.spec.whatwg.org/multipage/input.html#has-a-reversed-range
  bool HasReversedRange() const;
  bool IsReversedRangeUnderflowAndOverflow() const;
  nsresult GetReversedRangeUnderflowAndOverflowMessage(nsAString& aMessage);
};

// input type=week
class WeekInputType : public DateTimeInputTypeBase {
 public:
  static InputType* Create(HTMLInputElement* aInputElement, void* aMemory) {
    return new (aMemory) WeekInputType(aInputElement);
  }

  bool ConvertStringToNumber(nsAString& aValue,
                             Decimal& aResultValue) const override;
  bool ConvertNumberToString(Decimal aValue,
                             nsAString& aResultString) const override;

 private:
  explicit WeekInputType(HTMLInputElement* aInputElement)
      : DateTimeInputTypeBase(aInputElement) {}
};

// input type=month
class MonthInputType : public DateTimeInputTypeBase {
 public:
  static InputType* Create(HTMLInputElement* aInputElement, void* aMemory) {
    return new (aMemory) MonthInputType(aInputElement);
  }

  bool ConvertStringToNumber(nsAString& aValue,
                             Decimal& aResultValue) const override;
  bool ConvertNumberToString(Decimal aValue,
                             nsAString& aResultString) const override;

 private:
  explicit MonthInputType(HTMLInputElement* aInputElement)
      : DateTimeInputTypeBase(aInputElement) {}
};

// input type=datetime-local
class DateTimeLocalInputType : public DateTimeInputTypeBase {
 public:
  static InputType* Create(HTMLInputElement* aInputElement, void* aMemory) {
    return new (aMemory) DateTimeLocalInputType(aInputElement);
  }

  bool ConvertStringToNumber(nsAString& aValue,
                             Decimal& aResultValue) const override;
  bool ConvertNumberToString(Decimal aValue,
                             nsAString& aResultString) const override;

 private:
  explicit DateTimeLocalInputType(HTMLInputElement* aInputElement)
      : DateTimeInputTypeBase(aInputElement) {}
};

}  // namespace dom
}  // namespace mozilla

#endif /* mozilla_dom_DateTimeInputTypes_h__ */