@markuplint/rules 2.0.0-rc.1 → 2.0.0
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 +34 -66
- package/lib/attr-check.d.ts +19 -8
- package/lib/attr-check.js +2 -2
- package/lib/attr-duplication/index.d.ts +1 -1
- package/lib/attr-equal-space-after/index.d.ts +1 -1
- package/lib/attr-equal-space-before/index.d.ts +1 -1
- package/lib/attr-spacing/index.d.ts +3 -3
- package/lib/attr-value-quotes/index.d.ts +2 -2
- package/lib/case-sensitive-attr-name/index.d.ts +6 -2
- package/lib/case-sensitive-attr-name/index.js +28 -4
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/class-naming/index.js +1 -1
- package/lib/create-message.d.ts +12 -2
- package/lib/deprecated-attr/index.d.ts +1 -1
- package/lib/deprecated-attr/index.js +1 -1
- package/lib/deprecated-element/index.d.ts +1 -1
- package/lib/deprecated-element/index.js +1 -1
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/doctype/index.d.ts +2 -2
- package/lib/end-tag/index.d.ts +2 -0
- package/lib/end-tag/index.js +43 -0
- package/lib/helpers.d.ts +78 -45
- package/lib/helpers.js +26 -27
- package/lib/id-duplication/index.d.ts +1 -1
- package/lib/id-duplication/index.js +1 -1
- package/lib/indentation/index.d.ts +3 -3
- package/lib/index.d.ts +147 -60
- package/lib/index.js +2 -0
- package/lib/ineffective-attr/index.d.ts +1 -1
- package/lib/ineffective-attr/index.js +1 -1
- package/lib/invalid-attr/index.d.ts +16 -12
- package/lib/invalid-attr/index.js +10 -3
- package/lib/landmark-roles/index.d.ts +3 -3
- package/lib/landmark-roles/index.js +1 -1
- package/lib/no-boolean-attr-value/index.d.ts +1 -1
- package/lib/no-boolean-attr-value/index.js +2 -2
- package/lib/no-default-value/index.d.ts +1 -1
- package/lib/no-hard-code-id/index.d.ts +1 -1
- package/lib/no-refer-to-non-existent-id/index.d.ts +1 -1
- package/lib/no-refer-to-non-existent-id/index.js +2 -2
- package/lib/no-use-event-handler-attr/index.d.ts +2 -2
- package/lib/no-use-event-handler-attr/index.js +1 -1
- package/lib/permitted-contents/index.d.ts +2 -2
- package/lib/permitted-contents/index.js +13 -13
- package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +8 -8
- package/lib/permitted-contents/types.d.ts +8 -0
- package/lib/permitted-contents/types.js +2 -0
- package/lib/require-element/index.d.ts +1 -1
- package/lib/required-attr/index.d.ts +3 -3
- package/lib/required-attr/index.js +2 -2
- package/lib/required-element/index.d.ts +2 -2
- package/lib/required-h1/index.d.ts +3 -3
- package/lib/required-h1/index.js +2 -2
- package/lib/wai-aria/index.d.ts +7 -7
- package/lib/wai-aria/index.js +21 -21
- package/package.json +7 -7
- package/schema.json +3 -0
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -8,86 +8,54 @@
|
|
|
8
8
|
|
|
9
9
|
### Conformance checking
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
- [`attr-duplication`](./src/attr-duplication)
|
|
12
|
+
- [`character-reference`](./src/character-reference)
|
|
13
|
+
- [`deprecated-attr`](./src/deprecated-attr)
|
|
14
|
+
- [`deprecated-element`](./src/deprecated-element)
|
|
15
|
+
- [`disallowed-element`](./src/disallowed-element)
|
|
16
|
+
- [`doctype`](./src/doctype)
|
|
17
|
+
- [`id-duplication`](./src/id-duplication)
|
|
18
|
+
- [`ineffective-attr`](./src/ineffective-attr)
|
|
19
|
+
- [`invalid-attr`](./src/invalid-attr)
|
|
20
|
+
- [`permitted-contents`](./src/permitted-contents)
|
|
21
|
+
- [`required-attr`](./src/required-attr)
|
|
22
|
+
- [`required-element`](./src/required-element)
|
|
23
23
|
|
|
24
24
|
### Accessibility
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
| 🚧 | 🚧 | 🚧 | [heading-in-sectioning-content](./src/heading-in-sectioning-content/) | |
|
|
31
|
-
| 🚧 | 🚧 | 🚧 | [heading-in-sectioning-root](./src/heading-in-sectioning-root/) | |
|
|
32
|
-
| 🚧 | 🚧 | 🚧 | [heading-levels-skipping](./src/heading-levels-skipping/) | |
|
|
33
|
-
| 🚧 | 🚧 | 🚧 | [labeling-controls](./src/labeling-controls/) | |
|
|
34
|
-
| ✅ | ✅ | ✅ | [landmark-roles](./src/landmark-roles/) | |
|
|
35
|
-
| ✅ | ✅ | ✅ | [required-h1](./src/required-h1/) | |
|
|
26
|
+
- [`landmark-roles`](./src/landmark-roles)
|
|
27
|
+
- [`no-refer-to-non-existent-id`](./src/no-refer-to-non-existent-id)
|
|
28
|
+
- [`required-h1`](./src/required-h1)
|
|
29
|
+
- [`wai-aria`](./src/wai-aria)
|
|
36
30
|
|
|
37
|
-
###
|
|
31
|
+
### Naming Convention
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
| -------- | ---- | -------- | ------------------------------------- | ------- |
|
|
41
|
-
| 🚧 | 🚧 | 🚧 | [external-link](./src/external-link/) | 🚧 |
|
|
33
|
+
- [`class-naming`](./src/class-naming)
|
|
42
34
|
|
|
43
|
-
###
|
|
35
|
+
### Maintenability
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
| ✅ | ✅ | ✅ | [class-naming](./src/class-naming/) | |
|
|
48
|
-
| 🚧 | 🚧 | 🚧 | [custom-element-naming](./src/custom-element-naming/) | |
|
|
49
|
-
| 🚧 | 🚧 | 🚧 | [data-attr-naming](./src/data-attr-naming/) | |
|
|
50
|
-
| 🚧 | 🚧 | 🚧 | [required-element](./src/required-element/) | |
|
|
37
|
+
- [`no-hard-code-id`](./src/no-hard-code-id)
|
|
38
|
+
- [`no-use-event-handler-attr`](./src/no-use-event-handler-attr)
|
|
51
39
|
|
|
52
40
|
### Style
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
| ✅ | ✅ | ✅ | [indentation](./src/indentation/) | ✅ |
|
|
65
|
-
| 🚧 | 🚧 | 🚧 | [indentation-attr](./src/indentation-attr/) | 🚧 |
|
|
66
|
-
| 🚧 | 🚧 | 🚧 | [path](./src/path/) | |
|
|
67
|
-
| 🚧 | 🚧 | ✅ | [self-closing-tag](./src/self-closing-tag/) | 🚧 |
|
|
68
|
-
| 🚧 | 🚧 | 🚧 | [tag-omission](./src/tag-omission/) | 🚧 |
|
|
42
|
+
- [`attr-equal-space-after`](./src/attr-equal-space-after)
|
|
43
|
+
- [`attr-equal-space-before`](./src/attr-equal-space-before)
|
|
44
|
+
- [`attr-spacing`](./src/attr-spacing)
|
|
45
|
+
- [`attr-value-quotes`](./src/attr-value-quotes)
|
|
46
|
+
- [`case-sensitive-attr-name`](./src/case-sensitive-attr-name)
|
|
47
|
+
- [`case-sensitive-tag-name`](./src/case-sensitive-tag-name)
|
|
48
|
+
- [`end-tag`](./src/end-tag)
|
|
49
|
+
- [`indentation`](./src/indentation)
|
|
50
|
+
- [`no-boolean-attr-value`](./src/no-boolean-attr-value)
|
|
51
|
+
- [`no-default-value`](./src/no-default-value)
|
|
69
52
|
|
|
70
53
|
## Install
|
|
71
54
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
Prerequisites: [Node.js](https://nodejs.org) (Version 12.4.0 or later)
|
|
55
|
+
Generally, you **don't have to install** this package because markuplint dependents it defaultly.
|
|
75
56
|
|
|
76
57
|
```sh
|
|
77
|
-
$ npm install @markuplint/rules
|
|
78
|
-
|
|
79
|
-
$ yarn add @markuplint/rules
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Contributing
|
|
58
|
+
$ npm install -D @markuplint/rules
|
|
83
59
|
|
|
60
|
+
$ yarn add -D @markuplint/rules
|
|
84
61
|
```
|
|
85
|
-
$ git clone git@github.com:markuplint/markuplint.git -b main
|
|
86
|
-
$ yarn
|
|
87
|
-
$ yarn build
|
|
88
|
-
$ yarn test
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
Copyright © 2021 markuplint. Under the MIT License.
|
package/lib/attr-check.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Translator } from '@markuplint/i18n';
|
|
2
2
|
import type { Attribute as AttrSpec, AttributeType } from '@markuplint/ml-spec';
|
|
3
3
|
declare type Invalid = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
invalidType: 'non-existent' | 'invalid-value';
|
|
5
|
+
message: string;
|
|
6
|
+
loc?: Loc;
|
|
7
7
|
};
|
|
8
8
|
declare type Loc = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
raw: string;
|
|
10
|
+
line: number;
|
|
11
|
+
col: number;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Use in rules `invalid-attr` and `wai-aria`
|
|
@@ -18,6 +18,17 @@ declare type Loc = {
|
|
|
18
18
|
* @param isCustomRule
|
|
19
19
|
* @param spec
|
|
20
20
|
*/
|
|
21
|
-
export declare function attrCheck(
|
|
22
|
-
|
|
21
|
+
export declare function attrCheck(
|
|
22
|
+
t: Translator,
|
|
23
|
+
name: string,
|
|
24
|
+
value: string,
|
|
25
|
+
isCustomRule: boolean,
|
|
26
|
+
spec?: AttrSpec,
|
|
27
|
+
): Invalid | false;
|
|
28
|
+
export declare function valueCheck(
|
|
29
|
+
t: Translator,
|
|
30
|
+
name: string,
|
|
31
|
+
value: string,
|
|
32
|
+
type: AttributeType,
|
|
33
|
+
): string | [string, Loc] | false;
|
|
23
34
|
export {};
|
package/lib/attr-check.js
CHANGED
|
@@ -28,7 +28,7 @@ function attrCheck(t, name, value, isCustomRule, spec) {
|
|
|
28
28
|
(0, debug_1.log)('The "%s" attribute DOES\'NT EXIST in the spec', name);
|
|
29
29
|
return {
|
|
30
30
|
invalidType: 'non-existent',
|
|
31
|
-
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'),
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
const nameCaseSensitive = /[A-Z]/.test(spec.name);
|
|
@@ -36,7 +36,7 @@ function attrCheck(t, name, value, isCustomRule, spec) {
|
|
|
36
36
|
(0, debug_1.log)('The "%s" attribute name is unmatched in case-sensitive', name);
|
|
37
37
|
return {
|
|
38
38
|
invalidType: 'non-existent',
|
|
39
|
-
message: t('{0} is {1:c}', t('the "{0}" {1}', name, 'attribute'), 'disallowed') +
|
|
39
|
+
message: t('{0} is {1:c}', t('the "{0*}" {1}', name, 'attribute'), 'disallowed') +
|
|
40
40
|
t('. ') +
|
|
41
41
|
t('Did you mean "{0*}"?', spec.name),
|
|
42
42
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, null>;
|
|
2
2
|
export default _default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface AttrSpasingOptions {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
lineBreak?: 'either' | 'always' | 'never';
|
|
3
|
+
width?: number | false;
|
|
4
4
|
}
|
|
5
|
-
declare const _default: import(
|
|
5
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<boolean, AttrSpasingOptions>;
|
|
6
6
|
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare type Type = 'double' | 'single';
|
|
2
2
|
export declare type Quote = '"' | "'";
|
|
3
3
|
export declare type QuoteMap = {
|
|
4
|
-
|
|
4
|
+
[P in Type]: Quote;
|
|
5
5
|
};
|
|
6
|
-
declare const _default: import(
|
|
6
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<Type, null>;
|
|
7
7
|
export default _default;
|
|
@@ -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;
|
|
@@ -3,15 +3,27 @@ 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: '
|
|
6
|
+
defaultValue: 'lower',
|
|
7
7
|
async verify({ document, report, t }) {
|
|
8
8
|
await document.walkOn('Element', async (node) => {
|
|
9
9
|
if (node.isForeignElement || node.isCustomElement) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
let value;
|
|
13
|
+
// Convert deprecated value
|
|
14
|
+
switch (node.rule.value) {
|
|
15
|
+
case 'no-lower':
|
|
16
|
+
value = 'upper';
|
|
17
|
+
break;
|
|
18
|
+
case 'no-upper':
|
|
19
|
+
value = 'lower';
|
|
20
|
+
break;
|
|
21
|
+
default:
|
|
22
|
+
value = node.rule.value;
|
|
23
|
+
}
|
|
12
24
|
const ms = node.rule.severity === 'error' ? 'must' : 'should';
|
|
13
|
-
const deny =
|
|
14
|
-
const cases =
|
|
25
|
+
const deny = value === 'lower' ? /[A-Z]/ : /[a-z]/;
|
|
26
|
+
const cases = value === 'lower' ? 'lower' : 'upper';
|
|
15
27
|
const message = t(`{0} ${ms} be {1}`, t('{0} of {1}', 'attribute names', 'HTML elements'), `${cases}case`);
|
|
16
28
|
const attrSpecs = (0, ml_core_1.getAttrSpecs)(node.nameWithNS, document.specs);
|
|
17
29
|
for (const attr of node.attributes) {
|
|
@@ -50,6 +62,18 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
50
62
|
return;
|
|
51
63
|
}
|
|
52
64
|
const attrSpecs = (0, ml_core_1.getAttrSpecs)(node.nameWithNS, document.specs);
|
|
65
|
+
let value;
|
|
66
|
+
// Convert deprecated value
|
|
67
|
+
switch (node.rule.value) {
|
|
68
|
+
case 'no-lower':
|
|
69
|
+
value = 'upper';
|
|
70
|
+
break;
|
|
71
|
+
case 'no-upper':
|
|
72
|
+
value = 'lower';
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
value = node.rule.value;
|
|
76
|
+
}
|
|
53
77
|
if (node.attributes) {
|
|
54
78
|
for (const attr of node.attributes) {
|
|
55
79
|
if (attr.attrType === 'ps-attr') {
|
|
@@ -69,7 +93,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
69
93
|
continue;
|
|
70
94
|
}
|
|
71
95
|
}
|
|
72
|
-
if (
|
|
96
|
+
if (value === 'lower') {
|
|
73
97
|
attr.name.fix(attr.name.raw.toLowerCase());
|
|
74
98
|
}
|
|
75
99
|
else {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, null>;
|
|
2
2
|
export default _default;
|
|
@@ -25,7 +25,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
25
25
|
if (!classPatterns.some(pattern => (0, helpers_1.match)(className, pattern))) {
|
|
26
26
|
report({
|
|
27
27
|
scope: node,
|
|
28
|
-
message: t('{0} is unmatched with the below patterns: {1}', t('the "{0}" {1}', className, 'class name'), `"${classPatterns.join('", "')}"`),
|
|
28
|
+
message: t('{0} is unmatched with the below patterns: {1}', t('the "{0*}" {1}', className, 'class name'), `"${classPatterns.join('", "')}"`),
|
|
29
29
|
line: classAttr.line,
|
|
30
30
|
col: classAttr.col,
|
|
31
31
|
raw: classAttr.raw,
|
package/lib/create-message.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { Translator } from '@markuplint/i18n';
|
|
2
2
|
import type { AttributeType } from '@markuplint/ml-spec';
|
|
3
3
|
import type { UnmatchedResult } from '@markuplint/types';
|
|
4
|
-
export declare function createMessageValueExpected(
|
|
5
|
-
|
|
4
|
+
export declare function createMessageValueExpected(
|
|
5
|
+
t: Translator,
|
|
6
|
+
baseTarget: string,
|
|
7
|
+
type: AttributeType,
|
|
8
|
+
matches: UnmatchedResult,
|
|
9
|
+
): string;
|
|
10
|
+
export declare function __createMessageValueExpected(
|
|
11
|
+
t: Translator,
|
|
12
|
+
baseTarget: string,
|
|
13
|
+
expected: string | null,
|
|
14
|
+
matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candicate' | 'ref' | 'extra'>,
|
|
15
|
+
): string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, null>;
|
|
2
2
|
export default _default;
|
|
@@ -15,7 +15,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
if (attrSpec.deprecated || attrSpec.obsolete) {
|
|
18
|
-
const message = t('{0} is {1:c}', t('the "{0}" {1}', name.potential, 'attribute'), attrSpec.obsolete ? 'obsolete' : 'deprecated');
|
|
18
|
+
const message = t('{0} is {1:c}', t('the "{0*}" {1}', name.potential, 'attribute'), attrSpec.obsolete ? 'obsolete' : 'deprecated');
|
|
19
19
|
report({
|
|
20
20
|
scope: element,
|
|
21
21
|
message,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, null>;
|
|
2
2
|
export default _default;
|
|
@@ -13,7 +13,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
13
13
|
}
|
|
14
14
|
const spec = (0, ml_spec_1.getSpecByTagName)(el.nameWithNS, html_spec_1.default);
|
|
15
15
|
if (spec && (spec.obsolete || spec.deprecated || spec.nonStandard)) {
|
|
16
|
-
const message = t('{0} is {1:c}', t('the "{0}" {1}', el.nodeName, 'element'), spec.deprecated ? 'deprecated' : spec.obsolete ? 'obsolete' : 'non-standard');
|
|
16
|
+
const message = t('{0} is {1:c}', t('the "{0*}" {1}', el.nodeName, 'element'), spec.deprecated ? 'deprecated' : spec.obsolete ? 'obsolete' : 'non-standard');
|
|
17
17
|
report({
|
|
18
18
|
scope: el,
|
|
19
19
|
message,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<string[], null>;
|
|
2
2
|
export default _default;
|
package/lib/doctype/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare type Option = {
|
|
2
|
-
|
|
2
|
+
denyObsolateType: boolean;
|
|
3
3
|
};
|
|
4
|
-
declare const _default: import(
|
|
4
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<'always', Option>;
|
|
5
5
|
export default _default;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
+
const voidElements = [
|
|
5
|
+
'area',
|
|
6
|
+
'base',
|
|
7
|
+
'br',
|
|
8
|
+
'col',
|
|
9
|
+
'embed',
|
|
10
|
+
'hr',
|
|
11
|
+
'img',
|
|
12
|
+
'input',
|
|
13
|
+
'link',
|
|
14
|
+
'meta',
|
|
15
|
+
'param',
|
|
16
|
+
'source',
|
|
17
|
+
'track',
|
|
18
|
+
'wbr',
|
|
19
|
+
];
|
|
20
|
+
exports.default = (0, ml_core_1.createRule)({
|
|
21
|
+
defaultServerity: 'warning',
|
|
22
|
+
async verify({ document, report, t }) {
|
|
23
|
+
if (document.endTag === 'never') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
await document.walkOn('Element', el => {
|
|
27
|
+
var _a;
|
|
28
|
+
if (voidElements.some(vE => vE === el.nodeName.toLowerCase())) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (el.closeTag != null) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (document.endTag === 'xml' && ((_a = el.selfClosingSolidus) === null || _a === void 0 ? void 0 : _a.raw)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
report({
|
|
38
|
+
scope: el,
|
|
39
|
+
message: t('Missing {0}', t('the {0}', 'end tag')),
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
});
|
package/lib/helpers.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { Log } from './debug';
|
|
2
2
|
import type { Translator } from '@markuplint/i18n';
|
|
3
3
|
import type { Element, RuleConfigValue } from '@markuplint/ml-core';
|
|
4
|
-
import type { ARIRRoleAttribute, Attribute, PermittedRoles } from '@markuplint/ml-spec';
|
|
5
|
-
export declare function attrMatches<T extends RuleConfigValue, R>(
|
|
4
|
+
import type { ARIRRoleAttribute, Attribute, MLMLSpec, PermittedRoles } from '@markuplint/ml-spec';
|
|
5
|
+
export declare function attrMatches<T extends RuleConfigValue, R>(
|
|
6
|
+
node: Element<T, R>,
|
|
7
|
+
condition: Attribute['condition'],
|
|
8
|
+
): boolean;
|
|
6
9
|
export declare function match(needle: string, pattern: string): boolean;
|
|
7
10
|
/**
|
|
8
11
|
* PotentialCustomElementName
|
|
@@ -20,26 +23,44 @@ export declare function match(needle: string, pattern: string): boolean;
|
|
|
20
23
|
* Originally, it is not possible to define a name including ASCII upper alphas in the custom element, but it is not treated as illegal by the HTML parser.
|
|
21
24
|
*/
|
|
22
25
|
export declare const rePCENChar: string;
|
|
23
|
-
export declare function htmlSpec(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
export declare function htmlSpec(
|
|
27
|
+
specs: Readonly<MLMLSpec>,
|
|
28
|
+
nameWithNS: string,
|
|
29
|
+
): import('@markuplint/ml-spec').ElementSpec | null;
|
|
30
|
+
export declare function isValidAttr(
|
|
31
|
+
t: Translator,
|
|
32
|
+
name: string,
|
|
33
|
+
value: string,
|
|
34
|
+
isDynamicValue: boolean,
|
|
35
|
+
node: Element<any, any>,
|
|
36
|
+
attrSpecs: Attribute[],
|
|
37
|
+
log?: Log,
|
|
38
|
+
):
|
|
39
|
+
| false
|
|
40
|
+
| {
|
|
41
|
+
invalidType: 'non-existent' | 'invalid-value';
|
|
42
|
+
message: string;
|
|
43
|
+
loc?:
|
|
44
|
+
| {
|
|
45
|
+
raw: string;
|
|
46
|
+
line: number;
|
|
47
|
+
col: number;
|
|
48
|
+
}
|
|
49
|
+
| undefined;
|
|
50
|
+
};
|
|
33
51
|
export declare function toNormalizedValue(value: string, spec: Attribute): string;
|
|
34
|
-
export declare function ariaSpec(): {
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
export declare function ariaSpec(specs: Readonly<MLMLSpec>): {
|
|
53
|
+
roles: ARIRRoleAttribute[];
|
|
54
|
+
ariaAttrs: import('@markuplint/ml-spec').ARIAAttribute[];
|
|
37
55
|
};
|
|
38
|
-
export declare function getRoleSpec(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
export declare function getRoleSpec(
|
|
57
|
+
specs: Readonly<MLMLSpec>,
|
|
58
|
+
roleName: string,
|
|
59
|
+
): {
|
|
60
|
+
name: string;
|
|
61
|
+
isAbstract: boolean;
|
|
62
|
+
statesAndProps: import('@markuplint/ml-spec').ARIARoleOwnedPropOrState[];
|
|
63
|
+
superClassRoles: ARIRRoleAttribute[];
|
|
43
64
|
} | null;
|
|
44
65
|
/**
|
|
45
66
|
* Getting permitted ARIA roles.
|
|
@@ -48,11 +69,14 @@ export declare function getRoleSpec(roleName: string): {
|
|
|
48
69
|
* - If `true`, this mean is "Any".
|
|
49
70
|
* - If `false`, this mean is "No".
|
|
50
71
|
*/
|
|
51
|
-
export declare function getPermittedRoles(el: Element<any, any>): PermittedRoles;
|
|
52
|
-
export declare function getImplicitRole(el: Element<any, any>): string | false;
|
|
53
|
-
export declare function getComputedRole(
|
|
54
|
-
|
|
55
|
-
|
|
72
|
+
export declare function getPermittedRoles(specs: Readonly<MLMLSpec>, el: Element<any, any>): PermittedRoles;
|
|
73
|
+
export declare function getImplicitRole(specs: Readonly<MLMLSpec>, el: Element<any, any>): string | false;
|
|
74
|
+
export declare function getComputedRole(
|
|
75
|
+
specs: Readonly<MLMLSpec>,
|
|
76
|
+
el: Element<any, any>,
|
|
77
|
+
): {
|
|
78
|
+
name: string;
|
|
79
|
+
isImplicit: boolean;
|
|
56
80
|
} | null;
|
|
57
81
|
/**
|
|
58
82
|
*
|
|
@@ -63,23 +87,32 @@ export declare function getComputedRole(el: Element<any, any>): {
|
|
|
63
87
|
* @param tokenEnum
|
|
64
88
|
*/
|
|
65
89
|
export declare function checkAriaValue(type: string, value: string, tokenEnum: string[]): boolean;
|
|
66
|
-
export declare function checkAria(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
export declare function checkAria(
|
|
91
|
+
specs: Readonly<MLMLSpec>,
|
|
92
|
+
attrName: string,
|
|
93
|
+
currentValue: string,
|
|
94
|
+
role?: string,
|
|
95
|
+
):
|
|
96
|
+
| {
|
|
97
|
+
currentValue: string;
|
|
98
|
+
isValid: boolean;
|
|
99
|
+
}
|
|
100
|
+
| {
|
|
101
|
+
currentValue: string;
|
|
102
|
+
isValid: boolean;
|
|
103
|
+
name: string;
|
|
104
|
+
type: 'property' | 'state';
|
|
105
|
+
deprecated?: true | undefined;
|
|
106
|
+
isGlobal?: true | undefined;
|
|
107
|
+
value: import('@markuplint/ml-spec').ARIAAttributeValue;
|
|
108
|
+
conditionalValue?:
|
|
109
|
+
| {
|
|
110
|
+
role: string[];
|
|
111
|
+
value: import('@markuplint/ml-spec').ARIAAttributeValue;
|
|
112
|
+
}[]
|
|
113
|
+
| undefined;
|
|
114
|
+
enum: string[];
|
|
115
|
+
defaultValue?: string | undefined;
|
|
116
|
+
equivalentHtmlAttrs?: import('@markuplint/ml-spec').EquivalentHtmlAttr[] | undefined;
|
|
117
|
+
valueDescriptions?: Record<string, string> | undefined;
|
|
118
|
+
};
|