use-mask-input 1.0.2 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/example/App.example.d.ts +3 -0
  2. package/dist/{useMaskInput.test.d.ts → example/index.d.ts} +0 -0
  3. package/dist/index.js +1 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.modern.js +1 -2
  6. package/dist/index.modern.js.map +1 -1
  7. package/dist/useMaskInput.d.ts +3 -3
  8. package/node_modules/inputmask/README.md +94 -61
  9. package/node_modules/inputmask/dist/inputmask.es6.js +5 -0
  10. package/node_modules/inputmask/dist/inputmask.js +2900 -2868
  11. package/node_modules/inputmask/dist/inputmask.min.js +3 -3
  12. package/node_modules/inputmask/dist/jquery.inputmask.js +2840 -2807
  13. package/node_modules/inputmask/dist/jquery.inputmask.min.js +3 -3
  14. package/node_modules/inputmask/lib/bindings/inputmask.es6.js +5 -0
  15. package/node_modules/inputmask/lib/canUseDOM.js +7 -0
  16. package/node_modules/inputmask/lib/defaults.js +36 -2
  17. package/node_modules/inputmask/lib/definitions.js +1 -1
  18. package/node_modules/inputmask/lib/dependencyLibs/events.js +19 -9
  19. package/node_modules/inputmask/lib/environment.js +2 -0
  20. package/node_modules/inputmask/lib/eventhandlers.js +55 -44
  21. package/node_modules/inputmask/lib/eventruler.js +10 -9
  22. package/node_modules/inputmask/lib/extensions/inputmask.date.extensions.js +543 -430
  23. package/node_modules/inputmask/lib/extensions/inputmask.extensions.js +117 -99
  24. package/node_modules/inputmask/lib/extensions/inputmask.numeric.extensions.js +590 -574
  25. package/node_modules/inputmask/lib/global/window.js +2 -1
  26. package/node_modules/inputmask/lib/inputHandling.js +30 -18
  27. package/node_modules/inputmask/lib/inputmask.js +9 -2
  28. package/node_modules/inputmask/lib/inputmaskElement.js +2 -1
  29. package/node_modules/inputmask/lib/keycode.json +4 -0
  30. package/node_modules/inputmask/lib/mask-lexer.js +434 -436
  31. package/node_modules/inputmask/lib/mask.js +4 -4
  32. package/node_modules/inputmask/lib/masktoken.js +13 -0
  33. package/node_modules/inputmask/lib/polyfills/Array.includes.js +48 -0
  34. package/node_modules/inputmask/lib/{getPrototypeOf.js → polyfills/Object.getPrototypeOf.js} +0 -0
  35. package/node_modules/inputmask/lib/positioning.js +5 -5
  36. package/node_modules/inputmask/lib/validation-tests.js +108 -46
  37. package/node_modules/inputmask/lib/validation.js +82 -73
  38. package/node_modules/inputmask/package.json +41 -69
  39. package/package.json +40 -38
  40. package/node_modules/inputmask/CHANGELOG.md +0 -744
  41. package/node_modules/inputmask/index.js +0 -1
  42. package/node_modules/inputmask/lib/dependencyLibs/inputmask.dependencyLib.jqlite.js +0 -20
@@ -7,469 +7,582 @@
7
7
  import Inputmask from "../inputmask";
8
8
  import keyCode from "../keycode.json";
9
9
  import escapeRegex from "../escapeRegex";
10
+ import {seekNext} from "../positioning";
11
+ import {getMaskTemplate} from "../validation-tests";
10
12
 
11
13
  const $ = Inputmask.dependencyLib;
