@markuplint/types 3.0.0-alpha.6 → 3.0.0-dev.176

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 (107) hide show
  1. package/README.md +12 -8
  2. package/lib/check-multi-types.d.ts +1 -1
  3. package/lib/check-multi-types.js +5 -4
  4. package/lib/check.d.ts +6 -5
  5. package/lib/check.spec.js +64 -58
  6. package/lib/css-syntax.js +49 -47
  7. package/lib/css-syntax.spec.js +152 -149
  8. package/lib/defs.js +2 -2
  9. package/lib/enum.d.ts +2 -1
  10. package/lib/enum.js +1 -1
  11. package/lib/get-candidate.d.ts +1 -1
  12. package/lib/keyword-type.js +3 -2
  13. package/lib/list.d.ts +2 -1
  14. package/lib/list.js +2 -1
  15. package/lib/list.spec.js +118 -117
  16. package/lib/match-result.d.ts +3 -3
  17. package/lib/match-result.js +2 -1
  18. package/lib/number.d.ts +1 -1
  19. package/lib/primitive/index.spec.js +53 -52
  20. package/lib/primitive/is-quantity.d.ts +5 -1
  21. package/lib/primitive/is-uint.d.ts +1 -1
  22. package/lib/primitive/split-unit.js +2 -2
  23. package/lib/rfc/is-bcp-47.spec.js +9 -8
  24. package/lib/token/token-collection.d.ts +20 -14
  25. package/lib/token/token-collection.js +30 -23
  26. package/lib/token/token-collection.spec.js +156 -134
  27. package/lib/token/token.d.ts +10 -9
  28. package/lib/token/token.js +19 -20
  29. package/lib/token/types.d.ts +3 -0
  30. package/lib/token/types.js +2 -0
  31. package/lib/types.d.ts +44 -44
  32. package/lib/types.schema.d.ts +369 -318
  33. package/lib/w3c/check-serialized-permissions-policy.spec.js +30 -28
  34. package/lib/whatwg/check-autocomplete.js +6 -6
  35. package/lib/whatwg/check-autocomplete.spec.js +361 -360
  36. package/lib/whatwg/check-datetime/datetime-tokens.js +9 -6
  37. package/lib/whatwg/check-datetime/duration-string.js +12 -2
  38. package/lib/whatwg/check-datetime/index.spec.js +277 -276
  39. package/lib/whatwg/check-datetime/local-date-and-time-string.js +6 -2
  40. package/lib/whatwg/check-datetime/time-zone-offset-string.d.ts +1 -1
  41. package/lib/whatwg/check-datetime/time-zone-offset-string.js +3 -2
  42. package/lib/whatwg/check-mime-type.js +1 -1
  43. package/lib/whatwg/check-mime-type.spec.js +53 -52
  44. package/lib/whatwg/is-abs-url.spec.js +6 -5
  45. package/lib/whatwg/is-itemprop-name.js +1 -1
  46. package/package.json +13 -11
  47. package/{src/check.spec.ts → test/check.spec.js} +7 -1
  48. package/{src/css-syntax.spec.ts → test/css-syntax.spec.js} +10 -12
  49. package/{src/list.spec.ts → test/list.spec.js} +7 -7
  50. package/{src/primitive/index.spec.ts → test/primitive/index.spec.js} +1 -1
  51. package/{src/rfc/is-bcp-47.spec.ts → test/rfc/is-bcp-47.spec.js} +1 -1
  52. package/{src/token/token-collection.spec.ts → test/token/token-collection.spec.js} +2 -3
  53. package/{src/w3c/check-serialized-permissions-policy.spec.ts → test/w3c/check-serialized-permissions-policy.spec.js} +1 -3
  54. package/{src/whatwg/check-autocomplete.spec.ts → test/whatwg/check-autocomplete.spec.js} +1 -1
  55. package/{src/whatwg/check-datetime/index.spec.ts → test/whatwg/check-datetime/index.spec.js} +18 -15
  56. package/{src/whatwg/check-mime-type.spec.ts → test/whatwg/check-mime-type.spec.js} +1 -1
  57. package/{src/whatwg/is-abs-url.spec.ts → test/whatwg/is-abs-url.spec.js} +1 -1
  58. package/types.schema.json +369 -318
  59. package/gen/specific-schema.json +0 -98
  60. package/gen/types.ts +0 -66
  61. package/src/check-multi-types.ts +0 -35
  62. package/src/check.ts +0 -48
  63. package/src/css-syntax.ts +0 -188
  64. package/src/debug.ts +0 -3
  65. package/src/defs.ts +0 -811
  66. package/src/enum.ts +0 -25
  67. package/src/get-candidate.ts +0 -24
  68. package/src/index.ts +0 -3
  69. package/src/keyword-type.ts +0 -64
  70. package/src/list.ts +0 -34
  71. package/src/match-result.ts +0 -49
  72. package/src/number.ts +0 -46
  73. package/src/primitive/index.ts +0 -7
  74. package/src/primitive/is-float.ts +0 -8
  75. package/src/primitive/is-int.ts +0 -8
  76. package/src/primitive/is-non-zero-uint.ts +0 -8
  77. package/src/primitive/is-quantity.ts +0 -38
  78. package/src/primitive/is-uint.ts +0 -15
  79. package/src/primitive/range.ts +0 -14
  80. package/src/primitive/split-unit.ts +0 -20
  81. package/src/rfc/is-bcp-47.ts +0 -13
  82. package/src/token/index.ts +0 -2
  83. package/src/token/token-collection.ts +0 -444
  84. package/src/token/token.ts +0 -144
  85. package/src/types.schema.ts +0 -1062
  86. package/src/types.ts +0 -118
  87. package/src/w3c/check-serialized-permissions-policy.ts +0 -303
  88. package/src/whatwg/check-autocomplete.ts +0 -380
  89. package/src/whatwg/check-datetime/date-string.ts +0 -44
  90. package/src/whatwg/check-datetime/datetime-tokens.ts +0 -600
  91. package/src/whatwg/check-datetime/duration-string.ts +0 -399
  92. package/src/whatwg/check-datetime/global-date-and-time-string.ts +0 -96
  93. package/src/whatwg/check-datetime/index.ts +0 -36
  94. package/src/whatwg/check-datetime/local-date-and-time-string.ts +0 -163
  95. package/src/whatwg/check-datetime/month-string.ts +0 -31
  96. package/src/whatwg/check-datetime/time-string.ts +0 -49
  97. package/src/whatwg/check-datetime/time-zone-offset-string.ts +0 -93
  98. package/src/whatwg/check-datetime/week-string.ts +0 -41
  99. package/src/whatwg/check-datetime/year-string.ts +0 -26
  100. package/src/whatwg/check-datetime/yearless-date-string.ts +0 -38
  101. package/src/whatwg/check-mime-type.ts +0 -46
  102. package/src/whatwg/is-abs-url.ts +0 -31
  103. package/src/whatwg/is-browser-context-name.ts +0 -16
  104. package/src/whatwg/is-custom-element-name.ts +0 -76
  105. package/src/whatwg/is-itemprop-name.ts +0 -17
  106. package/tsconfig.test.json +0 -3
  107. package/tsconfig.tsbuildinfo +0 -1
