@markuplint/types 3.0.0-dev.25 → 3.0.0-dev.40
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.
- package/lib/css-syntax.js +6 -6
- package/lib/types.schema.d.ts +1 -1
- package/package.json +4 -6
- package/types.schema.json +16 -67
- package/gen/specific-schema.json +0 -98
- package/gen/types.ts +0 -66
- package/patches/css-tree+2.3.1.patch +0 -23
- package/src/check-multi-types.ts +0 -35
- package/src/check.spec.ts +0 -83
- package/src/check.ts +0 -48
- package/src/css-syntax.spec.ts +0 -167
- package/src/css-syntax.ts +0 -188
- package/src/debug.ts +0 -3
- package/src/defs.ts +0 -811
- package/src/enum.ts +0 -25
- package/src/get-candidate.ts +0 -24
- package/src/index.ts +0 -3
- package/src/keyword-type.ts +0 -64
- package/src/list.spec.ts +0 -133
- package/src/list.ts +0 -34
- package/src/match-result.ts +0 -49
- package/src/number.ts +0 -46
- package/src/primitive/index.spec.ts +0 -65
- package/src/primitive/index.ts +0 -7
- package/src/primitive/is-float.ts +0 -8
- package/src/primitive/is-int.ts +0 -8
- package/src/primitive/is-non-zero-uint.ts +0 -8
- package/src/primitive/is-quantity.ts +0 -38
- package/src/primitive/is-uint.ts +0 -15
- package/src/primitive/range.ts +0 -14
- package/src/primitive/split-unit.ts +0 -20
- package/src/rfc/is-bcp-47.spec.ts +0 -23
- package/src/rfc/is-bcp-47.ts +0 -13
- package/src/token/index.ts +0 -2
- package/src/token/token-collection.spec.ts +0 -147
- package/src/token/token-collection.ts +0 -444
- package/src/token/token.ts +0 -144
- package/src/types.schema.ts +0 -1113
- package/src/types.ts +0 -118
- package/src/w3c/check-serialized-permissions-policy.spec.ts +0 -38
- package/src/w3c/check-serialized-permissions-policy.ts +0 -303
- package/src/whatwg/check-autocomplete.spec.ts +0 -387
- package/src/whatwg/check-autocomplete.ts +0 -380
- package/src/whatwg/check-datetime/date-string.ts +0 -44
- package/src/whatwg/check-datetime/datetime-tokens.ts +0 -600
- package/src/whatwg/check-datetime/duration-string.ts +0 -399
- package/src/whatwg/check-datetime/global-date-and-time-string.ts +0 -96
- package/src/whatwg/check-datetime/index.spec.ts +0 -333
- package/src/whatwg/check-datetime/index.ts +0 -36
- package/src/whatwg/check-datetime/local-date-and-time-string.ts +0 -163
- package/src/whatwg/check-datetime/month-string.ts +0 -31
- package/src/whatwg/check-datetime/time-string.ts +0 -49
- package/src/whatwg/check-datetime/time-zone-offset-string.ts +0 -93
- package/src/whatwg/check-datetime/week-string.ts +0 -41
- package/src/whatwg/check-datetime/year-string.ts +0 -26
- package/src/whatwg/check-datetime/yearless-date-string.ts +0 -38
- package/src/whatwg/check-mime-type.spec.ts +0 -59
- package/src/whatwg/check-mime-type.ts +0 -46
- package/src/whatwg/is-abs-url.spec.ts +0 -8
- package/src/whatwg/is-abs-url.ts +0 -31
- package/src/whatwg/is-browser-context-name.ts +0 -16
- package/src/whatwg/is-custom-element-name.ts +0 -76
- package/src/whatwg/is-itemprop-name.ts +0 -17
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,600 +0,0 @@
|
|
|
1
|
-
import type { TokenEachCheck } from '../../token/token-collection';
|
|
2
|
-
|
|
3
|
-
import { log } from '../../debug';
|
|
4
|
-
import { matched, unmatched } from '../../match-result';
|
|
5
|
-
|
|
6
|
-
export const datetimeTokenCheck: Record<
|
|
7
|
-
| 'year'
|
|
8
|
-
| 'month'
|
|
9
|
-
| 'date'
|
|
10
|
-
| 'hour'
|
|
11
|
-
| 'minute'
|
|
12
|
-
| 'second'
|
|
13
|
-
| 'secondFractionalPart'
|
|
14
|
-
| 'week'
|
|
15
|
-
| 'hyphen'
|
|
16
|
-
| 'colon'
|
|
17
|
-
| 'extra'
|
|
18
|
-
| 'colonOrEnd'
|
|
19
|
-
| 'decimalPointOrEnd'
|
|
20
|
-
| 'localDateTimeSeparator'
|
|
21
|
-
| 'normalizedlocalDateTimeSeparator'
|
|
22
|
-
| 'plusOrMinusSign'
|
|
23
|
-
| 'weekSign',
|
|
24
|
-
TokenEachCheck
|
|
25
|
-
> &
|
|
26
|
-
Record<'_year' | '_month', number | null> = {
|
|
27
|
-
/**
|
|
28
|
-
* Temporary year state
|
|
29
|
-
*/
|
|
30
|
-
_year: null,
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Temporary month state
|
|
34
|
-
*/
|
|
35
|
-
_month: null,
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* > Four or more ASCII digits, representing year, where year > 0
|
|
39
|
-
*/
|
|
40
|
-
year(year) {
|
|
41
|
-
log('Parsing Datetime Year: "%s"', year?.value);
|
|
42
|
-
|
|
43
|
-
this._year = null;
|
|
44
|
-
|
|
45
|
-
if (!year || !year.value) {
|
|
46
|
-
return unmatched('', 'missing-token', {
|
|
47
|
-
expects: [{ type: 'common', value: 'year' }],
|
|
48
|
-
partName: 'year',
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!year.match(/^[0-9]+$/)) {
|
|
53
|
-
return year.unmatched({
|
|
54
|
-
reason: 'unexpected-token',
|
|
55
|
-
expects: [],
|
|
56
|
-
partName: 'year',
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (year.length < 4) {
|
|
61
|
-
return year.unmatched({
|
|
62
|
-
reason: { type: 'out-of-range-length-digit', gte: 4 },
|
|
63
|
-
expects: [],
|
|
64
|
-
partName: 'year',
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
this._year = year.toNumber();
|
|
69
|
-
|
|
70
|
-
if (this._year <= 0) {
|
|
71
|
-
return year.unmatched({
|
|
72
|
-
reason: { type: 'out-of-range', gt: 0 },
|
|
73
|
-
expects: [],
|
|
74
|
-
partName: 'year',
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* > Two ASCII digits, representing the month month, in the range 1 ≤ month ≤ 12
|
|
81
|
-
*/
|
|
82
|
-
month(month) {
|
|
83
|
-
log('Parsing Datetime Month: "%s"', month?.value);
|
|
84
|
-
|
|
85
|
-
this._month = null;
|
|
86
|
-
|
|
87
|
-
if (!month || !month.value) {
|
|
88
|
-
return unmatched('', 'missing-token', {
|
|
89
|
-
expects: [{ type: 'common', value: 'month' }],
|
|
90
|
-
partName: 'month',
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!month.match(/^[0-9]+$/)) {
|
|
95
|
-
return month.unmatched({
|
|
96
|
-
reason: 'unexpected-token',
|
|
97
|
-
expects: [],
|
|
98
|
-
partName: 'month',
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (month.length !== 2) {
|
|
103
|
-
return month.unmatched({
|
|
104
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
105
|
-
expects: [],
|
|
106
|
-
partName: 'month',
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
this._month = month.toNumber();
|
|
111
|
-
|
|
112
|
-
if (!(1 <= this._month && this._month <= 12)) {
|
|
113
|
-
return month.unmatched({
|
|
114
|
-
reason: { type: 'out-of-range', gte: 1, lte: 12 },
|
|
115
|
-
expects: [],
|
|
116
|
-
partName: 'month',
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* > Two ASCII digits, representing day, in the range 1 ≤ day ≤ maxday where maxday is the number of days in the month month and year year
|
|
123
|
-
*
|
|
124
|
-
* or
|
|
125
|
-
*
|
|
126
|
-
* In Yearless dates,
|
|
127
|
-
* > Two ASCII digits, representing day,
|
|
128
|
-
* > in the range 1 ≤ day ≤ maxday where maxday is the number of days
|
|
129
|
-
* > in the month month and any arbitrary leap year (e.g. 4 or 2000)
|
|
130
|
-
* > In other words, if the month is "02", meaning February,
|
|
131
|
-
* > then the day can be 29, as if the year was a leap year.
|
|
132
|
-
*/
|
|
133
|
-
date(date) {
|
|
134
|
-
log('Parsing Datetime Date: "%s"', date?.value);
|
|
135
|
-
|
|
136
|
-
if (!date || !date.value) {
|
|
137
|
-
return unmatched('', 'missing-token', {
|
|
138
|
-
expects: [{ type: 'common', value: 'date' }],
|
|
139
|
-
partName: 'date',
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (!date.match(/^[0-9]+$/)) {
|
|
144
|
-
return date.unmatched({
|
|
145
|
-
reason: 'unexpected-token',
|
|
146
|
-
expects: [],
|
|
147
|
-
partName: 'date',
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (date.length !== 2) {
|
|
152
|
-
return date.unmatched({
|
|
153
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
154
|
-
expects: [],
|
|
155
|
-
partName: 'date',
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Set the leap year if _year is null
|
|
160
|
-
const year = this._year || 2000;
|
|
161
|
-
const isLeap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
162
|
-
const month = this._month || 1;
|
|
163
|
-
const dayOfMonth = daysOfMonth[month] + (month === 2 && isLeap ? 1 : 0);
|
|
164
|
-
const _date = date.toNumber();
|
|
165
|
-
|
|
166
|
-
log('Temporary Year and Month: %s, %s', this._year, this._month);
|
|
167
|
-
log('Computed Year, Month, and Day of Month: %s, %s, %s', year, month, dayOfMonth);
|
|
168
|
-
|
|
169
|
-
if (!(1 <= _date && _date <= dayOfMonth)) {
|
|
170
|
-
return date.unmatched({
|
|
171
|
-
reason: { type: 'out-of-range', gte: 1, lte: dayOfMonth },
|
|
172
|
-
expects: [],
|
|
173
|
-
partName: 'date',
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* > Two ASCII digits, representing hour, in the range 0 ≤ hour ≤ 23
|
|
180
|
-
*/
|
|
181
|
-
hour(hour) {
|
|
182
|
-
log('Parsing Datetime Hour: "%s"', hour?.value);
|
|
183
|
-
|
|
184
|
-
if (!hour || !hour.value) {
|
|
185
|
-
return unmatched('', 'missing-token', {
|
|
186
|
-
expects: [{ type: 'common', value: 'hour' }],
|
|
187
|
-
partName: 'hour',
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (!hour.match(/^[0-9]+$/)) {
|
|
192
|
-
return hour.unmatched({
|
|
193
|
-
reason: 'unexpected-token',
|
|
194
|
-
expects: [],
|
|
195
|
-
partName: 'hour',
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (hour.length !== 2) {
|
|
200
|
-
return hour.unmatched({
|
|
201
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
202
|
-
expects: [],
|
|
203
|
-
partName: 'hour',
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const _hour = hour.toNumber();
|
|
208
|
-
|
|
209
|
-
if (!(0 <= _hour && _hour <= 23)) {
|
|
210
|
-
return hour.unmatched({
|
|
211
|
-
reason: { type: 'out-of-range', gte: 0, lte: 23 },
|
|
212
|
-
expects: [],
|
|
213
|
-
partName: 'hour',
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* > Two ASCII digits, representing minute, in the range 0 ≤ minute ≤ 59
|
|
220
|
-
*/
|
|
221
|
-
minute(minute) {
|
|
222
|
-
log('Parsing Datetime Minute: "%s"', minute?.value);
|
|
223
|
-
|
|
224
|
-
if (!minute || !minute.value) {
|
|
225
|
-
return unmatched('', 'missing-token', {
|
|
226
|
-
expects: [{ type: 'common', value: 'minute' }],
|
|
227
|
-
partName: 'minute',
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (!minute.match(/^[0-9]+$/)) {
|
|
232
|
-
return minute.unmatched({
|
|
233
|
-
reason: 'unexpected-token',
|
|
234
|
-
expects: [],
|
|
235
|
-
partName: 'minute',
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (minute.length !== 2) {
|
|
240
|
-
return minute.unmatched({
|
|
241
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
242
|
-
expects: [],
|
|
243
|
-
partName: 'minute',
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const _minute = minute.toNumber();
|
|
248
|
-
|
|
249
|
-
if (!(0 <= _minute && _minute <= 59)) {
|
|
250
|
-
return minute.unmatched({
|
|
251
|
-
reason: { type: 'out-of-range', gte: 0, lte: 59 },
|
|
252
|
-
expects: [],
|
|
253
|
-
partName: 'minute',
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* > Two ASCII digits, representing the integer part of second, in the range 0 ≤ s ≤ 59
|
|
260
|
-
*/
|
|
261
|
-
second(second) {
|
|
262
|
-
log('Parsing Datetime Second: "%s"', second?.value);
|
|
263
|
-
|
|
264
|
-
if (!second || !second.value) {
|
|
265
|
-
return unmatched('', 'missing-token', {
|
|
266
|
-
expects: [{ type: 'common', value: 'second' }],
|
|
267
|
-
partName: 'second',
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (!second.match(/^[0-9]+$/)) {
|
|
272
|
-
return second.unmatched({
|
|
273
|
-
reason: 'unexpected-token',
|
|
274
|
-
expects: [],
|
|
275
|
-
partName: 'second',
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (second.length !== 2) {
|
|
280
|
-
return second.unmatched({
|
|
281
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
282
|
-
expects: [],
|
|
283
|
-
partName: 'second',
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const _second = second.toNumber();
|
|
288
|
-
|
|
289
|
-
if (!(0 <= _second && _second <= 59)) {
|
|
290
|
-
return second.unmatched({
|
|
291
|
-
reason: { type: 'out-of-range', gte: 0, lte: 59 },
|
|
292
|
-
expects: [],
|
|
293
|
-
partName: 'second',
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* > One, two, or three ASCII digits, representing the fractional part of second
|
|
300
|
-
*/
|
|
301
|
-
secondFractionalPart(secondFP) {
|
|
302
|
-
log('Parsing Datetime Second Fractional Part: "%s"', secondFP?.value);
|
|
303
|
-
|
|
304
|
-
if (!secondFP || !secondFP.value) {
|
|
305
|
-
return unmatched('', 'missing-token', {
|
|
306
|
-
expects: [{ type: 'common', value: 'fractional part' }],
|
|
307
|
-
partName: 'fractional part',
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (!secondFP.match(/^[0-9]+$/)) {
|
|
312
|
-
return secondFP.unmatched({
|
|
313
|
-
reason: 'unexpected-token',
|
|
314
|
-
expects: [],
|
|
315
|
-
partName: 'fractional part',
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (!(1 <= secondFP.length && secondFP.length <= 3)) {
|
|
320
|
-
return secondFP.unmatched({
|
|
321
|
-
reason: { type: 'out-of-range-length-digit', gte: 1, lte: 3 },
|
|
322
|
-
expects: [],
|
|
323
|
-
partName: 'fractional part',
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
},
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* > Two ASCII digits, representing the week week, in the range 1 ≤ week ≤ maxweek, where maxweek is the week number of the last day of week-year year
|
|
330
|
-
*/
|
|
331
|
-
week(week) {
|
|
332
|
-
log('Parsing Datetime Week: "%s"', week?.value);
|
|
333
|
-
|
|
334
|
-
if (!week || !week.value) {
|
|
335
|
-
return unmatched('', 'missing-token', {
|
|
336
|
-
expects: [{ type: 'common', value: 'week' }],
|
|
337
|
-
partName: 'week',
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (!week.match(/^[0-9]+$/)) {
|
|
342
|
-
return week.unmatched({
|
|
343
|
-
reason: 'unexpected-token',
|
|
344
|
-
expects: [],
|
|
345
|
-
partName: 'week',
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (week.length !== 2) {
|
|
350
|
-
return week.unmatched({
|
|
351
|
-
reason: { type: 'out-of-range-length-digit', gte: 2, lte: 2 },
|
|
352
|
-
expects: [],
|
|
353
|
-
partName: 'week',
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
const maxweek = getMaxWeekNum(this._year || 0);
|
|
358
|
-
const _week = week.toNumber();
|
|
359
|
-
|
|
360
|
-
if (!(1 <= _week && _week <= maxweek)) {
|
|
361
|
-
return week.unmatched({
|
|
362
|
-
reason: { type: 'out-of-range', gte: 1, lte: maxweek },
|
|
363
|
-
expects: [],
|
|
364
|
-
partName: 'date',
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* > A U+002D HYPHEN-MINUS character (-)
|
|
371
|
-
*/
|
|
372
|
-
hyphen(hyphen) {
|
|
373
|
-
log('Parsing Datetime hyphen: "%s"', hyphen?.value);
|
|
374
|
-
|
|
375
|
-
if (!hyphen || !hyphen.value) {
|
|
376
|
-
return unmatched('', 'missing-token', {
|
|
377
|
-
expects: [{ type: 'common', value: 'hyphen' }],
|
|
378
|
-
partName: 'datetime',
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
if (!hyphen.match('-')) {
|
|
383
|
-
return hyphen.unmatched({
|
|
384
|
-
reason: 'unexpected-token',
|
|
385
|
-
expects: [{ type: 'common', value: 'hyphen' }],
|
|
386
|
-
partName: 'datetime',
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
},
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* > A U+003A COLON character (:)
|
|
393
|
-
*/
|
|
394
|
-
colon(colon) {
|
|
395
|
-
log('Parsing Datetime colon: "%s"', colon?.value);
|
|
396
|
-
|
|
397
|
-
if (!colon || !colon.value) {
|
|
398
|
-
return unmatched('', 'missing-token', {
|
|
399
|
-
expects: [{ type: 'common', value: 'colon' }],
|
|
400
|
-
partName: 'time',
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
if (!colon.match(':')) {
|
|
404
|
-
return colon.unmatched({
|
|
405
|
-
reason: 'unexpected-token',
|
|
406
|
-
expects: [{ type: 'common', value: 'colon' }],
|
|
407
|
-
partName: 'time',
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* > A U+003A COLON character (:)
|
|
414
|
-
* or
|
|
415
|
-
* End of token
|
|
416
|
-
*/
|
|
417
|
-
colonOrEnd(colon) {
|
|
418
|
-
if (!colon || !colon.value) {
|
|
419
|
-
return matched();
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
if (!colon.match(':')) {
|
|
423
|
-
return colon.unmatched({
|
|
424
|
-
reason: 'unexpected-token',
|
|
425
|
-
expects: [{ type: 'common', value: 'colon' }],
|
|
426
|
-
partName: 'time',
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
},
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* > A U+002E FULL STOP character (.)
|
|
433
|
-
* or
|
|
434
|
-
* End of token
|
|
435
|
-
*/
|
|
436
|
-
decimalPointOrEnd(dot) {
|
|
437
|
-
if (!dot || !dot.value) {
|
|
438
|
-
return matched();
|
|
439
|
-
}
|
|
440
|
-
if (!dot.match('.')) {
|
|
441
|
-
return dot.unmatched({
|
|
442
|
-
reason: 'unexpected-token',
|
|
443
|
-
expects: [{ type: 'common', value: 'decimal point' }],
|
|
444
|
-
partName: 'second',
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
},
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* > A U+0054 LATIN CAPITAL LETTER T character (T) or a U+0020 SPACE character
|
|
451
|
-
*/
|
|
452
|
-
localDateTimeSeparator(sep) {
|
|
453
|
-
log('Parsing Datetime Local-Date-Time separator: "%s"', sep?.value);
|
|
454
|
-
|
|
455
|
-
if (!sep || !sep.value) {
|
|
456
|
-
return unmatched('', 'missing-token', {
|
|
457
|
-
expects: [
|
|
458
|
-
{ type: 'const', value: 'T' },
|
|
459
|
-
{ type: 'common', value: 'space' },
|
|
460
|
-
],
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (!sep.match(['T', ' '])) {
|
|
465
|
-
return sep.unmatched({
|
|
466
|
-
reason: 'unexpected-token',
|
|
467
|
-
expects: [
|
|
468
|
-
{ type: 'const', value: 'T' },
|
|
469
|
-
{ type: 'common', value: 'space' },
|
|
470
|
-
],
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
},
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* > A U+0054 LATIN CAPITAL LETTER T character (T)
|
|
477
|
-
*/
|
|
478
|
-
normalizedlocalDateTimeSeparator(sep) {
|
|
479
|
-
log('Parsing Datetime Normalized-Local-Date-Time separator: %s', sep?.value);
|
|
480
|
-
|
|
481
|
-
if (!sep || !sep.value) {
|
|
482
|
-
return unmatched('', 'missing-token', {
|
|
483
|
-
expects: [{ type: 'const', value: 'T' }],
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
if (!sep.match('T')) {
|
|
488
|
-
return sep.unmatched({
|
|
489
|
-
reason: 'unexpected-token',
|
|
490
|
-
expects: [{ type: 'const', value: 'T' }],
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
},
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* > Either a U+002B PLUS SIGN character (+) or,
|
|
497
|
-
* > if the time-zone offset is not zero,
|
|
498
|
-
* > a U+002D HYPHEN-MINUS character (-),
|
|
499
|
-
* > representing the sign of the time-zone offset
|
|
500
|
-
*/
|
|
501
|
-
plusOrMinusSign(colon) {
|
|
502
|
-
if (!colon) {
|
|
503
|
-
return unmatched('', 'missing-token', {
|
|
504
|
-
expects: [
|
|
505
|
-
{ type: 'const', value: '+' },
|
|
506
|
-
{ type: 'const', value: '-' },
|
|
507
|
-
],
|
|
508
|
-
partName: 'time-zone',
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
if (!colon.match(['+', '-'])) {
|
|
512
|
-
return colon.unmatched({
|
|
513
|
-
reason: 'unexpected-token',
|
|
514
|
-
expects: [
|
|
515
|
-
{ type: 'const', value: '+' },
|
|
516
|
-
{ type: 'const', value: '-' },
|
|
517
|
-
],
|
|
518
|
-
partName: 'time-zone',
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
},
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* > A U+0057 LATIN CAPITAL LETTER W character (W)
|
|
525
|
-
*/
|
|
526
|
-
weekSign(weekSign) {
|
|
527
|
-
log('Parsing Datetime W sign: "%s"', weekSign?.value);
|
|
528
|
-
|
|
529
|
-
if (!weekSign || !weekSign.value) {
|
|
530
|
-
return unmatched('', 'missing-token', {
|
|
531
|
-
expects: [{ type: 'const', value: 'W' }],
|
|
532
|
-
partName: 'time-zone',
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
if (!weekSign.match('W')) {
|
|
537
|
-
return weekSign.unmatched({
|
|
538
|
-
reason: 'unexpected-token',
|
|
539
|
-
expects: [{ type: 'const', value: 'W' }],
|
|
540
|
-
partName: 'time-zone',
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
|
|
545
|
-
/**
|
|
546
|
-
* Extra token
|
|
547
|
-
*/
|
|
548
|
-
extra(extra) {
|
|
549
|
-
log('Parsing Datetime EXTRA STRING: "%s"', extra?.value);
|
|
550
|
-
|
|
551
|
-
if (extra && extra.value) {
|
|
552
|
-
return extra.unmatched({
|
|
553
|
-
reason: 'extra-token',
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
const daysOfMonth = [
|
|
560
|
-
0,
|
|
561
|
-
// 1
|
|
562
|
-
31,
|
|
563
|
-
// 2
|
|
564
|
-
28,
|
|
565
|
-
// 3
|
|
566
|
-
31,
|
|
567
|
-
// 4
|
|
568
|
-
30,
|
|
569
|
-
// 5
|
|
570
|
-
31,
|
|
571
|
-
// 6
|
|
572
|
-
30,
|
|
573
|
-
// 7
|
|
574
|
-
31,
|
|
575
|
-
// 8
|
|
576
|
-
31,
|
|
577
|
-
// 9
|
|
578
|
-
30,
|
|
579
|
-
// 10
|
|
580
|
-
31,
|
|
581
|
-
// 11
|
|
582
|
-
30,
|
|
583
|
-
// 12
|
|
584
|
-
31,
|
|
585
|
-
];
|
|
586
|
-
|
|
587
|
-
export function getMaxWeekNum(year: number) {
|
|
588
|
-
let date = 31;
|
|
589
|
-
while (date) {
|
|
590
|
-
const d = new Date(Date.UTC(year, 11, date, 0, 0, 0, 0));
|
|
591
|
-
d.setDate(d.getDate() + 4 - (d.getDay() || 7));
|
|
592
|
-
const yearStart = new Date(d.getFullYear(), 0, 1);
|
|
593
|
-
const weekNo = Math.ceil(((d.valueOf() - yearStart.valueOf()) / 86400000 + 1) / 7);
|
|
594
|
-
if (weekNo !== 1) {
|
|
595
|
-
return weekNo;
|
|
596
|
-
}
|
|
597
|
-
date--;
|
|
598
|
-
}
|
|
599
|
-
return NaN;
|
|
600
|
-
}
|