@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.
- package/lib/attr-check.d.ts +8 -1
- package/lib/attr-check.js +53 -455
- package/lib/attr-duplication/index.d.ts +1 -1
- package/lib/attr-duplication/index.js +0 -2
- package/lib/attr-equal-space-after/index.js +0 -1
- package/lib/attr-equal-space-before/index.js +0 -1
- package/lib/attr-spacing/index.js +0 -1
- package/lib/attr-value-quotes/index.js +0 -1
- package/lib/case-sensitive-attr-name/index.d.ts +6 -2
- package/lib/case-sensitive-attr-name/index.js +30 -8
- package/lib/case-sensitive-tag-name/index.js +0 -1
- package/lib/character-reference/index.d.ts +1 -2
- package/lib/character-reference/index.js +0 -2
- package/lib/class-naming/index.js +23 -23
- package/lib/create-message.d.ts +5 -0
- package/lib/create-message.js +270 -0
- package/lib/debug.d.ts +3 -0
- package/lib/debug.js +6 -0
- package/lib/deprecated-attr/index.d.ts +1 -1
- package/lib/deprecated-attr/index.js +2 -5
- package/lib/deprecated-element/index.d.ts +1 -1
- package/lib/deprecated-element/index.js +1 -3
- package/lib/disallowed-element/index.d.ts +2 -0
- package/lib/disallowed-element/index.js +34 -0
- package/lib/helpers.d.ts +15 -9
- package/lib/helpers.js +63 -68
- package/lib/id-duplication/index.d.ts +1 -1
- package/lib/id-duplication/index.js +1 -3
- package/lib/index.d.ts +28 -11
- package/lib/index.js +16 -0
- package/lib/ineffective-attr/index.d.ts +2 -0
- package/lib/ineffective-attr/index.js +40 -0
- package/lib/invalid-attr/index.d.ts +4 -2
- package/lib/invalid-attr/index.js +25 -9
- package/lib/landmark-roles/index.js +1 -2
- package/lib/no-boolean-attr-value/index.d.ts +2 -0
- package/lib/no-boolean-attr-value/index.js +47 -0
- package/lib/no-default-value/index.d.ts +2 -0
- package/lib/no-default-value/index.js +38 -0
- package/lib/no-hard-code-id/index.d.ts +2 -0
- package/lib/no-hard-code-id/index.js +27 -0
- package/lib/no-refer-to-non-existent-id/index.d.ts +2 -0
- package/lib/no-refer-to-non-existent-id/index.js +110 -0
- package/lib/no-use-event-handler-attr/index.d.ts +5 -0
- package/lib/no-use-event-handler-attr/index.js +37 -0
- package/lib/permitted-contents/index.js +24 -13
- package/lib/permitted-contents/types.d.ts +8 -0
- package/lib/permitted-contents/types.js +2 -0
- package/lib/require-element/index.d.ts +2 -0
- package/lib/require-element/index.js +38 -0
- package/lib/required-attr/index.d.ts +5 -1
- package/lib/required-attr/index.js +60 -19
- package/lib/required-element/index.d.ts +5 -0
- package/lib/required-element/index.js +44 -0
- package/lib/required-h1/index.d.ts +2 -3
- package/lib/required-h1/index.js +2 -3
- package/lib/wai-aria/index.d.ts +1 -1
- package/lib/wai-aria/index.js +23 -24
- package/package.json +10 -5
- package/schema.json +24 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/primitive-check.d.ts +0 -48
- package/lib/primitive-check.js +0 -109
package/lib/attr-check.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
32
|
-
if (
|
|
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: '
|
|
35
|
-
message:
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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 (
|
|
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
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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 (
|
|
481
|
-
|
|
482
|
-
|
|
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<
|
|
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 = '
|
|
2
|
-
|
|
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;
|