@markuplint/rules 3.0.0-alpha.0 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +1 -1
  2. package/lib/attr-check.js +1 -1
  3. package/lib/attr-duplication/index.js +1 -1
  4. package/lib/attr-value-quotes/index.js +1 -1
  5. package/lib/case-sensitive-attr-name/index.js +3 -3
  6. package/lib/case-sensitive-tag-name/index.js +3 -3
  7. package/lib/class-naming/index.js +1 -1
  8. package/lib/create-message.d.ts +1 -1
  9. package/lib/create-message.js +5 -5
  10. package/lib/deprecated-element/index.js +2 -2
  11. package/lib/doctype/index.d.ts +1 -1
  12. package/lib/doctype/index.js +1 -1
  13. package/lib/end-tag/index.js +1 -1
  14. package/lib/helpers.d.ts +7 -2
  15. package/lib/helpers.js +17 -11
  16. package/lib/index.d.ts +2 -6
  17. package/lib/ineffective-attr/index.js +1 -1
  18. package/lib/invalid-attr/index.js +3 -3
  19. package/lib/landmark-roles/index.js +1 -1
  20. package/lib/no-boolean-attr-value/index.js +1 -1
  21. package/lib/no-default-value/index.js +1 -1
  22. package/lib/no-hard-code-id/index.js +1 -1
  23. package/lib/no-use-event-handler-attr/index.js +2 -2
  24. package/lib/permitted-contents/choice.d.ts +3 -0
  25. package/lib/permitted-contents/choice.js +37 -0
  26. package/lib/permitted-contents/complex-branch.d.ts +13 -0
  27. package/lib/permitted-contents/complex-branch.js +27 -0
  28. package/lib/permitted-contents/content-model.d.ts +2 -0
  29. package/lib/permitted-contents/content-model.js +49 -0
  30. package/lib/permitted-contents/count-pattern.d.ts +13 -0
  31. package/lib/permitted-contents/count-pattern.js +155 -0
  32. package/lib/permitted-contents/debug.d.ts +2 -0
  33. package/lib/permitted-contents/debug.js +5 -0
  34. package/lib/permitted-contents/index.d.ts +1 -7
  35. package/lib/permitted-contents/index.js +75 -245
  36. package/lib/permitted-contents/matches-selector.d.ts +3 -0
  37. package/lib/permitted-contents/matches-selector.js +185 -0
  38. package/lib/permitted-contents/order.d.ts +13 -0
  39. package/lib/permitted-contents/order.js +89 -0
  40. package/lib/permitted-contents/recursive-branch.d.ts +4 -0
  41. package/lib/permitted-contents/recursive-branch.js +43 -0
  42. package/lib/permitted-contents/represent-transparent-nodes.d.ts +6 -0
  43. package/lib/permitted-contents/represent-transparent-nodes.js +79 -0
  44. package/lib/permitted-contents/start.d.ts +12 -0
  45. package/lib/permitted-contents/start.js +71 -0
  46. package/lib/permitted-contents/transparent.d.ts +2 -0
  47. package/lib/permitted-contents/transparent.js +34 -0
  48. package/lib/permitted-contents/types.d.ts +45 -0
  49. package/lib/permitted-contents/types.js +2 -0
  50. package/lib/permitted-contents/utils.d.ts +32 -0
  51. package/lib/permitted-contents/utils.js +184 -0
  52. package/lib/require-accessible-name/index.js +5 -1
  53. package/lib/required-attr/index.js +1 -1
  54. package/lib/use-list/index.js +2 -2
  55. package/lib/wai-aria/checkings/implicit-role.js +2 -2
  56. package/lib/wai-aria/index.js +1 -1
  57. package/package.json +8 -7
  58. package/tsconfig.tsbuildinfo +1 -1
  59. package/lib/__foo/index.d.ts +0 -2
  60. package/lib/__foo/index.js +0 -46
  61. package/lib/attr-equal-space-after/index.d.ts +0 -3
  62. package/lib/attr-equal-space-after/index.js +0 -90
  63. package/lib/attr-equal-space-before/index.d.ts +0 -3
  64. package/lib/attr-equal-space-before/index.js +0 -90
  65. package/lib/attr-spacing/index.d.ts +0 -6
  66. package/lib/attr-spacing/index.js +0 -100
  67. package/lib/helper/aria/get-aria.d.ts +0 -7
  68. package/lib/helper/aria/get-aria.js +0 -53
  69. package/lib/helper/aria/get-computed-role.d.ts +0 -10
  70. package/lib/helper/aria/get-computed-role.js +0 -24
  71. package/lib/helper/aria/get-implicit-role.d.ts +0 -7
  72. package/lib/helper/aria/get-implicit-role.js +0 -12
  73. package/lib/helper/aria/get-permitted-roles.d.ts +0 -14
  74. package/lib/helper/aria/get-permitted-roles.js +0 -26
  75. package/lib/helper/aria/resolve-version.d.ts +0 -2
  76. package/lib/helper/aria/resolve-version.js +0 -21
  77. package/lib/helper/spec/aria-spec.d.ts +0 -5
  78. package/lib/helper/spec/aria-spec.js +0 -12
  79. package/lib/helper/spec/get-role-spec.d.ts +0 -11
  80. package/lib/helper/spec/get-role-spec.js +0 -39
  81. package/lib/helper/spec/html-spec.d.ts +0 -2
  82. package/lib/helper/spec/html-spec.js +0 -14
  83. package/lib/indentation/index.d.ts +0 -7
  84. package/lib/indentation/index.js +0 -208
  85. package/lib/permitted-contents/array.combination.d.ts +0 -1
  86. package/lib/permitted-contents/array.combination.js +0 -33
  87. package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +0 -11
  88. package/lib/permitted-contents/permitted-content.spec-to-regexp.js +0 -230
  89. package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +0 -2
  90. package/lib/permitted-contents/unfold-content-models-to-tags.js +0 -8
  91. package/lib/wai-aria/checkings/checking-required-owned-elements.d.ts +0 -11
  92. package/lib/wai-aria/checkings/checking-required-owned-elements.js +0 -63
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.countPattern = void 0;
4
+ const debug_1 = require("./debug");
5
+ const recursive_branch_1 = require("./recursive-branch");
6
+ const utils_1 = require("./utils");
7
+ /**
8
+ * Check count
9
+ *
10
+ * @param pattern
11
+ * @param elements
12
+ * @param specs
13
+ * @param options
14
+ * @param depth
15
+ * @returns
16
+ */
17
+ function countPattern(pattern, elements, specs, options, depth) {
18
+ var _a, _b, _c, _d, _e;
19
+ const ptLog = debug_1.cmLog.extend(`countPattern#${depth}`);
20
+ const collection = new utils_1.Collection(elements);
21
+ let min;
22
+ let max;
23
+ let model;
24
+ let type;
25
+ let _type;
26
+ if ((0, utils_1.isRequire)(pattern)) {
27
+ min = (_a = pattern.min) !== null && _a !== void 0 ? _a : 1;
28
+ max = Math.max((_b = pattern.max) !== null && _b !== void 0 ? _b : 1, min);
29
+ model = pattern.require;
30
+ type = 'MISSING_NODE_REQUIRED';
31
+ _type = 'require';
32
+ }
33
+ else if ((0, utils_1.isOptional)(pattern)) {
34
+ min = 0;
35
+ max = Math.max((_c = pattern.max) !== null && _c !== void 0 ? _c : 1, 1);
36
+ model = pattern.optional;
37
+ _type = 'optional';
38
+ }
39
+ else if ((0, utils_1.isOneOrMore)(pattern)) {
40
+ min = 1;
41
+ max = Math.max((_d = pattern.max) !== null && _d !== void 0 ? _d : Infinity, 1);
42
+ model = pattern.oneOrMore;
43
+ type = 'MISSING_NODE_ONE_OR_MORE';
44
+ _type = 'one or more';
45
+ }
46
+ else if ((0, utils_1.isZeroOrMore)(pattern)) {
47
+ min = 0;
48
+ max = Math.max((_e = pattern.max) !== null && _e !== void 0 ? _e : Infinity, 1);
49
+ model = pattern.zeroOrMore;
50
+ _type = 'zero or more';
51
+ }
52
+ else {
53
+ throw new Error('Unreachable code');
54
+ }
55
+ ptLog('%s: %o', _type, model);
56
+ let prevResult = null;
57
+ // eslint-disable-next-line no-constant-condition
58
+ while (true) {
59
+ ptLog('%s', collection);
60
+ const result = (0, recursive_branch_1.recursiveBranch)(model, collection.unmatched, specs, options, depth);
61
+ const added = collection.addMatched(result.matched);
62
+ if (result.type === 'UNMATCHED_SELECTOR_BUT_MAY_EMPTY') {
63
+ ptLog('MATCHED_ZERO: %s', result.query);
64
+ return {
65
+ type: 'MATCHED_ZERO',
66
+ matched: collection.matched,
67
+ unmatched: collection.unmatched,
68
+ zeroMatch: true,
69
+ query: result.query,
70
+ hint: result.hint,
71
+ };
72
+ }
73
+ if (max < collection.matchedCount) {
74
+ collection.max(max);
75
+ ptLog('UNEXPECTED_EXTRA_NODE (max: %s): %s', max, result.query);
76
+ return {
77
+ type: 'UNEXPECTED_EXTRA_NODE',
78
+ matched: collection.matched,
79
+ unmatched: collection.unmatched,
80
+ zeroMatch: result.zeroMatch,
81
+ query: result.query,
82
+ hint: {
83
+ ...result.hint,
84
+ max,
85
+ },
86
+ };
87
+ }
88
+ if (prevResult) {
89
+ if (result.type === 'MISSING_NODE_ONE_OR_MORE' ||
90
+ result.type === 'MISSING_NODE_REQUIRED' ||
91
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS') {
92
+ ptLog('%s(continued): %s', result.type, collection);
93
+ return {
94
+ type: result.type,
95
+ matched: collection.matched,
96
+ unmatched: collection.unmatched,
97
+ zeroMatch: result.zeroMatch,
98
+ query: result.query,
99
+ hint: result.hint,
100
+ };
101
+ }
102
+ ptLog('%s(continued): %s', prevResult.type, collection);
103
+ return prevResult;
104
+ }
105
+ if (added && collection.unmatched.length > 0) {
106
+ continue;
107
+ }
108
+ if (collection.matchedCount + (result.zeroMatch ? 1 : 0) < min) {
109
+ const resultType = result.type === 'MISSING_NODE_REQUIRED' ||
110
+ result.type === 'MISSING_NODE_ONE_OR_MORE' ||
111
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS'
112
+ ? result.type
113
+ : type !== null && type !== void 0 ? type : 'MISSING_NODE_REQUIRED';
114
+ ptLog('%s(in %s): %s', resultType, type, result.query);
115
+ return {
116
+ type: resultType,
117
+ matched: collection.matched,
118
+ unmatched: collection.unmatched,
119
+ zeroMatch: result.zeroMatch,
120
+ query: result.query,
121
+ hint: result.hint,
122
+ };
123
+ }
124
+ const resultType = collection.matched.length === 0 ? 'MATCHED_ZERO' : 'MATCHED';
125
+ const zeroMatch = result.zeroMatch || min === 0 || resultType === 'MATCHED_ZERO';
126
+ const matchedResult = {
127
+ type: resultType,
128
+ matched: collection.matched,
129
+ unmatched: collection.unmatched,
130
+ zeroMatch,
131
+ query: result.query,
132
+ hint: result.hint,
133
+ };
134
+ if (!prevResult && collection.unmatched.length) {
135
+ ptLog('continue checking');
136
+ prevResult = matchedResult;
137
+ continue;
138
+ }
139
+ ptLog('%s: %s', resultType, collection);
140
+ if (result.type === 'MISSING_NODE_REQUIRED' ||
141
+ result.type === 'MISSING_NODE_ONE_OR_MORE' ||
142
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS') {
143
+ return {
144
+ type: result.type,
145
+ matched: collection.matched,
146
+ unmatched: collection.unmatched,
147
+ zeroMatch: result.zeroMatch,
148
+ query: result.query,
149
+ hint: result.hint,
150
+ };
151
+ }
152
+ return matchedResult;
153
+ }
154
+ }
155
+ exports.countPattern = countPattern;
@@ -0,0 +1,2 @@
1
+ /// <reference types="debug" />
2
+ export declare const cmLog: import("debug").Debugger;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cmLog = void 0;
4
+ const debug_1 = require("../debug");
5
+ exports.cmLog = debug_1.log.extend('content-model');
@@ -1,9 +1,3 @@
1
- import type { ContentModel } from '@markuplint/ml-spec';
2
- declare type TagRule = ContentModel & {
3
- tag: string;
4
- };
5
- declare type Options = {
6
- ignoreHasMutableChildren: boolean;
7
- };
1
+ import type { Options, TagRule } from './types';
8
2
  declare const _default: import("@markuplint/ml-core").RuleSeed<TagRule[], Options>;