12
- var currentYear = new Date().getFullYear(),
13
- //supported codes for formatting
14
- //http://blog.stevenlevithan.com/archives/date-time-format
15
- //https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7
16
- formatCode = { //regex, valueSetter, type, displayformatter
17
- d: ["[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", Date.prototype.getDate], //Day of the month as digits; no leading zero for single-digit days.
18
- dd: ["0[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", function () {
19
- return pad(Date.prototype.getDate.call(this), 2);
20
- }], //Day of the month as digits; leading zero for single-digit days.
21
- ddd: [""], //Day of the week as a three-letter abbreviation.
22
- dddd: [""], //Day of the week as its full name.
23
- m: ["[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
24
- return Date.prototype.getMonth.call(this) + 1;
25
- }], //Month as digits; no leading zero for single-digit months.
26
- mm: ["0[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
27
- return pad(Date.prototype.getMonth.call(this) + 1, 2);
28
- }], //Month as digits; leading zero for single-digit months.
29
- mmm: [""], //Month as a three-letter abbreviation.
30
- mmmm: [""], //Month as its full name.
31
- yy: ["[0-9]{2}", Date.prototype.setFullYear, "year", function () {
32
- return pad(Date.prototype.getFullYear.call(this), 2);
33
- }], //Year as last two digits; leading zero for years less than 10.
34
- yyyy: ["[0-9]{4}", Date.prototype.setFullYear, "year", function () {
35
- return pad(Date.prototype.getFullYear.call(this), 4);
36
- }],
37
- h: ["[1-9]|1[0-2]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (12-hour clock).
38
- hh: ["0[1-9]|1[0-2]", Date.prototype.setHours, "hours", function () {
39
- return pad(Date.prototype.getHours.call(this), 2);
40
- }], //Hours; leading zero for single-digit hours (12-hour clock).
41
- hx: [function (x) {
42
- return `[0-9]{${x}}`;
43
- }, Date.prototype.setHours, "hours", function (x) {
44
- return Date.prototype.getHours;
45
- }], //Hours; no limit; set maximum digits
46
- H: ["1?[0-9]|2[0-3]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (24-hour clock).
47
- HH: ["0[0-9]|1[0-9]|2[0-3]", Date.prototype.setHours, "hours", function () {
48
- return pad(Date.prototype.getHours.call(this), 2);
49
- }], //Hours; leading zero for single-digit hours (24-hour clock).
50
- Hx: [function (x) {
51
- return `[0-9]{${x}}`;
52
- }, Date.prototype.setHours, "hours", function (x) {
53
- return function () {
54
- return pad(Date.prototype.getHours.call(this), x);
55
- };
56
- }], //Hours; no limit; set maximum digits
57
- M: ["[1-5]?[0-9]", Date.prototype.setMinutes, "minutes", Date.prototype.getMinutes], //Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months.
58
- MM: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setMinutes, "minutes", function () {
59
- return pad(Date.prototype.getMinutes.call(this), 2);
60
- }], //Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months.
61
- s: ["[1-5]?[0-9]", Date.prototype.setSeconds, "seconds", Date.prototype.getSeconds], //Seconds; no leading zero for single-digit seconds.
62
- ss: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setSeconds, "seconds", function () {
63
- return pad(Date.prototype.getSeconds.call(this), 2);
64
- }], //Seconds; leading zero for single-digit seconds.
65
- l: ["[0-9]{3}", Date.prototype.setMilliseconds, "milliseconds", function () {
66
- return pad(Date.prototype.getMilliseconds.call(this), 3);
67
- }], //Milliseconds. 3 digits.
68
- L: ["[0-9]{2}", Date.prototype.setMilliseconds, "milliseconds", function () {
69
- return pad(Date.prototype.getMilliseconds.call(this), 2);
70
- }], //Milliseconds. 2 digits.
71
- t: ["[ap]"], //Lowercase, single-character time marker string: a or p.
72
- tt: ["[ap]m"], //two-character time marker string: am or pm.
73
- T: ["[AP]"], //single-character time marker string: A or P.
74
- TT: ["[AP]M"], //two-character time marker string: AM or PM.
75
- Z: [""], //US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500
76
- o: [""], //GMT/UTC timezone offset, e.g. -0500 or +0230.
77
- S: [""] //The date's ordinal suffix (st, nd, rd, or th).
78
- },
79
- formatAlias = {
80
- isoDate: "yyyy-mm-dd", //2007-06-09
81
- isoTime: "HH:MM:ss", //17:46:21
82
- isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", //2007-06-09T17:46:21
83
- isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" //2007-06-09T22:46:21Z
84
- };
14
+
15
+ class DateObject {
16
+ constructor(mask, format, opts) {
17
+ this.mask = mask;
18
+ this.format = format;
19
+ this.opts = opts;
20
+ this._date = new Date(1, 0, 1);
21
+ this.initDateObject(mask, this.opts);
22
+ }
23
+
24
+ get date() {
25
+ if (this._date === undefined) {
26
+ this._date = new Date(1, 0, 1);
27
+ this.initDateObject(undefined, this.opts);
28
+ }
29
+ return this._date;
30
+ }
31
+
32
+ initDateObject(mask, opts) {
33
+ let match;
34
+ getTokenizer(opts).lastIndex = 0;
35
+ while ((match = getTokenizer(opts).exec(this.format))) {
36
+ let dynMatches = new RegExp("\\d+$").exec(match[0]),
37
+ fcode = dynMatches ? (match[0][0] + "x") : match[0],
38
+ value;
39
+ if (mask !== undefined) {
40
+ if (dynMatches) {
41
+ let lastIndex = getTokenizer(opts).lastIndex,
42
+ tokanMatch = getTokenMatch(match.index, opts);
43
+ getTokenizer(opts).lastIndex = lastIndex;
44
+ value = mask.slice(0, mask.indexOf(tokanMatch.nextMatch[0]));
45
+ } else {
46
+ value = mask.slice(0, fcode.length);
47
+ }
48
+ mask = mask.slice(value.length);
49
+ }
50
+
51
+ if (Object.prototype.hasOwnProperty.call(formatCode, fcode)) {
52
+ this.setValue(this, value, fcode, formatCode[fcode][2], formatCode[fcode][1]);
53
+ }
54
+ }
55
+ }
56
+
57
+ setValue(dateObj, value, fcode, targetProp, dateOperation) {
58
+ if (value !== undefined) {
59
+ dateObj[targetProp] = targetProp === "ampm" ? value : value.replace(/[^0-9]/g, "0");
60
+ dateObj["raw" + targetProp] = value.replace(/\s/g, "_");
61
+ }
62
+ if (dateOperation !== undefined) {
63
+ let datavalue = dateObj[targetProp];
64
+ if ((targetProp === "day" && parseInt(datavalue) === 29) || (targetProp === "month" && parseInt(datavalue) === 2)) {
65
+ if (parseInt(dateObj.day) === 29 && parseInt(dateObj.month) === 2 && (dateObj.year === "" || dateObj.year === undefined)) {
66
+ //set temporary leap year in dateObj
67
+ dateObj._date.setFullYear(2012, 1, 29);
68
+ }
69
+ }
70
+ if (targetProp === "day") {
71
+ useDateObject = true;
72
+ if (parseInt(datavalue) === 0)
73
+ datavalue = 1;
74
+ }
75
+ if (targetProp === "month")
76
+ useDateObject = true;
77
+ if (targetProp === "year") {
78
+ useDateObject = true;
79
+ if (datavalue.length < 4)
80
+ datavalue = pad(datavalue, 4, true);
81
+ }
82
+ if (datavalue !== "" && !isNaN(datavalue)) dateOperation.call(dateObj._date, datavalue);
83
+ if (targetProp === "ampm")
84
+ dateOperation.call(dateObj._date, datavalue);
85
+ }
86
+ }
87
+
88
+ reset() {
89
+ this._date = new Date(1, 0, 1);
90
+ }
91
+
92
+ reInit() {
93
+ this._date = undefined;
94
+ this.date;
95
+ }
96
+ }
97
+
98
+ let currentYear = new Date().getFullYear(),
99
+ useDateObject = false,
100
+ //supported codes for formatting
101
+ //http://blog.stevenlevithan.com/archives/date-time-format
102
+ //https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7
103
+ formatCode = { //regex, valueSetter, type, displayformatter
104
+ d: ["[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", Date.prototype.getDate], //Day of the month as digits; no leading zero for single-digit days.
105
+ dd: ["0[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", function () {
106
+ return pad(Date.prototype.getDate.call(this), 2);
107
+ }], //Day of the month as digits; leading zero for single-digit days.
108
+ ddd: [""], //Day of the week as a three-letter abbreviation.
109
+ dddd: [""], //Day of the week as its full name.
110
+ m: ["[1-9]|1[012]", function (val) {
111
+ let mval = val ? parseInt(val) : 0;
112
+ if (mval > 0) mval--;
113
+ return Date.prototype.setMonth.call(this, mval);
114
+ }, "month", function () {
115
+ return Date.prototype.getMonth.call(this) + 1;
116
+ }], //Month as digits; no leading zero for single-digit months.
117
+ mm: ["0[1-9]|1[012]", function (val) {
118
+ let mval = val ? parseInt(val) : 0;
119
+ if (mval > 0) mval--;
120
+ return Date.prototype.setMonth.call(this, mval);
121
+ }, "month", function () {
122
+ return pad(Date.prototype.getMonth.call(this) + 1, 2);
123
+ }], //Month as digits; leading zero for single-digit months.
124
+ mmm: [""], //Month as a three-letter abbreviation.
125
+ mmmm: [""], //Month as its full name.
126
+ yy: ["[0-9]{2}", Date.prototype.setFullYear, "year", function () {
127
+ return pad(Date.prototype.getFullYear.call(this), 2);
128
+ }], //Year as last two digits; leading zero for years less than 10.
129
+ yyyy: ["[0-9]{4}", Date.prototype.setFullYear, "year", function () {
130
+ return pad(Date.prototype.getFullYear.call(this), 4);
131
+ }],
132
+ h: ["[1-9]|1[0-2]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (12-hour clock).
133
+ hh: ["0[1-9]|1[0-2]", Date.prototype.setHours, "hours", function () {
134
+ return pad(Date.prototype.getHours.call(this), 2);
135
+ }], //Hours; leading zero for single-digit hours (12-hour clock).
136
+ hx: [function (x) {
137
+ return `[0-9]{${x}}`;
138
+ }, Date.prototype.setHours, "hours", function (x) {
139
+ return Date.prototype.getHours;
140
+ }], //Hours; no limit; set maximum digits
141
+ H: ["1?[0-9]|2[0-3]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (24-hour clock).
142
+ HH: ["0[0-9]|1[0-9]|2[0-3]", Date.prototype.setHours, "hours", function () {
143
+ return pad(Date.prototype.getHours.call(this), 2);
144
+ }], //Hours; leading zero for single-digit hours (24-hour clock).
145
+ Hx: [function (x) {
146
+ return `[0-9]{${x}}`;
147
+ }, Date.prototype.setHours, "hours", function (x) {
148
+ return function () {
149
+ return pad(Date.prototype.getHours.call(this), x);
150
+ };
151
+ }], //Hours; no limit; set maximum digits
152
+ M: ["[1-5]?[0-9]", Date.prototype.setMinutes, "minutes", Date.prototype.getMinutes], //Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months.
153
+ MM: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setMinutes, "minutes", function () {
154
+ return pad(Date.prototype.getMinutes.call(this), 2);
155
+ }], //Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months.
156
+ s: ["[1-5]?[0-9]", Date.prototype.setSeconds, "seconds", Date.prototype.getSeconds], //Seconds; no leading zero for single-digit seconds.
157
+ ss: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setSeconds, "seconds", function () {
158
+ return pad(Date.prototype.getSeconds.call(this), 2);
159
+ }], //Seconds; leading zero for single-digit seconds.
160
+ l: ["[0-9]{3}", Date.prototype.setMilliseconds, "milliseconds", function () {
161
+ return pad(Date.prototype.getMilliseconds.call(this), 3);
162
+ }], //Milliseconds. 3 digits.
163
+ L: ["[0-9]{2}", Date.prototype.setMilliseconds, "milliseconds", function () {
164
+ return pad(Date.prototype.getMilliseconds.call(this), 2);
165
+ }], //Milliseconds. 2 digits.
166
+ t: ["[ap]", setAMPM, "ampm", getAMPM, 1], //Lowercase, single-character time marker string: a or p.
167
+ tt: ["[ap]m", setAMPM, "ampm", getAMPM, 2], //two-character time marker string: am or pm.
168
+ T: ["[AP]", setAMPM, "ampm", getAMPM, 1], //single-character time marker string: A or P.
169
+ TT: ["[AP]M", setAMPM, "ampm", getAMPM, 2], //two-character time marker string: AM or PM.
170
+ Z: [".*", undefined, "Z", getTimeZoneAbbreviated], //US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500
171
+ o: [""], //GMT/UTC timezone offset, e.g. -0500 or +0230.
172
+ S: [""] //The date's ordinal suffix (st, nd, rd, or th).
173
+ },
174
+ formatAlias = {
175
+ isoDate: "yyyy-mm-dd", //2007-06-09
176
+ isoTime: "HH:MM:ss", //17:46:21
177
+ isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", //2007-06-09T17:46:21
178
+ isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" //2007-06-09T22:46:21Z
179
+ };
180
+
181
+ function setAMPM(value) {
182
+ const hours = this.getHours();
183
+ if (value.toLowerCase().includes("p")) {
184
+ this.setHours(hours + 12);
185
+ // console.log("setAMPM + 12");
186
+ } else if (value.toLowerCase().includes("a") && hours >= 12) {
187
+ this.setHours(hours - 12);
188
+ }
189
+ }
190
+
191
+ function getAMPM() {
192
+ let date = this,
193
+ hours = date.getHours();
194
+ hours = hours || 12;
195
+ return hours >= 12 ? "PM" : "AM";
196
+ }
197
+
198
+ function getTimeZoneAbbreviated() {
199
+ //not perfect, but ok for now
200
+ let date = this, {1: tz} = date.toString().match(/\((.+)\)/);
201
+ if (tz.includes(" ")) {
202
+ tz = tz.replace("-", " ").toUpperCase();
203
+ tz = tz.split(" ").map(([first]) => first).join("");
204
+ }
205
+ return tz;
206
+ }
85
207
 
