@markuplint/rules 2.4.3 → 3.0.0-alpha.1
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 -6
- package/lib/attr-check.js +1 -1
- package/lib/attr-duplication/index.js +10 -7
- package/lib/attr-value-quotes/index.js +22 -26
- package/lib/case-sensitive-attr-name/index.d.ts +1 -5
- package/lib/case-sensitive-attr-name/index.js +52 -82
- package/lib/case-sensitive-tag-name/index.js +39 -31
- package/lib/character-reference/index.d.ts +2 -1
- package/lib/character-reference/index.js +6 -8
- package/lib/class-naming/index.js +12 -12
- package/lib/create-message.d.ts +1 -1
- package/lib/create-message.js +5 -5
- package/lib/deprecated-attr/index.js +17 -18
- package/lib/deprecated-element/index.js +5 -7
- package/lib/disallowed-element/index.js +8 -9
- package/lib/doctype/index.d.ts +1 -1
- package/lib/doctype/index.js +8 -8
- package/lib/end-tag/index.js +5 -2
- package/lib/helpers.d.ts +15 -28
- package/lib/helpers.js +42 -156
- package/lib/id-duplication/index.js +4 -6
- package/lib/index.d.ts +12 -21
- package/lib/index.js +0 -8
- package/lib/ineffective-attr/index.js +20 -28
- package/lib/invalid-attr/index.js +83 -83
- package/lib/landmark-roles/index.d.ts +2 -2
- package/lib/landmark-roles/index.js +10 -10
- package/lib/no-boolean-attr-value/index.js +34 -35
- package/lib/no-default-value/index.js +21 -25
- package/lib/no-hard-code-id/index.js +10 -14
- package/lib/no-refer-to-non-existent-id/index.d.ts +4 -1
- package/lib/no-refer-to-non-existent-id/index.js +77 -83
- package/lib/no-use-event-handler-attr/index.js +21 -23
- package/lib/permitted-contents/choice.d.ts +3 -0
- package/lib/permitted-contents/choice.js +37 -0
- package/lib/permitted-contents/complex-branch.d.ts +13 -0
- package/lib/permitted-contents/complex-branch.js +27 -0
- package/lib/permitted-contents/content-model.d.ts +2 -0
- package/lib/permitted-contents/content-model.js +49 -0
- package/lib/permitted-contents/count-pattern.d.ts +13 -0
- package/lib/permitted-contents/count-pattern.js +155 -0
- package/lib/permitted-contents/debug.d.ts +2 -0
- package/lib/permitted-contents/debug.js +5 -0
- package/lib/permitted-contents/index.d.ts +2 -5
- package/lib/permitted-contents/index.js +78 -249
- package/lib/permitted-contents/matches-selector.d.ts +3 -0
- package/lib/permitted-contents/matches-selector.js +185 -0
- package/lib/permitted-contents/order.d.ts +13 -0
- package/lib/permitted-contents/order.js +89 -0
- package/lib/permitted-contents/recursive-branch.d.ts +4 -0
- package/lib/permitted-contents/recursive-branch.js +43 -0
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +6 -0
- package/lib/permitted-contents/represent-transparent-nodes.js +79 -0
- package/lib/permitted-contents/start.d.ts +12 -0
- package/lib/permitted-contents/start.js +71 -0
- package/lib/permitted-contents/transparent.d.ts +2 -0
- package/lib/permitted-contents/transparent.js +34 -0
- package/lib/permitted-contents/types.d.ts +45 -0
- package/lib/permitted-contents/types.js +2 -0
- package/lib/permitted-contents/utils.d.ts +32 -0
- package/lib/permitted-contents/utils.js +184 -0
- package/lib/require-accessible-name/index.d.ts +5 -1
- package/lib/require-accessible-name/index.js +11 -4
- package/lib/required-attr/index.js +16 -25
- package/lib/required-element/index.d.ts +1 -1
- package/lib/required-element/index.js +6 -6
- package/lib/required-h1/index.d.ts +2 -2
- package/lib/required-h1/index.js +3 -3
- package/lib/use-list/index.js +2 -2
- package/lib/wai-aria/checkings/abstract-role.d.ts +3 -0
- package/lib/wai-aria/checkings/abstract-role.js +22 -0
- package/lib/wai-aria/checkings/default-value.d.ts +6 -0
- package/lib/wai-aria/checkings/default-value.js +17 -0
- package/lib/wai-aria/checkings/deprecated-props.d.ts +7 -0
- package/lib/wai-aria/checkings/deprecated-props.js +18 -0
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +7 -0
- package/lib/wai-aria/checkings/disallowed-prop.js +22 -0
- package/lib/wai-aria/checkings/implicit-props.d.ts +7 -0
- package/lib/wai-aria/checkings/implicit-props.js +50 -0
- package/lib/wai-aria/checkings/implicit-role.d.ts +3 -0
- package/lib/wai-aria/checkings/implicit-role.js +21 -0
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +11 -0
- package/lib/wai-aria/checkings/interaction-in-hidden.js +47 -0
- package/lib/wai-aria/checkings/no-global-prop.d.ts +6 -0
- package/lib/wai-aria/checkings/no-global-prop.js +14 -0
- package/lib/wai-aria/checkings/non-existant-role.d.ts +3 -0
- package/lib/wai-aria/checkings/non-existant-role.js +28 -0
- package/lib/wai-aria/checkings/permitted-roles.d.ts +3 -0
- package/lib/wai-aria/checkings/permitted-roles.js +28 -0
- package/lib/wai-aria/checkings/presentational-children.d.ts +29 -0
- package/lib/wai-aria/checkings/presentational-children.js +60 -0
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +11 -0
- package/lib/wai-aria/checkings/required-owned-elements.js +63 -0
- package/lib/wai-aria/checkings/required-prop.d.ts +9 -0
- package/lib/wai-aria/checkings/required-prop.js +27 -0
- package/lib/wai-aria/checkings/value.d.ts +7 -0
- package/lib/wai-aria/checkings/value.js +21 -0
- package/lib/wai-aria/index.d.ts +1 -8
- package/lib/wai-aria/index.js +66 -207
- package/lib/wai-aria/types.d.ts +13 -0
- package/lib/wai-aria/types.js +2 -0
- package/package.json +8 -7
- package/schema.json +0 -12
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/attr-equal-space-after/index.d.ts +0 -3
- package/lib/attr-equal-space-after/index.js +0 -90
- package/lib/attr-equal-space-before/index.d.ts +0 -3
- package/lib/attr-equal-space-before/index.js +0 -90
- package/lib/attr-spacing/index.d.ts +0 -6
- package/lib/attr-spacing/index.js +0 -100
- package/lib/indentation/index.d.ts +0 -7
- package/lib/indentation/index.js +0 -208
- package/lib/permitted-contents/array.combination.d.ts +0 -1
- package/lib/permitted-contents/array.combination.js +0 -33
- package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +0 -11
- package/lib/permitted-contents/permitted-content.spec-to-regexp.js +0 -225
- package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +0 -2
- package/lib/permitted-contents/unfold-content-models-to-tags.js +0 -8
package/README.md
CHANGED
|
@@ -33,27 +33,23 @@
|
|
|
33
33
|
|
|
34
34
|
- [`class-naming`](./src/class-naming)
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### Maintainability
|
|
37
37
|
|
|
38
38
|
- [`no-hard-code-id`](./src/no-hard-code-id)
|
|
39
39
|
- [`no-use-event-handler-attr`](./src/no-use-event-handler-attr)
|
|
40
40
|
|
|
41
41
|
### Style
|
|
42
42
|
|
|
43
|
-
- [`attr-equal-space-after`](./src/attr-equal-space-after)
|
|
44
|
-
- [`attr-equal-space-before`](./src/attr-equal-space-before)
|
|
45
|
-
- [`attr-spacing`](./src/attr-spacing)
|
|
46
43
|
- [`attr-value-quotes`](./src/attr-value-quotes)
|
|
47
44
|
- [`case-sensitive-attr-name`](./src/case-sensitive-attr-name)
|
|
48
45
|
- [`case-sensitive-tag-name`](./src/case-sensitive-tag-name)
|
|
49
46
|
- [`end-tag`](./src/end-tag)
|
|
50
|
-
- [`indentation`](./src/indentation)
|
|
51
47
|
- [`no-boolean-attr-value`](./src/no-boolean-attr-value)
|
|
52
48
|
- [`no-default-value`](./src/no-default-value)
|
|
53
49
|
|
|
54
50
|
## Install
|
|
55
51
|
|
|
56
|
-
Generally, you **don't have to install** this package because markuplint dependents it
|
|
52
|
+
Generally, you **don't have to install** this package because markuplint dependents it by default.
|
|
57
53
|
|
|
58
54
|
```sh
|
|
59
55
|
$ npm install -D @markuplint/rules
|
package/lib/attr-check.js
CHANGED
|
@@ -6,19 +6,22 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
6
6
|
const message = t('{0} is {1:c}', t('the {0}', 'attribute name'), 'duplicated');
|
|
7
7
|
await document.walkOn('Element', node => {
|
|
8
8
|
const attrNameStack = [];
|
|
9
|
-
for (const attr of node.
|
|
9
|
+
for (const attr of node.getAttributeTokens()) {
|
|
10
10
|
if (attr.isDuplicatable) {
|
|
11
11
|
continue;
|
|
12
12
|
}
|
|
13
|
-
const attrName = attr.
|
|
14
|
-
const name = node.
|
|
13
|
+
const attrName = attr.name;
|
|
14
|
+
const name = node.elementType === 'html' ? attrName.toLowerCase() : attrName;
|
|
15
15
|
if (attrNameStack.includes(name)) {
|
|
16
|
+
const scope = attr.nameNode || attr;
|
|
16
17
|
report({
|
|
17
|
-
scope:
|
|
18
|
+
scope: {
|
|
19
|
+
rule: node.rule,
|
|
20
|
+
startLine: scope.startLine,
|
|
21
|
+
startCol: scope.startCol,
|
|
22
|
+
raw: scope.raw,
|
|
23
|
+
},
|
|
18
24
|
message,
|
|
19
|
-
line: attrName.line,
|
|
20
|
-
col: attrName.col,
|
|
21
|
-
raw: attrName.raw,
|
|
22
25
|
});
|
|
23
26
|
}
|
|
24
27
|
else {
|
|
@@ -6,36 +6,32 @@ const quoteList = {
|
|
|
6
6
|
single: "'",
|
|
7
7
|
};
|
|
8
8
|
exports.default = (0, ml_core_1.createRule)({
|
|
9
|
-
|
|
9
|
+
defaultSeverity: 'warning',
|
|
10
10
|
defaultValue: 'double',
|
|
11
|
-
async verify(
|
|
12
|
-
await
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
col: attr.name.startCol,
|
|
25
|
-
raw: attr.raw.trim(),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
11
|
+
async verify({ document, report, t }) {
|
|
12
|
+
await document.walkOn('Attr', attr => {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const message = t('{0} is must {1} on {2}', 'Attribute value', 'quote', `${attr.rule.value} quotation mark`);
|
|
15
|
+
if (attr.isDynamicValue || attr.isDirective || !attr.equal || ((_a = attr.equal) === null || _a === void 0 ? void 0 : _a.raw) === '') {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const quote = (_b = attr.startQuote) === null || _b === void 0 ? void 0 : _b.raw;
|
|
19
|
+
if (quote !== quoteList[attr.rule.value]) {
|
|
20
|
+
report({
|
|
21
|
+
scope: attr,
|
|
22
|
+
message,
|
|
23
|
+
});
|
|
28
24
|
}
|
|
29
25
|
});
|
|
30
26
|
},
|
|
31
|
-
async fix(
|
|
32
|
-
await
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
async fix({ document }) {
|
|
28
|
+
await document.walkOn('Attr', attr => {
|
|
29
|
+
var _a;
|
|
30
|
+
const quote = quoteList[attr.rule.value];
|
|
31
|
+
if (quote && attr.startQuote && attr.startQuote.raw !== quote) {
|
|
32
|
+
attr.startQuote.fix(quote);
|
|
33
|
+
// TODO: attr.endQuote = new MLToken(quote);
|
|
34
|
+
(_a = attr.endQuote) === null || _a === void 0 ? void 0 : _a.fix(quote);
|
|
39
35
|
}
|
|
40
36
|
});
|
|
41
37
|
},
|
|
@@ -1,7 +1,3 @@
|
|
|
1
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>;
|
|
2
|
+
declare const _default: import("@markuplint/ml-core").RuleSeed<Value, null>;
|
|
7
3
|
export default _default;
|
|
@@ -2,105 +2,75 @@
|
|
|
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
|
-
|
|
5
|
+
defaultSeverity: 'warning',
|
|
6
6
|
defaultValue: 'lower',
|
|
7
7
|
async verify({ document, report, t }) {
|
|
8
|
-
await document.walkOn('
|
|
9
|
-
|
|
8
|
+
await document.walkOn('Attr', attr => {
|
|
9
|
+
var _a, _b, _c, _d;
|
|
10
|
+
const el = attr.ownerElement;
|
|
11
|
+
if (el.isForeignElement || el.elementType !== 'html') {
|
|
10
12
|
return;
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
}
|
|
24
|
-
const ms = node.rule.severity === 'error' ? 'must' : 'should';
|
|
14
|
+
const value = attr.rule.value;
|
|
15
|
+
const ms = attr.rule.severity === 'error' ? 'must' : 'should';
|
|
25
16
|
const deny = value === 'lower' ? /[A-Z]/ : /[a-z]/;
|
|
26
17
|
const cases = value === 'lower' ? 'lower' : 'upper';
|
|
27
18
|
const message = t(`{0} ${ms} be {1}`, t('{0} of {1}', 'attribute names', 'HTML elements'), `${cases}case`);
|
|
28
|
-
const attrSpecs = (0, ml_core_1.getAttrSpecs)(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (attrSpecs) {
|
|
42
|
-
const spec = attrSpecs.find(spec => spec.name === name.raw);
|
|
43
|
-
if (spec && spec.caseSensitive) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (deny.test(name.raw)) {
|
|
48
|
-
report({
|
|
49
|
-
scope: node,
|
|
50
|
-
message,
|
|
51
|
-
line: name.line,
|
|
52
|
-
col: name.col,
|
|
53
|
-
raw: name.raw,
|
|
54
|
-
});
|
|
19
|
+
const attrSpecs = (0, ml_core_1.getAttrSpecs)(el, document.specs);
|
|
20
|
+
/**
|
|
21
|
+
* Ignore when it has the potential name,
|
|
22
|
+
* it Interprets `tabIndex` to `tabindex` in JSX for example.
|
|
23
|
+
*/
|
|
24
|
+
if (((_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.raw) !== attr.name) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const name = attr.name;
|
|
28
|
+
if (attrSpecs) {
|
|
29
|
+
const spec = attrSpecs.find(spec => spec.name === name);
|
|
30
|
+
if (spec && spec.caseSensitive) {
|
|
31
|
+
return;
|
|
55
32
|
}
|
|
56
33
|
}
|
|
34
|
+
if (deny.test(name)) {
|
|
35
|
+
report({
|
|
36
|
+
scope: attr,
|
|
37
|
+
line: (_b = attr.nameNode) === null || _b === void 0 ? void 0 : _b.startLine,
|
|
38
|
+
col: (_c = attr.nameNode) === null || _c === void 0 ? void 0 : _c.startCol,
|
|
39
|
+
raw: (_d = attr.nameNode) === null || _d === void 0 ? void 0 : _d.raw,
|
|
40
|
+
message,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
57
43
|
});
|
|
58
44
|
},
|
|
59
45
|
async fix({ document }) {
|
|
60
|
-
await document.walkOn('
|
|
61
|
-
|
|
46
|
+
await document.walkOn('Attr', attr => {
|
|
47
|
+
var _a;
|
|
48
|
+
const el = attr.ownerElement;
|
|
49
|
+
if (el.isForeignElement || el.elementType !== 'html') {
|
|
62
50
|
return;
|
|
63
51
|
}
|
|
64
|
-
const attrSpecs = (0, ml_core_1.getAttrSpecs)(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
value = 'lower';
|
|
73
|
-
break;
|
|
74
|
-
default:
|
|
75
|
-
value = node.rule.value;
|
|
52
|
+
const attrSpecs = (0, ml_core_1.getAttrSpecs)(el, document.specs);
|
|
53
|
+
const value = attr.rule.value;
|
|
54
|
+
/**
|
|
55
|
+
* Ignore when it has the potential name,
|
|
56
|
+
* it Interprets `tabIndex` to `tabindex` in JSX for example.
|
|
57
|
+
*/
|
|
58
|
+
if (((_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.raw) !== attr.name) {
|
|
59
|
+
return;
|
|
76
60
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Ignore when it has the potential name,
|
|
84
|
-
* it Interprets `tabIndex` to `tabindex` in JSX for example.
|
|
85
|
-
*/
|
|
86
|
-
if (attr.name.raw !== attr.potentialName) {
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
const name = attr.getName();
|
|
90
|
-
if (attrSpecs) {
|
|
91
|
-
const spec = attrSpecs.find(spec => spec.name === name.raw);
|
|
92
|
-
if (spec && spec.caseSensitive) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (value === 'lower') {
|
|
97
|
-
attr.name.fix(attr.name.raw.toLowerCase());
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
attr.name.fix(attr.name.raw.toUpperCase());
|
|
101
|
-
}
|
|
61
|
+
const name = attr.name;
|
|
62
|
+
if (attrSpecs) {
|
|
63
|
+
const spec = attrSpecs.find(spec => spec.name === name);
|
|
64
|
+
if (spec && spec.caseSensitive) {
|
|
65
|
+
return;
|
|
102
66
|
}
|
|
103
67
|
}
|
|
68
|
+
if (value === 'lower') {
|
|
69
|
+
attr.nameNode.fix(name.toLowerCase());
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
attr.nameNode.fix(name.toUpperCase());
|
|
73
|
+
}
|
|
104
74
|
});
|
|
105
75
|
},
|
|
106
76
|
});
|
|
@@ -2,44 +2,52 @@
|
|
|
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
|
-
|
|
5
|
+
defaultSeverity: 'warning',
|
|
6
6
|
defaultValue: 'lower',
|
|
7
7
|
async verify({ document, report, t }) {
|
|
8
|
-
await document.
|
|
9
|
-
if ('
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
8
|
+
await document.walkOn('Element', el => {
|
|
9
|
+
if (el.isForeignElement || el.elementType !== 'html') {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const ms = el.rule.severity === 'error' ? 'must' : 'should';
|
|
13
|
+
const deny = el.rule.value === 'lower' ? /[A-Z]/ : /[a-z]/;
|
|
14
|
+
const message = t(`{0} ${ms} be {1}`, t('{0} of {1}', 'tag names', 'HTML elements'), `${el.rule.value}case`);
|
|
15
|
+
if (deny.test(el.rawName)) {
|
|
16
|
+
const loc = el.getNameLocation();
|
|
17
|
+
report({
|
|
18
|
+
scope: el,
|
|
19
|
+
message,
|
|
20
|
+
line: loc.line,
|
|
21
|
+
col: loc.col,
|
|
22
|
+
raw: el.rawName,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const closeTag = el.closeTag;
|
|
26
|
+
if (closeTag && deny.test(closeTag.raw)) {
|
|
27
|
+
report({
|
|
28
|
+
scope: {
|
|
29
|
+
rule: el.rule,
|
|
30
|
+
startLine: closeTag.startLine,
|
|
31
|
+
startCol: closeTag.startCol,
|
|
32
|
+
raw: closeTag.raw,
|
|
33
|
+
},
|
|
34
|
+
message,
|
|
35
|
+
});
|
|
26
36
|
}
|
|
27
37
|
});
|
|
28
38
|
},
|
|
29
39
|
async fix({ document }) {
|
|
30
|
-
await document.
|
|
31
|
-
if ('
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
await document.walkOn('Element', el => {
|
|
41
|
+
if (el.isForeignElement || el.elementType !== 'html') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const deny = el.rule.value === 'lower' ? /[A-Z]/ : /[a-z]/;
|
|
45
|
+
if (deny.test(el.nodeName)) {
|
|
46
|
+
if (el.rule.value === 'lower') {
|
|
47
|
+
el.fixNodeName(el.nodeName.toLowerCase());
|
|
34
48
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (node.rule.value === 'lower') {
|
|
38
|
-
node.fixNodeName(node.nodeName.toLowerCase());
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
node.fixNodeName(node.nodeName.toUpperCase());
|
|
42
|
-
}
|
|
49
|
+
else {
|
|
50
|
+
el.fixNodeName(el.nodeName.toUpperCase());
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
});
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import type { RuleConfigValue } from '@markuplint/ml-config';
|
|
2
|
+
declare const _default: import("@markuplint/ml-core").RuleSeed<RuleConfigValue, null>;
|
|
2
3
|
export default _default;
|
|
@@ -26,23 +26,21 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
26
26
|
const ms = severity === 'error' ? 'must' : 'should';
|
|
27
27
|
const message = t(`{0} ${ms} {1}`, 'Illegal characters', 'escape in character reference');
|
|
28
28
|
for (const attr of node.attributes) {
|
|
29
|
-
if (attr.
|
|
30
|
-
(attr.attrType === 'html-attr' && attr.isDynamicValue) ||
|
|
31
|
-
(attr.attrType === 'html-attr' && attr.isDirective)) {
|
|
29
|
+
if (attr.isDynamicValue || attr.isDirective) {
|
|
32
30
|
continue;
|
|
33
31
|
}
|
|
34
|
-
const
|
|
32
|
+
const valueNode = attr.valueNode;
|
|
35
33
|
targetNodes.push({
|
|
36
34
|
scope: node,
|
|
37
|
-
line:
|
|
38
|
-
col:
|
|
39
|
-
raw:
|
|
35
|
+
line: valueNode === null || valueNode === void 0 ? void 0 : valueNode.startLine,
|
|
36
|
+
col: valueNode === null || valueNode === void 0 ? void 0 : valueNode.startCol,
|
|
37
|
+
raw: valueNode === null || valueNode === void 0 ? void 0 : valueNode.raw,
|
|
40
38
|
message,
|
|
41
39
|
});
|
|
42
40
|
}
|
|
43
41
|
});
|
|
44
42
|
for (const targetNode of targetNodes) {
|
|
45
|
-
if (!('scope' in targetNode && 'line' in targetNode)) {
|
|
43
|
+
if (!('scope' in targetNode && 'line' in targetNode && targetNode.line != null)) {
|
|
46
44
|
continue;
|
|
47
45
|
}
|
|
48
46
|
const escapedText = targetNode.raw.replace(/&(?:[a-z]+|#[0-9]+|x[0-9]);/gi, $0 => '*'.repeat($0.length));
|
|
@@ -3,32 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
4
|
const helpers_1 = require("../helpers");
|
|
5
5
|
exports.default = (0, ml_core_1.createRule)({
|
|
6
|
-
|
|
6
|
+
defaultSeverity: 'warning',
|
|
7
7
|
defaultValue: null,
|
|
8
8
|
async verify({ document, report, t }) {
|
|
9
|
-
await document.walkOn('Element',
|
|
10
|
-
if (!
|
|
9
|
+
await document.walkOn('Element', el => {
|
|
10
|
+
if (!el.rule.value) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
const classPatterns = Array.isArray(
|
|
14
|
-
const attrs =
|
|
13
|
+
const classPatterns = Array.isArray(el.rule.value) ? el.rule.value : [el.rule.value];
|
|
14
|
+
const attrs = el.getAttributeToken('class');
|
|
15
15
|
for (const attr of attrs) {
|
|
16
|
-
if (attr.
|
|
16
|
+
if (attr.isDynamicValue) {
|
|
17
17
|
continue;
|
|
18
18
|
}
|
|
19
|
-
const classAttr = attr.
|
|
20
|
-
const classList =
|
|
19
|
+
const classAttr = attr.valueNode;
|
|
20
|
+
const classList = attr.value
|
|
21
21
|
.split(/\s+/g)
|
|
22
22
|
.map(c => c.trim())
|
|
23
23
|
.filter(c => c);
|
|
24
24
|
for (const className of classList) {
|
|
25
25
|
if (!classPatterns.some(pattern => (0, helpers_1.match)(className, pattern))) {
|
|
26
26
|
report({
|
|
27
|
-
scope:
|
|
27
|
+
scope: attr,
|
|
28
28
|
message: t('{0} is unmatched with the below patterns: {1}', t('the "{0*}" {1}', className, 'class name'), `"${classPatterns.join('", "')}"`),
|
|
29
|
-
line: classAttr.
|
|
30
|
-
col: classAttr.
|
|
31
|
-
raw: classAttr.raw,
|
|
29
|
+
line: classAttr === null || classAttr === void 0 ? void 0 : classAttr.startLine,
|
|
30
|
+
col: classAttr === null || classAttr === void 0 ? void 0 : classAttr.startCol,
|
|
31
|
+
raw: classAttr === null || classAttr === void 0 ? void 0 : classAttr.raw,
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
}
|
package/lib/create-message.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import type { Translator } from '@markuplint/i18n';
|
|
|
2
2
|
import type { AttributeType } from '@markuplint/ml-spec';
|
|
3
3
|
import type { UnmatchedResult } from '@markuplint/types';
|
|
4
4
|
export declare function createMessageValueExpected(t: Translator, baseTarget: string, type: AttributeType, matches: UnmatchedResult): string;
|
|
5
|
-
export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | '
|
|
5
|
+
export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candidate' | 'ref' | 'extra'>): string;
|
package/lib/create-message.js
CHANGED
|
@@ -26,7 +26,7 @@ function __createMessageValueExpected(t, baseTarget, expected, matches) {
|
|
|
26
26
|
let reasonPart;
|
|
27
27
|
let expectPart;
|
|
28
28
|
let unnecessaryPart;
|
|
29
|
-
let
|
|
29
|
+
let candidatePart;
|
|
30
30
|
let expectOrNeed = 'expects';
|
|
31
31
|
if (matches.partName) {
|
|
32
32
|
if (matches.partName === 'the content of the list') {
|
|
@@ -188,10 +188,10 @@ function __createMessageValueExpected(t, baseTarget, expected, matches) {
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
if (matches.
|
|
192
|
-
|
|
191
|
+
if (matches.candidate) {
|
|
192
|
+
candidatePart = t('Did you mean "{0*}"?', matches.candidate);
|
|
193
193
|
}
|
|
194
|
-
let message = [reasonPart, unnecessaryPart, expectPart,
|
|
194
|
+
let message = [reasonPart, unnecessaryPart, expectPart, candidatePart].filter(s => s).join(t('. '));
|
|
195
195
|
if (matches.ref) {
|
|
196
196
|
message += ` (${matches.ref})`;
|
|
197
197
|
}
|
|
@@ -232,7 +232,7 @@ function expectValueToWord(t, expect, type) {
|
|
|
232
232
|
return expect.value ? `%${expect.value}%` : '';
|
|
233
233
|
case 'format':
|
|
234
234
|
return t('the {0} format', expect.value);
|
|
235
|
-
case '
|
|
235
|
+
case 'regexp':
|
|
236
236
|
return t('{0} ({1})', 'regular expression', expect.value);
|
|
237
237
|
case 'syntax':
|
|
238
238
|
if ((0, types_1.isKeyword)(type) && type[0] === '<') {
|
|
@@ -3,27 +3,26 @@ 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
|
async verify({ document, report, t }) {
|
|
6
|
-
await document.walkOn('
|
|
7
|
-
|
|
6
|
+
await document.walkOn('Attr', attr => {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
const attrSpecs = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
|
|
8
9
|
if (!attrSpecs) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
}
|
|
12
|
+
const name = attr.name;
|
|
13
|
+
const attrSpec = attrSpecs.find(item => item.name === name);
|
|
14
|
+
if (!attrSpec) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (attrSpec.deprecated || attrSpec.obsolete) {
|
|
18
|
+
const message = t('{0} is {1:c}', t('the "{0*}" {1}', name, 'attribute'), attrSpec.obsolete ? 'obsolete' : 'deprecated');
|
|
19
|
+
report({
|
|
20
|
+
scope: attr,
|
|
21
|
+
line: (_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.startLine,
|
|
22
|
+
col: (_b = attr.nameNode) === null || _b === void 0 ? void 0 : _b.startCol,
|
|
23
|
+
raw: (_c = attr.nameNode) === null || _c === void 0 ? void 0 : _c.raw,
|
|
24
|
+
message,
|
|
25
|
+
});
|
|
27
26
|
}
|
|
28
27
|
});
|
|
29
28
|
},
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const html_spec_1 = tslib_1.__importDefault(require("@markuplint/html-spec"));
|
|
5
3
|
const ml_core_1 = require("@markuplint/ml-core");
|
|
6
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
7
4
|
exports.default = (0, ml_core_1.createRule)({
|
|
8
5
|
async verify({ document, report, t }) {
|
|
9
6
|
await document.walkOn('Element', el => {
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
if (!(el.namespaceURI === 'http://www.w3.org/1999/xhtml' ||
|
|
8
|
+
el.namespaceURI === 'http://www.w3.org/2000/svg') ||
|
|
9
|
+
el.elementType !== 'html') {
|
|
12
10
|
return;
|
|
13
11
|
}
|
|
14
|
-
const spec = (0,
|
|
12
|
+
const spec = (0, ml_core_1.getSpec)(el, document.specs.specs);
|
|
15
13
|
if (spec && (spec.obsolete || spec.deprecated || spec.nonStandard)) {
|
|
16
|
-
const message = t('{0} is {1:c}', t('the "{0*}" {1}', el.
|
|
14
|
+
const message = t('{0} is {1:c}', t('the "{0*}" {1}', el.localName, 'element'), spec.deprecated ? 'deprecated' : spec.obsolete ? 'obsolete' : 'non-standard');
|
|
17
15
|
report({
|
|
18
16
|
scope: el,
|
|
19
17
|
message,
|
|
@@ -3,31 +3,30 @@ 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
|
defaultValue: [],
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
for (const el of elements) {
|
|
6
|
+
async verify({ document, report, t }) {
|
|
7
|
+
for (const query of document.rule.value) {
|
|
8
|
+
const elements = document.querySelectorAll(query);
|
|
9
|
+
elements.forEach(el => {
|
|
11
10
|
const message = t('{0} is disallowed', t('the "{0*}" {1}', query, 'element'));
|
|
12
11
|
report({
|
|
13
12
|
scope: el,
|
|
14
13
|
message,
|
|
15
14
|
});
|
|
16
|
-
}
|
|
15
|
+
});
|
|
17
16
|
}
|
|
18
17
|
await document.walkOn('Element', el => {
|
|
19
|
-
if (el.rule.value ===
|
|
18
|
+
if (el.rule.value === document.rule.value) {
|
|
20
19
|
return;
|
|
21
20
|
}
|
|
22
21
|
for (const query of el.rule.value) {
|
|
23
22
|
const elements = el.querySelectorAll(query);
|
|
24
|
-
|
|
23
|
+
elements.forEach(el => {
|
|
25
24
|
const message = t('{0} is disallowed', t('the "{0*}" {1}', query, 'element'));
|
|
26
25
|
report({
|
|
27
26
|
scope: el,
|
|
28
27
|
message,
|
|
29
28
|
});
|
|
30
|
-
}
|
|
29
|
+
});
|
|
31
30
|
}
|
|
32
31
|
});
|
|
33
32
|
},
|
package/lib/doctype/index.d.ts
CHANGED