@markuplint/rules 2.4.0 → 3.0.0-alpha.66
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 +1 -5
- package/lib/__foo/index.d.ts +1 -1
- package/lib/attr-duplication/index.js +11 -8
- package/lib/attr-equal-space-after/index.d.ts +1 -1
- package/lib/attr-equal-space-after/index.js +2 -2
- package/lib/attr-equal-space-before/index.d.ts +1 -1
- package/lib/attr-equal-space-before/index.js +2 -2
- package/lib/attr-spacing/index.d.ts +3 -3
- package/lib/attr-spacing/index.js +2 -2
- package/lib/attr-value-quotes/index.js +21 -25
- package/lib/case-sensitive-attr-name/index.d.ts +1 -5
- package/lib/case-sensitive-attr-name/index.js +51 -81
- package/lib/case-sensitive-tag-name/index.js +38 -30
- package/lib/character-reference/index.d.ts +2 -1
- package/lib/character-reference/index.js +7 -9
- package/lib/class-naming/index.js +11 -11
- package/lib/deprecated-attr/index.js +17 -18
- package/lib/deprecated-element/index.js +6 -8
- package/lib/disallowed-element/index.js +8 -9
- package/lib/doctype/index.js +7 -7
- package/lib/end-tag/index.js +4 -1
- package/lib/helper/aria/get-aria.d.ts +7 -0
- package/lib/helper/aria/get-aria.js +53 -0
- package/lib/helper/aria/get-computed-role.d.ts +10 -0
- package/lib/helper/aria/get-computed-role.js +24 -0
- package/lib/helper/aria/get-implicit-role.d.ts +7 -0
- package/lib/helper/aria/get-implicit-role.js +12 -0
- package/lib/helper/aria/get-permitted-roles.d.ts +14 -0
- package/lib/helper/aria/get-permitted-roles.js +26 -0
- package/lib/helper/aria/resolve-version.d.ts +2 -0
- package/lib/helper/aria/resolve-version.js +21 -0
- package/lib/helper/spec/aria-spec.d.ts +5 -0
- package/lib/helper/spec/aria-spec.js +12 -0
- package/lib/helper/spec/get-role-spec.d.ts +11 -0
- package/lib/helper/spec/get-role-spec.js +39 -0
- package/lib/helper/spec/html-spec.d.ts +2 -0
- package/lib/helper/spec/html-spec.js +14 -0
- package/lib/helpers.d.ts +10 -28
- package/lib/helpers.js +29 -149
- package/lib/id-duplication/index.js +5 -7
- package/lib/indentation/index.d.ts +3 -3
- package/lib/indentation/index.js +4 -4
- package/lib/index.d.ts +14 -19
- package/lib/index.js +0 -8
- package/lib/ineffective-attr/index.js +19 -27
- 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 +33 -34
- package/lib/no-default-value/index.js +20 -24
- package/lib/no-hard-code-id/index.js +9 -13
- 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 +20 -22
- package/lib/permitted-contents/index.d.ts +5 -2
- package/lib/permitted-contents/index.js +67 -68
- package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +5 -5
- package/lib/permitted-contents/permitted-content.spec-to-regexp.js +19 -14
- package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +2 -2
- package/lib/require-accessible-name/index.d.ts +5 -1
- package/lib/require-accessible-name/index.js +6 -3
- 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 +4 -4
- 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/checking-required-owned-elements.d.ts +11 -0
- package/lib/wai-aria/checkings/checking-required-owned-elements.js +63 -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/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/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 +56 -207
- package/lib/wai-aria/types.d.ts +11 -0
- package/lib/wai-aria/types.js +2 -0
- package/package.json +5 -5
- package/schema.json +0 -12
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -33,21 +33,17 @@
|
|
|
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
|
|
package/lib/__foo/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import(
|
|
1
|
+
declare const _default: import('@markuplint/ml-core').RuleSeed<boolean, null>;
|
|
2
2
|
export default _default;
|
|
@@ -4,21 +4,24 @@ 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
6
|
const message = t('{0} is {1:c}', t('the {0}', 'attribute name'), 'duplicated');
|
|
7
|
-
await document.walkOn('Element',
|
|
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.isCustomElement ? attrName
|
|
13
|
+
const attrName = attr.name;
|
|
14
|
+
const name = node.isCustomElement ? attrName : attrName.toLowerCase();
|
|
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 {
|
|
@@ -7,7 +7,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
7
7
|
defaultServerity: 'warning',
|
|
8
8
|
defaultValue: 'never',
|
|
9
9
|
async verify(context) {
|
|
10
|
-
await context.document.walkOn('Element',
|
|
10
|
+
await context.document.walkOn('Element', node => {
|
|
11
11
|
for (const attr of node.attributes) {
|
|
12
12
|
if (attr.attrType === 'ps-attr' || !(attr.equal && attr.spacesAfterEqual && attr.spacesBeforeEqual)) {
|
|
13
13
|
continue;
|
|
@@ -52,7 +52,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
52
52
|
});
|
|
53
53
|
},
|
|
54
54
|
async fix({ document }) {
|
|
55
|
-
await document.walkOn('Element',
|
|
55
|
+
await document.walkOn('Element', node => {
|
|
56
56
|
for (const attr of node.attributes) {
|
|
57
57
|
if (attr.attrType === 'ps-attr' || !(attr.equal && attr.spacesAfterEqual && attr.spacesBeforeEqual)) {
|
|
58
58
|
continue;
|
|
@@ -7,7 +7,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
7
7
|
defaultServerity: 'warning',
|
|
8
8
|
defaultValue: 'never',
|
|
9
9
|
async verify(context) {
|
|
10
|
-
await context.document.walkOn('Element',
|
|
10
|
+
await context.document.walkOn('Element', node => {
|
|
11
11
|
for (const attr of node.attributes) {
|
|
12
12
|
if (attr.attrType === 'ps-attr' || !(attr.equal && attr.spacesAfterEqual && attr.spacesBeforeEqual)) {
|
|
13
13
|
continue;
|
|
@@ -52,7 +52,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
52
52
|
});
|
|
53
53
|
},
|
|
54
54
|
async fix({ document }) {
|
|
55
|
-
await document.walkOn('Element',
|
|
55
|
+
await document.walkOn('Element', node => {
|
|
56
56
|
for (const attr of node.attributes) {
|
|
57
57
|
if (attr.attrType === 'ps-attr' || !(attr.equal && attr.spacesAfterEqual && attr.spacesBeforeEqual)) {
|
|
58
58
|
continue;
|
|
@@ -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;
|
|
@@ -8,7 +8,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
8
8
|
width: 1,
|
|
9
9
|
},
|
|
10
10
|
async verify(context) {
|
|
11
|
-
await context.document.walkOn('Element',
|
|
11
|
+
await context.document.walkOn('Element', node => {
|
|
12
12
|
const attrs = node.attributes;
|
|
13
13
|
for (const attr of attrs) {
|
|
14
14
|
if (attr.attrType === 'ps-attr') {
|
|
@@ -63,7 +63,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
63
63
|
});
|
|
64
64
|
},
|
|
65
65
|
async fix({ document }) {
|
|
66
|
-
await document.walkOn('Element',
|
|
66
|
+
await document.walkOn('Element', node => {
|
|
67
67
|
const attrs = node.attributes;
|
|
68
68
|
for (const attr of attrs) {
|
|
69
69
|
if (attr.attrType === 'ps-attr') {
|
|
@@ -8,34 +8,30 @@ const quoteList = {
|
|
|
8
8
|
exports.default = (0, ml_core_1.createRule)({
|
|
9
9
|
defaultServerity: '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;
|
|
@@ -5,102 +5,72 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
5
5
|
defaultServerity: '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.isCustomElement) {
|
|
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.isCustomElement) {
|
|
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
|
});
|
|
@@ -5,41 +5,49 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
5
5
|
defaultServerity: '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.isCustomElement) {
|
|
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.isCustomElement) {
|
|
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;
|
|
@@ -6,7 +6,7 @@ const ignoreParentElement = ['script', 'style'];
|
|
|
6
6
|
exports.default = (0, ml_core_1.createRule)({
|
|
7
7
|
async verify({ document, report, t }) {
|
|
8
8
|
const targetNodes = [];
|
|
9
|
-
await document.walkOn('Text',
|
|
9
|
+
await document.walkOn('Text', node => {
|
|
10
10
|
if (node.parentNode && ignoreParentElement.includes(node.parentNode.nodeName.toLowerCase())) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
@@ -21,22 +21,20 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
21
21
|
message,
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
|
-
await document.walkOn('Element',
|
|
24
|
+
await document.walkOn('Element', node => {
|
|
25
25
|
const severity = node.rule.severity;
|
|
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
|
}
|
|
@@ -6,29 +6,29 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
6
6
|
defaultServerity: '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
|
}
|
|
@@ -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
|
-
await document.walkOn('Element',
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
await document.walkOn('Element', el => {
|
|
7
|
+
if (!(el.namespaceURI === 'http://www.w3.org/1999/xhtml' ||
|
|
8
|
+
el.namespaceURI === 'http://www.w3.org/2000/svg') ||
|
|
9
|
+
el.isCustomElement) {
|
|
12
10
|
return;
|
|
13
11
|
}
|
|
14
|
-
const spec = (0,
|
|
12
|
+
const spec = (0, ml_core_1.getSpec)(el, document.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,
|