9
3
  export default _default;
@@ -1,281 +1,111 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
3
  const ml_core_1 = require("@markuplint/ml-core");
5
- const ml_spec_1 = require("@markuplint/ml-spec");
6
- const permitted_content_spec_to_regexp_1 = tslib_1.__importDefault(require("./permitted-content.spec-to-regexp"));
7
- const expMapOnNodeId = new Map();
4
+ const content_model_1 = require("./content-model");
5
+ const represent_transparent_nodes_1 = require("./represent-transparent-nodes");
8
6
  exports.default = (0, ml_core_1.createRule)({
9
7
  defaultValue: [],
10
8
  defaultOptions: {
11
9
  ignoreHasMutableChildren: true,
12
10
  },
13
11
  async verify({ document, report, t }) {
14
- let idCounter = 0;
15
12
  await document.walkOn('Element', el => {
16
- var _a;
13
+ var _a, _b, _c;
17
14
  if (!el.rule.value) {
18
15
  return;
19
16
  }
20
17
  if (el.rule.option.ignoreHasMutableChildren && el.hasMutableChildren()) {
21
18
  return;
22
19
  }
23
- const specType = el.namespaceURI === 'http://www.w3.org/1999/xhtml'
24
- ? 'HTML'
25
- : el.namespaceURI === 'http://www.w3.org/2000/svg'
26
- ? 'SVG'
27
- : 'Any Language';
28
- const childNodes = el.getChildElementsAndTextNodeWithoutWhitespaces();
29
- const spec = !el.isCustomElement && ((_a = (0, ml_core_1.getSpec)(el, document.specs)) === null || _a === void 0 ? void 0 : _a.contentModel);
30
- const expGen = new permitted_content_spec_to_regexp_1.default(document.specs, idCounter++);
31
- if (spec) {
32
- if (spec.descendantOf && !el.closest(spec.descendantOf)) {
33
- report({
34
- scope: el,
35
- message: t('{0} must be {1}', t('the "{0*}" {1}', el.localName, 'element'), t('{0} of {1}', 'descendant', t('the "{0*}" {1}', spec.descendantOf, 'element'))),
36
- });
37
- return;
38
- }
39
- let matched = false;
40
- if (spec.conditional) {
41
- for (const conditional of spec.conditional) {
42
- matched = el.matches(conditional.condition);
43
- // console.log({ ...conditional, matched });
44
- if (matched) {
45
- try {
46
- const parentExp = getRegExpFromParentNode(document.specs, el, expGen);
47
- const exp = expGen.specToRegExp(conditional.contents, parentExp, el.namespaceURI);
48
- const conditionalResult = match(exp, childNodes, false, document.specs);
49
- if (!conditionalResult) {
50
- const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0*}" {1}', el.localName, 'element')), 'invalid');
51
- report({
52
- scope: el,
53
- message: specType !== 'Any Language'
54
- ? t('{0} according to {1}', message, `the ${specType} specification`)
55
- : message,
56
- line: el.startLine,
57
- col: el.startCol,
58
- raw: el.raw,
59
- });
60
- break;
61
- }
62
- }
63
- catch (e) {
64
- if (e instanceof Error) {
65
- // eslint-disable-next-line no-console
66
- console.warn(el.raw, 'conditional', conditional, e.message);
67
- }
68
- else {
69
- throw e;
70
- }
71
- }
72
- }
20
+ const results = (0, content_model_1.contentModel)(el, el.rule.value, el.rule.option);
21
+ for (const { type, scope, query, hint } of results) {
22
+ let message = '';
23
+ if (hint) {
24
+ if (hint.max != null) {
25
+ message =
26
+ t('there is more content than it needs') +
27
+ t('. ') +
28
+ t('the max number of elements required is {0}', `${hint.max}`);
73
29
  }
74
30
  }
75
- if (!matched) {
76
- try {
77
- const exp = getRegExpFromNode(document.specs, el, expGen);
78
- const specResult = match(exp, childNodes, false, document.specs);
79
- if (!specResult) {
80
- const message = t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0*}" {1}', el.localName, 'element')), 'invalid');
81
- report({
82
- scope: el,
83
- message: specType !== 'Any Language'
84
- ? t('{0} according to {1}', message, `the ${specType} specification`)
85
- : message,
86
- });
87
- }
31
+ switch (type) {
32
+ case 'MATCHED':
33
+ case 'MATCHED_ZERO': {
34
+ break;
88
35
  }
89
- catch (e) {
90
- if (e instanceof Error) {
91
- // eslint-disable-next-line no-console
92
- console.warn(el.raw, 'HTML Spec', e.message);
93
- }
94
- else {
95
- throw e;
96
- }
36
+ case 'MISSING_NODE_ONE_OR_MORE': {
37
+ message =
38
+ message ||
39
+ t('Require {0}', t('one or more elements')) + t('. ') + '(' + t('Need "{0*}"', query) + ')';
40
+ report({
41
+ scope,
42
+ message,
43
+ });
44
+ break;
97
45
  }
98
- }
99
- }
100
- for (const rule of el.rule.value) {
101
- if (rule.tag.toLowerCase() !== el.localName.toLowerCase()) {
102
- continue;
103
- }
104
- const parentExp = getRegExpFromParentNode(document.specs, el, expGen);
105
- try {
106
- const exp = expGen.specToRegExp(rule.contents, parentExp, el.namespaceURI);
107
- // Evaluate the custom element if the optional schema.
108
- const r = match(exp, childNodes, el.isCustomElement, document.specs);
109
- if (!r) {
46
+ case 'MISSING_NODE_REQUIRED': {
47
+ message =
48
+ message ||
49
+ t('Require {0}', t('an {0}', 'element')) + t('. ') + '(' + t('Need "{0*}"', query) + ')';
110
50
  report({
111
- scope: el,
112
- message: t('{0} is {1:c}', t('{0} of {1}', t('the {0}', 'content'), t('the "{0*}" {1}', el.localName, 'element')), 'invalid'),
113
- line: el.startLine,
114
- col: el.startCol,
115
- raw: el.raw,
51
+ scope,
52
+ message,
116
53
  });
117
- return;
54
+ break;
118
55
  }
119
- }
120
- catch (e) {
121
- if (e instanceof Error) {
122
- // eslint-disable-next-line no-console
123
- console.warn(el.raw, 'rule', rule, e.message);
56
+ case 'UNEXPECTED_EXTRA_NODE': {
57
+ const not = (_a = hint.not) !== null && _a !== void 0 ? _a : scope;
58
+ message =
59
+ message ||
60
+ (represent_transparent_nodes_1.transparentMode.has(scope)
61
+ ? t('{0} is not allowed in {1} through the transparent model in this context', name(not, t), name(el, t))
62
+ : t('{0} is not allowed in {1} in this context', name(not, t), name(el, t)));
63
+ report({
64
+ scope: not,
65
+ message,
66
+ });
67
+ break;
68
+ }
69
+ case 'TRANSPARENT_MODEL_DISALLOWS': {
70
+ const not = (_b = hint.not) !== null && _b !== void 0 ? _b : scope;
71
+ const tp = (_c = hint.transparent) !== null && _c !== void 0 ? _c : el;
72
+ report({
73
+ scope: not,
74
+ 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))),
75
+ });
76
+ break;
77
+ }
78
+ case 'VOID_ELEMENT': {
79
+ report({
80
+ scope: el,
81
+ message: t('{0} is {1}', t('the {0}', 'element'), t('a {0}', 'void element')),
82
+ });
83
+ break;
124
84
  }
125
- else {
126
- throw e;
85
+ default: {
86
+ throw new Error('Unreachable code');
127
87
  }
128
88
  }
129
89
  }
90
+ represent_transparent_nodes_1.transparentMode.clear();
130
91
  });
131
- expMapOnNodeId.clear();
132
92
  },
133
93
  });
134
- function normalization(el, evalCustomElement) {
135
- return el
136
- .map(node => {
137
- // FIXME: https://github.com/markuplint/markuplint/issues/388
138
- if (!evalCustomElement && node.is(node.ELEMENT_NODE) && node.isCustomElement) {
139
- return '';
140
- }
141
- if (!node.is(node.ELEMENT_NODE)) {
142
- return '<#text>';
143
- }
144
- const { localNameWithNS } = (0, ml_core_1.resolveNamespace)(node.localName, node.namespaceURI);
145
- return `<${localNameWithNS}>`;
146
- })
147
- .join('');
148
- }
149
- function getRegExpFromNode(specs, el, expGen) {
150
- var _a;
151
- // console.log({ n: node.nodeName });
152
- if (expMapOnNodeId.has(el.uuid)) {
153
- return expMapOnNodeId.get(el.uuid);
94
+ function name(scope, t) {
95
+ if (scope.is(scope.ELEMENT_NODE)) {
96
+ return t('the "{0}" {1}', scope.localName, 'element');
154
97
  }
155
- const parentExp = el.parentNode ? getRegExpFromNode(specs, el.parentNode, expGen) : null;
156
- const spec = el.nodeType === el.ELEMENT_NODE && !el.isCustomElement && ((_a = (0, ml_core_1.getSpec)(el, specs)) === null || _a === void 0 ? void 0 : _a.contentModel);
157
- const contentRule = spec ? spec.contents : true;
158
- const exp = expGen.specToRegExp(contentRule, parentExp, el.nodeType === el.ELEMENT_NODE ? el.namespaceURI : undefined);
159
- expMapOnNodeId.set(el.uuid, exp);
160
- return exp;
161
- }
162
- function getRegExpFromParentNode(specs, el, expGen) {
163
- // console.log({ p: node.nodeName });
164
- const parentExp = el.parentNode ? getRegExpFromNode(specs, el.parentNode, expGen) : null;
165
- return parentExp;
166
- }
167
- const matchingCacheMap = new Map();
168
- function match(exp, childNodes, evalCustomElement, specs) {
169
- const target = normalization(childNodes, evalCustomElement);
170
- const cacheKey = target +
171
- exp.source +
172
- childNodes.map(n => (n.is(n.ELEMENT_NODE) ? n.toNormalizeString() : n.originRaw)).join('');
173
- const res = matchingCacheMap.get(cacheKey);
174
- if (res != null) {
175
- return res;
98
+ if (scope.is(scope.TEXT_NODE)) {
99
+ return t('the {0}', 'text node');
176
100
  }
177
- const matched = _match(target, exp, childNodes, specs);
178
- matchingCacheMap.set(cacheKey, matched);
179
- return matched;
180
- }
181
- function _match(target, exp, childNodes, specs) {
182
- const result = exp.exec(target);
183
- if (!result) {
184
- return false;
101
+ if (scope.is(scope.CDATA_SECTION_NODE)) {
102
+ return t('the {0}', 'comment');
185
103
  }
186
- const capGroups = result.groups;
187
- // console.log({ exp, target, capGroups });
188
- if (!capGroups) {
189
- return true;
104
+ if (scope.is(scope.DOCUMENT_TYPE_NODE)) {
105
+ return t('the {0}', 'doctype');
190
106
  }
191
- const groupNames = Object.keys(capGroups);
192
- for (const groupName of groupNames) {
193
- const matched = capGroups[groupName];
194
- if (!matched) {
195
- continue;
196
- }
197
- const [type, , ..._selector] = groupName.split(/(?<=[a-z0-9])_/gi);
198
- // console.log({ type, _selector });
199
- switch (type) {
200
- case 'ACM': {
201
- const [model, tag] = _selector;
202
- const selectors = (0, ml_spec_1.contentModelCategoryToTagNames)(`#${model}`, specs).filter(selector => {
203
- const [, tagName] = /^([^[\]]+)(?:\[[^\]]+\])?$/.exec(selector) || [];
204
- return tagName.toLowerCase() === tag.toLowerCase();
205
- });
206
- for (const node of childNodes) {
207
- if (node.is(node.TEXT_NODE)) {
208
- continue;
209
- }
210
- if (node.nodeName.toLowerCase() !== tag.toLowerCase()) {
211
- continue;
212
- }
213
- for (const selector of selectors) {
214
- const matched = node.matches(selector);
215
- // console.log({ raw: node.raw, selector, matched });
216
- if (matched) {
217
- return true;
218
- }
219
- }
220
- return false;
221
- }
222
- break;
223
- }
224
- case 'NAD': {
225
- let targetsMaybeIncludesNotAllowedDescendants = Array.from(new Set(matched.split(/><|<|>/g).filter(_ => _)));
226
- const contents = new Set();
227
- const transparentGroupName = groupNames.find(name => /^TRANSPARENT_[0-9]+$/.test(name));
228
- const inTransparent = _selector.includes('__InTRANSPARENT')
229
- ? transparentGroupName && capGroups[transparentGroupName]
230
- ? capGroups[transparentGroupName].split(/><|<|>/g).filter(_ => _)
231
- : null
232
- : null;
233
- _selector.forEach(content => {
234
- if (content[0] === '_') {
235
- (0, ml_spec_1.contentModelCategoryToTagNames)(content.replace('_', '#'), specs).forEach(tag => contents.add(tag));
236
- return;
237
- }
238
- contents.add(content);
239
- });
240
- const selectors = Array.from(contents);
241
- targetsMaybeIncludesNotAllowedDescendants = targetsMaybeIncludesNotAllowedDescendants.filter(content => inTransparent ? inTransparent.includes(content) : true);
242
- // console.log({
243
- // groupName,
244
- // matched,
245
- // _selector,
246
- // type,
247
- // selectors,
248
- // inTransparent,
249
- // targetsMaybeIncludesNotAllowedDescendants,
250
- // });
251
- for (const node of childNodes) {
252
- for (const target of targetsMaybeIncludesNotAllowedDescendants) {
253
- if (node.is(node.TEXT_NODE)) {
254
- if (selectors.includes('#text')) {
255
- return false;
256
- }
257
- continue;
258
- }
259
- if (node.nodeName.toLowerCase() !== target.toLowerCase()) {
260
- continue;
261
- }
262
- for (const selector of selectors) {
263
- // console.log({ selector, target });
264
- // Self
265
- if (node.matches(selector)) {
266
- return false;
267
- }
268
- // Descendants
269
- const nodeList = node.querySelectorAll(selector);
270
- if (nodeList.length) {
271
- return false;
272
- }
273
- }
274
- }
275
- }
276
- break;
277
- }
278
- }
107
+ if (scope.is(scope.MARKUPLINT_PREPROCESSOR_BLOCK)) {
108
+ return t('the {0}', 'code block');
279
109
  }
280
- return true;
110
+ return t('the {0}', 'node');
281
111
  }
@@ -0,0 +1,3 @@
1
+ import type { ChildNode, Options, Result, Specs } from './types';
2
+ export declare type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
3
+ export declare function matchesSelector(query: string, node: ChildNode | undefined, specs: Specs, options: Options, depth: number): SelectorResult;