86
208
  function formatcode(match) {
87
- var dynMatches = new RegExp("\\d+$").exec(match[0]);
88
- if (dynMatches && dynMatches[0] !== undefined) {
89
- var fcode = formatCode[match[0][0] + "x"].slice("");
90
- fcode[0] = fcode[0](dynMatches[0]);
91
- fcode[3] = fcode[3](dynMatches[0]);
92
-
93
- return fcode;
94
- } else if (formatCode[match[0]]) {
95
- return formatCode[match[0]];
96
- }
209
+ var dynMatches = new RegExp("\\d+$").exec(match[0]);
210
+ if (dynMatches && dynMatches[0] !== undefined) {
211
+ var fcode = formatCode[match[0][0] + "x"].slice("");
212
+ fcode[0] = fcode[0](dynMatches[0]);
213
+ fcode[3] = fcode[3](dynMatches[0]);
214
+
215
+ return fcode;
216
+ } else if (formatCode[match[0]]) {
217
+ return formatCode[match[0]];
218
+ }
97
219
  }
98
220
 
99
221
  function getTokenizer(opts) {
100
- if (!opts.tokenizer) {
101
- var tokens = [], dyntokens = [];
102
- for (var ndx in formatCode) {
103
- if (/\.*x$/.test(ndx)) {
104
- var dynToken = ndx[0] + "\\d+";
105
- if (dyntokens.indexOf(dynToken) === -1) {
106
- dyntokens.push(dynToken);
107
- }
108
- } else if (tokens.indexOf(ndx[0]) === -1) {
109
- tokens.push(ndx[0]);
110
- }
111
- }
112
- opts.tokenizer = "(" + (dyntokens.length > 0 ? dyntokens.join("|") + "|" : "") + tokens.join("+|") + ")+?|.";
113
- opts.tokenizer = new RegExp(opts.tokenizer, "g");
114
- }
115
-
116
- return opts.tokenizer;
222
+ if (!opts.tokenizer) {
223
+ var tokens = [], dyntokens = [];
224
+ for (var ndx in formatCode) {
225
+ if (/\.*x$/.test(ndx)) {
226
+ var dynToken = ndx[0] + "\\d+";
227
+ if (dyntokens.indexOf(dynToken) === -1) {
228
+ dyntokens.push(dynToken);
229
+ }
230
+ } else if (tokens.indexOf(ndx[0]) === -1) {
231
+ tokens.push(ndx[0]);
232
+ }
233
+ }
234
+ opts.tokenizer = "(" + (dyntokens.length > 0 ? dyntokens.join("|") + "|" : "") + tokens.join("+|") + ")+?|.";
235
+ opts.tokenizer = new RegExp(opts.tokenizer, "g");
236
+ }
237
+
238
+ return opts.tokenizer;
117
239
  }
