@markuplint/rules 2.0.0-dev.23 → 2.0.0-rc.5

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 (63) hide show
  1. package/lib/attr-check.d.ts +8 -1
  2. package/lib/attr-check.js +53 -455
  3. package/lib/attr-duplication/index.d.ts +1 -1
  4. package/lib/attr-duplication/index.js +0 -2
  5. package/lib/attr-equal-space-after/index.js +0 -1
  6. package/lib/attr-equal-space-before/index.js +0 -1
  7. package/lib/attr-spacing/index.js +0 -1
  8. package/lib/attr-value-quotes/index.js +0 -1
  9. package/lib/case-sensitive-attr-name/index.d.ts +6 -2
  10. package/lib/case-sensitive-attr-name/index.js +30 -8
  11. package/lib/case-sensitive-tag-name/index.js +0 -1
  12. package/lib/character-reference/index.d.ts +1 -2
  13. package/lib/character-reference/index.js +0 -2
  14. package/lib/class-naming/index.js +23 -23
  15. package/lib/create-message.d.ts +5 -0
  16. package/lib/create-message.js +270 -0
  17. package/lib/debug.d.ts +3 -0
  18. package/lib/debug.js +6 -0
  19. package/lib/deprecated-attr/index.d.ts +1 -1
  20. package/lib/deprecated-attr/index.js +2 -5
  21. package/lib/deprecated-element/index.d.ts +1 -1
  22. package/lib/deprecated-element/index.js +1 -3
  23. package/lib/disallowed-element/index.d.ts +2 -0
  24. package/lib/disallowed-element/index.js +34 -0
  25. package/lib/helpers.d.ts +15 -9
  26. package/lib/helpers.js +63 -68
  27. package/lib/id-duplication/index.d.ts +1 -1
  28. package/lib/id-duplication/index.js +1 -3
  29. package/lib/index.d.ts +28 -11
  30. package/lib/index.js +16 -0
  31. package/lib/ineffective-attr/index.d.ts +2 -0
  32. package/lib/ineffective-attr/index.js +40 -0
  33. package/lib/invalid-attr/index.d.ts +4 -2
  34. package/lib/invalid-attr/index.js +25 -9
  35. package/lib/landmark-roles/index.js +1 -2
  36. package/lib/no-boolean-attr-value/index.d.ts +2 -0
  37. package/lib/no-boolean-attr-value/index.js +47 -0
  38. package/lib/no-default-value/index.d.ts +2 -0
  39. package/lib/no-default-value/index.js +38 -0
  40. package/lib/no-hard-code-id/index.d.ts +2 -0
  41. package/lib/no-hard-code-id/index.js +27 -0
  42. package/lib/no-refer-to-non-existent-id/index.d.ts +2 -0
  43. package/lib/no-refer-to-non-existent-id/index.js +110 -0
  44. package/lib/no-use-event-handler-attr/index.d.ts +5 -0
  45. package/lib/no-use-event-handler-attr/index.js +37 -0
  46. package/lib/permitted-contents/index.js +24 -13
  47. package/lib/permitted-contents/types.d.ts +8 -0
  48. package/lib/permitted-contents/types.js +2 -0
  49. package/lib/require-element/index.d.ts +2 -0
  50. package/lib/require-element/index.js +38 -0
  51. package/lib/required-attr/index.d.ts +5 -1
  52. package/lib/required-attr/index.js +60 -19
  53. package/lib/required-element/index.d.ts +5 -0
  54. package/lib/required-element/index.js +44 -0
  55. package/lib/required-h1/index.d.ts +2 -3
  56. package/lib/required-h1/index.js +2 -3
  57. package/lib/wai-aria/index.d.ts +1 -1
  58. package/lib/wai-aria/index.js +23 -24
  59. package/package.json +10 -5
  60. package/schema.json +24 -0
  61. package/tsconfig.tsbuildinfo +1 -1
  62. package/lib/primitive-check.d.ts +0 -48
  63. package/lib/primitive-check.js +0 -109
