@markuplint/rules 3.10.0 → 3.11.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/lib/attr-check.d.ts +8 -19
- package/lib/character-reference/index.js +1 -1
- package/lib/permitted-contents/utils.d.ts +1 -1
- package/package.json +11 -11
- package/test/character-reference/index.spec.js +15 -0
- package/test/deprecated-element/index.spec.js +0 -13
- package/test/permitted-contents/index.spec.js +24 -0
- package/test/require-accessible-name/index.spec.js +21 -0
- package/lib/wai-aria/checkings/_.d.ts +0 -15
- package/lib/wai-aria/checkings/_.js +0 -27
- package/lib/wai-aria/checkings/required-prop copy.d.ts +0 -15
- package/lib/wai-aria/checkings/required-prop copy.js +0 -27
- package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +0 -15
- package/lib/wai-aria/checkings/unadopted-explicit-roles.js +0 -17
- package/lib/xxx/index.d.ts +0 -2
- package/lib/xxx/index.js +0 -32
package/lib/attr-check.d.ts
CHANGED
|
@@ -2,14 +2,14 @@ import type { Translator } from '@markuplint/i18n';
|
|
|
2
2
|
import type { Attribute as AttrSpec, AttributeType } from '@markuplint/ml-spec';
|
|
3
3
|
import type { ReadonlyDeep } from 'type-fest';
|
|
4
4
|
type Invalid = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
invalidType: 'non-existent' | 'invalid-value' | 'disallowed-attr';
|
|
6
|
+
message: string;
|
|
7
|
+
loc?: Loc;
|
|
8
8
|
};
|
|
9
9
|
type Loc = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
raw: string;
|
|
11
|
+
line: number;
|
|
12
|
+
col: number;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
15
|
* Use in rules `invalid-attr` and `wai-aria`
|
|
@@ -19,17 +19,6 @@ type Loc = {
|
|
|
19
19
|
* @param isCustomRule
|
|
20
20
|
* @param spec
|
|
21
21
|
*/
|
|
22
|
-
export declare function attrCheck(
|
|
23
|
-
|
|
24
|
-
name: string,
|
|
25
|
-
value: string,
|
|
26
|
-
isCustomRule: boolean,
|
|
27
|
-
spec?: AttrSpec,
|
|
28
|
-
): Invalid | false;
|
|
29
|
-
export declare function valueCheck(
|
|
30
|
-
t: Translator,
|
|
31
|
-
name: string,
|
|
32
|
-
value: string,
|
|
33
|
-
type: ReadonlyDeep<AttributeType>,
|
|
34
|
-
): [string, Loc] | false;
|
|
22
|
+
export declare function attrCheck(t: Translator, name: string, value: string, isCustomRule: boolean, spec?: AttrSpec): Invalid | false;
|
|
23
|
+
export declare function valueCheck(t: Translator, name: string, value: string, type: ReadonlyDeep<AttributeType>): [string, Loc] | false;
|
|
35
24
|
export {};
|
|
@@ -43,7 +43,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
43
43
|
if (!('scope' in targetNode && 'line' in targetNode && targetNode.line != null)) {
|
|
44
44
|
continue;
|
|
45
45
|
}
|
|
46
|
-
const escapedText = targetNode.raw.replace(/&(?:[a-z]+|#[0-9]
|
|
46
|
+
const escapedText = targetNode.raw.replace(/&(?:[a-z]+|#[0-9]+|#x[0-9a-f]+);/gi, $0 => '*'.repeat($0.length));
|
|
47
47
|
(0, ml_core_1.getLocationFromChars)(defaultChars, escapedText, targetNode.line, targetNode.col).forEach(location => {
|
|
48
48
|
report({
|
|
49
49
|
scope: targetNode.scope,
|
|
@@ -29,7 +29,7 @@ export declare function mergeHints(a: Readonly<Hints>, b: Readonly<Hints>): Part
|
|
|
29
29
|
need?: string | undefined;
|
|
30
30
|
}> | undefined;
|
|
31
31
|
max?: number | undefined;
|
|
32
|
-
not?:
|
|
32
|
+
not?: ChildNode | undefined;
|
|
33
33
|
transparent?: Element | undefined;
|
|
34
34
|
}>;
|
|
35
35
|
export declare function cleanObject<T extends Object>(object: T): Partial<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/rules",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"description": "Built-in rules of markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -20,19 +20,19 @@
|
|
|
20
20
|
"./lib/permitted-contents/debug.js": "./lib/permitted-contents/debug.browser.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@markuplint/html-spec": "3.
|
|
24
|
-
"@markuplint/ml-core": "3.
|
|
25
|
-
"@markuplint/ml-spec": "3.
|
|
26
|
-
"@markuplint/selector": "3.
|
|
27
|
-
"@markuplint/shared": "3.
|
|
28
|
-
"@markuplint/types": "3.
|
|
29
|
-
"@types/debug": "^4.1.
|
|
23
|
+
"@markuplint/html-spec": "3.10.0",
|
|
24
|
+
"@markuplint/ml-core": "3.11.0",
|
|
25
|
+
"@markuplint/ml-spec": "3.10.0",
|
|
26
|
+
"@markuplint/selector": "3.10.0",
|
|
27
|
+
"@markuplint/shared": "3.7.0",
|
|
28
|
+
"@markuplint/types": "3.8.0",
|
|
29
|
+
"@types/debug": "^4.1.8",
|
|
30
30
|
"@ungap/structured-clone": "^1.2.0",
|
|
31
31
|
"ansi-colors": "^4.1.3",
|
|
32
32
|
"chrono-node": "^2.6.3",
|
|
33
33
|
"debug": "^4.3.4",
|
|
34
|
-
"tslib": "^2.5.
|
|
35
|
-
"type-fest": "^3.
|
|
34
|
+
"tslib": "^2.5.3",
|
|
35
|
+
"type-fest": "^3.11.1"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "9547b8dca20736a93e4d01af2d61bee314ba5718"
|
|
38
38
|
}
|
|
@@ -55,3 +55,18 @@ test('in EJS', async () => {
|
|
|
55
55
|
});
|
|
56
56
|
expect(violations.length).toBe(0);
|
|
57
57
|
});
|
|
58
|
+
|
|
59
|
+
describe('Issues', () => {
|
|
60
|
+
test('#1074', async () => {
|
|
61
|
+
const { violations } = await mlRuleTest(rule, '<span>▼</span><span>▼</span><span>&x25BC;</span>');
|
|
62
|
+
expect(violations).toStrictEqual([
|
|
63
|
+
{
|
|
64
|
+
severity: 'error',
|
|
65
|
+
message: 'Illegal characters must escape in character reference',
|
|
66
|
+
line: 1,
|
|
67
|
+
col: 48,
|
|
68
|
+
raw: '&',
|
|
69
|
+
},
|
|
70
|
+
]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -33,16 +33,3 @@ test('deprecated', async () => {
|
|
|
33
33
|
},
|
|
34
34
|
]);
|
|
35
35
|
});
|
|
36
|
-
|
|
37
|
-
test('svg', async () => {
|
|
38
|
-
const { violations } = await mlRuleTest(rule, '<svg><altGlyph>text</altGlyph></svg>');
|
|
39
|
-
expect(violations).toStrictEqual([
|
|
40
|
-
{
|
|
41
|
-
severity: 'error',
|
|
42
|
-
message: 'The "altGlyph" element is obsolete',
|
|
43
|
-
line: 1,
|
|
44
|
-
col: 6,
|
|
45
|
-
raw: '<altGlyph>',
|
|
46
|
-
},
|
|
47
|
-
]);
|
|
48
|
-
});
|
|
@@ -1368,4 +1368,28 @@ describe('Issues', () => {
|
|
|
1368
1368
|
.violations,
|
|
1369
1369
|
).toStrictEqual([]);
|
|
1370
1370
|
});
|
|
1371
|
+
|
|
1372
|
+
test('#1046', async () => {
|
|
1373
|
+
const sourceCode = '<span><div></div></span>';
|
|
1374
|
+
expect(
|
|
1375
|
+
(
|
|
1376
|
+
await mlRuleTest(rule, sourceCode, {
|
|
1377
|
+
rule: {
|
|
1378
|
+
severity: 'warning',
|
|
1379
|
+
},
|
|
1380
|
+
parser: {
|
|
1381
|
+
'.*': '@markuplint/jsx-parser',
|
|
1382
|
+
},
|
|
1383
|
+
})
|
|
1384
|
+
).violations,
|
|
1385
|
+
).toStrictEqual([
|
|
1386
|
+
{
|
|
1387
|
+
severity: 'warning',
|
|
1388
|
+
line: 1,
|
|
1389
|
+
col: 7,
|
|
1390
|
+
message: 'The "div" element is not allowed in the "span" element in this context',
|
|
1391
|
+
raw: '<div>',
|
|
1392
|
+
},
|
|
1393
|
+
]);
|
|
1394
|
+
});
|
|
1371
1395
|
});
|
|
@@ -443,4 +443,25 @@ describe('Issues', () => {
|
|
|
443
443
|
expect((await mlRuleTest(rule, '<dialog></dialog>')).violations.length).toBe(1);
|
|
444
444
|
expect((await mlRuleTest(rule, '<div role="dialog"></div>')).violations.length).toBe(1);
|
|
445
445
|
});
|
|
446
|
+
|
|
447
|
+
test('#1018', async () => {
|
|
448
|
+
expect(
|
|
449
|
+
(
|
|
450
|
+
await mlRuleTest(rule, '<button><slot /></button>', {
|
|
451
|
+
parser: {
|
|
452
|
+
'.*': '@markuplint/svelte-parser',
|
|
453
|
+
},
|
|
454
|
+
})
|
|
455
|
+
).violations.length,
|
|
456
|
+
).toBe(0);
|
|
457
|
+
expect(
|
|
458
|
+
(
|
|
459
|
+
await mlRuleTest(rule, '<button></button>', {
|
|
460
|
+
parser: {
|
|
461
|
+
'.*': '@markuplint/svelte-parser',
|
|
462
|
+
},
|
|
463
|
+
})
|
|
464
|
+
).violations.length,
|
|
465
|
+
).toBe(1);
|
|
466
|
+
});
|
|
446
467
|
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
2
|
-
import type { ElementChecker } from '@markuplint/ml-core';
|
|
3
|
-
import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingRequiredProp: ElementChecker<
|
|
5
|
-
boolean,
|
|
6
|
-
Options,
|
|
7
|
-
{
|
|
8
|
-
role?:
|
|
9
|
-
| (ARIARole & {
|
|
10
|
-
isImplicit?: boolean;
|
|
11
|
-
})
|
|
12
|
-
| null;
|
|
13
|
-
propSpecs: readonly ARIAProperty[];
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingRequiredProp = void 0;
|
|
4
|
-
const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
|
|
5
|
-
var _a;
|
|
6
|
-
if (!role) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (role.isImplicit) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
const requiredProps = role.ownedProperties.filter(s => s.required).map(s => s.name);
|
|
13
|
-
for (const requiredProp of requiredProps) {
|
|
14
|
-
const has = el.attributes.some(attr => {
|
|
15
|
-
const attrName = attr.name.toLowerCase();
|
|
16
|
-
return attrName === requiredProp;
|
|
17
|
-
});
|
|
18
|
-
if (!has) {
|
|
19
|
-
const propSpec = propSpecs.find(p => p.name === requiredProp);
|
|
20
|
-
return {
|
|
21
|
-
scope: el,
|
|
22
|
-
message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`)), t('the "{0*}" {1}', role.name, 'role')),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
exports.checkingRequiredProp = checkingRequiredProp;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
2
|
-
import type { ElementChecker } from '@markuplint/ml-core';
|
|
3
|
-
import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingRequiredProp: ElementChecker<
|
|
5
|
-
boolean,
|
|
6
|
-
Options,
|
|
7
|
-
{
|
|
8
|
-
role?:
|
|
9
|
-
| (ARIARole & {
|
|
10
|
-
isImplicit?: boolean;
|
|
11
|
-
})
|
|
12
|
-
| null;
|
|
13
|
-
propSpecs: readonly ARIAProperty[];
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingRequiredProp = void 0;
|
|
4
|
-
const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
|
|
5
|
-
var _a;
|
|
6
|
-
if (!role) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (role.isImplicit) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
const requiredProps = role.ownedProperties.filter(s => s.required).map(s => s.name);
|
|
13
|
-
for (const requiredProp of requiredProps) {
|
|
14
|
-
const has = el.attributes.some(attr => {
|
|
15
|
-
const attrName = attr.name.toLowerCase();
|
|
16
|
-
return attrName === requiredProp;
|
|
17
|
-
});
|
|
18
|
-
if (!has) {
|
|
19
|
-
const propSpec = propSpecs.find(p => p.name === requiredProp);
|
|
20
|
-
return {
|
|
21
|
-
scope: el,
|
|
22
|
-
message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${(_a = propSpec === null || propSpec === void 0 ? void 0 : propSpec.type) !== null && _a !== void 0 ? _a : 'property'}`)), t('the "{0*}" {1}', role.name, 'role')),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
exports.checkingRequiredProp = checkingRequiredProp;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
2
|
-
import type { ElementChecker } from '@markuplint/ml-core';
|
|
3
|
-
import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingUnadoptedExplicitRoles: ElementChecker<
|
|
5
|
-
boolean,
|
|
6
|
-
Options,
|
|
7
|
-
{
|
|
8
|
-
role?:
|
|
9
|
-
| (ARIARole & {
|
|
10
|
-
isImplicit?: boolean;
|
|
11
|
-
})
|
|
12
|
-
| null;
|
|
13
|
-
propSpecs: readonly ARIAProperty[];
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingUnadoptedExplicitRoles = void 0;
|
|
4
|
-
const checkingUnadoptedExplicitRoles = ({ el, role, propSpecs }) => t => {
|
|
5
|
-
if (!role) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
if (role.name) {
|
|
9
|
-
console.log(el.localName, role.name);
|
|
10
|
-
return {
|
|
11
|
-
scope: el,
|
|
12
|
-
message: '',
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
return;
|
|
16
|
-
};
|
|
17
|
-
exports.checkingUnadoptedExplicitRoles = checkingUnadoptedExplicitRoles;
|
package/lib/xxx/index.d.ts
DELETED
package/lib/xxx/index.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
-
exports.default = (0, ml_core_1.createRule)({
|
|
5
|
-
defaultValue: true,
|
|
6
|
-
defaultOptions: null,
|
|
7
|
-
async verify({ document, report, t }) {
|
|
8
|
-
// Element
|
|
9
|
-
await document.walkOn("Element", (el) => {
|
|
10
|
-
const raw = el.raw.trim();
|
|
11
|
-
if (/./i.test(raw)) {
|
|
12
|
-
report({
|
|
13
|
-
scope: el,
|
|
14
|
-
message: t("It is {0}", "issue"),
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
// Attribute
|
|
19
|
-
await document.walkOn("Attr", (attr) => {
|
|
20
|
-
var _a, _b, _c;
|
|
21
|
-
if (/./i.test(attr.name)) {
|
|
22
|
-
report({
|
|
23
|
-
scope: attr,
|
|
24
|
-
line: (_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.startLine,
|
|
25
|
-
col: (_b = attr.nameNode) === null || _b === void 0 ? void 0 : _b.startCol,
|
|
26
|
-
raw: (_c = attr.nameNode) === null || _c === void 0 ? void 0 : _c.raw,
|
|
27
|
-
message: t("It is {0}", "issue"),
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
},
|
|
32
|
-
});
|