@markuplint/rules 3.0.0-dev.24 → 3.0.0-dev.290
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 +42 -38
- package/lib/attr-duplication/index.d.ts +1 -1
- package/lib/attr-duplication/index.js +3 -5
- package/lib/attr-value-quotes/index.d.ts +1 -1
- package/lib/attr-value-quotes/index.js +5 -9
- package/lib/case-sensitive-attr-name/index.d.ts +1 -1
- package/lib/case-sensitive-attr-name/index.js +9 -13
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/case-sensitive-tag-name/index.js +2 -4
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/character-reference/index.js +7 -9
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/class-naming/index.js +9 -13
- package/lib/create-message.d.ts +3 -2
- package/lib/create-message.js +15 -17
- package/lib/debug.js +2 -6
- package/lib/deprecated-attr/index.d.ts +1 -1
- package/lib/deprecated-attr/index.js +6 -9
- package/lib/deprecated-element/index.d.ts +1 -1
- package/lib/deprecated-element/index.js +5 -7
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/disallowed-element/index.js +2 -4
- package/lib/doctype/index.d.ts +1 -1
- package/lib/doctype/index.js +2 -4
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/end-tag/index.js +5 -8
- package/lib/helpers.d.ts +10 -13
- package/lib/helpers.js +39 -37
- package/lib/id-duplication/index.d.ts +1 -1
- package/lib/id-duplication/index.js +2 -4
- package/lib/index.d.ts +102 -3
- package/lib/index.js +64 -62
- package/lib/ineffective-attr/index.d.ts +1 -1
- package/lib/ineffective-attr/index.js +5 -10
- package/lib/invalid-attr/index.d.ts +25 -5
- package/lib/invalid-attr/index.js +166 -43
- package/lib/label-has-control/index.d.ts +1 -1
- package/lib/label-has-control/index.js +2 -4
- package/lib/landmark-roles/index.d.ts +1 -1
- package/lib/landmark-roles/index.js +10 -9
- package/lib/no-boolean-attr-value/index.d.ts +1 -1
- package/lib/no-boolean-attr-value/index.js +6 -9
- package/lib/no-default-value/index.d.ts +1 -1
- package/lib/no-default-value/index.js +9 -12
- package/lib/no-empty-palpable-content/index.d.ts +1 -1
- package/lib/no-empty-palpable-content/index.js +13 -7
- package/lib/no-hard-code-id/index.d.ts +1 -1
- package/lib/no-hard-code-id/index.js +2 -4
- package/lib/no-refer-to-non-existent-id/index.d.ts +4 -4
- package/lib/no-refer-to-non-existent-id/index.js +79 -23
- package/lib/no-use-event-handler-attr/index.d.ts +1 -1
- package/lib/no-use-event-handler-attr/index.js +4 -6
- package/lib/permitted-contents/choice.d.ts +3 -2
- package/lib/permitted-contents/choice.js +54 -14
- package/lib/permitted-contents/complex-branch.d.ts +3 -2
- package/lib/permitted-contents/complex-branch.js +12 -14
- package/lib/permitted-contents/content-model.d.ts +2 -2
- package/lib/permitted-contents/content-model.js +11 -11
- package/lib/permitted-contents/count-pattern.d.ts +3 -2
- package/lib/permitted-contents/count-pattern.js +76 -74
- package/lib/permitted-contents/debug.browser.js +9 -12
- package/lib/permitted-contents/debug.d.ts +8 -1
- package/lib/permitted-contents/debug.js +12 -13
- package/lib/permitted-contents/index.d.ts +2 -2
- package/lib/permitted-contents/index.js +18 -24
- package/lib/permitted-contents/matches-selector.d.ts +2 -2
- package/lib/permitted-contents/matches-selector.js +17 -20
- package/lib/permitted-contents/order.d.ts +3 -2
- package/lib/permitted-contents/order.js +33 -28
- package/lib/permitted-contents/recursive-branch.d.ts +4 -3
- package/lib/permitted-contents/recursive-branch.js +11 -13
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +1 -1
- package/lib/permitted-contents/represent-transparent-nodes.js +18 -21
- package/lib/permitted-contents/start.d.ts +3 -2
- package/lib/permitted-contents/start.js +16 -22
- package/lib/permitted-contents/transparent.d.ts +2 -2
- package/lib/permitted-contents/transparent.js +6 -9
- package/lib/permitted-contents/types.d.ts +20 -13
- package/lib/permitted-contents/types.js +1 -2
- package/lib/permitted-contents/utils.d.ts +27 -8
- package/lib/permitted-contents/utils.js +164 -65
- package/lib/placeholder-label-option/index.d.ts +2 -0
- package/lib/placeholder-label-option/index.js +84 -0
- package/lib/require-accessible-name/index.d.ts +1 -1
- package/lib/require-accessible-name/index.js +10 -13
- package/lib/require-datetime/index.d.ts +6 -0
- package/lib/require-datetime/index.js +32 -0
- package/lib/require-datetime/types.d.ts +10 -0
- package/lib/require-datetime/types.js +1 -0
- package/lib/require-datetime/utils.d.ts +11 -0
- package/lib/require-datetime/utils.js +130 -0
- package/lib/required-attr/index.d.ts +2 -2
- package/lib/required-attr/index.js +24 -24
- package/lib/required-element/index.d.ts +1 -1
- package/lib/required-element/index.js +3 -5
- package/lib/required-h1/index.d.ts +1 -1
- package/lib/required-h1/index.js +4 -6
- package/lib/use-list/index.d.ts +2 -2
- package/lib/use-list/index.js +7 -9
- package/lib/wai-aria/checkings/abstract-role.d.ts +1 -1
- package/lib/wai-aria/checkings/abstract-role.js +5 -10
- package/lib/wai-aria/checkings/default-value.d.ts +2 -2
- package/lib/wai-aria/checkings/default-value.js +2 -6
- package/lib/wai-aria/checkings/deprecated-props.d.ts +2 -2
- package/lib/wai-aria/checkings/deprecated-props.js +3 -8
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/disallowed-prop.js +27 -8
- package/lib/wai-aria/checkings/implicit-props.d.ts +3 -3
- package/lib/wai-aria/checkings/implicit-props.js +7 -11
- package/lib/wai-aria/checkings/implicit-role.d.ts +1 -1
- package/lib/wai-aria/checkings/implicit-role.js +4 -9
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +1 -1
- package/lib/wai-aria/checkings/interaction-in-hidden.js +7 -9
- package/lib/wai-aria/checkings/no-global-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/no-global-prop.js +2 -7
- package/lib/wai-aria/checkings/non-existent-role.d.ts +1 -1
- package/lib/wai-aria/checkings/non-existent-role.js +4 -9
- package/lib/wai-aria/checkings/permitted-roles.d.ts +1 -1
- package/lib/wai-aria/checkings/permitted-roles.js +4 -9
- package/lib/wai-aria/checkings/presentational-children.d.ts +1 -1
- package/lib/wai-aria/checkings/presentational-children.js +7 -10
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +1 -1
- package/lib/wai-aria/checkings/required-owned-elements.js +10 -12
- package/lib/wai-aria/checkings/required-prop.d.ts +2 -2
- package/lib/wai-aria/checkings/required-prop.js +2 -7
- package/lib/wai-aria/checkings/value.d.ts +3 -3
- package/lib/wai-aria/checkings/value.js +7 -11
- package/lib/wai-aria/index.d.ts +2 -2
- package/lib/wai-aria/index.js +38 -39
- package/lib/wai-aria/types.js +1 -2
- package/package.json +21 -14
- package/schema.json +6 -0
- package/tsconfig.test.json +0 -3
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
/// <reference types="debug" />
|
|
2
|
+
import color from 'ansi-colors';
|
|
2
3
|
export declare const cmLog: import("debug").Debugger;
|
|
3
|
-
export
|
|
4
|
+
export declare const bgGreen: color.StyleFunction;
|
|
5
|
+
export declare const green: color.StyleFunction;
|
|
6
|
+
export declare const bgRed: color.StyleFunction;
|
|
7
|
+
export declare const bgBlue: color.StyleFunction;
|
|
8
|
+
export declare const blue: color.StyleFunction;
|
|
9
|
+
export declare const bgMagenta: color.StyleFunction;
|
|
10
|
+
export declare const cyan: color.StyleFunction;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Object.defineProperty(exports, "cyan", { enumerable: true, get: function () { return ansi_colors_1.cyan; } });
|
|
1
|
+
import color from 'ansi-colors';
|
|
2
|
+
import { log } from '../debug.js';
|
|
3
|
+
export const cmLog = log.extend('content-model');
|
|
4
|
+
/* eslint-disable import/no-named-as-default-member */
|
|
5
|
+
export const bgGreen = color.bgGreen;
|
|
6
|
+
export const green = color.green;
|
|
7
|
+
export const bgRed = color.bgRed;
|
|
8
|
+
export const bgBlue = color.bgBlue;
|
|
9
|
+
export const blue = color.blue;
|
|
10
|
+
export const bgMagenta = color.bgMagenta;
|
|
11
|
+
export const cyan = color.cyan;
|
|
12
|
+
/* eslint-enable import/no-named-as-default-member */
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Options, TagRule } from './types';
|
|
2
|
-
declare const _default: import("@markuplint/ml-core").RuleSeed<TagRule[], Options
|
|
1
|
+
import type { Options, TagRule } from './types.js';
|
|
2
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<TagRule[], Options>>;
|
|
3
3
|
export default _default;
|
|
@@ -1,32 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
|
|
6
|
-
exports.default = (0, ml_core_1.createRule)({
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
import { contentModel } from './content-model.js';
|
|
3
|
+
import { transparentMode } from './represent-transparent-nodes.js';
|
|
4
|
+
export default createRule({
|
|
7
5
|
defaultValue: [],
|
|
8
6
|
defaultOptions: {
|
|
9
7
|
ignoreHasMutableChildren: true,
|
|
10
8
|
},
|
|
11
9
|
async verify({ document, report, t }) {
|
|
12
10
|
await document.walkOn('Element', el => {
|
|
13
|
-
var _a, _b, _c;
|
|
14
|
-
if (!el.rule.value) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
11
|
if (el.rule.options.ignoreHasMutableChildren && el.hasMutableChildren()) {
|
|
18
12
|
return;
|
|
19
13
|
}
|
|
20
|
-
const results =
|
|
14
|
+
const results = contentModel(el, el.rule.value, el.rule.options);
|
|
21
15
|
for (const { type, scope, query, hint } of results) {
|
|
22
16
|
let message = '';
|
|
23
|
-
if (hint) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
t('
|
|
27
|
-
|
|
28
|
-
t('the max number of elements required is {0}', `${hint.max}`);
|
|
29
|
-
}
|
|
17
|
+
if (hint.max != null) {
|
|
18
|
+
message =
|
|
19
|
+
t('there is more content than it needs') +
|
|
20
|
+
t('. ') +
|
|
21
|
+
t('the max number of elements required is {0}', `${hint.max}`);
|
|
30
22
|
}
|
|
31
23
|
switch (type) {
|
|
32
24
|
case 'MATCHED':
|
|
@@ -54,10 +46,10 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
54
46
|
break;
|
|
55
47
|
}
|
|
56
48
|
case 'UNEXPECTED_EXTRA_NODE': {
|
|
57
|
-
const not =
|
|
49
|
+
const not = hint.not ?? scope;
|
|
58
50
|
message =
|
|
59
51
|
message ||
|
|
60
|
-
(
|
|
52
|
+
(transparentMode.has(scope)
|
|
61
53
|
? t('{0} is not allowed in {1} through the transparent model in this context', name(not, t), name(el, t))
|
|
62
54
|
: t('{0} is not allowed in {1} in this context', name(not, t), name(el, t)));
|
|
63
55
|
report({
|
|
@@ -67,8 +59,8 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
67
59
|
break;
|
|
68
60
|
}
|
|
69
61
|
case 'TRANSPARENT_MODEL_DISALLOWS': {
|
|
70
|
-
const not =
|
|
71
|
-
const tp =
|
|
62
|
+
const not = hint.not ?? scope;
|
|
63
|
+
const tp = hint.transparent ?? el;
|
|
72
64
|
report({
|
|
73
65
|
scope: not,
|
|
74
66
|
message: t('{0} is {1} but {2}', name(tp, t), t('a {0}', 'transparent model'), t('also disallows {0} in this context', name(not, t))),
|
|
@@ -87,11 +79,13 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
87
79
|
}
|
|
88
80
|
}
|
|
89
81
|
}
|
|
90
|
-
|
|
82
|
+
transparentMode.clear();
|
|
91
83
|
});
|
|
92
84
|
},
|
|
93
85
|
});
|
|
94
|
-
function name(
|
|
86
|
+
function name(
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
88
|
+
scope, t) {
|
|
95
89
|
if (scope.is(scope.ELEMENT_NODE)) {
|
|
96
90
|
return t('the "{0}" {1}', scope.localName, 'element');
|
|
97
91
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { ChildNode,
|
|
1
|
+
import type { ChildNode, Result, Specs } from './types.js';
|
|
2
2
|
export type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
|
|
3
|
-
export declare function matchesSelector(query: string, node: ChildNode | undefined, specs: Specs,
|
|
3
|
+
export declare function matchesSelector(query: string, node: ChildNode | undefined, specs: Specs, depth: number): SelectorResult;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const nodeLog = debug_1.cmLog.extend(`node#${depth}`);
|
|
1
|
+
import { contentModelCategoryToTagNames } from '@markuplint/ml-spec';
|
|
2
|
+
import { cmLog } from './debug.js';
|
|
3
|
+
import { cleanObject, matches } from './utils.js';
|
|
4
|
+
export function matchesSelector(query,
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
|
+
node, specs, depth) {
|
|
7
|
+
const nodeLog = cmLog.extend(`node#${depth}`);
|
|
9
8
|
const { selector, hasText, hasCustom } = optCondition(query, specs);
|
|
10
9
|
if (node == null) {
|
|
11
10
|
if (hasText) {
|
|
12
11
|
nodeLog('<#text>.matches(%s) => ""', query);
|
|
13
12
|
return {
|
|
14
13
|
type: 'MATCHED_ZERO',
|
|
15
|
-
matched:
|
|
14
|
+
matched: [],
|
|
16
15
|
unmatched: [],
|
|
17
16
|
zeroMatch: true,
|
|
18
17
|
query,
|
|
@@ -84,7 +83,7 @@ function matchesSelector(query, node, specs, options, depth) {
|
|
|
84
83
|
hint: {},
|
|
85
84
|
};
|
|
86
85
|
}
|
|
87
|
-
const result =
|
|
86
|
+
const result = matches(selector, node, specs);
|
|
88
87
|
nodeLog('%s.matches(%s) => %s', node.raw, query, result.matched);
|
|
89
88
|
if (result.matched) {
|
|
90
89
|
return {
|
|
@@ -103,9 +102,9 @@ function matchesSelector(query, node, specs, options, depth) {
|
|
|
103
102
|
unmatched: [node],
|
|
104
103
|
zeroMatch: true,
|
|
105
104
|
query,
|
|
106
|
-
hint: {
|
|
105
|
+
hint: cleanObject({
|
|
107
106
|
not: result.not,
|
|
108
|
-
},
|
|
107
|
+
}),
|
|
109
108
|
};
|
|
110
109
|
}
|
|
111
110
|
return {
|
|
@@ -114,9 +113,9 @@ function matchesSelector(query, node, specs, options, depth) {
|
|
|
114
113
|
unmatched: [node],
|
|
115
114
|
zeroMatch: false,
|
|
116
115
|
query,
|
|
117
|
-
hint: {
|
|
116
|
+
hint: cleanObject({
|
|
118
117
|
not: result.not,
|
|
119
|
-
},
|
|
118
|
+
}),
|
|
120
119
|
};
|
|
121
120
|
}
|
|
122
121
|
return {
|
|
@@ -128,7 +127,6 @@ function matchesSelector(query, node, specs, options, depth) {
|
|
|
128
127
|
hint: {},
|
|
129
128
|
};
|
|
130
129
|
}
|
|
131
|
-
exports.matchesSelector = matchesSelector;
|
|
132
130
|
const conditionWithoutSpecs = {
|
|
133
131
|
'#custom': {
|
|
134
132
|
selector: '#custom',
|
|
@@ -143,12 +141,11 @@ const conditionWithoutSpecs = {
|
|
|
143
141
|
};
|
|
144
142
|
const optConditionSpecsBaseCaches = new Map();
|
|
145
143
|
function optCondition(query, specs) {
|
|
146
|
-
var _a;
|
|
147
144
|
const condWithoutSpecs = conditionWithoutSpecs[query];
|
|
148
145
|
if (condWithoutSpecs) {
|
|
149
146
|
return condWithoutSpecs;
|
|
150
147
|
}
|
|
151
|
-
const queryCaches =
|
|
148
|
+
const queryCaches = optConditionSpecsBaseCaches.get(specs) ?? new Map();
|
|
152
149
|
const cached = queryCaches.get(query);
|
|
153
150
|
if (cached) {
|
|
154
151
|
return cached;
|
|
@@ -156,9 +153,9 @@ function optCondition(query, specs) {
|
|
|
156
153
|
let hasCustom = false;
|
|
157
154
|
let hasText = false;
|
|
158
155
|
const selector = query.replace(/^(?::model\(([^)]+)\)|#([a-z-]+))(.*)$/, (_, $model, _model, $last) => {
|
|
159
|
-
const _selectors =
|
|
156
|
+
const _selectors = contentModelCategoryToTagNames(`#${$model ?? _model}`, specs.def);
|
|
160
157
|
if (_selectors.length === 0) {
|
|
161
|
-
throw new Error(`${$model
|
|
158
|
+
throw new Error(`${$model ?? _model} is empty`);
|
|
162
159
|
}
|
|
163
160
|
const selectors = [];
|
|
164
161
|
for (const selector of _selectors) {
|
|
@@ -172,7 +169,7 @@ function optCondition(query, specs) {
|
|
|
172
169
|
}
|
|
173
170
|
selectors.push(selector);
|
|
174
171
|
}
|
|
175
|
-
return `:is(${selectors.join(',')})${$last
|
|
172
|
+
return `:is(${selectors.join(',')})${$last ?? ''}`;
|
|
176
173
|
});
|
|
177
174
|
const result = {
|
|
178
175
|
selector,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { ChildNode, Options, Result, Specs } from './types';
|
|
1
|
+
import type { ChildNode, Options, Result, Specs } from './types.js';
|
|
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
|
*
|
|
@@ -10,4 +11,4 @@ import type { PermittedContentPattern } from '@markuplint/ml-spec';
|
|
|
10
11
|
* @param depth
|
|
11
12
|
* @returns
|
|
12
13
|
*/
|
|
13
|
-
export declare function order(contents:
|
|
14
|
+
export declare function order(contents: ReadonlyDeep<PermittedContentPattern[]>, nodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): Result;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const complex_branch_1 = require("./complex-branch");
|
|
6
|
-
const debug_1 = require("./debug");
|
|
7
|
-
const utils_1 = require("./utils");
|
|
1
|
+
import { deepCopy } from '../helpers.js';
|
|
2
|
+
import { complexBranch } from './complex-branch.js';
|
|
3
|
+
import { cmLog } from './debug.js';
|
|
4
|
+
import { Collection, mergeHints, modelLog } from './utils.js';
|
|
8
5
|
/**
|
|
9
6
|
* Check ordered array
|
|
10
7
|
*
|
|
@@ -15,42 +12,50 @@ const utils_1 = require("./utils");
|
|
|
15
12
|
* @param depth
|
|
16
13
|
* @returns
|
|
17
14
|
*/
|
|
18
|
-
function order(contents,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
15
|
+
export function order(contents,
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
17
|
+
nodes, specs, options, depth) {
|
|
18
|
+
const orderLog = cmLog.extend(`order#${depth}`);
|
|
19
|
+
const btLog = cmLog.extend(`backtrack#${depth}`);
|
|
20
|
+
const patterns = deepCopy(contents);
|
|
21
|
+
const collection = new Collection(nodes);
|
|
22
|
+
orderLog('Model:\n RegEx: %s\n Schema: %o', modelLog(patterns, ''), patterns);
|
|
24
23
|
orderLog('Starts: %s', collection);
|
|
25
24
|
let result = undefined;
|
|
26
25
|
let backtrackMode = false;
|
|
27
26
|
let afterBacktrack = false;
|
|
28
27
|
const unmatchedResults = [];
|
|
29
|
-
while (patterns.length) {
|
|
30
|
-
result =
|
|
28
|
+
while (patterns.length > 0 && patterns[0]) {
|
|
29
|
+
result = complexBranch(patterns[0], collection.unmatched, specs, options, depth);
|
|
31
30
|
collection.addMatched(result.matched);
|
|
32
|
-
orderLog('stack: %s', collection);
|
|
33
31
|
if (result.type !== 'UNEXPECTED_EXTRA_NODE' && result.type !== 'MATCHED' && result.type !== 'MATCHED_ZERO') {
|
|
34
32
|
unmatchedResults.push(result);
|
|
35
33
|
if (backtrackMode) {
|
|
36
34
|
collection.back();
|
|
37
|
-
btLog('
|
|
35
|
+
btLog('🔙◀BACK');
|
|
38
36
|
backtrackMode = false;
|
|
39
37
|
afterBacktrack = true;
|
|
40
38
|
continue;
|
|
41
39
|
}
|
|
42
|
-
orderLog('conformed (%s): %s', result.type, collection.toString(true));
|
|
43
40
|
const barelyMatchedResult = unmatchedResults.sort((a, b) => b.matched.length - a.matched.length)[0];
|
|
44
41
|
if (!barelyMatchedResult) {
|
|
45
42
|
throw new Error('Unreachable code');
|
|
46
43
|
}
|
|
44
|
+
orderLog('Result (%s): %s%s', result.type, collection.toString(true), barelyMatchedResult.hint.missing?.barelyMatchedElements != null
|
|
45
|
+
? `; But ${barelyMatchedResult.hint.missing.barelyMatchedElements} elements hit out of pattern`
|
|
46
|
+
: '');
|
|
47
47
|
return {
|
|
48
48
|
type: barelyMatchedResult.type,
|
|
49
49
|
matched: collection.matched,
|
|
50
50
|
unmatched: collection.unmatched,
|
|
51
51
|
zeroMatch: barelyMatchedResult.zeroMatch,
|
|
52
52
|
query: barelyMatchedResult.query,
|
|
53
|
-
hint: barelyMatchedResult.hint,
|
|
53
|
+
hint: mergeHints(barelyMatchedResult.hint, {
|
|
54
|
+
missing: {
|
|
55
|
+
barelyMatchedElements: collection.matched.length,
|
|
56
|
+
need: barelyMatchedResult.query,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
54
59
|
};
|
|
55
60
|
}
|
|
56
61
|
if (afterBacktrack) {
|
|
@@ -65,25 +70,25 @@ function order(contents, nodes, specs, options, depth) {
|
|
|
65
70
|
}
|
|
66
71
|
patterns.shift();
|
|
67
72
|
}
|
|
68
|
-
if (collection.unmatched.length) {
|
|
69
|
-
orderLog('
|
|
73
|
+
if (collection.unmatched.length > 0) {
|
|
74
|
+
orderLog('Result (UNEXPECTED_EXTRA_NODE): %s', collection.toString(true));
|
|
70
75
|
return {
|
|
71
76
|
type: 'UNEXPECTED_EXTRA_NODE',
|
|
72
77
|
matched: collection.matched,
|
|
73
78
|
unmatched: collection.unmatched,
|
|
74
79
|
zeroMatch: false,
|
|
75
|
-
query:
|
|
76
|
-
hint:
|
|
80
|
+
query: result?.query ?? 'N/A',
|
|
81
|
+
hint: result?.hint ?? {},
|
|
77
82
|
};
|
|
78
83
|
}
|
|
79
|
-
|
|
84
|
+
const resultType = collection.matched.length > 0 ? 'MATCHED' : 'MATCHED_ZERO';
|
|
85
|
+
orderLog('Result (%s): %s', resultType, collection.toString(true));
|
|
80
86
|
return {
|
|
81
|
-
type:
|
|
87
|
+
type: resultType,
|
|
82
88
|
matched: collection.matched,
|
|
83
89
|
unmatched: collection.unmatched,
|
|
84
90
|
zeroMatch: false,
|
|
85
|
-
query:
|
|
86
|
-
hint:
|
|
91
|
+
query: result?.query ?? 'N/A',
|
|
92
|
+
hint: result?.hint ?? {},
|
|
87
93
|
};
|
|
88
94
|
}
|
|
89
|
-
exports.order = order;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { SelectorResult } from './matches-selector';
|
|
2
|
-
import type { ChildNode, Options, Specs } from './types';
|
|
1
|
+
import type { SelectorResult } from './matches-selector.js';
|
|
2
|
+
import type { ChildNode, Options, Specs } from './types.js';
|
|
3
3
|
import type { PermittedContentPattern, Model } from '@markuplint/ml-spec';
|
|
4
|
-
|
|
4
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
5
|
+
export declare function recursiveBranch(model: ReadonlyDeep<Model | PermittedContentPattern[]>, nodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): SelectorResult;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return (0, order_1.order)(model, nodes, specs, options, depth + 1);
|
|
1
|
+
import { matchesSelector } from './matches-selector.js';
|
|
2
|
+
import { order } from './order.js';
|
|
3
|
+
import { Collection, isModel } from './utils.js';
|
|
4
|
+
export function recursiveBranch(model,
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
|
+
nodes, specs, options, depth) {
|
|
7
|
+
if (!isModel(model)) {
|
|
8
|
+
return order(model, nodes, specs, options, depth + 1);
|
|
10
9
|
}
|
|
11
10
|
if (typeof model === 'string') {
|
|
12
|
-
return
|
|
11
|
+
return matchesSelector(model, nodes[0], specs, depth);
|
|
13
12
|
}
|
|
14
|
-
const collection = new
|
|
13
|
+
const collection = new Collection(nodes);
|
|
15
14
|
let lastUnmatched = null;
|
|
16
15
|
for (const query of model) {
|
|
17
|
-
const result =
|
|
16
|
+
const result = matchesSelector(query, collection.unmatched[0], specs, depth);
|
|
18
17
|
collection.addMatched(result.matched);
|
|
19
18
|
if (result.type === 'MATCHED' || result.type === 'MATCHED_ZERO') {
|
|
20
19
|
return {
|
|
@@ -40,4 +39,3 @@ function recursiveBranch(model, nodes, specs, options, depth) {
|
|
|
40
39
|
}
|
|
41
40
|
return lastUnmatched;
|
|
42
41
|
}
|
|
43
|
-
exports.recursiveBranch = recursiveBranch;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChildNode, Options, Result, Specs } from './types';
|
|
1
|
+
import type { ChildNode, Options, Result, Specs } from './types.js';
|
|
2
2
|
export declare const transparentMode: Map<ChildNode, true>;
|
|
3
3
|
export declare function representTransparentNodes(nodes: ChildNode[], specs: Specs, options: Options): {
|
|
4
4
|
nodes: ChildNode[];
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function representTransparentNodes(nodes, specs, options) {
|
|
9
|
-
var _a;
|
|
1
|
+
import { getContentModel } from '@markuplint/ml-spec';
|
|
2
|
+
import { order } from './order.js';
|
|
3
|
+
import { Collection, getChildNodesWithoutWhitespaces, isTransparent, matches } from './utils.js';
|
|
4
|
+
export const transparentMode = new Map();
|
|
5
|
+
export function representTransparentNodes(
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
7
|
+
nodes, specs, options) {
|
|
10
8
|
const result = [];
|
|
11
9
|
const errors = [];
|
|
12
|
-
const parent =
|
|
10
|
+
const parent = nodes[0]?.parentElement;
|
|
13
11
|
if (parent) {
|
|
14
12
|
const { errors: parentErrors } = representTransparentNodes([parent], specs, options);
|
|
15
13
|
errors.push(...parentErrors);
|
|
@@ -19,37 +17,37 @@ function representTransparentNodes(nodes, specs, options) {
|
|
|
19
17
|
result.push(node);
|
|
20
18
|
continue;
|
|
21
19
|
}
|
|
22
|
-
const models =
|
|
20
|
+
const models = getContentModel(node, specs.specs);
|
|
23
21
|
if (models == null || typeof models === 'boolean') {
|
|
24
22
|
result.push(node);
|
|
25
23
|
continue;
|
|
26
24
|
}
|
|
27
|
-
const noTransparentModels = models.filter(m => !
|
|
25
|
+
const noTransparentModels = models.filter(m => !isTransparent(m));
|
|
28
26
|
if (noTransparentModels.length === models.length) {
|
|
29
27
|
result.push(node);
|
|
30
28
|
continue;
|
|
31
29
|
}
|
|
32
|
-
const collection = new
|
|
30
|
+
const collection = new Collection(getChildNodesWithoutWhitespaces(node));
|
|
33
31
|
let unmatched;
|
|
34
|
-
if (noTransparentModels.length) {
|
|
35
|
-
const result =
|
|
32
|
+
if (noTransparentModels.length > 0) {
|
|
33
|
+
const result = order(noTransparentModels, collection.unmatched, specs, options, Infinity);
|
|
36
34
|
unmatched = result.unmatched;
|
|
37
35
|
}
|
|
38
36
|
else {
|
|
39
37
|
unmatched = collection.unmatched;
|
|
40
38
|
}
|
|
41
|
-
const transparent = models.find(m =>
|
|
42
|
-
if (!transparent || !
|
|
39
|
+
const transparent = models.find(m => isTransparent(m));
|
|
40
|
+
if (!transparent || !isTransparent(transparent)) {
|
|
43
41
|
throw new Error('Unreachable code');
|
|
44
42
|
}
|
|
45
43
|
for (const _child of unmatched) {
|
|
46
44
|
const child = _child;
|
|
47
|
-
if (
|
|
45
|
+
if (transparentMode.has(child)) {
|
|
48
46
|
continue;
|
|
49
47
|
}
|
|
50
|
-
|
|
48
|
+
transparentMode.set(child, true);
|
|
51
49
|
if (child.is(child.ELEMENT_NODE)) {
|
|
52
|
-
const transparentCondMatched =
|
|
50
|
+
const transparentCondMatched = matches(transparent.transparent, child, specs);
|
|
53
51
|
if (!transparentCondMatched.matched) {
|
|
54
52
|
errors.push({
|
|
55
53
|
type: 'TRANSPARENT_MODEL_DISALLOWS',
|
|
@@ -73,4 +71,3 @@ function representTransparentNodes(nodes, specs, options) {
|
|
|
73
71
|
errors,
|
|
74
72
|
};
|
|
75
73
|
}
|
|
76
|
-
exports.representTransparentNodes = representTransparentNodes;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { ContentModelResult, Element, Options, Specs } from './types';
|
|
1
|
+
import type { ContentModelResult, Element, Options, Specs } from './types.js';
|
|
2
2
|
import type { ContentModel } from '@markuplint/ml-spec';
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
4
|
/**
|
|
4
5
|
* Check start
|
|
5
6
|
*
|
|
@@ -9,4 +10,4 @@ import type { ContentModel } from '@markuplint/ml-spec';
|
|
|
9
10
|
* @param options
|
|
10
11
|
* @returns
|
|
11
12
|
*/
|
|
12
|
-
export declare function start(contents: ContentModel['contents']
|
|
13
|
+
export declare function start(contents: ReadonlyDeep<ContentModel['contents']>, el: Element, specs: Specs, options: Options): ContentModelResult[];
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const order_1 = require("./order");
|
|
5
|
-
const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
1
|
+
import { order } from './order.js';
|
|
2
|
+
import { representTransparentNodes } from './represent-transparent-nodes.js';
|
|
3
|
+
import { getChildNodesWithoutWhitespaces } from './utils.js';
|
|
7
4
|
/**
|
|
8
5
|
* Check start
|
|
9
6
|
*
|
|
@@ -13,10 +10,11 @@ const utils_1 = require("./utils");
|
|
|
13
10
|
* @param options
|
|
14
11
|
* @returns
|
|
15
12
|
*/
|
|
16
|
-
function start(contents,
|
|
17
|
-
|
|
13
|
+
export function start(contents,
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
15
|
+
el, specs, options) {
|
|
18
16
|
if (contents === false) {
|
|
19
|
-
if (el.childNodes.length) {
|
|
17
|
+
if (el.childNodes.length > 0) {
|
|
20
18
|
return [
|
|
21
19
|
{
|
|
22
20
|
type: 'NOTHING',
|
|
@@ -46,26 +44,22 @@ function start(contents, el, specs, options) {
|
|
|
46
44
|
},
|
|
47
45
|
];
|
|
48
46
|
}
|
|
49
|
-
const { nodes, errors } =
|
|
50
|
-
const result =
|
|
47
|
+
const { nodes, errors } = representTransparentNodes(getChildNodesWithoutWhitespaces(el), specs, options);
|
|
48
|
+
const result = order(contents, nodes, specs, options, 0);
|
|
51
49
|
return [
|
|
52
50
|
{
|
|
53
51
|
type: result.type,
|
|
54
52
|
scope: result.type === 'MISSING_NODE_REQUIRED' || result.type === 'MISSING_NODE_ONE_OR_MORE'
|
|
55
53
|
? el
|
|
56
|
-
:
|
|
54
|
+
: result.unmatched[0] ?? el,
|
|
57
55
|
query: result.query,
|
|
58
56
|
hint: result.hint,
|
|
59
57
|
},
|
|
60
|
-
...errors.map(error => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
hint: error.hint,
|
|
67
|
-
});
|
|
68
|
-
}),
|
|
58
|
+
...errors.map(error => ({
|
|
59
|
+
type: error.type,
|
|
60
|
+
scope: error.unmatched[0] ?? el,
|
|
61
|
+
query: error.query,
|
|
62
|
+
hint: error.hint,
|
|
63
|
+
})),
|
|
69
64
|
];
|
|
70
65
|
}
|
|
71
|
-
exports.start = start;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { ChildNode,
|
|
2
|
-
export declare function transparent(nodes: ChildNode[]
|
|
1
|
+
import type { ChildNode, Result } from './types.js';
|
|
2
|
+
export declare function transparent(nodes: readonly ChildNode[]): Result;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var _a;
|
|
8
|
-
if (nodes.length === 0 || ((_a = nodes[0].parentElement) === null || _a === void 0 ? void 0 : _a.parentElement)) {
|
|
1
|
+
import { cmLog } from './debug.js';
|
|
2
|
+
const transparentLog = cmLog.extend('transparent');
|
|
3
|
+
export function transparent(
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
5
|
+
nodes) {
|
|
6
|
+
if (nodes.length === 0 || nodes[0]?.parentElement?.parentElement) {
|
|
9
7
|
transparentLog('Skipped');
|
|
10
8
|
return {
|
|
11
9
|
type: nodes.length === 0 ? 'MATCHED_ZERO' : 'MATCHED',
|
|
@@ -26,4 +24,3 @@ function transparent(nodes, specs, options, depth) {
|
|
|
26
24
|
hint: {},
|
|
27
25
|
};
|
|
28
26
|
}
|
|
29
|
-
exports.transparent = transparent;
|