@@ -1,8 +1,14 @@
1
1
  import type { Translator } from '@markuplint/i18n';
2
- import type { Attribute as AttrSpec } from '@markuplint/ml-spec';
2
+ import type { Attribute as AttrSpec, AttributeType } from '@markuplint/ml-spec';
3
3
  declare type Invalid = {
4
4
  invalidType: 'non-existent' | 'invalid-value';
5
5
  message: string;
6
+ loc?: Loc;
7
+ };
8
+ declare type Loc = {
9
+ raw: string;
10
+ line: number;
11
+ col: number;
6
12
  };
7
13
  /**
8
14
  * Use in rules `invalid-attr` and `wai-aria`
@@ -13,4 +19,5 @@ declare type Invalid = {
13
19
  * @param spec
14
20
  */
15
21
  export declare function attrCheck(t: Translator, name: string, value: string, isCustomRule: boolean, spec?: AttrSpec): Invalid | false;
22
+ export declare function valueCheck(t: Translator, name: string, value: string, type: AttributeType): string | [string, Loc] | false;
16
23
  export {};
package/lib/attr-check.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.attrCheck = void 0;
4
- const primitive_check_1 = require("./primitive-check");
3
+ exports.valueCheck = exports.attrCheck = void 0;
4
+ const types_1 = require("@markuplint/types");
5
+ const create_message_1 = require("./create-message");
6
+ const debug_1 = require("./debug");
5
7
  /**
6
8
  * Use in rules `invalid-attr` and `wai-aria`
7
9
  *
@@ -23,476 +25,72 @@ function attrCheck(t, name, value, isCustomRule, spec) {
23
25
  }
24
26
  // Existance
25
27
  if (!spec) {
28
+ (0, debug_1.log)('The "%s" attribute DOES\'NT EXIST in the spec', name);
26
29
  return {
27
30
  invalidType: 'non-existent',
28
- message: t('{0} is {1:c}', t('the "{0}" {1}', name, 'attribute'), 'disallowed'),
31
+ message: t('{0} is {1:c}', t('the "{0*}" {1}', name, 'attribute'), 'disallowed'),
29
32
  };
30
33
  }
31
- const invalid = valueCheck(t, name, value, spec);
32
- if (invalid) {
34
+ const nameCaseSensitive = /[A-Z]/.test(spec.name);
35
+ if (nameCaseSensitive && name !== spec.name) {
36
+ (0, debug_1.log)('The "%s" attribute name is unmatched in case-sensitive', name);
33
37
  return {
34
- invalidType: 'invalid-value',
35
- message: invalid,
38
+ invalidType: 'non-existent',
39
+ message: t('{0} is {1:c}', t('the "{0*}" {1}', name, 'attribute'), 'disallowed') +
40
+ t('. ') +
41
+ t('Did you mean "{0*}"?', spec.name),
36
42
  };
37
43
  }
38
- return false;
39
- }
40
- exports.attrCheck = attrCheck;
41
- function valueCheck(t, name, value, spec) {
42
- // Valid because any string value is acceptable
43
- if (typeof spec.type !== 'string' && 'enum' in spec.type) {
44
- // has "enum"
45
- return includesEnum(t, name, value, spec.type.enum);
46
- }
47
- const t_theNameAttribute = t('the "{0}" {1}', name, 'attribute');
48
- if (spec.type === 'NonEmptyString' && value === '') {
49
- return t('{0} must not be {1}', t('{0} of {1}', t('the {0}', 'value'), t_theNameAttribute), 'empty string');
50
- }
51
- if (spec.type === 'Boolean') {
52
- // Valid because an attribute is exist
53
- return false;
54
- }
55
- if (spec.type === 'Function') {
56
- // TODO: To eval function-body string
57
- return false;
58
- }
59
- if (spec.type === 'Date') {
60
- // TODO: https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value
61
- return false;
62
- }
63
- if (spec.type === 'Int') {
64
- if ((0, primitive_check_1.intCheck)(value)) {
65
- return false;
66
- }
67
- return t('{0} expects {1}', t_theNameAttribute, 'integer');
68
- }
69
- if (spec.type === 'Uint') {
70
- if ((0, primitive_check_1.uintCheck)(value)) {
71
- return false;
72
- }
73
- return t('{0} expects {1}', t_theNameAttribute, 'non-negative integer');
74
- }
75
- if (spec.type === 'Float') {
76
- if ((0, primitive_check_1.floatCheck)(value)) {
77
- return false;
78
- }
79
- return t('{0} expects {1}', t_theNameAttribute, 'floating-point number');
80
- }
81
- if (spec.type === 'NonZeroUint') {
82
- if ((0, primitive_check_1.nonZeroUintCheck)(value)) {
83
- return false;
84
- }
85
- return t('{0} expects {1}', t_theNameAttribute, t('{0} greater than {1}', 'floating-point number', 'zero'));
86
- }
87
- if (spec.type === 'ZeroToOne') {
88
- if ((0, primitive_check_1.range)(value, 0, 1)) {
89
- return false;
90
- }
91
- return t('{0} expects {1:c}', t_theNameAttribute, t('in the range between {0} and {1}', 'zero', 'one'));
92
- }
93
- if (spec.type === 'AcceptList') {
94
- // TODO: https://html.spec.whatwg.org/multipage/input.html#attr-input-accept
95
- return false;
96
- }
97
- if (spec.type === 'AutoComplete') {
98
- // TODO: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill-detail-tokens
99
- return false;
100
- }
101
- if (spec.type === 'BCP47') {
102
- // TODO: https://tools.ietf.org/html/bcp47
103
- return false;
104
- }
105
- if (spec.type === 'Color') {
106
- // TODO: https://drafts.csswg.org/css-color/#typedef-color
107
- return false;
108
- }
109
- if (spec.type === 'ColSpan') {
110
- /**
111
- * > value must be a valid non-negative integer greater than zero and less than or equal to 1000.
112
- *
113
- * @see https://html.spec.whatwg.org/multipage/tables.html#attr-tdth-colspan
114
- */
115
- if ((0, primitive_check_1.intCheck)(value) && (0, primitive_check_1.range)(value, 0, 1000)) {
116
- return false;
117
- }
118
- return t('{0} expects {1:c}', t_theNameAttribute, t('{0:c} and {1:c}', t('{0} greater than {1}', 'non-negative integer', 'zero'), t('less than or equal to {0}', 1000)));
119
- }
120
- if (spec.type === 'Coords') {
121
- // TODO: https://html.spec.whatwg.org/multipage/image-maps.html#attr-area-coords
122
- return false;
123
- }
124
- if (spec.type === 'Crossorigin') {
125
- // TODO: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
126
- return false;
127
- }
128
- if (spec.type === 'DateTime') {
129
- // TODO: https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value
130
- return false;
131
- }
132
- if (spec.type === 'Destination') {
133
- // TODO: https://html.spec.whatwg.org/multipage/semantics.html#attr-link-as
134
- return false;
135
- }
136
- if (spec.type === 'DOMID') {
137
- // TODO: Searching ID in Document
138
- return false;
139
- }
140
- if (spec.type === 'DOMIDList') {
141
- // TODO: Searching ID in Document
142
- return false;
143
- }
144
- if (spec.type === 'IRI') {
145
- // TODO: https://developer.mozilla.org/ja/docs/Web/SVG/Content_type#iri
146
- return false;
147
- }
148
- if (spec.type === 'ItemType') {
149
- // TODO: https://html.spec.whatwg.org/multipage/microdata.html#attr-itemtype
150
- return false;
151
- }
152
- if (spec.type === 'LinkSizes') {
153
- // TODO: https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes
154
- return false;
155
- }
156
- if (spec.type === 'LinkType') {
157
- // TODO: https://html.spec.whatwg.org/multipage/links.html#linkTypes
158
- return false;
159
- }
160
- if (spec.type === 'LinkTypeList') {
161
- // TODO: https://html.spec.whatwg.org/multipage/links.html#linkTypes
162
- return false;
163
- }
164
- if (spec.type === 'MediaQuery') {
165
- // TODO: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-media-query-list
166
- return false;
167
- }
168
- if (spec.type === 'MediaQueryList') {
169
- // TODO: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-media-query-list
170
- return false;
171
- }
172
- if (spec.type === 'MIMEType') {
173
- // TODO: https://mimesniff.spec.whatwg.org/#valid-mime-type
174
- return false;
175
- }
176
- if (spec.type === 'ReferrerPolicy') {
177
- /**
178
- * @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#referrer-policy-attributes
179
- */
180
- return includesEnum(t, name, value, [
181
- '',
182
- 'no-referrer',
183
- 'no-referrer-when-downgrade',
184
- 'same-origin',
185
- 'origin',
186
- 'strict-origin',
187
- 'origin-when-cross-origin',
188
- 'strict-origin-when-cross-origin',
189
- 'unsafe-url',
190
- ]);
191
- }
192
- if (spec.type === 'RowSpan') {
193
- /**
194
- * > value must be a valid non-negative integer less than or equal to 65534.
195
- *
196
- * @see https://html.spec.whatwg.org/multipage/tables.html#attr-tdth-rowspan
197
- */
198
- if ((0, primitive_check_1.intCheck)(value) && (0, primitive_check_1.range)(value, 0, 65534)) {
199
- return false;
44
+ const types = Array.isArray(spec.type) ? spec.type : [spec.type];
45
+ const invalidList = types.map(type => {
46
+ if (!type) {
47
+ (0, debug_1.log)('attrCheck: %o', arguments);
48
+ throw new Error('type is empty in spec');
200
49
  }
201
- return t('{0} expects {1:c}', t_theNameAttribute, t('{0:c} and {1:c}', t('{0} greater than {1}', 'non-negative integer', 'zero'), t('less than or equal to {0}', 65534)));
202
- }
203
- if (spec.type === 'SourceSizeList') {
204
- // TODO: https://html.spec.whatwg.org/multipage/images.html#sizes-attributes
205
- return false;
206
- }
207
- if (spec.type === 'SrcSet') {
208
- // TODO: https://html.spec.whatwg.org/multipage/images.html#srcset-attribute
209
- return false;
210
- }
211
- if (spec.type === 'TabIndex') {
212
- /**
213
- * > ## omitted (or non-integer values)
214
- * >
215
- * > The user agent will decide whether the element is focusable, and if it is, whether it is sequentially focusable or click focusable (or both).
216
- * >
217
- * > ## −1 (or other negative integer values)
218
- * >
219
- * > Causes the element to be focusable, and indicates that the author would prefer the element to be click focusable but not sequentially focusable. The user agent might ignore this preference for click and sequential focusability, e.g., for specific element types according to platform conventions, or for keyboard-only users.
220
- * >
221
- * > ## 0
222
- * >
223
- * > Causes the element to be focusable, and indicates that the author would prefer the element to be both click focusable and sequentially focusable. The user agent might ignore this preference for click and sequential focusabiity.
224
- * >
225
- * > ## positive integer values
226
- * >
227
- * > Behaves the same as 0, but in addition creates a relative ordering within a tabindex-ordered focus navigation scope, so that elements with higher tabindex attribute value come later.
228
- *
229
- * @see https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
230
- */
231
- if ((0, primitive_check_1.intCheck)(value)) {
232
- const i = parseInt(value);
233
- if (-1 <= i) {
234
- return false;
50
+ const invalid = valueCheck(t, name, value, type);
51
+ if (invalid) {
52
+ if (typeof invalid === 'string') {
53
+ return {
54
+ invalidType: 'invalid-value',
55
+ message: invalid,
56
+ };
235
57
  }
236
- if (-1 > i) {
237
- return t('{0} behaves the same as {1} if {2}', t_theNameAttribute, '-1', t('less than {0}', '-1'));
238
- }
239
- }
240
- return t('{0} expects {1:c}', t_theNameAttribute, t('either {0}', t(['-1', 'zero', 'non-negative integer'])));
241
- }
242
- if (spec.type === 'Target') {
243
- // TODO: https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target
244
- return false;
245
- }
246
- if (spec.type === 'URL') {
247
- // TODO: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#valid-url-potentially-surrounded-by-spaces
248
- return false;
249
- }
250
- if (spec.type === 'URLHash') {
251
- /**
252
- * https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-hash-name-reference
253
- */
254
- const valid = value[0] === '#';
255
- if (valid) {
256
- return false;
257
- }
258
- return t('{0} expects {1:c}', t_theNameAttribute, t('valid {0}', 'hash-name reference'));
259
- }
260
- if (spec.type === 'URLList') {
261
- // TODO: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#valid-url-potentially-surrounded-by-spaces
262
- return false;
263
- }
264
- if (spec.type === 'CSSAngle') {
265
- /**
266
- * @see https://drafts.csswg.org/css-values/#angles
267
- */
268
- const valid = (0, primitive_check_1.numberCheckWithUnit)(value, ['deg', 'grad', 'rad', 'turn']);
269
- if (valid) {
270
- return false;
271
- }
272
- return t('{0} expects {1}', t_theNameAttribute, 'angle');
273
- }
274
- if (spec.type === 'CSSBlendMode') {
275
- /**
276
- * @see https://drafts.fxtf.org/compositing/#ltblendmodegt
277
- */
278
- return includesEnum(t, name, value, [
279
- 'normal',
280
- 'multiply',
281
- 'screen',
282
- 'overlay',
283
- 'darken',
284
- 'lighten',
285
- 'color-dodge',
286
- 'color-burn',
287
- 'hard-light',
288
- 'soft-light',
289
- 'difference',
290
- 'exclusion',
291
- 'hue',
292
- 'saturation',
293
- 'color',
294
- 'luminosity',
295
- ]);
296
- }
297
- if (spec.type === 'CSSClipPath') {
298
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
299
- return false;
300
- }
301
- if (spec.type === 'CSSCustomIdent') {
302
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
303
- return false;
304
- }
305
- if (spec.type === 'CSSDisplay') {
306
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/display
307
- return false;
308
- }
309
- if (spec.type === 'CSSFilter') {
310
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/filter
311
- return false;
312
- }
313
- if (spec.type === 'CSSFontFamily') {
314
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
315
- return false;
316
- }
317
- if (spec.type === 'CSSFontSize') {
318
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/font-size
319
- return false;
320
- }
321
- if (spec.type === 'CSSFontVariant') {
322
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant
323
- return false;
324
- }
325
- if (spec.type === 'CSSFontWeight') {
326
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
327
- return false;
328
- }
329
- if (spec.type === 'CSSMask') {
330
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/mask
331
- return false;
332
- }
333
- if (spec.type === 'CSSOpacity') {
334
- /**
335
- * @see https://drafts.csswg.org/css-color/#typedef-alpha-value
336
- */
337
- const { num, unit } = (0, primitive_check_1.splitUnit)(value);
338
- if (unit === '%') {
339
- const vaild = (0, primitive_check_1.range)(num, 0, 100);
340
- if (vaild) {
341
- return false;
58
+ else {
59
+ return {
60
+ invalidType: 'invalid-value',
61
+ message: invalid[0],
62
+ loc: invalid[1],
63
+ };
342
64
  }
343
- return t('{0} expects {1:c}', t_theNameAttribute, t('{0} as {1}', t('{0} to {1}', '0%', '100%'), 'alpha channel value'));
344
65
  }
345
- const vaild = (0, primitive_check_1.range)(num, 0, 1);
346
- if (vaild) {
347
- return false;
348
- }
349
- return t('{0} expects {1:c}', t_theNameAttribute, t('{0} as {1}', t('{0} to {1}', '0', '1'), 'alpha channel value'));
350
- }
351
- if (spec.type === 'CSSTextDecoration') {
352
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration
353
- return false;
354
- }
355
- if (spec.type === 'CSSTransformList') {
356
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function
357
- return false;
358
- }
359
- if (spec.type === 'CSSTransformOrigin') {
360
- // TODO: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
361
- return false;
362
- }
363
- if (spec.type === 'CSSURL') {
364
- // TODO: https://www.w3.org/TR/css3-values/#url-value
365
- return false;
366
- }
367
- if (spec.type === 'SVGAnimatableValue') {
368
- // TODO
369
- /**
370
- * The exact value type for this attribute depends on the value of the attribute
371
- * that will be animated.
372
- *
373
- * ```svg
374
- * <rect x="10" y="10" height="100">
375
- * <animate attributeName="width" fill="freeze" from="100" to="150" dur="3s"/>
376
- * </rect>
377
- * ```
378
- *
379
- * The `from` and `to` attributes of the `animate` element are SVGAnimatableValue.
380
- */
381
- return false;
382
- }
383
- if (spec.type === 'SVGBeginValueList') {
384
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/begin
385
- return false;
386
- }
387
- if (spec.type === 'SVGClockValue') {
388
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#clock-value
389
- return false;
390
- }
391
- if (spec.type === 'SVGColorMatrix') {
392
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feColorMatrix
393
- return false;
394
- }
395
- if (spec.type === 'SVGDashArray') {
396
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
397
- return false;
398
- }
399
- if (spec.type === 'SVGEndValueList') {
400
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/end
401
66
  return false;
402
- }
403
- if (spec.type === 'SVGFilterPrimitiveReference') {
404
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/result#usage_notes
405
- return false;
406
- }
407
- if (spec.type === 'SVGKernelMatrix') {
408
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/kernelMatrix
409
- return false;
410
- }
411
- if (spec.type === 'SVGKeyPoints') {
412
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/keyPoints
413
- return false;
414
- }
415
- if (spec.type === 'SVGKeySplines') {
416
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/keySplines
417
- return false;
418
- }
419
- if (spec.type === 'SVGKeyTimes') {
420
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/keyTimes
421
- return false;
422
- }
423
- if (spec.type === 'SVGLanguageTags') {
424
- /**
425
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/systemLanguage
426
- */
427
- // TODO: List of BCP47
67
+ });
68
+ if (invalidList.some(i => !i)) {
428
69
  return false;
429
70
  }
430
- if (spec.type === 'SVGLength') {
431
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#length
432
- return false;
433
- }
434
- if (spec.type === 'SVGLengthList') {
435
- /**
436
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#length
437
- */
438
- // TODO: List of SVGLength
439
- return false;
440
- }
441
- if (spec.type === 'SVGNumberList') {
442
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/tableValues#usage_notes
443
- return false;
444
- }
445
- if (spec.type === 'SVGNumberOptionalNumber') {
446
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#number-optional-number
447
- return false;
448
- }
449
- if (spec.type === 'SVGOrigin') {
450
- // TODO: https://www.w3.org/TR/2001/REC-smil-animation-20010904/#MotionOriginAttribute
451
- return false;
452
- }
453
- if (spec.type === 'SVGPaint') {
454
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#paint
455
- return false;
456
- }
457
- if (spec.type === 'SVGPathCommands') {
458
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands
459
- return false;
460
- }
461
- if (spec.type === 'SVGPercentage') {
462
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#percentage
463
- return false;
464
- }
465
- if (spec.type === 'SVGPercentageList') {
466
- /**
467
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#percentage
468
- */
469
- // TODO: List of SVGPercentage
470
- return false;
471
- }
472
- if (spec.type === 'SVGPoints') {
473
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/points
71
+ const invalid = invalidList.find(i => i);
72
+ return invalid || false;
73
+ }
74
+ exports.attrCheck = attrCheck;
75
+ function valueCheck(t, name, value, type) {
76
+ if (type === 'Boolean') {
77
+ // Valid because an attribute is exist
474
78
  return false;
475
79
  }
476
- if (spec.type === 'SVGPreserveAspectRatio') {
477
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio
478
- return false;
80
+ const matches = (0, types_1.check)(value, type);
81
+ if (debug_1.log.enabled) {
82
+ (0, debug_1.log)(`Result ([${name}="${value}"]): %O`, { ...matches, type });
479
83
  }
480
- if (spec.type === 'SVGViewBox') {
481
- // TODO: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
482
- return false;
84
+ if (!matches.matched) {
85
+ const location = {
86
+ raw: matches.raw,
87
+ line: matches.line - 1,
88
+ col: matches.column - 1,
89
+ };
90
+ const base = t('the "{0*}" {1}', name, 'attribute');
91
+ const message = (0, create_message_1.createMessageValueExpected)(t, base, type, matches);
92
+ return [message, location];
483
93
  }
484
94
  return false;
485
95
  }
486
- /**
487
- *
488
- * @param name
489
- * @param value
490
- * @param enumValues
491
- */
492
- function includesEnum(t, name, value, enumValues) {
493
- const valid = enumValues.includes(value.toLowerCase());
494
- if (valid) {
495
- return false;
496
- }
497
- return t('{0} expects {1:c}', t('the "{0}" {1}', name, 'attribute'), t('either {0}', t(enumValues)));
498
- }
96
+ exports.valueCheck = valueCheck;
@@ -1,2 +1,2 @@
1
- declare const _default: import("@markuplint/ml-core").RuleSeed<null, null>;
1
+ declare const _default: import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, null>;
2
2
  export default _default;
@@ -2,8 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  exports.default = (0, ml_core_1.createRule)({
5
- defaultValue: null,
6
- defaultOptions: null,
7
5
  async verify({ document, report, t }) {
8
6
  const message = t('{0} is {1:c}', t('the {0}', 'attribute name'), 'duplicated');
9
7
  await document.walkOn('Element', async (node) => {
@@ -6,7 +6,6 @@ const neverMsg = 'Never insert {0} after {1} of {2}';
6
6
  exports.default = (0, ml_core_1.createRule)({
7
7
  defaultServerity: 'warning',
8
8
  defaultValue: 'never',
9
- defaultOptions: null,
10
9
  async verify(context) {
11
10
  await context.document.walkOn('Element', async (node) => {
12
11
  for (const attr of node.attributes) {
@@ -6,7 +6,6 @@ const neverMsg = 'Never insert {0} before {1} of {2}';
6
6
  exports.default = (0, ml_core_1.createRule)({
7
7
  defaultServerity: 'warning',
8
8
  defaultValue: 'never',
9
- defaultOptions: null,
10
9
  async verify(context) {
11
10
  await context.document.walkOn('Element', async (node) => {
12
11
  for (const attr of node.attributes) {
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  exports.default = (0, ml_core_1.createRule)({
5
5
  defaultServerity: 'warning',
6
- defaultValue: true,
7
6
  defaultOptions: {
8
7
  lineBreak: 'either',
9
8
  width: 1,
@@ -8,7 +8,6 @@ const quoteList = {
8
8
  exports.default = (0, ml_core_1.createRule)({
9
9
  defaultServerity: 'warning',
10
10
  defaultValue: 'double',
11
- defaultOptions: null,
12
11
  async verify(context) {
13
12
  await context.document.walkOn('Element', async (node) => {
14
13
  const message = context.translate('{0} is must {1} on {2}', 'Attribute value', 'quote', `${node.rule.value} quotation mark`);
@@ -1,3 +1,7 @@
1
- export declare type Value = 'no-upper' | 'no-lower';
2
- declare const _default: import("@markuplint/ml-core").RuleSeed<Value, null>;
1
+ export declare type Value = 'lower' | 'upper';
2
+ /**
3
+ * @deprecated
4
+ */
5
+ export declare type Value_v1 = 'no-upper' | 'no-lower';
6
+ declare const _default: import("@markuplint/ml-core").RuleSeed<Value | Value_v1, null>;
3
7
  export default _default;