118
240
 
119
241
  function prefillYear(dateParts, currentResult, opts) {
120
- if (dateParts.year !== dateParts.rawyear) {
121
- var crrntyear = currentYear.toString(),
122
- enteredPart = dateParts.rawyear.replace(/[^0-9]/g, ""),
123
- currentYearPart = crrntyear.slice(0, enteredPart.length),
124
- currentYearNextPart = crrntyear.slice(enteredPart.length);
125
- if (enteredPart.length === 2 && enteredPart === currentYearPart) {
126
- const entryCurrentYear = new Date(currentYear, dateParts.month - 1, dateParts.day);
127
- if (dateParts.day == entryCurrentYear.getDate() && (!opts.max || opts.max.date.getTime() >= entryCurrentYear.getTime())) {
128
- //update dateParts
129
- dateParts.date.setFullYear(currentYear);
130
- dateParts.year = crrntyear;
131
- //update result
132
- currentResult.insert = [{
133
- pos: currentResult.pos + 1,
134
- c: currentYearNextPart[0]
135
- }, {
136
- pos: currentResult.pos + 2,
137
- c: currentYearNextPart[1]
138
- }];
139
- }
140
- }
141
- }
142
-
143
- return currentResult;
242
+ if (dateParts.year !== dateParts.rawyear) {
243
+ var crrntyear = currentYear.toString(),
244
+ enteredPart = dateParts.rawyear.replace(/[^0-9]/g, ""),
245
+ currentYearPart = crrntyear.slice(0, enteredPart.length),
246
+ currentYearNextPart = crrntyear.slice(enteredPart.length);
247
+ if (enteredPart.length === 2 && enteredPart === currentYearPart) {
248
+ const entryCurrentYear = new Date(currentYear, dateParts.month - 1, dateParts.day);
249
+ if (dateParts.day == entryCurrentYear.getDate() && (!opts.max || opts.max.date.getTime() >= entryCurrentYear.getTime())) {
250
+ //update dateParts
251
+ dateParts.date.setFullYear(currentYear);
252
+ dateParts.year = crrntyear;
253
+ //update result
254
+ currentResult.insert = [{
255
+ pos: currentResult.pos + 1,
256
+ c: currentYearNextPart[0]
257
+ }, {
258
+ pos: currentResult.pos + 2,
259
+ c: currentYearNextPart[1]
260
+ }];
261
+ }
262
+ }
263
+ }
264
+
265
+ return currentResult;
144
266
  }
145
267
 
