@markuplint/rules 3.0.0-alpha.66 → 3.0.0-dev.176
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 +10 -44
- package/lib/attr-check.d.ts +22 -10
- package/lib/attr-check.js +32 -23
- package/lib/attr-duplication/index.d.ts +3 -1
- package/lib/attr-duplication/index.js +3 -2
- package/lib/attr-value-quotes/index.d.ts +5 -5
- package/lib/attr-value-quotes/index.js +1 -1
- package/lib/case-sensitive-attr-name/index.d.ts +2 -2
- package/lib/case-sensitive-attr-name/index.js +3 -3
- package/lib/case-sensitive-tag-name/index.d.ts +2 -2
- package/lib/case-sensitive-tag-name/index.js +3 -3
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/character-reference/index.js +1 -1
- package/lib/class-naming/index.d.ts +2 -2
- package/lib/class-naming/index.js +3 -5
- package/lib/create-message.d.ts +13 -2
- package/lib/create-message.js +9 -8
- package/lib/debug.d.ts +1 -1
- package/lib/debug.js +1 -1
- package/lib/deprecated-attr/index.d.ts +3 -1
- package/lib/deprecated-element/index.d.ts +3 -1
- package/lib/deprecated-element/index.js +4 -4
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/doctype/index.d.ts +3 -3
- package/lib/doctype/index.js +2 -2
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/end-tag/index.js +3 -18
- package/lib/helpers.d.ts +38 -47
- package/lib/helpers.js +42 -93
- package/lib/id-duplication/index.d.ts +3 -1
- package/lib/index.d.ts +242 -62
- package/lib/index.js +10 -1
- package/lib/ineffective-attr/index.d.ts +3 -1
- package/lib/ineffective-attr/index.js +3 -6
- package/lib/invalid-attr/index.d.ts +40 -12
- package/lib/invalid-attr/index.js +159 -28
- package/lib/label-has-control/index.d.ts +4 -0
- package/lib/label-has-control/index.js +28 -0
- package/lib/landmark-roles/index.d.ts +6 -6
- package/lib/landmark-roles/index.js +10 -6
- package/lib/no-boolean-attr-value/index.d.ts +3 -1
- package/lib/no-boolean-attr-value/index.js +1 -1
- package/lib/no-default-value/index.d.ts +3 -1
- package/lib/no-default-value/index.js +1 -1
- package/lib/no-empty-palpable-content/index.d.ts +6 -0
- package/lib/no-empty-palpable-content/index.js +42 -0
- package/lib/no-hard-code-id/index.d.ts +3 -1
- package/lib/no-hard-code-id/index.js +1 -1
- package/lib/no-refer-to-non-existent-id/index.d.ts +9 -4
- package/lib/no-refer-to-non-existent-id/index.js +65 -5
- package/lib/no-use-event-handler-attr/index.d.ts +3 -3
- package/lib/no-use-event-handler-attr/index.js +6 -6
- package/lib/permitted-contents/choice.d.ts +10 -0
- package/lib/permitted-contents/choice.js +72 -0
- package/lib/permitted-contents/complex-branch.d.ts +20 -0
- package/lib/permitted-contents/complex-branch.js +29 -0
- package/lib/permitted-contents/content-model.d.ts +2 -0
- package/lib/permitted-contents/content-model.js +53 -0
- package/lib/permitted-contents/count-pattern.d.ts +29 -0
- package/lib/permitted-contents/count-pattern.js +162 -0
- package/lib/permitted-contents/debug.browser.d.ts +30 -0
- package/lib/permitted-contents/debug.browser.js +14 -0
- package/lib/permitted-contents/debug.d.ts +3 -0
- package/lib/permitted-contents/debug.js +13 -0
- package/lib/permitted-contents/index.d.ts +2 -8
- package/lib/permitted-contents/index.js +76 -249
- package/lib/permitted-contents/matches-selector.d.ts +8 -0
- package/lib/permitted-contents/matches-selector.js +187 -0
- package/lib/permitted-contents/order.d.ts +20 -0
- package/lib/permitted-contents/order.js +99 -0
- package/lib/permitted-contents/recursive-branch.d.ts +11 -0
- package/lib/permitted-contents/recursive-branch.js +45 -0
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +10 -0
- package/lib/permitted-contents/represent-transparent-nodes.js +78 -0
- package/lib/permitted-contents/start.d.ts +18 -0
- package/lib/permitted-contents/start.js +73 -0
- package/lib/permitted-contents/transparent.d.ts +2 -0
- package/lib/permitted-contents/transparent.js +31 -0
- package/lib/permitted-contents/types.d.ts +52 -0
- package/lib/permitted-contents/types.js +2 -0
- package/lib/permitted-contents/utils.d.ts +100 -0
- package/lib/permitted-contents/utils.js +302 -0
- package/lib/placeholder-label-option/index.d.ts +2 -0
- package/lib/placeholder-label-option/index.js +88 -0
- package/lib/require-accessible-name/index.d.ts +3 -3
- package/lib/require-accessible-name/index.js +12 -4
- package/lib/require-datetime/index.d.ts +6 -0
- package/lib/require-datetime/index.js +34 -0
- package/lib/require-datetime/types.d.ts +10 -0
- package/lib/require-datetime/types.js +2 -0
- package/lib/require-datetime/utils.d.ts +11 -0
- package/lib/require-datetime/utils.js +137 -0
- package/lib/required-attr/index.d.ts +5 -5
- package/lib/required-attr/index.js +20 -17
- package/lib/required-element/index.d.ts +3 -3
- package/lib/required-element/index.js +3 -2
- package/lib/required-h1/index.d.ts +3 -3
- package/lib/required-h1/index.js +4 -3
- package/lib/use-list/index.d.ts +4 -4
- package/lib/use-list/index.js +9 -7
- package/lib/wai-aria/checkings/_.d.ts +15 -0
- package/lib/wai-aria/checkings/_.js +27 -0
- package/lib/wai-aria/checkings/abstract-role.js +1 -1
- package/lib/wai-aria/checkings/default-value.d.ts +7 -3
- package/lib/wai-aria/checkings/deprecated-props.d.ts +8 -4
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
- package/lib/wai-aria/checkings/disallowed-prop.js +27 -3
- package/lib/wai-aria/checkings/implicit-props.d.ts +8 -4
- package/lib/wai-aria/checkings/implicit-props.js +3 -2
- package/lib/wai-aria/checkings/implicit-role.js +2 -2
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +11 -0
- package/lib/wai-aria/checkings/interaction-in-hidden.js +49 -0
- package/lib/wai-aria/checkings/no-global-prop.d.ts +7 -3
- package/lib/wai-aria/checkings/{non-existant-role.d.ts → non-existent-role.d.ts} +1 -1
- package/lib/wai-aria/checkings/{non-existant-role.js → non-existent-role.js} +4 -4
- package/lib/wai-aria/checkings/permitted-roles.js +1 -1
- package/lib/wai-aria/checkings/presentational-children.d.ts +29 -0
- package/lib/wai-aria/checkings/presentational-children.js +62 -0
- package/lib/wai-aria/checkings/{checking-required-owned-elements.d.ts → required-owned-elements.d.ts} +7 -3
- package/lib/wai-aria/checkings/required-owned-elements.js +103 -0
- package/lib/wai-aria/checkings/required-prop copy.d.ts +15 -0
- package/lib/wai-aria/checkings/required-prop copy.js +27 -0
- package/lib/wai-aria/checkings/required-prop.d.ts +12 -6
- package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +15 -0
- package/lib/wai-aria/checkings/unadopted-explicit-roles.js +17 -0
- package/lib/wai-aria/checkings/value.d.ts +19 -4
- package/lib/wai-aria/checkings/value.js +77 -5
- package/lib/wai-aria/index.d.ts +1 -1
- package/lib/wai-aria/index.js +27 -16
- package/lib/wai-aria/types.d.ts +11 -9
- package/lib/xxx/index.d.ts +2 -0
- package/lib/xxx/index.js +32 -0
- package/package.json +18 -12
- package/schema.json +12 -0
- package/test/attr-check.spec.js +77 -0
- package/test/attr-duplication/index.spec.js +159 -0
- package/test/attr-value-quotes/index.spec.js +133 -0
- package/test/case-sensitive-attr-name/index.spec.js +65 -0
- package/test/case-sensitive-tag-name/index.spec.js +80 -0
- package/test/character-reference/index.spec.js +57 -0
- package/test/class-naming/index.spec.js +470 -0
- package/test/create-message.spec.js +497 -0
- package/test/deprecated-attr/index.spec.js +48 -0
- package/test/deprecated-element/index.spec.js +48 -0
- package/test/disallowed-element/index.spec.js +90 -0
- package/test/doctype/index.spec.js +50 -0
- package/test/end-tag/index.spec.js +162 -0
- package/test/id-duplication/index.spec.js +47 -0
- package/test/ineffective-attr/index.spec.js +31 -0
- package/test/invalid-attr/index.spec.js +1632 -0
- package/test/label-has-control/index.spec.js +29 -0
- package/test/landmark-roles/index.spec.js +187 -0
- package/test/no-boolean-attr-value/index.spec.js +41 -0
- package/test/no-default-value/index.spec.js +74 -0
- package/test/no-empty-palpable-content/index.spec.js +115 -0
- package/test/no-hard-code-id/index.spec.js +100 -0
- package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
- package/test/no-use-event-handler-attr/index.spec.js +57 -0
- package/test/permitted-contents/choice.spec.js +174 -0
- package/test/permitted-contents/count-pattern.spec.js +308 -0
- package/test/permitted-contents/index.spec.js +1371 -0
- package/test/permitted-contents/matches-selector.spec.js +59 -0
- package/test/permitted-contents/order.spec.js +351 -0
- package/test/permitted-contents/recursive-branch.spec.js +41 -0
- package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
- package/test/permitted-contents/start.spec.js +67 -0
- package/test/placeholder-label-option/index.spec.js +113 -0
- package/test/require-accessible-name/index.spec.js +446 -0
- package/test/require-datetime/index.spec.js +54 -0
- package/test/require-datetime/utils.spec.js +52 -0
- package/test/required-attr/index.spec.js +414 -0
- package/test/required-element/index.spec.js +188 -0
- package/test/required-h1/index.spec.js +69 -0
- package/test/use-list/index.spec.js +109 -0
- package/test/wai-aria/checkings/value.spec.js +33 -0
- package/test/wai-aria/index.spec.js +1173 -0
- 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.js +0 -63
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _Collection_locked, _Collection_matched, _Collection_nodes, _Collection_origin;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.modelLog = exports.UnsupportedError = exports.Collection = exports.cleanObject = exports.mergeHints = exports.normalizeModel = 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 debug_1 = require("./debug");
|
|
8
|
+
const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
|
|
9
|
+
const getChildNodesWithoutWhitespacesCaches = new Map();
|
|
10
|
+
function getChildNodesWithoutWhitespaces(
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
12
|
+
el) {
|
|
13
|
+
let nodes = getChildNodesWithoutWhitespacesCaches.get(el);
|
|
14
|
+
if (nodes) {
|
|
15
|
+
return nodes;
|
|
16
|
+
}
|
|
17
|
+
nodes = Array.from(el.childNodes).filter(node => {
|
|
18
|
+
return !(node.is(node.TEXT_NODE) && node.isWhitespace());
|
|
19
|
+
});
|
|
20
|
+
getChildNodesWithoutWhitespacesCaches.set(el, nodes);
|
|
21
|
+
return nodes;
|
|
22
|
+
}
|
|
23
|
+
exports.getChildNodesWithoutWhitespaces = getChildNodesWithoutWhitespaces;
|
|
24
|
+
function isModel(model) {
|
|
25
|
+
if (typeof model === 'string') {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
let modelMode = false;
|
|
29
|
+
for (const m of model) {
|
|
30
|
+
if (typeof m === 'string') {
|
|
31
|
+
modelMode = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (modelMode) {
|
|
35
|
+
throw new TypeError(`Invalid schema: ${JSON.stringify(model)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return modelMode;
|
|
39
|
+
}
|
|
40
|
+
exports.isModel = isModel;
|
|
41
|
+
function matches(selector,
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
43
|
+
node, specs) {
|
|
44
|
+
const selectorResult = (0, selector_1.createSelector)(selector, specs).search(node);
|
|
45
|
+
const matched = selectorResult.filter((r) => r.matched);
|
|
46
|
+
if (matched.length > 0) {
|
|
47
|
+
return {
|
|
48
|
+
matched: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const not = selectorResult
|
|
52
|
+
.map(r => { var _a; return (r.matched ? [] : (_a = r.not) !== null && _a !== void 0 ? _a : []); })
|
|
53
|
+
.flat()
|
|
54
|
+
.map(descendants)
|
|
55
|
+
.flat()
|
|
56
|
+
.shift();
|
|
57
|
+
return {
|
|
58
|
+
matched: false,
|
|
59
|
+
not,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
exports.matches = matches;
|
|
63
|
+
function descendants(
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
65
|
+
selectorResult) {
|
|
66
|
+
let nodes = selectorResult.nodes.slice();
|
|
67
|
+
while (selectorResult.has.length > 0) {
|
|
68
|
+
for (const dep of selectorResult.has) {
|
|
69
|
+
if (dep.has.length === 0) {
|
|
70
|
+
nodes = dep.nodes;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
selectorResult = dep;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
return nodes;
|
|
79
|
+
}
|
|
80
|
+
function isRequire(content) {
|
|
81
|
+
return 'require' in content;
|
|
82
|
+
}
|
|
83
|
+
exports.isRequire = isRequire;
|
|
84
|
+
function isOptional(content) {
|
|
85
|
+
return 'optional' in content;
|
|
86
|
+
}
|
|
87
|
+
exports.isOptional = isOptional;
|
|
88
|
+
function isOneOrMore(content) {
|
|
89
|
+
return 'oneOrMore' in content;
|
|
90
|
+
}
|
|
91
|
+
exports.isOneOrMore = isOneOrMore;
|
|
92
|
+
function isZeroOrMore(content) {
|
|
93
|
+
return 'zeroOrMore' in content;
|
|
94
|
+
}
|
|
95
|
+
exports.isZeroOrMore = isZeroOrMore;
|
|
96
|
+
function isChoice(content) {
|
|
97
|
+
return 'choice' in content;
|
|
98
|
+
}
|
|
99
|
+
exports.isChoice = isChoice;
|
|
100
|
+
function isTransparent(content) {
|
|
101
|
+
return 'transparent' in content;
|
|
102
|
+
}
|
|
103
|
+
exports.isTransparent = isTransparent;
|
|
104
|
+
function normalizeModel(pattern) {
|
|
105
|
+
var _a, _b, _c, _d, _e;
|
|
106
|
+
let model;
|
|
107
|
+
let min;
|
|
108
|
+
let max;
|
|
109
|
+
let repeat;
|
|
110
|
+
let missingType;
|
|
111
|
+
if (isRequire(pattern)) {
|
|
112
|
+
model = pattern.require;
|
|
113
|
+
min = (_a = pattern.min) !== null && _a !== void 0 ? _a : 1;
|
|
114
|
+
max = Math.max((_b = pattern.max) !== null && _b !== void 0 ? _b : 1, min);
|
|
115
|
+
missingType = 'MISSING_NODE_REQUIRED';
|
|
116
|
+
}
|
|
117
|
+
else if (isOptional(pattern)) {
|
|
118
|
+
model = pattern.optional;
|
|
119
|
+
min = 0;
|
|
120
|
+
max = Math.max((_c = pattern.max) !== null && _c !== void 0 ? _c : 1, 1);
|
|
121
|
+
}
|
|
122
|
+
else if (isOneOrMore(pattern)) {
|
|
123
|
+
model = pattern.oneOrMore;
|
|
124
|
+
min = 1;
|
|
125
|
+
max = Math.max((_d = pattern.max) !== null && _d !== void 0 ? _d : Infinity, 1);
|
|
126
|
+
missingType = 'MISSING_NODE_ONE_OR_MORE';
|
|
127
|
+
}
|
|
128
|
+
else if (isZeroOrMore(pattern)) {
|
|
129
|
+
model = pattern.zeroOrMore;
|
|
130
|
+
min = 0;
|
|
131
|
+
max = Math.max((_e = pattern.max) !== null && _e !== void 0 ? _e : Infinity, 1);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
throw new Error('Unreachable code');
|
|
135
|
+
}
|
|
136
|
+
if (min === 0 && max === 1) {
|
|
137
|
+
repeat = '?';
|
|
138
|
+
}
|
|
139
|
+
else if (min === 0 && !Number.isFinite(max)) {
|
|
140
|
+
repeat = '*';
|
|
141
|
+
}
|
|
142
|
+
else if (min === 1 && max === 1) {
|
|
143
|
+
repeat = '';
|
|
144
|
+
}
|
|
145
|
+
else if (min === 1 && !Number.isFinite(max)) {
|
|
146
|
+
repeat = '+';
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
repeat = `{${min},${max}}`;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
model,
|
|
153
|
+
min,
|
|
154
|
+
max,
|
|
155
|
+
repeat,
|
|
156
|
+
missingType,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
exports.normalizeModel = normalizeModel;
|
|
160
|
+
function mergeHints(
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
162
|
+
a,
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
164
|
+
b) {
|
|
165
|
+
const missing = [a.missing, b.missing].sort((a, b) => { var _a, _b; return ((_a = b === null || b === void 0 ? void 0 : b.barelyMatchedElements) !== null && _a !== void 0 ? _a : 0) - ((_b = a === null || a === void 0 ? void 0 : a.barelyMatchedElements) !== null && _b !== void 0 ? _b : 0); })[0];
|
|
166
|
+
return cleanObject({
|
|
167
|
+
...a,
|
|
168
|
+
...b,
|
|
169
|
+
missing: missing && cleanObject(missing),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
exports.mergeHints = mergeHints;
|
|
173
|
+
function cleanObject(object) {
|
|
174
|
+
const newObject = {};
|
|
175
|
+
Object.entries(object).forEach(([key, value]) => {
|
|
176
|
+
if (value !== undefined) {
|
|
177
|
+
newObject[key] = value;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
return newObject;
|
|
181
|
+
}
|
|
182
|
+
exports.cleanObject = cleanObject;
|
|
183
|
+
class Collection {
|
|
184
|
+
constructor(
|
|
185
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
186
|
+
origin) {
|
|
187
|
+
_Collection_locked.set(this, new Set());
|
|
188
|
+
_Collection_matched.set(this, new Set());
|
|
189
|
+
_Collection_nodes.set(this, void 0);
|
|
190
|
+
_Collection_origin.set(this, void 0);
|
|
191
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_origin, origin.slice(), "f");
|
|
192
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_nodes, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")), "f");
|
|
193
|
+
}
|
|
194
|
+
get matched() {
|
|
195
|
+
return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f"));
|
|
196
|
+
}
|
|
197
|
+
get matchedCount() {
|
|
198
|
+
return tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
199
|
+
}
|
|
200
|
+
get nodes() {
|
|
201
|
+
return tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f").slice();
|
|
202
|
+
}
|
|
203
|
+
get unmatched() {
|
|
204
|
+
return Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f")).filter(n => !tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n));
|
|
205
|
+
}
|
|
206
|
+
addMatched(
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
208
|
+
nodes) {
|
|
209
|
+
const i = tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
210
|
+
for (const node of nodes) {
|
|
211
|
+
if (!tslib_1.__classPrivateFieldGet(this, _Collection_nodes, "f").has(node)) {
|
|
212
|
+
throw new ReferenceError(`External Node: ${node.nodeName}`);
|
|
213
|
+
}
|
|
214
|
+
tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").add(node);
|
|
215
|
+
}
|
|
216
|
+
return i < tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").size;
|
|
217
|
+
}
|
|
218
|
+
back() {
|
|
219
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_matched, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f")), "f");
|
|
220
|
+
}
|
|
221
|
+
lock() {
|
|
222
|
+
tslib_1.__classPrivateFieldSet(this, _Collection_locked, new Set(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")), "f");
|
|
223
|
+
}
|
|
224
|
+
max(max) {
|
|
225
|
+
const sliced = Array.from(tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f")).slice(max);
|
|
226
|
+
sliced.forEach(n => tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").delete(n));
|
|
227
|
+
}
|
|
228
|
+
toString(highlightExtraNodes = false) {
|
|
229
|
+
const out = [];
|
|
230
|
+
for (const n of tslib_1.__classPrivateFieldGet(this, _Collection_origin, "f")) {
|
|
231
|
+
const raw = n.is(n.TEXT_NODE) ? `:text(${n.raw.replace(/\n/g, '\\n')})` : n.raw;
|
|
232
|
+
if (tslib_1.__classPrivateFieldGet(this, _Collection_locked, "f").has(n)) {
|
|
233
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
234
|
+
out.push(debug_1.bgBlue.bold(raw));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
out.push(debug_1.bgGreen.bold(raw));
|
|
238
|
+
}
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (tslib_1.__classPrivateFieldGet(this, _Collection_matched, "f").has(n)) {
|
|
242
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
243
|
+
out.push(debug_1.blue.bold(raw));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
out.push(debug_1.green.bold(raw));
|
|
247
|
+
}
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (highlightExtraNodes) {
|
|
251
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
252
|
+
out.push(debug_1.bgMagenta.bold(raw));
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
out.push(debug_1.bgRed.bold(raw));
|
|
256
|
+
}
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (represent_transparent_nodes_1.transparentMode.has(n)) {
|
|
260
|
+
out.push((0, debug_1.cyan)(raw));
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
out.push(raw);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return `[ ${out.join(', ')} ]`;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.Collection = Collection;
|
|
270
|
+
_Collection_locked = new WeakMap(), _Collection_matched = new WeakMap(), _Collection_nodes = new WeakMap(), _Collection_origin = new WeakMap();
|
|
271
|
+
class UnsupportedError extends Error {
|
|
272
|
+
}
|
|
273
|
+
exports.UnsupportedError = UnsupportedError;
|
|
274
|
+
function modelLog(model, repeat) {
|
|
275
|
+
if (!isModel(model)) {
|
|
276
|
+
return orderLog(model, repeat);
|
|
277
|
+
}
|
|
278
|
+
if (typeof model === 'string') {
|
|
279
|
+
return `<${model}>${repeat}`;
|
|
280
|
+
}
|
|
281
|
+
return `(<${model.join('>|<')}>)${repeat}`;
|
|
282
|
+
}
|
|
283
|
+
exports.modelLog = modelLog;
|
|
284
|
+
function orderLog(order, repeat) {
|
|
285
|
+
return order.length === 1 && order[0]
|
|
286
|
+
? markRepeat(patternLog(order[0]), repeat)
|
|
287
|
+
: markRepeat(order.map(pattern => patternLog(pattern)).join(''), repeat);
|
|
288
|
+
}
|
|
289
|
+
function patternLog(pattern) {
|
|
290
|
+
if (isTransparent(pattern)) {
|
|
291
|
+
// 適当
|
|
292
|
+
return `:transparent(${modelLog(pattern.transparent, '')})`;
|
|
293
|
+
}
|
|
294
|
+
if (isChoice(pattern)) {
|
|
295
|
+
return `(${pattern.choice.map(candidate => orderLog(candidate, '')).join('|')})`;
|
|
296
|
+
}
|
|
297
|
+
const { model, repeat } = normalizeModel(pattern);
|
|
298
|
+
return modelLog(model, repeat);
|
|
299
|
+
}
|
|
300
|
+
function markRepeat(pattern, repeat) {
|
|
301
|
+
return repeat ? `(${pattern})${repeat}` : pattern;
|
|
302
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
verify({ document, report, t }) {
|
|
6
|
+
document.querySelectorAll('select').forEach(select => {
|
|
7
|
+
if (hasPlaceholderLabelOption(select)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (!needPlaceholderLabelOption(select)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
report({
|
|
14
|
+
scope: select,
|
|
15
|
+
message: t('need {0}', t('the {0}', 'placeholder label option')),
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* > If a select element has a required attribute specified,
|
|
22
|
+
* > does not have a multiple attribute specified,
|
|
23
|
+
* > and has a display size of 1,
|
|
24
|
+
* > then the select element must have a placeholder label option.
|
|
25
|
+
*
|
|
26
|
+
* @param select
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
function needPlaceholderLabelOption(
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
31
|
+
select) {
|
|
32
|
+
var _a;
|
|
33
|
+
const hasRequired = select.hasAttribute('required');
|
|
34
|
+
if (!hasRequired) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const hasMultiple = select.hasAttribute('multiple');
|
|
38
|
+
if (hasMultiple) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const size = (_a = select.getAttribute('size')) !== null && _a !== void 0 ? _a : '1';
|
|
42
|
+
if (size !== '1') {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* > If a select element has a required attribute specified,
|
|
49
|
+
* > does not have a multiple attribute specified,
|
|
50
|
+
* > and has a display size of 1;
|
|
51
|
+
* > and if the value of the first option element
|
|
52
|
+
* > in the select element's list of options (if any) is the empty string,
|
|
53
|
+
* > and that option element's parent node is the select element (and not an optgroup element),
|
|
54
|
+
* > then that option is the select element's **placeholder label option**.
|
|
55
|
+
*
|
|
56
|
+
* @param select
|
|
57
|
+
* @returns
|
|
58
|
+
*/
|
|
59
|
+
function hasPlaceholderLabelOption(
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
61
|
+
select) {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
// > has a required attribute specified
|
|
64
|
+
if (!select.hasAttribute('required')) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// > does not have a multiple attribute specified
|
|
68
|
+
if (select.hasAttribute('multiple')) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// > has a display size of 1
|
|
72
|
+
const size = (_a = select.getAttribute('size')) !== null && _a !== void 0 ? _a : '1';
|
|
73
|
+
if (size !== '1') {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// > in the select element's list of options (if any) is the empty string
|
|
77
|
+
const firstOption = select.querySelector('option');
|
|
78
|
+
if (!firstOption) {
|
|
79
|
+
// if any
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
// > that option element's parent node is the select element (and not an optgroup element)
|
|
83
|
+
if (((_b = firstOption.parentElement) === null || _b === void 0 ? void 0 : _b.localName) === 'optgroup') {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const value = firstOption.getAttribute('value');
|
|
87
|
+
return value === '' || value === null;
|
|
88
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ARIAVersion } from '@markuplint/ml-spec';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type Option = {
|
|
3
|
+
ariaVersion: ARIAVersion;
|
|
4
4
|
};
|
|
5
|
-
declare const _default: import(
|
|
5
|
+
declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Option>>;
|
|
6
6
|
export default _default;
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
+
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
4
5
|
const helpers_1 = require("../helpers");
|
|
5
6
|
exports.default = (0, ml_core_1.createRule)({
|
|
6
7
|
defaultOptions: {
|
|
7
|
-
ariaVersion:
|
|
8
|
+
ariaVersion: ml_spec_1.ARIA_RECOMMENDED_VERSION,
|
|
8
9
|
},
|
|
9
10
|
async verify({ document, report, t }) {
|
|
10
11
|
await document.walkOn('Element', el => {
|
|
12
|
+
var _a;
|
|
13
|
+
if (((_a = el.pretenderContext) === null || _a === void 0 ? void 0 : _a.type) === 'pretender') {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
11
16
|
if ((0, helpers_1.accnameMayBeMutable)(el, document)) {
|
|
12
17
|
return;
|
|
13
18
|
}
|
|
14
|
-
|
|
19
|
+
if (!(0, ml_spec_1.isExposed)(el, document.specs, el.rule.options.ariaVersion)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const computed = (0, ml_core_1.getComputedRole)(document.specs, el, el.rule.options.ariaVersion);
|
|
15
23
|
if (!computed.role) {
|
|
16
24
|
return;
|
|
17
25
|
}
|
|
18
|
-
const roleSpec = (0, ml_core_1.getRoleSpec)(document.specs, computed.role.name, el.namespaceURI, el.rule.
|
|
26
|
+
const roleSpec = (0, ml_core_1.getRoleSpec)(document.specs, computed.role.name, el.namespaceURI, el.rule.options.ariaVersion);
|
|
19
27
|
if (!roleSpec || !roleSpec.accessibleNameRequired) {
|
|
20
28
|
return;
|
|
21
29
|
}
|
|
22
|
-
const hasAccessibleName = !!el.getAccessibleName().trim();
|
|
30
|
+
const hasAccessibleName = !!el.getAccessibleName(el.rule.options.ariaVersion).trim();
|
|
23
31
|
if (!hasAccessibleName) {
|
|
24
32
|
report({ scope: el, message: t('Require {0}', 'accessible name') });
|
|
25
33
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
+
const types_1 = require("@markuplint/types");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
exports.default = (0, ml_core_1.createRule)({
|
|
7
|
+
defaultOptions: {
|
|
8
|
+
langs: undefined,
|
|
9
|
+
},
|
|
10
|
+
verify({ document, report, t }) {
|
|
11
|
+
document.querySelectorAll('time:not([datetime])').forEach(time => {
|
|
12
|
+
if (time.hasMutableChildren()) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const content = time.textContent.trim();
|
|
16
|
+
const result = (0, types_1.check)(content, 'DateTime');
|
|
17
|
+
if (result.matched) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const candidate = (0, utils_1.getCandidateDatetimeString)(content, time.rule.options.langs);
|
|
21
|
+
if (candidate) {
|
|
22
|
+
report({
|
|
23
|
+
scope: time,
|
|
24
|
+
message: t('need {0*}', `datetime="${candidate}"`),
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
report({
|
|
29
|
+
scope: time,
|
|
30
|
+
message: t('need {0}', t('the "{0*}" {1}', 'datetime', 'attribute')),
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DateTimeKey = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'ms';
|
|
2
|
+
export type DateTimeData = Partial<Record<DateTimeKey, number>>;
|
|
3
|
+
export type DateTime = {
|
|
4
|
+
datetime: DateTimeData;
|
|
5
|
+
zone?: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* @see https://github.com/wanasit/chrono#locales
|
|
9
|
+
*/
|
|
10
|
+
export type Lang = 'en' | 'ja' | 'fr' | 'nl' | 'ru' | 'de' | 'pt' | 'zh';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DateTime, Lang } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Datetime-ish text to a datetime data
|
|
4
|
+
*
|
|
5
|
+
* @param content
|
|
6
|
+
* @param langs
|
|
7
|
+
* @param base Reference date for a test
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseADatetime(content: string, langs: readonly Lang[], base?: Readonly<Date>): DateTime | null;
|
|
11
|
+
export declare function getCandidateDatetimeString(content: string, langs?: Lang[]): string | null;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCandidateDatetimeString = exports.parseADatetime = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chrono = tslib_1.__importStar(require("chrono-node"));
|
|
6
|
+
const defaultLangs = ['en', 'ja', 'fr', 'nl', 'ru', 'de', 'pt', 'zh'];
|
|
7
|
+
/**
|
|
8
|
+
* Datetime-ish text to a datetime data
|
|
9
|
+
*
|
|
10
|
+
* @param content
|
|
11
|
+
* @param langs
|
|
12
|
+
* @param base Reference date for a test
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
function parseADatetime(content, langs, base) {
|
|
16
|
+
var _a;
|
|
17
|
+
const date = parseTryMultipleLangs(content, langs, base);
|
|
18
|
+
if (!date) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const data = {};
|
|
22
|
+
if (date.isCertain('year')) {
|
|
23
|
+
data.year = date.get('year');
|
|
24
|
+
}
|
|
25
|
+
if (date.isCertain('month')) {
|
|
26
|
+
data.month = date.get('month');
|
|
27
|
+
}
|
|
28
|
+
if (date.isCertain('day')) {
|
|
29
|
+
data.day = date.get('day');
|
|
30
|
+
}
|
|
31
|
+
if (date.isCertain('hour')) {
|
|
32
|
+
data.hour = date.get('hour');
|
|
33
|
+
}
|
|
34
|
+
if (date.isCertain('hour')) {
|
|
35
|
+
data.minute = (_a = date.get('minute')) !== null && _a !== void 0 ? _a : 0;
|
|
36
|
+
}
|
|
37
|
+
if (date.isCertain('second')) {
|
|
38
|
+
data.second = date.get('second');
|
|
39
|
+
}
|
|
40
|
+
if (date.isCertain('millisecond')) {
|
|
41
|
+
data.ms = date.get('millisecond');
|
|
42
|
+
}
|
|
43
|
+
const datetime = {
|
|
44
|
+
datetime: data,
|
|
45
|
+
};
|
|
46
|
+
if (date.isCertain('timezoneOffset')) {
|
|
47
|
+
datetime.zone = date.get('timezoneOffset');
|
|
48
|
+
}
|
|
49
|
+
return datetime;
|
|
50
|
+
}
|
|
51
|
+
exports.parseADatetime = parseADatetime;
|
|
52
|
+
function getCandidateDatetimeString(content, langs = defaultLangs) {
|
|
53
|
+
const date = parseADatetime(content, langs);
|
|
54
|
+
if (!date) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
let datetimeStr = toDatetimeString(date.datetime);
|
|
58
|
+
if (!datetimeStr) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
if (date.zone != null) {
|
|
62
|
+
const plusMinus = date.zone < 0 ? '-' : '+';
|
|
63
|
+
const hour = Math.floor(Math.abs(date.zone) / 60);
|
|
64
|
+
const minute = Math.abs(date.zone) % 60;
|
|
65
|
+
datetimeStr += `${plusMinus}${f(hour, 2)}${f(minute, 2)}`;
|
|
66
|
+
}
|
|
67
|
+
return datetimeStr;
|
|
68
|
+
}
|
|
69
|
+
exports.getCandidateDatetimeString = getCandidateDatetimeString;
|
|
70
|
+
function toDatetimeString(date) {
|
|
71
|
+
if (only(date, ['year', 'month'])) {
|
|
72
|
+
return `${f(date.year, 4)}-${f(date.month, 2)}`;
|
|
73
|
+
}
|
|
74
|
+
if (only(date, ['year', 'month', 'day'])) {
|
|
75
|
+
return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}`;
|
|
76
|
+
}
|
|
77
|
+
if (only(date, ['month', 'day'])) {
|
|
78
|
+
return `${f(date.month, 2)}-${f(date.day, 2)}`;
|
|
79
|
+
}
|
|
80
|
+
if (only(date, ['hour', 'minute'])) {
|
|
81
|
+
return `${f(date.hour, 2)}:${f(date.minute, 2)}`;
|
|
82
|
+
}
|
|
83
|
+
if (only(date, ['hour', 'minute', 'second'])) {
|
|
84
|
+
return `${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}`;
|
|
85
|
+
}
|
|
86
|
+
if (only(date, ['hour', 'minute', 'second', 'ms'])) {
|
|
87
|
+
return `${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}.${date.ms}`;
|
|
88
|
+
}
|
|
89
|
+
if (only(date, ['year', 'month', 'day', 'hour', 'minute'])) {
|
|
90
|
+
return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}`;
|
|
91
|
+
}
|
|
92
|
+
if (only(date, ['year', 'month', 'day', 'hour', 'minute', 'second'])) {
|
|
93
|
+
return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}`;
|
|
94
|
+
}
|
|
95
|
+
if (only(date, ['year', 'month', 'day', 'hour', 'minute', 'second', 'ms'])) {
|
|
96
|
+
return `${f(date.year, 4)}-${f(date.month, 2)}-${f(date.day, 2)}T${f(date.hour, 2)}:${f(date.minute, 2)}:${f(date.second, 2)}.${date.ms}`;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function parseTryMultipleLangs(content, langs, base) {
|
|
101
|
+
for (const lang of langs) {
|
|
102
|
+
const results = chrono[lang].casual.parse(content, base);
|
|
103
|
+
// Is not multiple datetime contents
|
|
104
|
+
if (results.length < 1) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const result = results[0];
|
|
108
|
+
if (!result) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Is not a range or period
|
|
112
|
+
if (result.end) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
return result.start;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
function only(date, keys) {
|
|
120
|
+
const list = Object.keys(date);
|
|
121
|
+
for (const exists of list) {
|
|
122
|
+
if (!keys.includes(exists)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Formatter
|
|
130
|
+
*
|
|
131
|
+
* @param n
|
|
132
|
+
* @param pad zero padding
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
135
|
+
function f(n, pad) {
|
|
136
|
+
return n.toString(10).padStart(pad, '0');
|
|
137
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
type RequiredAttributes = string | (string | Attr)[];
|
|
2
|
+
type Attr = {
|
|
3
|
+
name: string;
|
|
4
|
+
value?: string | string[];
|
|
5
5
|
};
|
|
6
|
-
declare const _default: import(
|
|
6
|
+
declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<RequiredAttributes, undefined>>;
|
|
7
7
|
export default _default;
|