@markuplint/rules 3.0.0-alpha.0 → 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 +1 -1
- package/lib/attr-check.js +1 -1
- package/lib/attr-duplication/index.js +1 -1
- package/lib/attr-value-quotes/index.js +1 -1
- package/lib/case-sensitive-attr-name/index.js +3 -3
- package/lib/case-sensitive-tag-name/index.js +3 -3
- package/lib/class-naming/index.js +1 -1
- package/lib/create-message.d.ts +1 -1
- package/lib/create-message.js +5 -5
- package/lib/deprecated-element/index.js +2 -2
- package/lib/doctype/index.d.ts +1 -1
- package/lib/doctype/index.js +1 -1
- package/lib/end-tag/index.js +1 -1
- package/lib/helpers.d.ts +7 -2
- package/lib/helpers.js +17 -11
- package/lib/index.d.ts +2 -6
- package/lib/ineffective-attr/index.js +1 -1
- package/lib/invalid-attr/index.js +3 -3
- package/lib/landmark-roles/index.js +1 -1
- package/lib/no-boolean-attr-value/index.js +1 -1
- package/lib/no-default-value/index.js +1 -1
- package/lib/no-hard-code-id/index.js +1 -1
- package/lib/no-use-event-handler-attr/index.js +2 -2
- 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 +1 -7
- package/lib/permitted-contents/index.js +75 -245
- 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.js +5 -1
- package/lib/required-attr/index.js +1 -1
- package/lib/use-list/index.js +2 -2
- package/lib/wai-aria/checkings/implicit-role.js +2 -2
- package/lib/wai-aria/index.js +1 -1
- package/package.json +8 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/__foo/index.d.ts +0 -2
- package/lib/__foo/index.js +0 -46
- 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/helper/aria/get-aria.d.ts +0 -7
- package/lib/helper/aria/get-aria.js +0 -53
- package/lib/helper/aria/get-computed-role.d.ts +0 -10
- package/lib/helper/aria/get-computed-role.js +0 -24
- package/lib/helper/aria/get-implicit-role.d.ts +0 -7
- package/lib/helper/aria/get-implicit-role.js +0 -12
- package/lib/helper/aria/get-permitted-roles.d.ts +0 -14
- package/lib/helper/aria/get-permitted-roles.js +0 -26
- package/lib/helper/aria/resolve-version.d.ts +0 -2
- package/lib/helper/aria/resolve-version.js +0 -21
- package/lib/helper/spec/aria-spec.d.ts +0 -5
- package/lib/helper/spec/aria-spec.js +0 -12
- package/lib/helper/spec/get-role-spec.d.ts +0 -11
- package/lib/helper/spec/get-role-spec.js +0 -39
- package/lib/helper/spec/html-spec.d.ts +0 -2
- package/lib/helper/spec/html-spec.js +0 -14
- 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 -230
- 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/lib/wai-aria/checkings/checking-required-owned-elements.d.ts +0 -11
- package/lib/wai-aria/checkings/checking-required-owned-elements.js +0 -63
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _Collection_locked, _Collection_matched, _Collection_nodes, _Collection_origin;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.UnsupportedError = exports.Collection = exports.isTransparent = exports.isChoice = exports.isZeroOrMore = exports.isOneOrMore = exports.isOptional = exports.isRequire = exports.matches = exports.isModel = exports.getChildNodesWithoutWhitespaces = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const selector_1 = require("@markuplint/selector");
|
|
7
|
+
const ansi_colors_1 = require("ansi-colors");
|
|
8
|
+
const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
|
|
9
|
+
const getChildNodesWithoutWhitespacesCaches = new Map();
|
|
10
|
+
function getChildNodesWithoutWhitespaces(el) {
|
|
11
|
+
let nodes = getChildNodesWithoutWhitespacesCaches.get(el);
|
|
12
|
+
if (nodes) {
|
|
13
|
+
return nodes;
|
|
14
|
+
}
|
|
15
|
+
nodes = Array.from(el.childNodes).filter(node => {
|
|
16
|
+
return !(node.is(node.TEXT_NODE) && node.isWhitespace());
|
|
17
|
+
});
|
|
18
|
+
getChildNodesWithoutWhitespacesCaches.set(el, nodes);
|
|
19
|
+
return nodes;
|
|
20
|
+
}
|
|
21
|
+
exports.getChildNodesWithoutWhitespaces = getChildNodesWithoutWhitespaces;
|
|
22
|
+
function isModel(model) {
|
|
23
|
+
if (typeof model === 'string') {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
let modelMode = false;
|
|
27
|
+
for (const m of model) {
|
|
28
|
+
if (typeof m === 'string') {
|
|
29
|
+
modelMode = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (modelMode) {
|
|
33
|
+
throw new TypeError(`Invalid schema: ${JSON.stringify(model)}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return modelMode;
|
|
37
|
+
}
|
|
38
|
+
exports.isModel = isModel;
|
|
39
|
+
function matches(selector, node, specs) {
|
|
40
|
+
const selectorResult = (0, selector_1.createSelector)(selector, specs).search(node);
|
|
41
|
+
const matched = selectorResult.filter((r) => r.matched);
|
|
42
|
+
if (matched.length) {
|
|
43
|
+
return {
|
|
44
|
+
matched: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const not = selectorResult
|
|
48
|
+
.map(r => { var _a; return (r.matched ? [] : (_a = r.not) !== null && _a !== void 0 ? _a : []); })
|
|
49
|
+
.flat()
|
|
50
|
+
.map(descendants)
|
|
51
|
+
.flat()
|
|
52
|
+
.shift();
|
|
53
|
+
return {
|
|
54
|
+
matched: false,
|
|
55
|
+
not,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
exports.matches = matches;
|
|
59
|
+
function descendants(selectorResult) {
|
|
60
|
+
let nodes = selectorResult.nodes.slice();
|
|
61
|
+
while (selectorResult.has.length) {
|
|
62
|
+
for (const dep of selectorResult.has) {
|
|
63
|
+
if (!dep.has.length) {
|
|
64
|
+
nodes = dep.nodes;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
selectorResult = dep;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return nodes;
|
|
73
|
+
}
|
|
74
|
+
function isRequire(content) {
|
|
75
|
+
return 'require' in content;
|
|
76
|
+
}
|
|
77
|
+
exports.isRequire = isRequire;
|
|
78
|
+
function isOptional(content) {
|
|
79
|
+
return 'optional' in content;
|
|
80
|
+
}
|
|
81
|
+
exports.isOptional = isOptional;
|
|
82
|
+
function isOneOrMore(content) {
|
|
83
|
+
return 'oneOrMore' in content;
|
|
84
|
+
}
|
|
85
|
+
exports.isOneOrMore = isOneOrMore;
|
|
86
|
+
function isZeroOrMore(content) {
|
|
87
|
+
return 'zeroOrMore' in content;
|
|
88
|
+
}
|
|
89
|
+
exports.isZeroOrMore = isZeroOrMore;
|
|
90
|
+
function isChoice(content) {
|
|
91
|
+
return 'choice' in content;
|
|
92
|
+
}
|
|
93
|
+
exports.isChoice = isChoice;
|
|
94
|
+
function isTransparent(content) {
|
|
95
|
+
return 'transparent' in content;
|
|
96
|
+
}
|
|
97
|
+
exports.isTransparent = isTransparent;
|
|
98
|
+
class Collection {
|
|
99
|
+
constructor(origin) {
|
|
100
|
+
_Collection_locked.set(this, new Set());
|
|
101
|
+
_Collection_matched.set(this, new Set());
|
|
102
|
+
_Collection_nodes.set(this, void 0);
|
|
103
|
+
_Collection_origin.set(this, void 0);
|
|
104
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_origin, origin.slice(), "f");
|
|
105
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_nodes, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")), "f");
|
|
106
|
+
}
|
|
107
|
+
get matched() {
|
|
108
|
+
return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f"));
|
|
109
|
+
}
|
|
110
|
+
get matchedCount() {
|
|
111
|
+
return tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
112
|
+
}
|
|
113
|
+
get nodes() {
|
|
114
|
+
return tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f").slice();
|
|
115
|
+
}
|
|
116
|
+
get unmatched() {
|
|
117
|
+
return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f")).filter(n => !tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n));
|
|
118
|
+
}
|
|
119
|
+
addMatched(nodes) {
|
|
120
|
+
const i = tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
121
|
+
for (const node of nodes) {
|
|
122
|
+
if (!tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f").has(node)) {
|
|
123
|
+
throw new ReferenceError(`External Node: ${node.nodeName}`);
|
|
124
|
+
}
|
|
125
|
+
tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").add(node);
|
|
126
|
+
}
|
|
127
|
+
return i < tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
128
|
+
}
|
|
129
|
+
back() {
|
|
130
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_matched, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f")), "f");
|
|
131
|
+
}
|
|
132
|
+
lock() {
|
|
133
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_locked, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")), "f");
|
|
134
|
+
}
|
|
135
|
+
max(max) {
|
|
136
|
+
const sliced = Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")).slice(max);
|
|
137
|
+
sliced.forEach(n => tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").delete(n));
|
|
138
|
+
}
|
|
139
|
+
toString(highlightExtraNodes = false) {
|
|
140
|
+
const out = [];
|
|
141
|
+
for (const n of tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")) {
|
|
142
|
+
const raw = n.is(n.TEXT_NODE) ? `:text(${n.raw.replace(/\n/g, '\\n')})` : n.raw;
|
|
143
|
+
if (tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f").has(n)) {
|
|
144
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
145
|
+
out.push(ansi_colors_1.bgBlue.bold(raw));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
out.push(ansi_colors_1.bgGreen.bold(raw));
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n)) {
|
|
153
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
154
|
+
out.push(ansi_colors_1.blue.bold(raw));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
out.push(ansi_colors_1.green.bold(raw));
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (highlightExtraNodes) {
|
|
162
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
163
|
+
out.push(ansi_colors_1.bgMagenta.bold(raw));
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
out.push(ansi_colors_1.bgRed.bold(raw));
|
|
167
|
+
}
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
171
|
+
out.push((0, ansi_colors_1.cyan)(raw));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
out.push(raw);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return `[ ${out.join(', ')} ]`;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.Collection = Collection;
|
|
181
|
+
_Collection_locked = new WeakMap(), _Collection_matched = new WeakMap(), _Collection_nodes = new WeakMap(), _Collection_origin = new WeakMap();
|
|
182
|
+
class UnsupportedError extends Error {
|
|
183
|
+
}
|
|
184
|
+
exports.UnsupportedError = UnsupportedError;
|
|
@@ -8,6 +8,10 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
8
8
|
},
|
|
9
9
|
async verify({ document, report, t }) {
|
|
10
10
|
await document.walkOn('Element', el => {
|
|
11
|
+
var _a;
|
|
12
|
+
if (((_a = el.pretenderContext) === null || _a === void 0 ? void 0 : _a.type) === 'pretender') {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
11
15
|
if ((0, helpers_1.accnameMayBeMutable)(el, document)) {
|
|
12
16
|
return;
|
|
13
17
|
}
|
|
@@ -19,7 +23,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
19
23
|
if (!roleSpec || !roleSpec.accessibleNameRequired) {
|
|
20
24
|
return;
|
|
21
25
|
}
|
|
22
|
-
const hasAccessibleName = !!el.getAccessibleName().trim();
|
|
26
|
+
const hasAccessibleName = !!el.getAccessibleName(el.rule.option.ariaVersion).trim();
|
|
23
27
|
if (!hasAccessibleName) {
|
|
24
28
|
report({ scope: el, message: t('Require {0}', 'accessible name') });
|
|
25
29
|
}
|
|
@@ -12,7 +12,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
12
12
|
const customRequiredAttrs = typeof el.rule.value === 'string' ? [el.rule.value] : el.rule.value;
|
|
13
13
|
const attrSpec = (0, ml_core_1.getAttrSpecs)(el, document.specs);
|
|
14
14
|
const attributeSpecs = {};
|
|
15
|
-
if (attrSpec &&
|
|
15
|
+
if (attrSpec && el.elementType === 'html') {
|
|
16
16
|
for (const spec of attrSpec) {
|
|
17
17
|
if (spec.required || spec.requiredEither || spec.condition) {
|
|
18
18
|
attributeSpecs[spec.name] = {
|
package/lib/use-list/index.js
CHANGED
|
@@ -54,12 +54,12 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
54
54
|
'+', // plus signs
|
|
55
55
|
],
|
|
56
56
|
},
|
|
57
|
-
|
|
57
|
+
defaultSeverity: 'warning',
|
|
58
58
|
async verify({ document, report, t }) {
|
|
59
59
|
await document.walkOn('Text', textNode => {
|
|
60
60
|
const text = (0, helpers_1.decodeCharRef)(textNode.raw.trim());
|
|
61
61
|
if (!text) {
|
|
62
|
-
//
|
|
62
|
+
// empty
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
if (text.length === 1) {
|
|
@@ -4,13 +4,13 @@ exports.checkingImplicitRole = void 0;
|
|
|
4
4
|
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
5
|
const checkingImplicitRole = ({ attr }) => t => {
|
|
6
6
|
var _a;
|
|
7
|
-
const
|
|
7
|
+
const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.option.version, attr.ownerMLDocument.specs);
|
|
8
8
|
const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
|
|
9
9
|
if (!tokens) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
for (const token of tokens) {
|
|
13
|
-
if (
|
|
13
|
+
if (implicitRole === token.raw) {
|
|
14
14
|
return {
|
|
15
15
|
scope: token,
|
|
16
16
|
message: t('{0} is {1}', t('the "{0*}" {1}', token.raw, 'role'), t('{0} of {1}', 'the implicit role', t('the "{0*}" {1}', attr.ownerElement.localName, 'element'))),
|
package/lib/wai-aria/index.js
CHANGED
|
@@ -34,7 +34,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
34
34
|
const roleAttr = el.getAttributeNode('role');
|
|
35
35
|
const propAttrs = el.attributes.filter(attr => /^aria-/i.test(attr.name));
|
|
36
36
|
const ariaAttrs = new helpers_1.Collection(roleAttr, ...propAttrs);
|
|
37
|
-
const elSpec = (0, ml_core_1.getSpec)(el, document.specs);
|
|
37
|
+
const elSpec = (0, ml_core_1.getSpec)(el, document.specs.specs);
|
|
38
38
|
if (!elSpec) {
|
|
39
39
|
return;
|
|
40
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/rules",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.1",
|
|
4
4
|
"description": "Rules for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -17,16 +17,17 @@
|
|
|
17
17
|
"clean": "tsc --build --clean"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@markuplint/html-spec": "3.0.0-alpha.
|
|
21
|
-
"@markuplint/ml-core": "3.0.0-alpha.
|
|
22
|
-
"@markuplint/ml-spec": "3.0.0-alpha.
|
|
23
|
-
"@markuplint/types": "3.0.0-alpha.
|
|
20
|
+
"@markuplint/html-spec": "3.0.0-alpha.1",
|
|
21
|
+
"@markuplint/ml-core": "3.0.0-alpha.1",
|
|
22
|
+
"@markuplint/ml-spec": "3.0.0-alpha.1",
|
|
23
|
+
"@markuplint/types": "3.0.0-alpha.1",
|
|
24
|
+
"@ungap/structured-clone": "^1.0.1",
|
|
24
25
|
"debug": "^4.3.4",
|
|
25
26
|
"html-entities": "^2.3.3",
|
|
26
|
-
"tslib": "^2.
|
|
27
|
+
"tslib": "^2.4.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@types/debug": "^4.1.7"
|
|
30
31
|
},
|
|
31
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "56de89456146a06777eb5b6d4e8ba456147dd18b"
|
|
32
33
|
}
|