146
268
  function isValidDate(dateParts, currentResult, opts) {
147
- if (!isFinite(dateParts.rawday)
148
- || (dateParts.day == "29" && !isFinite(dateParts.rawyear))
149
- || new Date(dateParts.date.getFullYear(), isFinite(dateParts.rawmonth) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day) {
150
- return currentResult;
151
- } else { //take corrective action if possible
152
- if (dateParts.day == "29") {
153
- var tokenMatch = getTokenMatch(currentResult.pos, opts);
154
- if (tokenMatch.targetMatch[0] === "yyyy" && currentResult.pos - tokenMatch.targetMatchIndex === 2) {
155
- currentResult.remove = currentResult.pos + 1;
156
- return currentResult;
157
- }
158
- }
159
- return false;
160
- }
269
+ if (!useDateObject) return true;
270
+ if (dateParts.rawday === undefined
271
+ || (!isFinite(dateParts.rawday) && new Date(dateParts.date.getFullYear(), isFinite(dateParts.rawmonth) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day)
272
+ || (dateParts.day == "29" && (!isFinite(dateParts.rawyear) || dateParts.rawyear === undefined || dateParts.rawyear === ""))
273
+ || new Date(dateParts.date.getFullYear(), isFinite(dateParts.rawmonth) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day) {
274
+ return currentResult;
275
+ } else { //take corrective action if possible
276
+ if (dateParts.day == "29") {
277
+ var tokenMatch = getTokenMatch(currentResult.pos, opts);
278
+ if (tokenMatch.targetMatch[0] === "yyyy" && currentResult.pos - tokenMatch.targetMatchIndex === 2) {
279
+ currentResult.remove = currentResult.pos + 1;
280
+ return currentResult;
281
+ }
282
+ } else if (dateParts.month == "02" && dateParts.day == "30" && currentResult.c !== undefined) {
283
+ dateParts.day = "03";
284
+ dateParts.date.setDate(3);
285
+ dateParts.date.setMonth(1);
286
+ currentResult.insert = [{pos: currentResult.pos, c: "0"}, {pos: currentResult.pos + 1, c: currentResult.c}];
287
+ currentResult.caret = seekNext.call(this, currentResult.pos + 1);
288
+ return currentResult;
289
+ }
290
+ return false;
291
+ }
161
292
  }
162
293
 
163
294
  function isDateInRange(dateParts, result, opts, maskset, fromCheckval) {
164
- if (!result) return result;
165
- if (opts.min) {
166
- if (dateParts["rawyear"]) {
167
- var rawYear = dateParts["rawyear"].replace(/[^0-9]/g, ""),
168
- minYear = opts.min.year.substr(0, rawYear.length), maxYear;
169
- if (rawYear < minYear) { //is out of range?
170
- var tokenMatch = getTokenMatch(result.pos, opts);
171
- rawYear = dateParts["rawyear"].substr(0, (result.pos - tokenMatch.targetMatchIndex) + 1);
172
- minYear = opts.min.year.substr(0, rawYear.length);
173
- if (minYear <= rawYear) { //this can match
174
- result.remove = tokenMatch.targetMatchIndex + rawYear.length;
175
- return result;
176
- } else {
177
- if (tokenMatch.targetMatch[0] === "yyyy") {
178
- rawYear = dateParts["rawyear"].substr(1, 1);
179
- } else {
180
- rawYear = dateParts["rawyear"].substr(0, 1);
181
- }
182
- minYear = opts.min.year.substr(2, 1);
183
- maxYear = opts.max ? opts.max.year.substr(2, 1) : rawYear;
184
- if (rawYear.length === 1 && minYear <= rawYear <= maxYear && fromCheckval !== true) { //this can match
185
- if (tokenMatch.targetMatch[0] === "yyyy") {
186
- result.insert = [{
187
- pos: result.pos + 1, c: rawYear, strict: true
188
- }];
189
- result.caret = result.pos + 2;
190
- maskset.validPositions[result.pos].input = opts.min.year[1]; //postval ~ position is already validated
191
- } else {
192
- result.insert = [{
193
- pos: result.pos + 1, c: opts.min.year[1], strict: true
194
- }, {
195
- pos: result.pos + 2, c: rawYear, strict: true
196
- }];
197
- result.caret = result.pos + 3;
198
- maskset.validPositions[result.pos].input = opts.min.year[0]; //postval ~ position is already validated
199
- }
200
- return result;
201
- }
202
- result = false;
203
- }
204
- }
205
- }
206
- if (result && dateParts["year"] && dateParts["year"] === dateParts["rawyear"]) {
207
- if (opts.min.date.getTime() === opts.min.date.getTime()) {
208
- result = opts.min.date.getTime() <= dateParts.date.getTime();
209
- }
210
- }
211
- }
212
-
213
- if (result && opts.max && opts.max.date.getTime() === opts.max.date.getTime()) {
214
- result = opts.max.date.getTime() >= dateParts.date.getTime();
215
- }
216
- return result;
295
+ if (!result) return result;
296
+ if (result && opts.min) {
297
+ if (/*useDateObject && (dateParts["year"] === undefined || dateParts["yearSet"]) && */opts.min.date.getTime() === opts.min.date.getTime()) {
298
+ let match;
299
+ dateParts.reset();
300
+ getTokenizer(opts).lastIndex = 0;
301
+ while ((match = getTokenizer(opts).exec(opts.inputFormat))) {
302
+ var fcode;
303
+ if ((fcode = formatcode(match))) {
304
+ if (fcode[3]) {
305
+ var setFn = fcode[1];
306
+ var current = dateParts[fcode[2]],
307
+ minVal = opts.min[fcode[2]],
308
+ maxVal = opts.max ? opts.max[fcode[2]] : minVal,
309
+ curVal = [];
310
+
311
+ let forceCurrentValue = false;
312
+ for (let i = 0; i < minVal.length; i++) {
313
+ if (maskset.validPositions[i + match.index] === undefined && !forceCurrentValue) {
314
+ curVal[i] = minVal[i];
315
+ // ADD +1 to whoile
316
+ if (fcode[2] === "year" && current.length - 1 == i && minVal != maxVal)
317
+ curVal = (parseInt(curVal.join("")) + 1).toString().split("");
318
+ if (fcode[2] === "ampm" && minVal != maxVal && opts.min.date.getTime() > dateParts.date.getTime())
319
+ curVal[i] = maxVal[i];
320
+ } else {
321
+ curVal[i] = current[i];
322
+ forceCurrentValue = forceCurrentValue || current[i] > minVal[i];
323
+ }
324
+ }
325
+
326
+ setFn.call(dateParts._date, curVal.join(""));
327
+ }
328
+ }
329
+ }
330
+
331
+ result = opts.min.date.getTime() <= dateParts.date.getTime();
332
+ dateParts.reInit();
333
+ }
334
+ }
335
+
336
+ if (result && opts.max) {
337
+ if (opts.max.date.getTime() === opts.max.date.getTime()) {
338
+ result = opts.max.date.getTime() >= dateParts.date.getTime();
339
+ }
340
+ }
341
+ return result;
217
342
  }
218
343
 
219
344
  //parse the given format and return a mask pattern
220
345
  //when a dateObjValue is passed a datestring in the requested format is returned
221
346
  function parse(format, dateObjValue, opts, raw) {
222
- //parse format to regex string
223
- var mask = "", match, fcode;
224
- getTokenizer(opts).lastIndex = 0;
225
- while ((match = getTokenizer(opts).exec(format))) {
226
- if (dateObjValue === undefined) {
227
- if ((fcode = formatcode(match))) {
228
- mask += "(" + fcode[0] + ")";
229
- } else {
230
- switch (match[0]) {
231
- case "[":
232
- mask += "(";
233
- break;
234
- case "]":
235
- mask += ")?";
236
- break;
237
- default:
238
- mask += escapeRegex(match[0]);
239
- }
240
- }
241
- } else {
242
- if ((fcode = formatcode(match))) {
243
- if (raw !== true && fcode[3]) {
244
- var getFn = fcode[3];
245
- mask += getFn.call(dateObjValue.date);
246
- } else if (fcode[2]) {
247
- mask += dateObjValue["raw" + fcode[2]];
248
- } else {
249
- mask += match[0];
250
- }
251
- } else {
252
- mask += match[0];
253
- }
254
- }
255
- }
256
- return mask;
347
+ //parse format to regex string
348
+ var mask = "", match, fcode;
349
+ getTokenizer(opts).lastIndex = 0;
350
+ while ((match = getTokenizer(opts).exec(format))) {
351
+ if (dateObjValue === undefined) {
352
+ if ((fcode = formatcode(match))) {
353
+ mask += "(" + fcode[0] + ")";
354
+ } else {
355
+ switch (match[0]) {
356
+ case "[":
357
+ mask += "(";
358
+ break;
359
+ case "]":
360
+ mask += ")?";
361
+ break;
362
+ default:
363
+ mask += escapeRegex(match[0]);
364
+ }
365
+ }
366
+ } else {
367
+ if ((fcode = formatcode(match))) {
368
+ if (raw !== true && fcode[3]) {
369
+ var getFn = fcode[3];
370
+ mask += getFn.call(dateObjValue.date);
371
+ } else if (fcode[2]) {
372
+ mask += dateObjValue["raw" + fcode[2]];
373
+ } else {
374
+ mask += match[0];
375
+ }
376
+ } else {
377
+ mask += match[0];
378
+ }
379
+ }
380
+ }
381
+ return mask;
257
382
  }
258
383
 
259
384
  //padding function
260
- function pad(val, len) {
261
- val = String(val);
262
- len = len || 2;
263
- while (val.length < len) val = "0" + val;
264
- return val;
385
+ function pad(val, len, right) {
386
+ val = String(val);
387
+ len = len || 2;
388
+ while (val.length < len) val = right ? val + "0" : "0" + val;
389
+ return val;
265
390
  }
266
391
 
267
- function analyseMask(maskString, format, opts) {
268
- var dateObj = {"date": new Date(1, 0, 1)}, targetProp, mask = maskString, match, dateOperation;
269
-
270
- function setValue(dateObj, value, opts) {
271
- dateObj[targetProp] = value.replace(/[^0-9]/g, "0");
272
- dateObj["raw" + targetProp] = value;
273
-
274
- if (dateOperation !== undefined) {
275
- dateOperation.call(dateObj.date, targetProp == "month" ? parseInt(dateObj[targetProp]) - 1 : dateObj[targetProp]);
276
- }
277
- }
278
-
279
- if (typeof mask === "string") {
280
- getTokenizer(opts).lastIndex = 0;
281
- while ((match = getTokenizer(opts).exec(format))) {
282
- let dynMatches = new RegExp("\\d+$").exec(match[0]),
283
- fcode = dynMatches ? (match[0][0] + "x") : match[0],
284
- value;
285
- if (dynMatches) {
286
- let lastIndex = getTokenizer(opts).lastIndex,
287
- tokanMatch = getTokenMatch(match.index, opts);
288
- getTokenizer(opts).lastIndex = lastIndex;
289
- value = mask.slice(0, mask.indexOf(tokanMatch.nextMatch[0]));
290
- } else {
291
- value = mask.slice(0, fcode.length);
292
- }
293
-
294
- if (Object.prototype.hasOwnProperty.call(formatCode, fcode)) {
295
- // targetValidator = formatCode[match[0]][0];
296
- targetProp = formatCode[fcode][2];
297
- dateOperation = formatCode[fcode][1];
298
- setValue(dateObj, value, opts);
299
- }
300
- mask = mask.slice(value.length);
301
- }
302
-
303
- return dateObj;
304
- } else if (mask && typeof mask === "object" && Object.prototype.hasOwnProperty.call(mask, "date")) {
305
- return mask;
306
- }
307
- return undefined;
392
+ function analyseMask(mask, format, opts) {
393
+ if (typeof mask === "string") {
394
+ return new DateObject(mask, format, opts);
395
+ } else if (mask && typeof mask === "object" && Object.prototype.hasOwnProperty.call(mask, "date")) {
396
+ return mask;
397
+ }
398
+ return undefined;
308
399
  }
309
400
 
310
401
  function importDate(dateObj, opts) {
311
- return parse(opts.inputFormat, {date: dateObj}, opts);
402
+ return parse(opts.inputFormat, {date: dateObj}, opts);
312
403
  }
313
404
 
314
405
  function getTokenMatch(pos, opts) {
315
- var calcPos = 0, targetMatch, match, matchLength = 0;
316
- getTokenizer(opts).lastIndex = 0;
317
- while ((match = getTokenizer(opts).exec(opts.inputFormat))) {
318
- var dynMatches = new RegExp("\\d+$").exec(match[0]);
319
- matchLength = dynMatches ? parseInt(dynMatches[0]) : match[0].length;
320
- calcPos += matchLength;
321
- if (calcPos >= pos) {
322
- targetMatch = match;
323
- match = getTokenizer(opts).exec(opts.inputFormat);
324
- break;
325
- }
326
- }
327
- return {
328
- targetMatchIndex: calcPos - matchLength,
329
- nextMatch: match,
330
- targetMatch: targetMatch
331
- };
406
+ var calcPos = 0, targetMatch, match, matchLength = 0;
407
+ getTokenizer(opts).lastIndex = 0;
408
+ while ((match = getTokenizer(opts).exec(opts.inputFormat))) {
409
+ var dynMatches = new RegExp("\\d+$").exec(match[0]);
410
+ matchLength = dynMatches ? parseInt(dynMatches[0]) : match[0].length;
411
+ calcPos += matchLength;
412
+ if (calcPos >= pos + 1) {
413
+ targetMatch = match;
414
+ match = getTokenizer(opts).exec(opts.inputFormat);
415
+ break;
416
+ }
417
+ }
418
+ return {
419
+ targetMatchIndex: calcPos - matchLength,
420
+ nextMatch: match,
421
+ targetMatch: targetMatch
422
+ };
332
423
  }
333
424
 
334
425
 
335
426
  Inputmask.extendAliases({
336
- "datetime": {
337
- mask: function (opts) {
338
- //do not allow numeric input in datetime alias
339
- opts.numericInput = false;
340
-
341
- //localize
342
- formatCode.S = opts.i18n.ordinalSuffix.join("|");
343
-
344
- opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAlias
345
- opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAlias
346
- opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAlias
347
- opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[[\]]/, "");
348
- opts.regex = parse(opts.inputFormat, undefined, opts);
349
- opts.min = analyseMask(opts.min, opts.inputFormat, opts);
350
- opts.max = analyseMask(opts.max, opts.inputFormat, opts);
351
- return null; //migrate to regex mask
352
- },
353
- placeholder: "", //set default as none (~ auto); when a custom placeholder is passed it will be used
354
- inputFormat: "isoDateTime", //format used to input the date
355
- displayFormat: undefined, //visual format when the input looses focus
356
- outputFormat: undefined, //unmasking format
357
- min: null, //needs to be in the same format as the inputfornat
358
- max: null, //needs to be in the same format as the inputfornat,
359
- skipOptionalPartCharacter: "",
360
- // Internationalization strings
361
- i18n: {
362
- dayNames: [
363
- "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
364
- "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
365
- ],
366
- monthNames: [
367
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
368
- "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
369
- ],
370
- ordinalSuffix: ["st", "nd", "rd", "th"]
371
- },
372
- preValidation: function (buffer, pos, c, isSelection, opts, maskset, caretPos, strict) {
373
- if (strict) return true;
374
- if (isNaN(c) && buffer[pos] !== c) {
375
- var tokenMatch = getTokenMatch(pos, opts);
376
- if (tokenMatch.nextMatch && tokenMatch.nextMatch[0] === c && tokenMatch.targetMatch[0].length > 1) {
377
- var validator = formatCode[tokenMatch.targetMatch[0]][0];
378
- if (new RegExp(validator).test("0" + buffer[pos - 1])) {
379
- buffer[pos] = buffer[pos - 1];
380
- buffer[pos - 1] = "0";
381
- return {
382
- fuzzy: true,
383
- buffer: buffer,
384
- refreshFromBuffer: {start: pos - 1, end: pos + 1},
385
- pos: pos + 1
386
- };
387
- }
388
- }
389
- }
390
- return true;
391
- },
392
- postValidation: function (buffer, pos, c, currentResult, opts, maskset, strict, fromCheckval) {
393
- if (strict) return true;
394
- var tokenMatch, validator;
395
- if (currentResult === false) {
396
- tokenMatch = getTokenMatch(pos + 1, opts);
397
- if (tokenMatch.targetMatch && tokenMatch.targetMatchIndex === pos && tokenMatch.targetMatch[0].length > 1 && formatCode[tokenMatch.targetMatch[0]] !== undefined) {
398
- validator = formatCode[tokenMatch.targetMatch[0]][0];
399
- if (new RegExp(validator).test("0" + c)) {
400
- return {
401
- insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}],
402
- pos: pos + 1
403
- };
404
- }
405
- }
406
- return currentResult;
407
- }
408
-
409
- if (currentResult.fuzzy) {
410
- buffer = currentResult.buffer;
411
- pos = currentResult.pos;
412
- }
413
-
414
- //full validate target
415
- tokenMatch = getTokenMatch(pos, opts);
416
- if (tokenMatch.targetMatch && tokenMatch.targetMatch[0] && formatCode[tokenMatch.targetMatch[0]] !== undefined) {
417
- validator = formatCode[tokenMatch.targetMatch[0]][0];
418
- var part = buffer.slice(tokenMatch.targetMatchIndex, tokenMatch.targetMatchIndex + tokenMatch.targetMatch[0].length);
419
- if (new RegExp(validator).test(part.join("")) === false && tokenMatch.targetMatch[0].length === 2 && maskset.validPositions[tokenMatch.targetMatchIndex] && maskset.validPositions[tokenMatch.targetMatchIndex + 1]) {
420
- maskset.validPositions[tokenMatch.targetMatchIndex + 1].input = "0";
421
- }
422
- }
423
-
424
- var result = currentResult, dateParts = analyseMask(buffer.join(""), opts.inputFormat, opts);
425
- if (result && dateParts.date.getTime() === dateParts.date.getTime()) { //check for a valid date ~ an invalid date returns NaN which isn't equal
426
- result = prefillYear(dateParts, result, opts);
427
- result = isValidDate(dateParts, result, opts);
428
- result = isDateInRange(dateParts, result, opts, maskset, fromCheckval);
429
- }
430
-
431
- if (pos && result && currentResult.pos !== pos) {
432
- return {
433
- buffer: parse(opts.inputFormat, dateParts, opts).split(""),
434
- refreshFromBuffer: {start: pos, end: currentResult.pos}
435
- };
436
- }
437
-
438
- return result;
439
- }
440
- ,
441
- onKeyDown: function (e, buffer, caretPos, opts) {
442
- var input = this;
443
- if (e.ctrlKey && e.keyCode === keyCode.RIGHT) {
444
- input.inputmask._valueSet(importDate(new Date(), opts));
445
- $(input).trigger("setvalue");
446
- }
447
- }
448
- ,
449
- onUnMask: function (maskedValue, unmaskedValue, opts) {
450
- return unmaskedValue ? parse(opts.outputFormat, analyseMask(maskedValue, opts.inputFormat, opts), opts, true) : unmaskedValue;
451
- }
452
- ,
453
- casing: function (elem, test, pos, validPositions) {
454
- if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase();
455
- if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase();
456
- return elem;
457
- }
458
- ,
459
- onBeforeMask: function (initialValue, opts) {
460
- if (Object.prototype.toString.call(initialValue) === "[object Date]") {
461
- initialValue = importDate(initialValue, opts);
462
- }
463
-
464
- return initialValue;
465
- }
466
- ,
467
- insertMode: false,
468
- shiftPositions:
469
- false,
470
- keepStatic:
471
- false,
472
- inputmode:
473
- "numeric"
474
- }
475
- });
427
+ "datetime": {
428
+ mask: function (opts) {
429
+ //do not allow numeric input in datetime alias
430
+ opts.numericInput = false;
431
+
432
+ //localize
433
+ formatCode.S = opts.i18n.ordinalSuffix.join("|");
434
+
435
+ opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAlias
436
+ opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAlias
437
+ opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAlias
438
+ opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[[\]]/, "");
439
+ opts.regex = parse(opts.inputFormat, undefined, opts);
440
+ opts.min = analyseMask(opts.min, opts.inputFormat, opts);
441
+ opts.max = analyseMask(opts.max, opts.inputFormat, opts);
442
+ return null; //migrate to regex mask
443
+ },
444
+ placeholder: "", //set default as none (~ auto); when a custom placeholder is passed it will be used
445
+ inputFormat: "isoDateTime", //format used to input the date
446
+ displayFormat: null, //visual format when the input looses focus
447
+ outputFormat: null, //unmasking format
448
+ min: null, //needs to be in the same format as the inputfornat
449
+ max: null, //needs to be in the same format as the inputfornat,
450
+ skipOptionalPartCharacter: "",
451
+ // Internationalization strings
452
+ i18n: {
453
+ dayNames: [
454
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
455
+ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
456
+ ],
457
+ monthNames: [
458
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
459
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
460
+ ],
461
+ ordinalSuffix: ["st", "nd", "rd", "th"]
462
+ },
463
+ preValidation: function (buffer, pos, c, isSelection, opts, maskset, caretPos, strict) {
464
+ if (strict) return true;
465
+ if (isNaN(c) && buffer[pos] !== c) {
466
+ var tokenMatch = getTokenMatch(pos, opts);
467
+ if (tokenMatch.nextMatch && tokenMatch.nextMatch[0] === c && tokenMatch.targetMatch[0].length > 1) {
468
+ var validator = formatCode[tokenMatch.targetMatch[0]][0];
469
+ if (new RegExp(validator).test("0" + buffer[pos - 1])) {
470
+ buffer[pos] = buffer[pos - 1];
471
+ buffer[pos - 1] = "0";
472
+ return {
473
+ fuzzy: true,
474
+ buffer: buffer,
475
+ refreshFromBuffer: {start: pos - 1, end: pos + 1},
476
+ pos: pos + 1
477
+ };
478
+ }
479
+ }
480
+ }
481
+ return true;
482
+ },
483
+ postValidation: function (buffer, pos, c, currentResult, opts, maskset, strict, fromCheckval) {
484
+ const inputmask = this;
485
+
486
+ if (strict) return true;
487
+ var tokenMatch, validator;
488
+ if (currentResult === false) { //try some shifting
489
+ tokenMatch = getTokenMatch(pos + 1, opts);
490
+ if (tokenMatch.targetMatch && tokenMatch.targetMatchIndex === pos && tokenMatch.targetMatch[0].length > 1 && formatCode[tokenMatch.targetMatch[0]] !== undefined) {
491
+ validator = formatCode[tokenMatch.targetMatch[0]][0];
492
+ } else {
493
+ tokenMatch = getTokenMatch(pos + 2, opts);
494
+ if (tokenMatch.targetMatch && tokenMatch.targetMatchIndex === pos + 1 && tokenMatch.targetMatch[0].length > 1 && formatCode[tokenMatch.targetMatch[0]] !== undefined) {
495
+ validator = formatCode[tokenMatch.targetMatch[0]][0];
496
+ }
497
+ }
498
+ if (validator !== undefined) {
499
+ if (maskset.validPositions[pos + 1] !== undefined && new RegExp(validator).test(c + "0")) {
500
+ buffer[pos] = c;
501
+ buffer[pos + 1] = "0";
502
+ currentResult = {
503
+ //insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}],
504
+ pos: pos + 2, //this will triggeer a refreshfrombuffer
505
+ caret: pos
506
+ };
507
+ } else if (new RegExp(validator).test("0" + c)) {
508
+ buffer[pos] = "0";
509
+ buffer[pos + 1] = c;
510
+ currentResult = {
511
+ //insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}],
512
+ pos: pos + 2 //this will triggeer a refreshfrombuffer
513
+ };
514
+ }
515
+ }
516
+
517
+ if (currentResult === false) return currentResult;
518
+ }
519
+
520
+ if (currentResult.fuzzy) {
521
+ buffer = currentResult.buffer;
522
+ pos = currentResult.pos;
523
+ }
524
+
525
+ //full validate target
526
+ tokenMatch = getTokenMatch(pos, opts);
527
+ if (tokenMatch.targetMatch && tokenMatch.targetMatch[0] && formatCode[tokenMatch.targetMatch[0]] !== undefined) {
528
+ let fcode = formatCode[tokenMatch.targetMatch[0]];
529
+ validator = fcode[0];
530
+ var part = buffer.slice(tokenMatch.targetMatchIndex, tokenMatch.targetMatchIndex + tokenMatch.targetMatch[0].length);
531
+ if (new RegExp(validator).test(part.join("")) === false && tokenMatch.targetMatch[0].length === 2 && maskset.validPositions[tokenMatch.targetMatchIndex] && maskset.validPositions[tokenMatch.targetMatchIndex + 1]) {
532
+ maskset.validPositions[tokenMatch.targetMatchIndex + 1].input = "0";
533
+ }
534
+ if (fcode[2] == "year") {
535
+ var _buffer = getMaskTemplate.call(inputmask, false, 1, undefined, true);
536
+ for (let i = pos + 1; i < buffer.length; i++) {
537
+ buffer[i] = _buffer[i];
538
+ delete maskset.validPositions[i];
539
+ }
540
+ }
541
+ }
542
+
543
+ var result = currentResult, dateParts = analyseMask(buffer.join(""), opts.inputFormat, opts);
544
+ if (result && dateParts.date.getTime() === dateParts.date.getTime()) { //check for a valid date ~ an invalid date returns NaN which isn't equal
545
+ if (opts.prefillYear) result = prefillYear(dateParts, result, opts);
546
+ result = isValidDate.call(inputmask, dateParts, result, opts);
547
+ result = isDateInRange(dateParts, result, opts, maskset, fromCheckval);
548
+ }
549
+
550
+ if (pos !== undefined && result && currentResult.pos !== pos) {
551
+ return {
552
+ buffer: parse(opts.inputFormat, dateParts, opts).split(""),
553
+ refreshFromBuffer: {start: pos, end: currentResult.pos},
554
+ pos: currentResult.caret || currentResult.pos //correct caret position
555
+ };
556
+ }
557
+
558
+ return result;
559
+ },
560
+ onKeyDown: function (e, buffer, caretPos, opts) {
561
+ var input = this;
562
+ if (e.ctrlKey && e.keyCode === keyCode.RIGHT) {
563
+ input.inputmask._valueSet(importDate(new Date(), opts));
564
+ $(input).trigger("setvalue");
565
+ }
566
+ },
567
+ onUnMask: function (maskedValue, unmaskedValue, opts) {
568
+ return unmaskedValue ? parse(opts.outputFormat, analyseMask(maskedValue, opts.inputFormat, opts), opts, true) : unmaskedValue;
569
+ },
570
+ casing: function (elem, test, pos, validPositions) {
571
+ if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase();
572
+ if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase();
573
+ return elem;
574
+ },
575
+ onBeforeMask: function (initialValue, opts) {
576
+ if (Object.prototype.toString.call(initialValue) === "[object Date]") {
577
+ initialValue = importDate(initialValue, opts);
578
+ }
579
+
580
+ return initialValue;
581
+ },
582
+ insertMode: false,
583
+ shiftPositions: false,
584
+ keepStatic: false,
585
+ inputmode: "numeric",
586
+ prefillYear: true //Allows to disable prefill for datetime year.
587
+ }
588
+ });