@markuplint/rules 3.4.0 → 3.6.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 +3 -2
- package/lib/attr-check.js +19 -22
- package/lib/attr-duplication/index.d.ts +3 -1
- package/lib/attr-duplication/index.js +2 -1
- package/lib/attr-value-quotes/index.d.ts +1 -1
- package/lib/case-sensitive-attr-name/index.d.ts +1 -1
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/class-naming/index.js +2 -4
- package/lib/create-message.d.ts +2 -1
- package/lib/create-message.js +5 -4
- package/lib/deprecated-attr/index.d.ts +3 -1
- package/lib/deprecated-element/index.d.ts +3 -1
- package/lib/deprecated-element/index.js +2 -2
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/doctype/index.d.ts +1 -1
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/helpers.d.ts +18 -36
- package/lib/helpers.js +27 -14
- package/lib/id-duplication/index.d.ts +3 -1
- package/lib/index.d.ts +175 -3
- package/lib/index.js +2 -1
- package/lib/ineffective-attr/index.d.ts +3 -1
- package/lib/ineffective-attr/index.js +2 -5
- package/lib/invalid-attr/index.d.ts +1 -1
- package/lib/invalid-attr/index.js +8 -8
- package/lib/label-has-control/index.d.ts +3 -1
- package/lib/landmark-roles/index.d.ts +1 -1
- package/lib/landmark-roles/index.js +7 -3
- package/lib/no-boolean-attr-value/index.d.ts +3 -1
- package/lib/no-default-value/index.d.ts +3 -1
- package/lib/no-empty-palpable-content/index.d.ts +1 -1
- package/lib/no-hard-code-id/index.d.ts +3 -1
- package/lib/no-refer-to-non-existent-id/index.d.ts +8 -6
- package/lib/no-refer-to-non-existent-id/index.js +4 -14
- package/lib/no-use-event-handler-attr/index.d.ts +1 -1
- package/lib/permitted-contents/choice.d.ts +3 -2
- package/lib/permitted-contents/choice.js +3 -1
- package/lib/permitted-contents/complex-branch.d.ts +3 -2
- package/lib/permitted-contents/complex-branch.js +4 -2
- package/lib/permitted-contents/content-model.d.ts +1 -1
- package/lib/permitted-contents/content-model.js +7 -3
- package/lib/permitted-contents/count-pattern.d.ts +5 -4
- package/lib/permitted-contents/count-pattern.js +9 -3
- package/lib/permitted-contents/index.d.ts +1 -1
- package/lib/permitted-contents/index.js +8 -11
- package/lib/permitted-contents/matches-selector.d.ts +1 -2
- package/lib/permitted-contents/matches-selector.js +4 -2
- package/lib/permitted-contents/order.d.ts +3 -2
- package/lib/permitted-contents/order.js +7 -5
- package/lib/permitted-contents/recursive-branch.d.ts +2 -1
- package/lib/permitted-contents/recursive-branch.js +5 -3
- package/lib/permitted-contents/represent-transparent-nodes.js +4 -2
- package/lib/permitted-contents/start.d.ts +2 -1
- package/lib/permitted-contents/start.js +4 -2
- package/lib/permitted-contents/transparent.d.ts +2 -2
- package/lib/permitted-contents/transparent.js +3 -1
- package/lib/permitted-contents/types.d.ts +10 -9
- package/lib/permitted-contents/utils.d.ts +44 -80
- package/lib/permitted-contents/utils.js +23 -9
- package/lib/placeholder-label-option/index.d.ts +1 -1
- package/lib/placeholder-label-option/index.js +11 -6
- package/lib/require-accessible-name/index.d.ts +1 -1
- package/lib/require-datetime/index.d.ts +1 -1
- package/lib/require-datetime/utils.d.ts +1 -1
- package/lib/require-datetime/utils.js +3 -2
- package/lib/required-attr/index.d.ts +1 -1
- package/lib/required-attr/index.js +5 -5
- package/lib/required-element/index.d.ts +1 -1
- package/lib/required-h1/index.d.ts +1 -1
- package/lib/use-list/index.d.ts +2 -2
- package/lib/use-list/index.js +4 -3
- package/lib/wai-aria/checkings/default-value.d.ts +1 -1
- package/lib/wai-aria/checkings/deprecated-props.d.ts +1 -1
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +4 -8
- package/lib/wai-aria/checkings/disallowed-prop.js +1 -1
- package/lib/wai-aria/checkings/implicit-props.d.ts +2 -2
- package/lib/wai-aria/checkings/implicit-props.js +3 -2
- package/lib/wai-aria/checkings/interaction-in-hidden.js +3 -1
- package/lib/wai-aria/checkings/no-global-prop.d.ts +1 -1
- package/lib/wai-aria/checkings/presentational-children.js +3 -1
- package/lib/wai-aria/checkings/required-owned-elements.js +5 -3
- package/lib/wai-aria/checkings/required-prop.d.ts +1 -1
- package/lib/wai-aria/checkings/value.d.ts +7 -2
- package/lib/wai-aria/checkings/value.js +3 -1
- package/lib/wai-aria/index.d.ts +1 -1
- package/package.json +10 -9
|
@@ -9,7 +9,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
9
9
|
defaultOptions: {},
|
|
10
10
|
async verify({ document, report, t }) {
|
|
11
11
|
await document.walkOn('Attr', attr => {
|
|
12
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l
|
|
12
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
13
13
|
// Default
|
|
14
14
|
const allowToAddPropertiesForPretender = (_a = attr.rule.options.allowToAddPropertiesForPretender) !== null && _a !== void 0 ? _a : true;
|
|
15
15
|
if (attr.isDirective) {
|
|
@@ -33,7 +33,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
33
33
|
}
|
|
34
34
|
const valueNode = attr.valueNode;
|
|
35
35
|
const value = attr.value;
|
|
36
|
-
if (attr.rule.options.ignoreAttrNamePrefix) {
|
|
36
|
+
if (attr.rule.options.ignoreAttrNamePrefix != null) {
|
|
37
37
|
const ignoreAttrNamePrefixes = Array.isArray(attr.rule.options.ignoreAttrNamePrefix)
|
|
38
38
|
? attr.rule.options.ignoreAttrNamePrefix
|
|
39
39
|
: [attr.rule.options.ignoreAttrNamePrefix];
|
|
@@ -75,7 +75,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
75
75
|
log('Checking %s[%s="%s"]', attr.nodeName, name, value);
|
|
76
76
|
invalid = (0, helpers_1.isValidAttr)(t, name, value, attr.isDynamicValue || false, attr.ownerElement, attrSpecs, log);
|
|
77
77
|
}
|
|
78
|
-
if (invalid) {
|
|
78
|
+
if (invalid !== false) {
|
|
79
79
|
switch (invalid.invalidType) {
|
|
80
80
|
case 'disallowed-attr': {
|
|
81
81
|
report({
|
|
@@ -92,15 +92,15 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
92
92
|
scope: attr,
|
|
93
93
|
message: invalid.message,
|
|
94
94
|
line: ((_b = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startLine) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = invalid.loc) === null || _c === void 0 ? void 0 : _c.line) !== null && _d !== void 0 ? _d : 0),
|
|
95
|
-
col:
|
|
96
|
-
? ((
|
|
97
|
-
: ((
|
|
98
|
-
raw: (
|
|
95
|
+
col: invalid.loc && invalid.loc.line > 0
|
|
96
|
+
? ((_e = invalid.loc) === null || _e === void 0 ? void 0 : _e.col) + 1
|
|
97
|
+
: ((_f = valueNode === null || valueNode === void 0 ? void 0 : valueNode.startCol) !== null && _f !== void 0 ? _f : 0) + ((_h = (_g = invalid.loc) === null || _g === void 0 ? void 0 : _g.col) !== null && _h !== void 0 ? _h : 0),
|
|
98
|
+
raw: (_k = (_j = invalid.loc) === null || _j === void 0 ? void 0 : _j.raw) !== null && _k !== void 0 ? _k : value,
|
|
99
99
|
});
|
|
100
100
|
break;
|
|
101
101
|
}
|
|
102
102
|
case 'non-existent': {
|
|
103
|
-
if (allowToAddPropertiesForPretender && ((
|
|
103
|
+
if (allowToAddPropertiesForPretender && ((_l = attr.ownerElement.pretenderContext) === null || _l === void 0 ? void 0 : _l.type) === 'origin') {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
const spec = (0, ml_core_1.getSpec)(attr.ownerElement, document.specs.specs);
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: Readonly<
|
|
2
|
+
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
+
>;
|
|
2
4
|
export default _default;
|
|
@@ -4,5 +4,5 @@ type Options = {
|
|
|
4
4
|
};
|
|
5
5
|
type TopLevelRoles = 'banner' | 'main' | 'complementary' | 'contentinfo';
|
|
6
6
|
type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
|
|
7
|
-
declare const _default: import('@markuplint/ml-core').RuleSeed<boolean, Options
|
|
7
|
+
declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
|
|
8
8
|
export default _default;
|
|
@@ -106,13 +106,17 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
});
|
|
109
|
-
function landmarkRoleElementUUIDList(
|
|
109
|
+
function landmarkRoleElementUUIDList(
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
111
|
+
roleset) {
|
|
110
112
|
return Object.values(roleset)
|
|
111
113
|
.map(elements => elements.map(element => element.uuid))
|
|
112
114
|
.flat();
|
|
113
115
|
}
|
|
114
|
-
function hasLabel(
|
|
115
|
-
|
|
116
|
+
function hasLabel(
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
118
|
+
el) {
|
|
119
|
+
const hasHeading = el.querySelectorAll('h1, h2, h3, h4, h5, h6').length > 0;
|
|
116
120
|
if (hasHeading && el.matches('[aria-labelledby]')) {
|
|
117
121
|
return true;
|
|
118
122
|
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: Readonly<
|
|
2
|
+
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
+
>;
|
|
2
4
|
export default _default;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: Readonly<
|
|
2
|
+
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
+
>;
|
|
2
4
|
export default _default;
|
|
@@ -2,5 +2,5 @@ type Options = {
|
|
|
2
2
|
extendsExposableElements?: boolean;
|
|
3
3
|
ignoreIfAriaBusy?: boolean;
|
|
4
4
|
};
|
|
5
|
-
declare const _default: import('@markuplint/ml-core').RuleSeed<boolean, Options
|
|
5
|
+
declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
|
|
6
6
|
export default _default;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: Readonly<
|
|
2
|
+
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
+
>;
|
|
2
4
|
export default _default;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { ARIAVersion } from '@markuplint/ml-spec';
|
|
2
|
-
declare const _default:
|
|
3
|
-
import('@markuplint/ml-core').
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
declare const _default: Readonly<
|
|
3
|
+
import('@markuplint/ml-core').RuleSeed<
|
|
4
|
+
import('@markuplint/ml-core').RuleConfigValue,
|
|
5
|
+
{
|
|
6
|
+
ariaVersion: ARIAVersion;
|
|
7
|
+
fragmentRefersNameAttr: boolean;
|
|
8
|
+
}
|
|
9
|
+
>
|
|
8
10
|
>;
|
|
9
11
|
export default _default;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const ml_core_1 = require("@markuplint/ml-core");
|
|
4
|
+
const shared_1 = require("@markuplint/shared");
|
|
4
5
|
const HYPERLINK_SELECTOR = 'a[href], area[href]';
|
|
5
6
|
exports.default = (0, ml_core_1.createRule)({
|
|
6
7
|
defaultOptions: {
|
|
@@ -25,7 +26,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
25
26
|
hasDynamicId = true;
|
|
26
27
|
}
|
|
27
28
|
if (attr.valueType !== 'code') {
|
|
28
|
-
idList.add(attr.value);
|
|
29
|
+
idList.add((0, shared_1.decodeEntities)(attr.value));
|
|
29
30
|
}
|
|
30
31
|
});
|
|
31
32
|
if (hasDynamicId) {
|
|
@@ -40,7 +41,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
40
41
|
hasDynamicName = true;
|
|
41
42
|
}
|
|
42
43
|
if (attr.valueType !== 'code') {
|
|
43
|
-
nameList.add(attr.value);
|
|
44
|
+
nameList.add((0, shared_1.decodeEntities)(attr.value));
|
|
44
45
|
}
|
|
45
46
|
});
|
|
46
47
|
await document.walkOn('Attr', attr => {
|
|
@@ -140,7 +141,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
140
141
|
if (rawFragment == null) {
|
|
141
142
|
return;
|
|
142
143
|
}
|
|
143
|
-
const decodedFragment =
|
|
144
|
+
const decodedFragment = (0, shared_1.decodeHref)(rawFragment);
|
|
144
145
|
// > 2. If fragment is the empty string, then return the special value top of the document.
|
|
145
146
|
// >
|
|
146
147
|
// > 9. If decodedFragment is an ASCII case-insensitive match for the string top, then return the top of the document.
|
|
@@ -160,14 +161,3 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
160
161
|
});
|
|
161
162
|
},
|
|
162
163
|
});
|
|
163
|
-
function decode(fragment) {
|
|
164
|
-
try {
|
|
165
|
-
return decodeURI(fragment);
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
if (e instanceof URIError) {
|
|
169
|
-
return fragment;
|
|
170
|
-
}
|
|
171
|
-
throw e;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ChildNode, Options, Result, Specs } from './types';
|
|
2
2
|
import type { PermittedContentChoice } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
export declare function choice(
|
|
4
|
-
pattern: PermittedContentChoice
|
|
5
|
-
elements: ChildNode[],
|
|
5
|
+
pattern: ReadonlyDeep<PermittedContentChoice>,
|
|
6
|
+
elements: readonly ChildNode[],
|
|
6
7
|
specs: Specs,
|
|
7
8
|
options: Options,
|
|
8
9
|
depth: number,
|
|
@@ -5,7 +5,9 @@ const debug_1 = require("./debug");
|
|
|
5
5
|
const order_1 = require("./order");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const indexes = new WeakMap();
|
|
8
|
-
function choice(pattern,
|
|
8
|
+
function choice(pattern,
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
10
|
+
elements, specs, options, depth) {
|
|
9
11
|
const choiceLog = debug_1.cmLog.extend(`choice#${depth}`);
|
|
10
12
|
const collection = new utils_1.Collection(elements);
|
|
11
13
|
const unmatchedResults = [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ChildNode, Options, Result, Specs } from './types';
|
|
2
2
|
import type { PermittedContentPattern } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
/**
|
|
4
5
|
* Check content condition
|
|
5
6
|
*
|
|
@@ -11,8 +12,8 @@ import type { PermittedContentPattern } from '@markuplint/ml-spec';
|
|
|
11
12
|
* @returns
|
|
12
13
|
*/
|
|
13
14
|
export declare function complexBranch(
|
|
14
|
-
pattern: PermittedContentPattern
|
|
15
|
-
elements: ChildNode[],
|
|
15
|
+
pattern: ReadonlyDeep<PermittedContentPattern>,
|
|
16
|
+
elements: readonly ChildNode[],
|
|
16
17
|
specs: Specs,
|
|
17
18
|
options: Options,
|
|
18
19
|
depth: number,
|
|
@@ -15,12 +15,14 @@ const utils_1 = require("./utils");
|
|
|
15
15
|
* @param depth
|
|
16
16
|
* @returns
|
|
17
17
|
*/
|
|
18
|
-
function complexBranch(pattern,
|
|
18
|
+
function complexBranch(pattern,
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
20
|
+
elements, specs, options, depth) {
|
|
19
21
|
if ((0, utils_1.isChoice)(pattern)) {
|
|
20
22
|
return (0, choice_1.choice)(pattern, elements, specs, options, depth);
|
|
21
23
|
}
|
|
22
24
|
if ((0, utils_1.isTransparent)(pattern)) {
|
|
23
|
-
return (0, transparent_1.transparent)(elements
|
|
25
|
+
return (0, transparent_1.transparent)(elements);
|
|
24
26
|
}
|
|
25
27
|
return (0, count_pattern_1.countPattern)(pattern, elements, specs, options, depth);
|
|
26
28
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ContentModelResult, Element, Options, TagRule } from './types';
|
|
2
|
-
export declare function contentModel(el: Element, rules: TagRule[], options: Options): ContentModelResult[];
|
|
2
|
+
export declare function contentModel(el: Element, rules: readonly TagRule[], options: Options): ContentModelResult[];
|
|
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.contentModel = void 0;
|
|
4
4
|
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
5
|
const start_1 = require("./start");
|
|
6
|
-
function contentModel(
|
|
6
|
+
function contentModel(
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
|
+
el, rules, options) {
|
|
7
9
|
const model = createModel(el, rules);
|
|
8
10
|
if (model == null) {
|
|
9
11
|
return [
|
|
@@ -19,14 +21,16 @@ function contentModel(el, rules, options) {
|
|
|
19
21
|
return result;
|
|
20
22
|
}
|
|
21
23
|
exports.contentModel = contentModel;
|
|
22
|
-
function createModel(
|
|
24
|
+
function createModel(
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
26
|
+
el, rules) {
|
|
23
27
|
const specs = cachedSpecs(el.ownerMLDocument.specs, rules);
|
|
24
28
|
const model = (0, ml_spec_1.getContentModel)(el, specs.specs);
|
|
25
29
|
return model;
|
|
26
30
|
}
|
|
27
31
|
const caches = new Map();
|
|
28
32
|
function cachedSpecs(specs, rules) {
|
|
29
|
-
if (
|
|
33
|
+
if (rules.length === 0) {
|
|
30
34
|
return specs;
|
|
31
35
|
}
|
|
32
36
|
const key = JSON.stringify(rules);
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
PermittedContentRequire,
|
|
6
6
|
PermittedContentZeroOrMore,
|
|
7
7
|
} from '@markuplint/ml-spec';
|
|
8
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
8
9
|
/**
|
|
9
10
|
* Check count
|
|
10
11
|
*
|
|
@@ -17,10 +18,10 @@ import type {
|
|
|
17
18
|
*/
|
|
18
19
|
export declare function countPattern(
|
|
19
20
|
pattern:
|
|
20
|
-
| PermittedContentOneOrMore
|
|
21
|
-
| PermittedContentOptional
|
|
22
|
-
| PermittedContentRequire
|
|
23
|
-
| PermittedContentZeroOrMore
|
|
21
|
+
| ReadonlyDeep<PermittedContentOneOrMore>
|
|
22
|
+
| ReadonlyDeep<PermittedContentOptional>
|
|
23
|
+
| ReadonlyDeep<PermittedContentRequire>
|
|
24
|
+
| ReadonlyDeep<PermittedContentZeroOrMore>,
|
|
24
25
|
elements: readonly ChildNode[],
|
|
25
26
|
specs: Specs,
|
|
26
27
|
options: Options,
|
|
@@ -14,7 +14,9 @@ const utils_1 = require("./utils");
|
|
|
14
14
|
* @param depth
|
|
15
15
|
* @returns
|
|
16
16
|
*/
|
|
17
|
-
function countPattern(pattern,
|
|
17
|
+
function countPattern(pattern,
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
19
|
+
elements, specs, options, depth) {
|
|
18
20
|
const ptLog = debug_1.cmLog.extend(`countPattern#${depth}`);
|
|
19
21
|
const collection = new utils_1.Collection(elements);
|
|
20
22
|
const { model, min, max, repeat, missingType } = (0, utils_1.normalizeModel)(pattern);
|
|
@@ -119,7 +121,7 @@ function countPattern(pattern, elements, specs, options, depth) {
|
|
|
119
121
|
},
|
|
120
122
|
}),
|
|
121
123
|
};
|
|
122
|
-
if (
|
|
124
|
+
if (collection.unmatched.length > 0) {
|
|
123
125
|
prevResult = matchedResult;
|
|
124
126
|
ptLog('continue⤴️ (add prev)');
|
|
125
127
|
continue;
|
|
@@ -142,7 +144,11 @@ function countPattern(pattern, elements, specs, options, depth) {
|
|
|
142
144
|
}
|
|
143
145
|
exports.countPattern = countPattern;
|
|
144
146
|
const cLog = debug_1.cmLog.extend('countCompereResult');
|
|
145
|
-
function compereResult(
|
|
147
|
+
function compereResult(
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
149
|
+
a,
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
151
|
+
b) {
|
|
146
152
|
var _a;
|
|
147
153
|
cLog('current: %s %O\nbarely: %s %O', a.type, a.hint, b === null || b === void 0 ? void 0 : b.type, b === null || b === void 0 ? void 0 : b.hint);
|
|
148
154
|
if (b == null) {
|
|
@@ -11,22 +11,17 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
11
11
|
async verify({ document, report, t }) {
|
|
12
12
|
await document.walkOn('Element', el => {
|
|
13
13
|
var _a, _b, _c;
|
|
14
|
-
if (!el.rule.value) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
14
|
if (el.rule.options.ignoreHasMutableChildren && el.hasMutableChildren()) {
|
|
18
15
|
return;
|
|
19
16
|
}
|
|
20
17
|
const results = (0, content_model_1.contentModel)(el, el.rule.value, el.rule.options);
|
|
21
18
|
for (const { type, scope, query, hint } of results) {
|
|
22
19
|
let message = '';
|
|
23
|
-
if (hint) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
t('
|
|
27
|
-
|
|
28
|
-
t('the max number of elements required is {0}', `${hint.max}`);
|
|
29
|
-
}
|
|
20
|
+
if (hint.max != null) {
|
|
21
|
+
message =
|
|
22
|
+
t('there is more content than it needs') +
|
|
23
|
+
t('. ') +
|
|
24
|
+
t('the max number of elements required is {0}', `${hint.max}`);
|
|
30
25
|
}
|
|
31
26
|
switch (type) {
|
|
32
27
|
case 'MATCHED':
|
|
@@ -91,7 +86,9 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
91
86
|
});
|
|
92
87
|
},
|
|
93
88
|
});
|
|
94
|
-
function name(
|
|
89
|
+
function name(
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
91
|
+
scope, t) {
|
|
95
92
|
if (scope.is(scope.ELEMENT_NODE)) {
|
|
96
93
|
return t('the "{0}" {1}', scope.localName, 'element');
|
|
97
94
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { ChildNode,
|
|
1
|
+
import type { ChildNode, Result, Specs } from './types';
|
|
2
2
|
export type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
|
|
3
3
|
export declare function matchesSelector(
|
|
4
4
|
query: string,
|
|
5
5
|
node: ChildNode | undefined,
|
|
6
6
|
specs: Specs,
|
|
7
|
-
options: Options,
|
|
8
7
|
depth: number,
|
|
9
8
|
): SelectorResult;
|
|
@@ -4,7 +4,9 @@ exports.matchesSelector = void 0;
|
|
|
4
4
|
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
5
|
const debug_1 = require("./debug");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
-
function matchesSelector(query,
|
|
7
|
+
function matchesSelector(query,
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
9
|
+
node, specs, depth) {
|
|
8
10
|
const nodeLog = debug_1.cmLog.extend(`node#${depth}`);
|
|
9
11
|
const { selector, hasText, hasCustom } = optCondition(query, specs);
|
|
10
12
|
if (node == null) {
|
|
@@ -12,7 +14,7 @@ function matchesSelector(query, node, specs, options, depth) {
|
|
|
12
14
|
nodeLog('<#text>.matches(%s) => ""', query);
|
|
13
15
|
return {
|
|
14
16
|
type: 'MATCHED_ZERO',
|
|
15
|
-
matched:
|
|
17
|
+
matched: [],
|
|
16
18
|
unmatched: [],
|
|
17
19
|
zeroMatch: true,
|
|
18
20
|
query,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ChildNode, Options, Result, Specs } from './types';
|
|
2
2
|
import type { PermittedContentPattern } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
/**
|
|
4
5
|
* Check ordered array
|
|
5
6
|
*
|
|
@@ -11,8 +12,8 @@ import type { PermittedContentPattern } from '@markuplint/ml-spec';
|
|
|
11
12
|
* @returns
|
|
12
13
|
*/
|
|
13
14
|
export declare function order(
|
|
14
|
-
contents:
|
|
15
|
-
nodes:
|
|
15
|
+
contents: ReadonlyDeep<PermittedContentPattern[]>,
|
|
16
|
+
nodes: readonly ChildNode[],
|
|
16
17
|
specs: Specs,
|
|
17
18
|
options: Options,
|
|
18
19
|
depth: number,
|
|
@@ -15,7 +15,9 @@ const utils_1 = require("./utils");
|
|
|
15
15
|
* @param depth
|
|
16
16
|
* @returns
|
|
17
17
|
*/
|
|
18
|
-
function order(contents,
|
|
18
|
+
function order(contents,
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
20
|
+
nodes, specs, options, depth) {
|
|
19
21
|
var _a, _b, _c, _d, _e;
|
|
20
22
|
const orderLog = debug_1.cmLog.extend(`order#${depth}`);
|
|
21
23
|
const btLog = debug_1.cmLog.extend(`backtrack#${depth}`);
|
|
@@ -27,7 +29,7 @@ function order(contents, nodes, specs, options, depth) {
|
|
|
27
29
|
let backtrackMode = false;
|
|
28
30
|
let afterBacktrack = false;
|
|
29
31
|
const unmatchedResults = [];
|
|
30
|
-
while (patterns.length && patterns[0]) {
|
|
32
|
+
while (patterns.length > 0 && patterns[0]) {
|
|
31
33
|
result = (0, complex_branch_1.complexBranch)(patterns[0], collection.unmatched, specs, options, depth);
|
|
32
34
|
collection.addMatched(result.matched);
|
|
33
35
|
if (result.type !== 'UNEXPECTED_EXTRA_NODE' && result.type !== 'MATCHED' && result.type !== 'MATCHED_ZERO') {
|
|
@@ -43,7 +45,7 @@ function order(contents, nodes, specs, options, depth) {
|
|
|
43
45
|
if (!barelyMatchedResult) {
|
|
44
46
|
throw new Error('Unreachable code');
|
|
45
47
|
}
|
|
46
|
-
orderLog('Result (%s): %s%s', result.type, collection.toString(true), ((_a = barelyMatchedResult.hint.missing) === null || _a === void 0 ? void 0 : _a.barelyMatchedElements)
|
|
48
|
+
orderLog('Result (%s): %s%s', result.type, collection.toString(true), ((_a = barelyMatchedResult.hint.missing) === null || _a === void 0 ? void 0 : _a.barelyMatchedElements) != null
|
|
47
49
|
? `; But ${barelyMatchedResult.hint.missing.barelyMatchedElements} elements hit out of pattern`
|
|
48
50
|
: '');
|
|
49
51
|
return {
|
|
@@ -72,7 +74,7 @@ function order(contents, nodes, specs, options, depth) {
|
|
|
72
74
|
}
|
|
73
75
|
patterns.shift();
|
|
74
76
|
}
|
|
75
|
-
if (collection.unmatched.length) {
|
|
77
|
+
if (collection.unmatched.length > 0) {
|
|
76
78
|
orderLog('Result (UNEXPECTED_EXTRA_NODE): %s', collection.toString(true));
|
|
77
79
|
return {
|
|
78
80
|
type: 'UNEXPECTED_EXTRA_NODE',
|
|
@@ -83,7 +85,7 @@ function order(contents, nodes, specs, options, depth) {
|
|
|
83
85
|
hint: (_c = result === null || result === void 0 ? void 0 : result.hint) !== null && _c !== void 0 ? _c : {},
|
|
84
86
|
};
|
|
85
87
|
}
|
|
86
|
-
const resultType = collection.matched.length ? 'MATCHED' : 'MATCHED_ZERO';
|
|
88
|
+
const resultType = collection.matched.length > 0 ? 'MATCHED' : 'MATCHED_ZERO';
|
|
87
89
|
orderLog('Result (%s): %s', resultType, collection.toString(true));
|
|
88
90
|
return {
|
|
89
91
|
type: resultType,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { SelectorResult } from './matches-selector';
|
|
2
2
|
import type { ChildNode, Options, Specs } from './types';
|
|
3
3
|
import type { PermittedContentPattern, Model } from '@markuplint/ml-spec';
|
|
4
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
4
5
|
export declare function recursiveBranch(
|
|
5
|
-
model: Model | PermittedContentPattern[]
|
|
6
|
+
model: ReadonlyDeep<Model | PermittedContentPattern[]>,
|
|
6
7
|
nodes: readonly ChildNode[],
|
|
7
8
|
specs: Specs,
|
|
8
9
|
options: Options,
|
|
@@ -4,17 +4,19 @@ exports.recursiveBranch = void 0;
|
|
|
4
4
|
const matches_selector_1 = require("./matches-selector");
|
|
5
5
|
const order_1 = require("./order");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
-
function recursiveBranch(model,
|
|
7
|
+
function recursiveBranch(model,
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
9
|
+
nodes, specs, options, depth) {
|
|
8
10
|
if (!(0, utils_1.isModel)(model)) {
|
|
9
11
|
return (0, order_1.order)(model, nodes, specs, options, depth + 1);
|
|
10
12
|
}
|
|
11
13
|
if (typeof model === 'string') {
|
|
12
|
-
return (0, matches_selector_1.matchesSelector)(model, nodes[0], specs,
|
|
14
|
+
return (0, matches_selector_1.matchesSelector)(model, nodes[0], specs, depth);
|
|
13
15
|
}
|
|
14
16
|
const collection = new utils_1.Collection(nodes);
|
|
15
17
|
let lastUnmatched = null;
|
|
16
18
|
for (const query of model) {
|
|
17
|
-
const result = (0, matches_selector_1.matchesSelector)(query, collection.unmatched[0], specs,
|
|
19
|
+
const result = (0, matches_selector_1.matchesSelector)(query, collection.unmatched[0], specs, depth);
|
|
18
20
|
collection.addMatched(result.matched);
|
|
19
21
|
if (result.type === 'MATCHED' || result.type === 'MATCHED_ZERO') {
|
|
20
22
|
return {
|
|
@@ -5,7 +5,9 @@ const ml_spec_1 = require("@markuplint/ml-spec");
|
|
|
5
5
|
const order_1 = require("./order");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
exports.transparentMode = new Map();
|
|
8
|
-
function representTransparentNodes(
|
|
8
|
+
function representTransparentNodes(
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
10
|
+
nodes, specs, options) {
|
|
9
11
|
var _a;
|
|
10
12
|
const result = [];
|
|
11
13
|
const errors = [];
|
|
@@ -31,7 +33,7 @@ function representTransparentNodes(nodes, specs, options) {
|
|
|
31
33
|
}
|
|
32
34
|
const collection = new utils_1.Collection((0, utils_1.getChildNodesWithoutWhitespaces)(node));
|
|
33
35
|
let unmatched;
|
|
34
|
-
if (noTransparentModels.length) {
|
|
36
|
+
if (noTransparentModels.length > 0) {
|
|
35
37
|
const result = (0, order_1.order)(noTransparentModels, collection.unmatched, specs, options, Infinity);
|
|
36
38
|
unmatched = result.unmatched;
|
|
37
39
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ContentModelResult, Element, Options, Specs } from './types';
|
|
2
2
|
import type { ContentModel } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
/**
|
|
4
5
|
* Check start
|
|
5
6
|
*
|
|
@@ -10,7 +11,7 @@ import type { ContentModel } from '@markuplint/ml-spec';
|
|
|
10
11
|
* @returns
|
|
11
12
|
*/
|
|
12
13
|
export declare function start(
|
|
13
|
-
contents: ContentModel['contents']
|
|
14
|
+
contents: ReadonlyDeep<ContentModel['contents']>,
|
|
14
15
|
el: Element,
|
|
15
16
|
specs: Specs,
|
|
16
17
|
options: Options,
|
|
@@ -13,10 +13,12 @@ const utils_1 = require("./utils");
|
|
|
13
13
|
* @param options
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
|
-
function start(contents,
|
|
16
|
+
function start(contents,
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
18
|
+
el, specs, options) {
|
|
17
19
|
var _a;
|
|
18
20
|
if (contents === false) {
|
|
19
|
-
if (el.childNodes.length) {
|
|
21
|
+
if (el.childNodes.length > 0) {
|
|
20
22
|
return [
|
|
21
23
|
{
|
|
22
24
|
type: 'NOTHING',
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { ChildNode,
|
|
2
|
-
export declare function transparent(nodes: ChildNode[]
|
|
1
|
+
import type { ChildNode, Result } from './types';
|
|
2
|
+
export declare function transparent(nodes: readonly ChildNode[]): Result;
|
|
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.transparent = void 0;
|
|
4
4
|
const debug_1 = require("./debug");
|
|
5
5
|
const transparentLog = debug_1.cmLog.extend('transparent');
|
|
6
|
-
function transparent(
|
|
6
|
+
function transparent(
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
|
+
nodes) {
|
|
7
9
|
var _a, _b;
|
|
8
10
|
if (nodes.length === 0 || ((_b = (_a = nodes[0]) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.parentElement)) {
|
|
9
11
|
transparentLog('Skipped');
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { Element as _Element, ChildNode as _ChildNode } from '@markuplint/ml-core';
|
|
2
2
|
import type { ContentModel, MLMLSpec } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
export type Element = _Element<TagRule[], Options>;
|
|
4
5
|
export type ChildNode = _ChildNode<TagRule[], Options>;
|
|
5
6
|
export type Specs = {
|
|
6
|
-
cites: MLMLSpec['cites'];
|
|
7
|
-
def: MLMLSpec['def'];
|
|
8
|
-
specs: {
|
|
9
|
-
name: string;
|
|
10
|
-
contentModel: {
|
|
11
|
-
contents: MLMLSpec['specs'][0]['contentModel']['contents'];
|
|
7
|
+
readonly cites: MLMLSpec['cites'];
|
|
8
|
+
readonly def: MLMLSpec['def'];
|
|
9
|
+
readonly specs: readonly {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly contentModel: {
|
|
12
|
+
readonly contents: MLMLSpec['specs'][0]['contentModel']['contents'];
|
|
12
13
|
};
|
|
13
14
|
}[];
|
|
14
15
|
};
|
|
@@ -44,8 +45,8 @@ export type TransparentModel = {
|
|
|
44
45
|
additionalCondition: string;
|
|
45
46
|
};
|
|
46
47
|
export type TagRule = {
|
|
47
|
-
tag: string;
|
|
48
|
-
} & ContentModel
|
|
48
|
+
readonly tag: string;
|
|
49
|
+
} & ReadonlyDeep<ContentModel>;
|
|
49
50
|
export type Options = {
|
|
50
|
-
ignoreHasMutableChildren: boolean;
|
|
51
|
+
readonly ignoreHasMutableChildren: boolean;
|
|
51
52
|
};
|