@@ -1,399 +0,0 @@
1
- import type { CustomSyntaxChecker } from '../../types';
2
-
3
- import { log } from '../../debug';
4
- import { matched, unmatched } from '../../match-result';
5
- import { TokenCollection } from '../../token';
6
-
7
- import { datetimeTokenCheck } from './datetime-tokens';
8
-
9
- /**
10
- * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#durations
11
- */
12
- export const checkDurationISO8601LikeString: CustomSyntaxChecker = () =>
13
- function checkDurationISO8601LikeString(value) {
14
- log('CHECK: duration-string (ISO8601 like)');
15
-
16
- // PnDTnHnMnS
17
- const tokens = TokenCollection.fromPatterns(value, [
18
- // Start sign P
19
- /[^0-9T]?/,
20
- // date part
21
- /[^T]*/,
22
- // Time sign T
23
- /[^0-9]?/,
24
- // Time part
25
- /.*/,
26
- ]);
27
-
28
- log('Duration ISO8601: "%s" => %O', tokens.value, tokens);
29
-
30
- const res = tokens.eachCheck(
31
- p => {
32
- if (!p || !p.value) {
33
- return unmatched('', 'missing-token', {
34
- expects: [{ type: 'const', value: 'P' }],
35
- partName: 'duration',
36
- });
37
- }
38
-
39
- if (!p.match('P', false)) {
40
- return p.unmatched({
41
- reason: 'unexpected-token',
42
- expects: [{ type: 'const', value: 'P' }],
43
- partName: 'duration',
44
- });
45
- }
46
- },
47
- d => {
48
- if (!d || !d.value) {
49
- return;
50
- }
51
-
52
- const [num, sign, extra] = TokenCollection.fromPatterns(d, [/[0-9]+/, /./]);
53
-
54
- log('Date part: "%s" => %O', d.value, { num, sign });
55
-
56
- if (!num.match(/^[0-9]+$/)) {
57
- return num.unmatched({
58
- reason: 'unexpected-token',
59
- expects: [],
60
- partName: 'date',
61
- });
62
- }
63
-
64
- if (!sign || !sign.value) {
65
- return unmatched('', 'missing-token', {
66
- expects: [{ type: 'const', value: 'D' }],
67
- partName: 'date',
68
- });
69
- }
70
-
71
- if (!sign.match('D', false)) {
72
- return sign.unmatched({
73
- reason: 'unexpected-token',
74
- expects: [{ type: 'const', value: 'D' }],
75
- partName: 'date',
76
- });
77
- }
78
-
79
- if (extra && extra.value) {
80
- return extra.unmatched({
81
- reason: 'unexpected-token',
82
- expects: [{ type: 'const', value: 'T' }],
83
- });
84
- }
85
- },
86
- t => {
87
- if (!t || !t.value) {
88
- return unmatched('', 'missing-token', {
89
- expects: [{ type: 'const', value: 'T' }],
90
- });
91
- }
92
-
93
- if (!t.match('T', false)) {
94
- return t.unmatched({
95
- reason: 'unexpected-token',
96
- expects: [{ type: 'const', value: 'T' }],
97
- });
98
- }
99
- },
100
- time => {
101
- if (!time) {
102
- return unmatched('', 'missing-token', {
103
- expects: [
104
- { type: 'common', value: 'hour' },
105
- { type: 'common', value: 'minute' },
106
- { type: 'common', value: 'second' },
107
- ],
108
- partName: 'time',
109
- });
110
- }
111
-
112
- const timeTokens = TokenCollection.fromPatterns(time, [
113
- // Hour part
114
- /[0-9]+(\.[0-9]*)?[^0-9]?/,
115
- // Minute part
116
- /[0-9]+(\.[0-9]*)?[^0-9]?/,
117
- // Second part
118
- /[0-9]+(\.[0-9]*)?[^0-9]?/,
119
- ]);
120
-
121
- log('Time part: "%s" => %O', timeTokens.value, timeTokens);
122
-
123
- const [h, m, s] = timeTokens;
124
-
125
- if ((h?.value || '') + (m?.value || '') + (s?.value || '') === '') {
126
- return unmatched('', 'missing-token', {
127
- expects: [
128
- { type: 'common', value: 'hour' },
129
- { type: 'common', value: 'minute' },
130
- { type: 'common', value: 'second' },
131
- ],
132
- });
133
- }
134
-
135
- const specified = new Set<'H' | 'M' | 'S'>();
136
-
137
- for (const t of timeTokens) {
138
- if (!t || !t.value) {
139
- continue;
140
- }
141
-
142
- if (specified.has('S')) {
143
- return t.unmatched({
144
- reason: 'extra-token',
145
- });
146
- }
147
-
148
- const [num, dpfp, sign] = TokenCollection.fromPatterns(t, [/[0-9]+/, /(\.[0-9]*)?/, /[^0-9]+/]);
149
-
150
- log('Time part (h|m|s): "%s" => %O', t.value, { num, dpfp, sign });
151
-
152
- if (!num.match(/^[0-9]+$/)) {
153
- return num.unmatched({
154
- reason: 'unexpected-token',
155
- expects: [{ type: 'common', value: 'number' }],
156
- partName: 'time',
157
- });
158
- }
159
-
160
- if (dpfp && dpfp.value) {
161
- const [dp, fp] = TokenCollection.fromPatterns(dpfp, [/\./, /[0-9]+/]);
162
-
163
- log('Second fractional part (h|m|s): "%s" => %O', dpfp.value, { dp, fp });
164
-
165
- if (!dp.match('.')) {
166
- return dp.unmatched({
167
- reason: 'unexpected-token',
168
- expects: [],
169
- partName: 'decimal point',
170
- });
171
- }
172
-
173
- if (!fp || !fp.value) {
174
- return unmatched('', 'missing-token', {
175
- expects: [{ type: 'common', value: 'fractional part' }],
176
- partName: 'second',
177
- });
178
- }
179
-
180
- if (!fp.match(/^[0-9]+$/)) {
181
- return fp.unmatched({
182
- reason: 'unexpected-token',
183
- expects: [],
184
- partName: 'fractional part',
185
- });
186
- }
187
-
188
- if (!(1 <= fp.length && fp.length <= 3)) {
189
- return fp.unmatched({
190
- reason: { type: 'out-of-range-length-digit', gte: 1, lte: 3 },
191
- expects: [],
192
- partName: 'fractional part',
193
- });
194
- }
195
- }
196
-
197
- const expects = [
198
- { type: 'const', value: 'H' },
199
- { type: 'const', value: 'M' },
200
- { type: 'const', value: 'S' },
201
- ] as const;
202
-
203
- if (!sign || !sign.value) {
204
- return unmatched('', 'missing-token', {
205
- expects: expects.filter(e => !specified.has(e.value)),
206
- partName: 'time',
207
- });
208
- }
209
-
210
- if (specified.has('M') && sign.match('H', false)) {
211
- return sign.unmatched({
212
- reason: 'unexpected-token',
213
- expects: [{ type: 'const', value: 'S' }],
214
- partName: 'time',
215
- });
216
- }
217
-
218
- if (
219
- !sign.match(['H', 'M', 'S'], false) ||
220
- (sign.match('H', false) && specified.has('H')) ||
221
- (sign.match('M', false) && specified.has('M'))
222
- ) {
223
- return sign.unmatched({
224
- reason: 'unexpected-token',
225
- expects: expects.filter(e => !specified.has(e.value)),
226
- partName: 'time',
227
- });
228
- }
229
-
230
- specified.add(sign.value as 'H' | 'M' | 'S');
231
- }
232
- },
233
- datetimeTokenCheck.extra,
234
- );
235
-
236
- if (!res.matched) {
237
- log('Failed: %O', res);
238
- }
239
-
240
- return res;
241
- };
242
-
243
- export const checkDurationComponentListString: CustomSyntaxChecker = () =>
244
- function checkDurationComponentListString(value) {
245
- log('CHECK: duration-string (duration component list)');
246
-
247
- if (!value) {
248
- return unmatched('', 'empty-token', {
249
- expects: [{ type: 'common', value: 'time' }],
250
- });
251
- }
252
-
253
- const patterns = [
254
- // 1. Zero or more ASCII whitespace.
255
- /\s*/,
256
- // 2. One or more ASCII digits, representing a number of time units,
257
- // scaled by the duration time component scale specified (see below)
258
- // to represent a number of seconds.
259
- /[0-9]+/,
260
- // 3. If the duration time component scale specified is 1 (i.e. the units are seconds),
261
- // then, optionally, a U+002E FULL STOP character (.) followed by
262
- // one, two, or three ASCII digits, representing a fraction of a second.
263
- /(\.[0-9]*)?/,
264
- // 4. Zero or more ASCII whitespace.
265
- /\s*/,
266
- // 5. One of the following characters, representing the duration time component scale
267
- // of the time unit used in the numeric part of the duration time component:
268
- /[^0-9]/,
269
- // 6. Zero or more ASCII whitespace.
270
- /\s*/,
271
- ];
272
-
273
- const tokens = TokenCollection.fromPatterns(value, patterns, { repeat: true });
274
- const components = tokens.chunk(patterns.length);
275
-
276
- const specified = new Set<'w' | 'd' | 'h' | 'm' | 's'>();
277
-
278
- for (const component of components) {
279
- log('Duration Component: "%s" => %O', component.value, component);
280
-
281
- const [, , dpfp, , unit] = component;
282
-
283
- const res = component.eachCheck(
284
- ws => {},
285
- num => {
286
- if (!num || !num.value) {
287
- const reason = dpfp?.value || unit?.value ? 'unexpected-token' : 'missing-token';
288
- return unmatched('', reason, {
289
- expects: [{ type: 'common', value: 'time' }],
290
- });
291
- }
292
- },
293
- dpfp => {
294
- if (!dpfp || !dpfp.value) {
295
- return;
296
- }
297
-
298
- const unitExpects = (
299
- [
300
- { type: 'const', value: 'w' },
301
- { type: 'const', value: 'd' },
302
- { type: 'const', value: 'h' },
303
- { type: 'const', value: 'm' },
304
- { type: 'const', value: 's' },
305
- ] as const
306
- ).filter(e => !specified.has(e.value));
307
-
308
- if (specified.has('s')) {
309
- return dpfp.unmatched({
310
- reason: 'unexpected-token',
311
- expects: unitExpects,
312
- partName: 'unit',
313
- });
314
- }
315
-
316
- const [, fp] = TokenCollection.fromPatterns(dpfp, [/\./, /[0-9]+/]);
317
-
318
- if (!fp || !fp.value) {
319
- return unmatched('', 'missing-token', {
320
- expects: [{ type: 'common', value: 'fractional part' }],
321
- partName: 'fractional part',
322
- });
323
- }
324
-
325
- if (!fp.match(/[0-9]+/)) {
326
- return fp.unmatched({
327
- reason: 'unexpected-token',
328
- expects: [{ type: 'common', value: 'fractional part' }],
329
- partName: 'fractional part',
330
- });
331
- }
332
-
333
- if (!(1 <= fp.length && fp.length <= 3)) {
334
- return fp.unmatched({
335
- reason: { type: 'out-of-range-length-digit', gte: 1, lte: 3 },
336
- expects: [],
337
- partName: 'fractional part',
338
- });
339
- }
340
- },
341
- ws => {},
342
- unit => {
343
- const expects = (
344
- [
345
- { type: 'const', value: 'w' },
346
- { type: 'const', value: 'd' },
347
- { type: 'const', value: 'h' },
348
- { type: 'const', value: 'm' },
349
- { type: 'const', value: 's' },
350
- ] as const
351
- ).filter(e => !specified.has(e.value));
352
-
353
- if (!unit || !unit.value) {
354
- return unmatched('', 'missing-token', {
355
- expects,
356
- partName: 'unit',
357
- });
358
- }
359
-
360
- const unitVal = unit.value.toLowerCase() as 'w' | 'd' | 'h' | 'm' | 's';
361
-
362
- if (specified.has(unitVal)) {
363
- return unit.unmatched({
364
- reason: 'duplicated',
365
- expects,
366
- partName: 'unit',
367
- });
368
- }
369
-
370
- if (dpfp && dpfp.value && unit.match(['w', 'd', 'h', 'm'])) {
371
- return unit.unmatched({
372
- reason: 'unexpected-token',
373
- expects: [{ type: 'const', value: 's' }],
374
- partName: 'unit',
375
- });
376
- }
377
-
378
- if (!unit.match(['w', 'd', 'h', 'm', 's'])) {
379
- return unit.unmatched({
380
- reason: 'unexpected-token',
381
- expects,
382
- partName: 'unit',
383
- });
384
- }
385
-
386
- specified.add(unitVal);
387
- },
388
- ws => {},
389
- );
390
-
391
- if (!res.matched) {
392
- log('Failed: %O', res);
393
-
394
- return res;
395
- }
396
- }
397
-
398
- return matched();
399
- };
@@ -1,96 +0,0 @@
1
- import type { CustomSyntaxChecker } from '../../types';
2
-
3
- import { log } from '../../debug';
4
- import { unmatched } from '../../match-result';
5
- import { TokenCollection } from '../../token';
6
-
7
- import { datetimeTokenCheck } from './datetime-tokens';
8
- import { parseTimeZone } from './time-zone-offset-string';
9
-
10
- /**
11
- * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#global-dates-and-times
12
- */
13
- export const checkGlobalDateAndTimeString: CustomSyntaxChecker = () =>
14
- function checkGlobalDateAndTimeString(value) {
15
- log('CHECK: global-date-and-time-string');
16
-
17
- const tokens = TokenCollection.fromPatterns(value, [
18
- // YYYY
19
- /[^-]*/,
20
- // -
21
- /[^0-9]?/,
22
- // MM
23
- /[^-]*/,
24
- // -
25
- /[^0-9]?/,
26
- // DD
27
- /[^T\s]*/,
28
- // T \s
29
- /[^0-9]?/,
30
- // hh
31
- /[^:]*/,
32
- // :
33
- /[^0-9]?/,
34
- // mm
35
- /[^:Z+-]*/,
36
- // :ss.sss
37
- /(:[^Z+-]*)?/,
38
- // time-zone
39
- /.*/,
40
- ]);
41
-
42
- log('Global Date and Time "%s" => %O', tokens.value, tokens);
43
-
44
- const res = tokens.eachCheck(
45
- datetimeTokenCheck.year,
46
- datetimeTokenCheck.hyphen,
47
- datetimeTokenCheck.month,
48
- datetimeTokenCheck.hyphen,
49
- datetimeTokenCheck.date,
50
- datetimeTokenCheck.localDateTimeSeparator,
51
- datetimeTokenCheck.hour,
52
- datetimeTokenCheck.colon,
53
- datetimeTokenCheck.minute,
54
- second => {
55
- if (!second || !second.value) {
56
- return;
57
- }
58
-
59
- const secondTokens = TokenCollection.fromPatterns(second, [/:?/, /[0-9]*/, /\.?/, /[0-9]*/]);
60
-
61
- log('Second Part: "%s" => %O', secondTokens.value, secondTokens);
62
-
63
- const res = secondTokens.eachCheck(
64
- datetimeTokenCheck.colon,
65
- datetimeTokenCheck.second,
66
- datetimeTokenCheck.decimalPointOrEnd,
67
- datetimeTokenCheck.secondFractionalPart,
68
- );
69
-
70
- if (!res.matched) {
71
- return res;
72
- }
73
- },
74
- zone => {
75
- if (!zone || !zone.value) {
76
- return unmatched(value, 'missing-token', {
77
- expects: [{ type: 'common', value: 'time-zone' }],
78
- partName: 'time-zone',
79
- });
80
- }
81
-
82
- const res = parseTimeZone(zone);
83
-
84
- if (!res.matched) {
85
- return res;
86
- }
87
- },
88
- datetimeTokenCheck.extra,
89
- );
90
-
91
- if (!res.matched) {
92
- log('Failed: %O', res);
93
- }
94
-
95
- return res;
96
- };
@@ -1,36 +0,0 @@
1
- import type { CustomSyntaxChecker } from '../../types';
2
-
3
- import { checkMultiTypes } from '../../check-multi-types';
4
-
5
- import { checkDateString } from './date-string';
6
- import { checkDurationComponentListString, checkDurationISO8601LikeString } from './duration-string';
7
- import { checkGlobalDateAndTimeString } from './global-date-and-time-string';
8
- import { checkLocalDateAndTimeString, checkNormalizedLocalDateAndTimeString } from './local-date-and-time-string';
9
- import { checkMonthString } from './month-string';
10
- import { checkTimeString } from './time-string';
11
- import { checkTimeZoneOffsetString } from './time-zone-offset-string';
12
- import { checkWeekString } from './week-string';
13
- import { checkYearString } from './year-string';
14
- import { checkYearlessDateString } from './yearless-date-string';
15
-
16
- const checks = [
17
- checkDateString(),
18
- checkTimeString(),
19
- checkMonthString(),
20
- checkYearlessDateString(),
21
- checkLocalDateAndTimeString(),
22
- checkNormalizedLocalDateAndTimeString(),
23
- checkTimeZoneOffsetString(),
24
- checkGlobalDateAndTimeString(),
25
- checkWeekString(),
26
- checkYearString(),
27
- checkDurationISO8601LikeString(),
28
- checkDurationComponentListString(),
29
- ];
30
-
31
- /**
32
- * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#dates-and-times
33
- */
34
- export const checkDateTime: CustomSyntaxChecker = () => value => {
35
- return checkMultiTypes(value, checks);
36
- };
@@ -1,163 +0,0 @@
1
- import type { CustomSyntaxChecker } from '../../types';
2
-
3
- import { log } from '../../debug';
4
- import { TokenCollection } from '../../token';
5
-
6
- import { datetimeTokenCheck } from './datetime-tokens';
7
-
8
- /**
9
- * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-local-date-and-time-string
10
- */
11
- export const checkLocalDateAndTimeString: CustomSyntaxChecker = () =>
12
- function checkLocalDateAndTimeString(value) {
13
- log('CHECK: local-date-and-time-string');
14
-
15
- const tokens = TokenCollection.fromPatterns(value, [
16
- // YYYY
17
- /[^-]*/,
18
- // -
19
- /[^0-9]?/,
20
- // MM
21
- /[^-]*/,
22
- // -
23
- /[^0-9]?/,
24
- // DD
25
- /[^T\s]*/,
26
- // T
27
- /[^0-9]?/,
28
- // hh
29
- /[^:]*/,
30
- // :
31
- /[^0-9]?/,
32
- // mm
33
- /[^:]*/,
34
- // :
35
- /[^0-9]?/,
36
- // ss
37
- /[^.]*/,
38
- // .
39
- /[^0-9]?/,
40
- // sss
41
- /.[0-9]*/,
42
- ]);
43
-
44
- log('Local Date and Time: "%s" => %O', tokens.value, tokens);
45
-
46
- const res = tokens.eachCheck(
47
- datetimeTokenCheck.year,
48
- datetimeTokenCheck.hyphen,
49
- datetimeTokenCheck.month,
50
- datetimeTokenCheck.hyphen,
51
- datetimeTokenCheck.date,
52
- datetimeTokenCheck.localDateTimeSeparator,
53
- datetimeTokenCheck.hour,
54
- datetimeTokenCheck.colon,
55
- datetimeTokenCheck.minute,
56
- datetimeTokenCheck.colonOrEnd,
57
- datetimeTokenCheck.second,
58
- datetimeTokenCheck.decimalPointOrEnd,
59
- datetimeTokenCheck.secondFractionalPart,
60
- datetimeTokenCheck.extra,
61
- );
62
-
63
- if (!res.matched) {
64
- log('Failed: %O', res);
65
- }
66
-
67
- return res;
68
- };
69
-
70
- /**
71
- * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
72
- */
73
- export const checkNormalizedLocalDateAndTimeString: CustomSyntaxChecker = () =>
74
- function checkNormalizedLocalDateAndTimeString(value) {
75
- log('CHECK: normalized-local-date-and-time-string');
76
-
77
- const tokens = TokenCollection.fromPatterns(value, [
78
- // YYYY
79
- /[^-]*/,
80
- // -
81
- /[^0-9]?/,
82
- // MM
83
- /[^-]*/,
84
- // -
85
- /[^0-9]?/,
86
- // DD
87
- /[^T]*/,
88
- // T
89
- /[^0-9]?/,
90
- // hh
91
- /[^:]*/,
92
- // :
93
- /[^0-9]?/,
94
- // mm
95
- /[^:]*/,
96
- // :
97
- /[^0-9]?/,
98
- // ss
99
- /[^.]*/,
100
- // .
101
- /[^0-9]?/,
102
- // sss
103
- /.[0-9]*/,
104
- ]);
105
-
106
- log('Normalized Local Date and Time: "%s" => %O', tokens.value, tokens);
107
-
108
- const res = tokens.eachCheck(
109
- datetimeTokenCheck.year,
110
- datetimeTokenCheck.hyphen,
111
- datetimeTokenCheck.month,
112
- datetimeTokenCheck.hyphen,
113
- datetimeTokenCheck.date,
114
- datetimeTokenCheck.normalizedlocalDateTimeSeparator,
115
- datetimeTokenCheck.hour,
116
- datetimeTokenCheck.colon,
117
- datetimeTokenCheck.minute,
118
- datetimeTokenCheck.colonOrEnd,
119
- datetimeTokenCheck.second,
120
- datetimeTokenCheck.decimalPointOrEnd,
121
- datetimeTokenCheck.secondFractionalPart,
122
- datetimeTokenCheck.extra,
123
- );
124
-
125
- if (!res.matched) {
126
- log('Failed: %O', res);
127
- return res;
128
- }
129
-
130
- /**
131
- * > A valid time string representing the time,
132
- * > expressed as the shortest possible string for the given time
133
- * > (e.g. omitting the seconds component entirely
134
- * > if the given time is zero seconds past the minute)
135
- */
136
- const [, , , , , , , , , , second, , fp] = tokens;
137
-
138
- const _second = second.toNumber() || 0;
139
- const _fp = fp.toNumber() || 0;
140
-
141
- log('Omitting the seconds component: "%s.%s" => %d, %d', second?.value, fp?.value, _second, _fp);
142
-
143
- if (second.value && _second === 0 && (!fp.value || (fp.value && _fp === 0))) {
144
- const res = second.unmatched({
145
- partName: 'second',
146
- reason: 'extra-token',
147
- });
148
- log('Failed: %O', res);
149
- return res;
150
- }
151
-
152
- if (fp.value && _fp === 0) {
153
- const res = fp.unmatched({
154
- partName: 'fractional part',
155
- reason: 'extra-token',
156
- });
157
- log('Failed: %O', res);
158
- return res;
159
- }
160
-
161
- log('Failed: %O', res);
162
- return res;
163
- };