@markuplint/config-presets 3.0.0-alpha.4 → 3.0.0-alpha.6
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/README.md +2 -2
- package/package.json +2 -2
- package/preset.recommended-react.json +1 -1
- package/preset.recommended-static-html.json +1 -1
- package/preset.recommended-svelte.json +1 -1
- package/preset.recommended-vue.json +1 -1
- package/preset.recommended.json +1 -1
- package/build.mjs +0 -107
- package/preset.___test.json +0 -3
- package/src/README.md +0 -39
- package/src/preset.a11y.json +0 -178
- package/src/preset.code-styles.json +0 -3
- package/src/preset.html-standard.json +0 -116
- package/src/preset.performance.json +0 -70
- package/src/preset.rdfa.json +0 -27
- package/src/preset.recommended-react.json +0 -19
- package/src/preset.recommended-static-html.json +0 -19
- package/src/preset.recommended-svelte.json +0 -19
- package/src/preset.recommended-vue.json +0 -19
- package/src/preset.recommended.json +0 -10
- package/src/preset.security.json +0 -23
package/README.md
CHANGED
|
@@ -45,8 +45,8 @@ No merge cells| |✅|✅|✅|✅|✅|✅|❌|❌|❌|❌|❌|
|
|
|
45
45
|
[`<summary>` no contains interactive contents](https://github.com/whatwg/html/issues/2272#issuecomment-1242415594)|There is a case where an assistive technology can't access contents, or contents don't propagate a mouse event to `<summary>`.|✅|✅|✅|✅|✅|✅|❌|❌|❌|❌|❌|
|
|
46
46
|
[No duplicate attr](https://html.spec.whatwg.org/multipage/parsing.html#parse-error-duplicate-attribute)|The parser ignores all such duplicate occurrences of the attribute.|✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
47
47
|
Use **character reference**| |✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
48
|
-
No use
|
|
49
|
-
No use
|
|
48
|
+
No use deprecated attr|You should not use deprecated attributes from the viewpoint of compatibility.|✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
49
|
+
No use deprecated element|You should not use deprecated elements from the viewpoint of compatibility.|✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
50
50
|
[Require `doctype`](https://html.spec.whatwg.org/multipage/syntax.html#syntax-doctype)|It has the effect of avoiding quirks mode.|✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
51
51
|
No use ineffective attr| |✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
|
52
52
|
Allow only **permitted contents**| |✅|✅|✅|✅|✅|❌|❌|✅|❌|❌|❌|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/config-presets",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
4
|
"description": "markuplint config presets",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
"jsonc-parser": "^3.2.0",
|
|
18
18
|
"mustache": "^4.2.0"
|
|
19
19
|
},
|
|
20
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "b185a06d4ea09a1bf32458f7be4abe510eb57b89"
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"extends":["markuplint:code-
|
|
1
|
+
{"extends":["markuplint:code-styles","markuplint:html-standard","markuplint:a11y","markuplint:performance","markuplint:security","markuplint:rdfa"],"rules":{"no-hard-code-id":true}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"extends":["markuplint:code-
|
|
1
|
+
{"extends":["markuplint:code-styles","markuplint:html-standard","markuplint:a11y","markuplint:performance","markuplint:security","markuplint:rdfa"],"rules":{"end-tag":true}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"extends":["markuplint:code-
|
|
1
|
+
{"extends":["markuplint:code-styles","markuplint:html-standard","markuplint:a11y","markuplint:performance","markuplint:security","markuplint:rdfa"],"rules":{"no-hard-code-id":true}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"extends":["markuplint:code-
|
|
1
|
+
{"extends":["markuplint:code-styles","markuplint:html-standard","markuplint:a11y","markuplint:performance","markuplint:security","markuplint:rdfa"],"rules":{"no-hard-code-id":true}}
|
package/preset.recommended.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"extends":["markuplint:code-
|
|
1
|
+
{"extends":["markuplint:code-styles","markuplint:html-standard","markuplint:a11y","markuplint:performance","markuplint:security","markuplint:rdfa"]}
|
package/build.mjs
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { readFile, rm, writeFile } from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import glob from 'glob';
|
|
5
|
-
import { promisify } from 'util';
|
|
6
|
-
import { stripComments, visit } from 'jsonc-parser';
|
|
7
|
-
import mustache from 'mustache';
|
|
8
|
-
|
|
9
|
-
const asyncGlob = promisify(glob);
|
|
10
|
-
|
|
11
|
-
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const srcDir = path.resolve(dirname, 'src');
|
|
13
|
-
|
|
14
|
-
const currents = await asyncGlob('preset.*.json,!preset.___json');
|
|
15
|
-
await Promise.all(currents.map(current => rm(current)));
|
|
16
|
-
|
|
17
|
-
const files = await asyncGlob(path.resolve(srcDir, '*.json'));
|
|
18
|
-
const md = await readFile(path.resolve(srcDir, 'README.md'), { encoding: 'utf-8' });
|
|
19
|
-
|
|
20
|
-
const presets = [];
|
|
21
|
-
const rules = {};
|
|
22
|
-
const extended = {};
|
|
23
|
-
|
|
24
|
-
for (const file of files) {
|
|
25
|
-
const filename = path.basename(file);
|
|
26
|
-
const code = await readFile(path.resolve(dirname, 'src', filename), { encoding: 'utf-8' });
|
|
27
|
-
const json = JSON.parse(stripComments(code));
|
|
28
|
-
const compressed = JSON.stringify(json);
|
|
29
|
-
await writeFile(path.resolve(dirname, filename), compressed, { encoding: 'utf-8' });
|
|
30
|
-
|
|
31
|
-
const name = filename.replace(/^preset\.|\.json/g, '');
|
|
32
|
-
presets.push(name);
|
|
33
|
-
extended[name] = (json['extends'] || []).map(name => name.replace('markuplint:', ''));
|
|
34
|
-
|
|
35
|
-
visit(
|
|
36
|
-
code,
|
|
37
|
-
{
|
|
38
|
-
onComment(offset, length) {
|
|
39
|
-
const comment = code.substring(offset, offset + length);
|
|
40
|
-
const line = comment.split('\n');
|
|
41
|
-
const [heading = '', desc = ''] = comment
|
|
42
|
-
.split(/\n\s*\*\s*\n/g)
|
|
43
|
-
.map(section => cleanComment(section))
|
|
44
|
-
.filter(s => !/^@see\s/.test(s));
|
|
45
|
-
const text = line.map(line => cleanComment(line)).filter(s => s);
|
|
46
|
-
const url = (text.find(t => /^@see\s/i.test(t)) || '').replace(/^@see\s/i, '');
|
|
47
|
-
|
|
48
|
-
if (!heading) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (rules[heading]?.config) {
|
|
53
|
-
rules[heading].config.push(name);
|
|
54
|
-
} else {
|
|
55
|
-
rules[heading] = {
|
|
56
|
-
desc,
|
|
57
|
-
url,
|
|
58
|
-
config: [name],
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{ disallowComments: false },
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
presets.sort((a, b) => {
|
|
68
|
-
if (a.includes('recommended')) {
|
|
69
|
-
return -1;
|
|
70
|
-
}
|
|
71
|
-
return a - b;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const renderMd = mustache.render(md, {
|
|
75
|
-
presets: () => {
|
|
76
|
-
const line = [];
|
|
77
|
-
line.push(`Ruleset|Description|${presets.map(p => `\`${p}\``).join('|')}|`);
|
|
78
|
-
line.push(`---|---|${'---|'.repeat(presets.length)}`);
|
|
79
|
-
|
|
80
|
-
Object.entries(rules).forEach(([name, context]) => {
|
|
81
|
-
const title = context.url ? `[${name}](${context.url})` : name;
|
|
82
|
-
const checks = presets.map(preset => {
|
|
83
|
-
const configs = [preset, ...extended[preset]];
|
|
84
|
-
const has = configs.some(config => context.config?.includes(config));
|
|
85
|
-
return has ? '✅' : '❌';
|
|
86
|
-
});
|
|
87
|
-
line.push(`${title}|${context.desc || ' '}|${checks.join('|')}|`);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return line.join('\n');
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
*
|
|
96
|
-
* @param {string} text
|
|
97
|
-
* @returns
|
|
98
|
-
*/
|
|
99
|
-
function cleanComment(text) {
|
|
100
|
-
const t1 = text.trim();
|
|
101
|
-
const t2 = t1.replace(/^\/\*\*(?:[\n\s]*\*[\n\s]*)?|^\*\/|^\*|^\*[\s\n]*|[\s\n]*\*\/$/g, '');
|
|
102
|
-
const t3 = t2.replace(/\s*\n\s*(?:\*\s*)?/g, ' ');
|
|
103
|
-
const t4 = t3.trim();
|
|
104
|
-
return t4;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
await writeFile('README.md', renderMd, { encoding: 'utf-8' });
|
package/preset.___test.json
DELETED
package/src/README.md
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# @markuplint/config-presets
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@markuplint/config-presets)
|
|
4
|
-
[](https://travis-ci.org/markuplint/markuplint)
|
|
5
|
-
[](https://coveralls.io/github/markuplint/markuplint?branch=main)
|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
To the `extends` property of the configuration, specify like below:
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{
|
|
13
|
-
"extends": ["markuplint:recommended"]
|
|
14
|
-
}
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
You can choose some presets appropriately for your preference.
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"extends": ["markuplint:html-standard", "markuplint:a11y"]
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Presets
|
|
26
|
-
|
|
27
|
-
{{{ presets }}}
|
|
28
|
-
|
|
29
|
-
## Install
|
|
30
|
-
|
|
31
|
-
`markuplint` package includes this package.
|
|
32
|
-
|
|
33
|
-
If you are installing purposely, how below:
|
|
34
|
-
|
|
35
|
-
```sh
|
|
36
|
-
$ npm install @markuplint/config-presets
|
|
37
|
-
|
|
38
|
-
$ yarn add @markuplint/config-presets
|
|
39
|
-
```
|
package/src/preset.a11y.json
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"rules": {
|
|
3
|
-
"disallowed-element": [
|
|
4
|
-
/**
|
|
5
|
-
* Disallow `<hgroup>`
|
|
6
|
-
*
|
|
7
|
-
* The hgroup element should not be used because no assistive technology supports it.
|
|
8
|
-
*
|
|
9
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup
|
|
10
|
-
*/
|
|
11
|
-
"hgroup"
|
|
12
|
-
],
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Must not duplicate **ID**
|
|
16
|
-
*
|
|
17
|
-
* Be able to avoid problems in assistive technologies from the viewpoint of machine readability.
|
|
18
|
-
*
|
|
19
|
-
* @see https://www.w3.org/WAI/WCAG21/Techniques/html/H93.html
|
|
20
|
-
*/
|
|
21
|
-
"id-duplication": true,
|
|
22
|
-
|
|
23
|
-
"invalid-attr": {
|
|
24
|
-
"option": {
|
|
25
|
-
"attrs": {
|
|
26
|
-
/**
|
|
27
|
-
* Disallow `autofocus` attr
|
|
28
|
-
*
|
|
29
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus#accessibility_considerations
|
|
30
|
-
*/
|
|
31
|
-
"autofocus": {
|
|
32
|
-
"disallowed": true
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Disallow `autofocus` attr
|
|
37
|
-
*
|
|
38
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey#accessibility_concerns
|
|
39
|
-
*/
|
|
40
|
-
"accesskey": {
|
|
41
|
-
"disallowed": true
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* `tabindex` attr only `-1` or `0`
|
|
46
|
-
*
|
|
47
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex#accessibility_concerns
|
|
48
|
-
*/
|
|
49
|
-
"tabindex": {
|
|
50
|
-
"enum": ["-1", "0"]
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* `<label>` should have control
|
|
58
|
-
*
|
|
59
|
-
*/
|
|
60
|
-
"label-has-control": true,
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Use **landmark**
|
|
64
|
-
*
|
|
65
|
-
* @see https://www.w3.org/TR/wai-aria-practices/examples/landmarks/
|
|
66
|
-
*/
|
|
67
|
-
"landmark-roles": true,
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* No refer to no existent **ID**
|
|
71
|
-
*/
|
|
72
|
-
"no-refer-to-non-existent-id": true,
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Require **accessible name**
|
|
76
|
-
*/
|
|
77
|
-
"require-accessible-name": true,
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Require `<h1>`
|
|
81
|
-
*
|
|
82
|
-
*/
|
|
83
|
-
"required-h1": true,
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Use `<ul>`
|
|
87
|
-
*
|
|
88
|
-
*/
|
|
89
|
-
"use-list": true,
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Conform to **WAI-ARIA**
|
|
93
|
-
*
|
|
94
|
-
*/
|
|
95
|
-
"wai-aria": true
|
|
96
|
-
},
|
|
97
|
-
"nodeRules": [
|
|
98
|
-
{
|
|
99
|
-
"selector": ":where(html)",
|
|
100
|
-
"rules": {
|
|
101
|
-
/**
|
|
102
|
-
* Require `<html lang>`
|
|
103
|
-
*
|
|
104
|
-
*/
|
|
105
|
-
"required-attr": ["lang"]
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
"selector": ":where(abbr)",
|
|
110
|
-
"rules": {
|
|
111
|
-
/**
|
|
112
|
-
* Require `<abbr title>`
|
|
113
|
-
*/
|
|
114
|
-
"required-attr": ["title"]
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"selector": ":where(video, audio)",
|
|
119
|
-
"rules": {
|
|
120
|
-
/**
|
|
121
|
-
* Require `<track>`
|
|
122
|
-
*
|
|
123
|
-
*/
|
|
124
|
-
"required-element": ["track"]
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"selector": ":where(video[autoplay])",
|
|
129
|
-
"rules": {
|
|
130
|
-
/**
|
|
131
|
-
* Require `<video muted>`
|
|
132
|
-
*
|
|
133
|
-
*/
|
|
134
|
-
"required-attr": ["muted"]
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
/**
|
|
139
|
-
* No merge cells
|
|
140
|
-
*
|
|
141
|
-
*/
|
|
142
|
-
"selector": ":where(th, td)",
|
|
143
|
-
"rules": {
|
|
144
|
-
"invalid-attr": {
|
|
145
|
-
"option": {
|
|
146
|
-
"attrs": {
|
|
147
|
-
"colspan": {
|
|
148
|
-
"disallowed": true
|
|
149
|
-
},
|
|
150
|
-
"rowspan": {
|
|
151
|
-
"disallowed": true
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"selector": ":where(summary)",
|
|
160
|
-
"rules": {
|
|
161
|
-
/**
|
|
162
|
-
* `<summary>` no contains interactive contents
|
|
163
|
-
*
|
|
164
|
-
* There is a case where an assistive technology can't access contents, or contents don't propagate a mouse event to `<summary>`.
|
|
165
|
-
*
|
|
166
|
-
* > The link is not discoverable at all to JAWS when navigating with its virtual cursor.
|
|
167
|
-
* > If navigating to the summary element via the Tab key,
|
|
168
|
-
* > JAWS announces "example text, button" as the name and role of the element.
|
|
169
|
-
* > If hitting Tab key again, JAWS again announces "example text,
|
|
170
|
-
* > button" even though keyboard focus is on the link.
|
|
171
|
-
*
|
|
172
|
-
* @see https://github.com/whatwg/html/issues/2272#issuecomment-1242415594
|
|
173
|
-
*/
|
|
174
|
-
"disallowed-element": [":model(interactive)"]
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
]
|
|
178
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"rules": {
|
|
3
|
-
/**
|
|
4
|
-
* No duplicate attr
|
|
5
|
-
*
|
|
6
|
-
* The parser ignores all such duplicate occurrences of the attribute.
|
|
7
|
-
*
|
|
8
|
-
* @see https://html.spec.whatwg.org/multipage/parsing.html#parse-error-duplicate-attribute
|
|
9
|
-
*/
|
|
10
|
-
"attr-duplication": true,
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Use **character reference**
|
|
14
|
-
*
|
|
15
|
-
*/
|
|
16
|
-
"character-reference": true,
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* No use depreacted attr
|
|
20
|
-
*
|
|
21
|
-
* You should not use deprecated attributes from the viewpoint of compatibility.
|
|
22
|
-
*/
|
|
23
|
-
"deprecated-attr": true,
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* No use depreacted element
|
|
27
|
-
*
|
|
28
|
-
* You should not use deprecated elements from the viewpoint of compatibility.
|
|
29
|
-
*/
|
|
30
|
-
"deprecated-element": true,
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Require `doctype`
|
|
34
|
-
*
|
|
35
|
-
* It has the effect of avoiding quirks mode.
|
|
36
|
-
*
|
|
37
|
-
* @see https://html.spec.whatwg.org/multipage/syntax.html#syntax-doctype
|
|
38
|
-
*/
|
|
39
|
-
"doctype": true,
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Must not duplicate **ID**
|
|
43
|
-
*
|
|
44
|
-
*/
|
|
45
|
-
"id-duplication": true,
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* No use ineffective attr
|
|
49
|
-
*
|
|
50
|
-
*/
|
|
51
|
-
"ineffective-attr": true,
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* No refer to no existent **ID**
|
|
55
|
-
*/
|
|
56
|
-
"no-refer-to-non-existent-id": true,
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Allow only **permitted contents**
|
|
60
|
-
*
|
|
61
|
-
*/
|
|
62
|
-
"permitted-contents": true,
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Specify required attr
|
|
66
|
-
*
|
|
67
|
-
*/
|
|
68
|
-
"required-attr": true
|
|
69
|
-
},
|
|
70
|
-
"nodeRules": [
|
|
71
|
-
{
|
|
72
|
-
/**
|
|
73
|
-
* Specify `charset=UTF-8`
|
|
74
|
-
*
|
|
75
|
-
* @see https://html.spec.whatwg.org/multipage/semantics.html#charset
|
|
76
|
-
*/
|
|
77
|
-
"selector": ":where(head)",
|
|
78
|
-
"rules": {
|
|
79
|
-
"required-element": ["meta[charset=\"UTF-8\" i]"]
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
/**
|
|
84
|
-
* No use `<small>` as **subheadings**
|
|
85
|
-
*
|
|
86
|
-
* Should not use it in `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`, and `<h6>`.
|
|
87
|
-
*
|
|
88
|
-
* @see https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-small-element
|
|
89
|
-
*/
|
|
90
|
-
"selector": "h1, h2, h3, h4, h5, h6",
|
|
91
|
-
"rules": {
|
|
92
|
-
"disallowed-element": {
|
|
93
|
-
"value": ["small"],
|
|
94
|
-
"reason": "The small element must not be used for subheadings. https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-small-element"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
/**
|
|
100
|
-
* No use `<caption>` within `<figure>`
|
|
101
|
-
*
|
|
102
|
-
* When `<table>` is the only content in `<figure>` other than `<figcaption>`, `<caption>` should be omitted in favor of `<figcaption>`.
|
|
103
|
-
*
|
|
104
|
-
* @see https://html.spec.whatwg.org/multipage/tables.html#the-caption-element
|
|
105
|
-
*/
|
|
106
|
-
"selector": ":where(figcaption ~ table, table:has(~ figcaption))",
|
|
107
|
-
"rules": {
|
|
108
|
-
"disallowed-element": {
|
|
109
|
-
"value": ["caption"],
|
|
110
|
-
"reason": "When a table element is the only content in a figure element other than the figcaption, the caption element should be omitted in favor of the figcaption. (https://html.spec.whatwg.org/multipage/tables.html#the-caption-element)"
|
|
111
|
-
},
|
|
112
|
-
"require-accessible-name": false
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nodeRules": [
|
|
3
|
-
{
|
|
4
|
-
/**
|
|
5
|
-
* Require `charset=UTF-8`
|
|
6
|
-
*
|
|
7
|
-
* @see https://html.spec.whatwg.org/multipage/semantics.html#charset
|
|
8
|
-
*/
|
|
9
|
-
"selector": ":where(head)",
|
|
10
|
-
"rules": {
|
|
11
|
-
"required-element": ["meta[charset=\"UTF-8\" i]"]
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
/**
|
|
16
|
-
* Require `defer` attr
|
|
17
|
-
*
|
|
18
|
-
* Should load and parse scripts lazily to avoid render-blocking.
|
|
19
|
-
*/
|
|
20
|
-
"selector": ":where(script[src]:not([type=module]))",
|
|
21
|
-
"rules": {
|
|
22
|
-
"required-attr": ["defer"]
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
/**
|
|
27
|
-
* Require **aspect-ratio**
|
|
28
|
-
*
|
|
29
|
-
* Require `width` and `height` attr with `<img>` to avoid **Cumulative Layout Shift**
|
|
30
|
-
*/
|
|
31
|
-
"selector": ":where(img[src])",
|
|
32
|
-
"rules": {
|
|
33
|
-
"required-attr": ["width", "height"]
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
/**
|
|
38
|
-
* Require async decoding image
|
|
39
|
-
*
|
|
40
|
-
* Require `decoding=async` with `<img>` to avoid render-blocking.
|
|
41
|
-
*/
|
|
42
|
-
"selector": ":where(img[src][width][height])",
|
|
43
|
-
"rules": {
|
|
44
|
-
"required-attr": [
|
|
45
|
-
{
|
|
46
|
-
"name": "decoding",
|
|
47
|
-
"value": "async"
|
|
48
|
-
}
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
/**
|
|
54
|
-
* Require loading `<iframe>` lazily
|
|
55
|
-
*
|
|
56
|
-
* Require `loading=lazy` with `<iframe>` to avoid render-blocking that causes loading if its element is out of the viewport.
|
|
57
|
-
*/
|
|
58
|
-
"selector": ":where(iframe)",
|
|
59
|
-
"rules": {
|
|
60
|
-
"required-attr": [
|
|
61
|
-
"title",
|
|
62
|
-
{
|
|
63
|
-
"name": "loading",
|
|
64
|
-
"value": "lazy"
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
|
-
}
|
package/src/preset.rdfa.json
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nodeRules": [
|
|
3
|
-
{
|
|
4
|
-
/**
|
|
5
|
-
* Allow `property` attr with `<meta>`
|
|
6
|
-
*
|
|
7
|
-
* Be able to use **Open-Graph** etc.
|
|
8
|
-
*/
|
|
9
|
-
"selector": ":where(meta[property])",
|
|
10
|
-
"rules": {
|
|
11
|
-
"invalid-attr": {
|
|
12
|
-
"option": {
|
|
13
|
-
"attrs": {
|
|
14
|
-
"property": {
|
|
15
|
-
"type": "NoEmptyAny"
|
|
16
|
-
},
|
|
17
|
-
"content": {
|
|
18
|
-
"type": "NoEmptyAny"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"required-attr": false
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
]
|
|
27
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"markuplint:code-style",
|
|
4
|
-
"markuplint:html-standard",
|
|
5
|
-
"markuplint:a11y",
|
|
6
|
-
"markuplint:performance",
|
|
7
|
-
"markuplint:security",
|
|
8
|
-
"markuplint:rdfa"
|
|
9
|
-
],
|
|
10
|
-
"rules": {
|
|
11
|
-
/**
|
|
12
|
-
* No hard coding **ID**
|
|
13
|
-
*
|
|
14
|
-
* The component that hard-coded ID cannot mount to an app duplicated because the IDs must be unique in a document.
|
|
15
|
-
* Recommend to specify dynamic IDs to avoid doing that.
|
|
16
|
-
*/
|
|
17
|
-
"no-hard-code-id": true
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"markuplint:code-style",
|
|
4
|
-
"markuplint:html-standard",
|
|
5
|
-
"markuplint:a11y",
|
|
6
|
-
"markuplint:performance",
|
|
7
|
-
"markuplint:security",
|
|
8
|
-
"markuplint:rdfa"
|
|
9
|
-
],
|
|
10
|
-
"rules": {
|
|
11
|
-
/**
|
|
12
|
-
* No omit **end-tag**
|
|
13
|
-
*
|
|
14
|
-
* Recommend to write an end-tag always because it is too difficult
|
|
15
|
-
* for a human decide an element is end-tag omittable.
|
|
16
|
-
*/
|
|
17
|
-
"end-tag": true
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"markuplint:code-style",
|
|
4
|
-
"markuplint:html-standard",
|
|
5
|
-
"markuplint:a11y",
|
|
6
|
-
"markuplint:performance",
|
|
7
|
-
"markuplint:security",
|
|
8
|
-
"markuplint:rdfa"
|
|
9
|
-
],
|
|
10
|
-
"rules": {
|
|
11
|
-
/**
|
|
12
|
-
* No hard coding **ID**
|
|
13
|
-
*
|
|
14
|
-
* The component that hard-coded ID cannot mount to an app duplicated because the IDs must be unique in a document.
|
|
15
|
-
* Recommend to specify dynamic IDs to avoid doing that.
|
|
16
|
-
*/
|
|
17
|
-
"no-hard-code-id": true
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": [
|
|
3
|
-
"markuplint:code-style",
|
|
4
|
-
"markuplint:html-standard",
|
|
5
|
-
"markuplint:a11y",
|
|
6
|
-
"markuplint:performance",
|
|
7
|
-
"markuplint:security",
|
|
8
|
-
"markuplint:rdfa"
|
|
9
|
-
],
|
|
10
|
-
"rules": {
|
|
11
|
-
/**
|
|
12
|
-
* No hard coding **ID**
|
|
13
|
-
*
|
|
14
|
-
* The component that hard-coded ID cannot mount to an app duplicated because the IDs must be unique in a document.
|
|
15
|
-
* Recommend to specify dynamic IDs to avoid doing that.
|
|
16
|
-
*/
|
|
17
|
-
"no-hard-code-id": true
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/preset.security.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"nodeRules": [
|
|
3
|
-
{
|
|
4
|
-
/**
|
|
5
|
-
* Require `noreferrer` with `target=_blank`
|
|
6
|
-
*
|
|
7
|
-
* Require `rel=noreferrer` with an element that has `target=_blank` to prevent leaking referrer information and to block operating referrer documents.
|
|
8
|
-
*/
|
|
9
|
-
"selector": ":where(a[target=_blank], area[target=_blank])",
|
|
10
|
-
"rules": {
|
|
11
|
-
"required-attr": {
|
|
12
|
-
"value": [
|
|
13
|
-
{
|
|
14
|
-
"name": "rel",
|
|
15
|
-
"value": "/(?<![^\\s]+)noreferrer(?![^\\s]+)/"
|
|
16
|
-
}
|
|
17
|
-
],
|
|
18
|
-
"reason": "The \"rel\" attribute should be required with \"noreferrer\" if the \"a\" element has the \"target=_blank\""
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|