@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.
Files changed (211) hide show
  1. package/README.md +10 -44
  2. package/lib/attr-check.d.ts +22 -10
  3. package/lib/attr-check.js +32 -23
  4. package/lib/attr-duplication/index.d.ts +3 -1
  5. package/lib/attr-duplication/index.js +3 -2
  6. package/lib/attr-value-quotes/index.d.ts +5 -5
  7. package/lib/attr-value-quotes/index.js +1 -1
  8. package/lib/case-sensitive-attr-name/index.d.ts +2 -2
  9. package/lib/case-sensitive-attr-name/index.js +3 -3
  10. package/lib/case-sensitive-tag-name/index.d.ts +2 -2
  11. package/lib/case-sensitive-tag-name/index.js +3 -3
  12. package/lib/character-reference/index.d.ts +1 -1
  13. package/lib/character-reference/index.js +1 -1
  14. package/lib/class-naming/index.d.ts +2 -2
  15. package/lib/class-naming/index.js +3 -5
  16. package/lib/create-message.d.ts +13 -2
  17. package/lib/create-message.js +9 -8
  18. package/lib/debug.d.ts +1 -1
  19. package/lib/debug.js +1 -1
  20. package/lib/deprecated-attr/index.d.ts +3 -1
  21. package/lib/deprecated-element/index.d.ts +3 -1
  22. package/lib/deprecated-element/index.js +4 -4
  23. package/lib/disallowed-element/index.d.ts +1 -1
  24. package/lib/doctype/index.d.ts +3 -3
  25. package/lib/doctype/index.js +2 -2
  26. package/lib/end-tag/index.d.ts +1 -1
  27. package/lib/end-tag/index.js +3 -18
  28. package/lib/helpers.d.ts +38 -47
  29. package/lib/helpers.js +42 -93
  30. package/lib/id-duplication/index.d.ts +3 -1
  31. package/lib/index.d.ts +242 -62
  32. package/lib/index.js +10 -1
  33. package/lib/ineffective-attr/index.d.ts +3 -1
  34. package/lib/ineffective-attr/index.js +3 -6
  35. package/lib/invalid-attr/index.d.ts +40 -12
  36. package/lib/invalid-attr/index.js +159 -28
  37. package/lib/label-has-control/index.d.ts +4 -0
  38. package/lib/label-has-control/index.js +28 -0
  39. package/lib/landmark-roles/index.d.ts +6 -6
  40. package/lib/landmark-roles/index.js +10 -6
  41. package/lib/no-boolean-attr-value/index.d.ts +3 -1
  42. package/lib/no-boolean-attr-value/index.js +1 -1
  43. package/lib/no-default-value/index.d.ts +3 -1
  44. package/lib/no-default-value/index.js +1 -1
  45. package/lib/no-empty-palpable-content/index.d.ts +6 -0
  46. package/lib/no-empty-palpable-content/index.js +42 -0
  47. package/lib/no-hard-code-id/index.d.ts +3 -1
  48. package/lib/no-hard-code-id/index.js +1 -1
  49. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -4
  50. package/lib/no-refer-to-non-existent-id/index.js +65 -5
  51. package/lib/no-use-event-handler-attr/index.d.ts +3 -3
  52. package/lib/no-use-event-handler-attr/index.js +6 -6
  53. package/lib/permitted-contents/choice.d.ts +10 -0
  54. package/lib/permitted-contents/choice.js +72 -0
  55. package/lib/permitted-contents/complex-branch.d.ts +20 -0
  56. package/lib/permitted-contents/complex-branch.js +29 -0
  57. package/lib/permitted-contents/content-model.d.ts +2 -0
  58. package/lib/permitted-contents/content-model.js +53 -0
  59. package/lib/permitted-contents/count-pattern.d.ts +29 -0
  60. package/lib/permitted-contents/count-pattern.js +162 -0
  61. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  62. package/lib/permitted-contents/debug.browser.js +14 -0
  63. package/lib/permitted-contents/debug.d.ts +3 -0
  64. package/lib/permitted-contents/debug.js +13 -0
  65. package/lib/permitted-contents/index.d.ts +2 -8
  66. package/lib/permitted-contents/index.js +76 -249
  67. package/lib/permitted-contents/matches-selector.d.ts +8 -0
  68. package/lib/permitted-contents/matches-selector.js +187 -0
  69. package/lib/permitted-contents/order.d.ts +20 -0
  70. package/lib/permitted-contents/order.js +99 -0
  71. package/lib/permitted-contents/recursive-branch.d.ts +11 -0
  72. package/lib/permitted-contents/recursive-branch.js +45 -0
  73. package/lib/permitted-contents/represent-transparent-nodes.d.ts +10 -0
  74. package/lib/permitted-contents/represent-transparent-nodes.js +78 -0
  75. package/lib/permitted-contents/start.d.ts +18 -0
  76. package/lib/permitted-contents/start.js +73 -0
  77. package/lib/permitted-contents/transparent.d.ts +2 -0
  78. package/lib/permitted-contents/transparent.js +31 -0
  79. package/lib/permitted-contents/types.d.ts +52 -0
  80. package/lib/permitted-contents/types.js +2 -0
  81. package/lib/permitted-contents/utils.d.ts +100 -0
  82. package/lib/permitted-contents/utils.js +302 -0
  83. package/lib/placeholder-label-option/index.d.ts +2 -0
  84. package/lib/placeholder-label-option/index.js +88 -0
  85. package/lib/require-accessible-name/index.d.ts +3 -3
  86. package/lib/require-accessible-name/index.js +12 -4
  87. package/lib/require-datetime/index.d.ts +6 -0
  88. package/lib/require-datetime/index.js +34 -0
  89. package/lib/require-datetime/types.d.ts +10 -0
  90. package/lib/require-datetime/types.js +2 -0
  91. package/lib/require-datetime/utils.d.ts +11 -0
  92. package/lib/require-datetime/utils.js +137 -0
  93. package/lib/required-attr/index.d.ts +5 -5
  94. package/lib/required-attr/index.js +20 -17
  95. package/lib/required-element/index.d.ts +3 -3
  96. package/lib/required-element/index.js +3 -2
  97. package/lib/required-h1/index.d.ts +3 -3
  98. package/lib/required-h1/index.js +4 -3
  99. package/lib/use-list/index.d.ts +4 -4
  100. package/lib/use-list/index.js +9 -7
  101. package/lib/wai-aria/checkings/_.d.ts +15 -0
  102. package/lib/wai-aria/checkings/_.js +27 -0
  103. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  104. package/lib/wai-aria/checkings/default-value.d.ts +7 -3
  105. package/lib/wai-aria/checkings/deprecated-props.d.ts +8 -4
  106. package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
  107. package/lib/wai-aria/checkings/disallowed-prop.js +27 -3
  108. package/lib/wai-aria/checkings/implicit-props.d.ts +8 -4
  109. package/lib/wai-aria/checkings/implicit-props.js +3 -2
  110. package/lib/wai-aria/checkings/implicit-role.js +2 -2
  111. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +11 -0
  112. package/lib/wai-aria/checkings/interaction-in-hidden.js +49 -0
  113. package/lib/wai-aria/checkings/no-global-prop.d.ts +7 -3
  114. package/lib/wai-aria/checkings/{non-existant-role.d.ts → non-existent-role.d.ts} +1 -1
  115. package/lib/wai-aria/checkings/{non-existant-role.js → non-existent-role.js} +4 -4
  116. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  117. package/lib/wai-aria/checkings/presentational-children.d.ts +29 -0
  118. package/lib/wai-aria/checkings/presentational-children.js +62 -0
  119. package/lib/wai-aria/checkings/{checking-required-owned-elements.d.ts → required-owned-elements.d.ts} +7 -3
  120. package/lib/wai-aria/checkings/required-owned-elements.js +103 -0
  121. package/lib/wai-aria/checkings/required-prop copy.d.ts +15 -0
  122. package/lib/wai-aria/checkings/required-prop copy.js +27 -0
  123. package/lib/wai-aria/checkings/required-prop.d.ts +12 -6
  124. package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +15 -0
  125. package/lib/wai-aria/checkings/unadopted-explicit-roles.js +17 -0
  126. package/lib/wai-aria/checkings/value.d.ts +19 -4
  127. package/lib/wai-aria/checkings/value.js +77 -5
  128. package/lib/wai-aria/index.d.ts +1 -1
  129. package/lib/wai-aria/index.js +27 -16
  130. package/lib/wai-aria/types.d.ts +11 -9
  131. package/lib/xxx/index.d.ts +2 -0
  132. package/lib/xxx/index.js +32 -0
  133. package/package.json +18 -12
  134. package/schema.json +12 -0
  135. package/test/attr-check.spec.js +77 -0
  136. package/test/attr-duplication/index.spec.js +159 -0
  137. package/test/attr-value-quotes/index.spec.js +133 -0
  138. package/test/case-sensitive-attr-name/index.spec.js +65 -0
  139. package/test/case-sensitive-tag-name/index.spec.js +80 -0
  140. package/test/character-reference/index.spec.js +57 -0
  141. package/test/class-naming/index.spec.js +470 -0
  142. package/test/create-message.spec.js +497 -0
  143. package/test/deprecated-attr/index.spec.js +48 -0
  144. package/test/deprecated-element/index.spec.js +48 -0
  145. package/test/disallowed-element/index.spec.js +90 -0
  146. package/test/doctype/index.spec.js +50 -0
  147. package/test/end-tag/index.spec.js +162 -0
  148. package/test/id-duplication/index.spec.js +47 -0
  149. package/test/ineffective-attr/index.spec.js +31 -0
  150. package/test/invalid-attr/index.spec.js +1632 -0
  151. package/test/label-has-control/index.spec.js +29 -0
  152. package/test/landmark-roles/index.spec.js +187 -0
  153. package/test/no-boolean-attr-value/index.spec.js +41 -0
  154. package/test/no-default-value/index.spec.js +74 -0
  155. package/test/no-empty-palpable-content/index.spec.js +115 -0
  156. package/test/no-hard-code-id/index.spec.js +100 -0
  157. package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
  158. package/test/no-use-event-handler-attr/index.spec.js +57 -0
  159. package/test/permitted-contents/choice.spec.js +174 -0
  160. package/test/permitted-contents/count-pattern.spec.js +308 -0
  161. package/test/permitted-contents/index.spec.js +1371 -0
  162. package/test/permitted-contents/matches-selector.spec.js +59 -0
  163. package/test/permitted-contents/order.spec.js +351 -0
  164. package/test/permitted-contents/recursive-branch.spec.js +41 -0
  165. package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
  166. package/test/permitted-contents/start.spec.js +67 -0
  167. package/test/placeholder-label-option/index.spec.js +113 -0
  168. package/test/require-accessible-name/index.spec.js +446 -0
  169. package/test/require-datetime/index.spec.js +54 -0
  170. package/test/require-datetime/utils.spec.js +52 -0
  171. package/test/required-attr/index.spec.js +414 -0
  172. package/test/required-element/index.spec.js +188 -0
  173. package/test/required-h1/index.spec.js +69 -0
  174. package/test/use-list/index.spec.js +109 -0
  175. package/test/wai-aria/checkings/value.spec.js +33 -0
  176. package/test/wai-aria/index.spec.js +1173 -0
  177. package/lib/__foo/index.d.ts +0 -2
  178. package/lib/__foo/index.js +0 -46
  179. package/lib/attr-equal-space-after/index.d.ts +0 -3
  180. package/lib/attr-equal-space-after/index.js +0 -90
  181. package/lib/attr-equal-space-before/index.d.ts +0 -3
  182. package/lib/attr-equal-space-before/index.js +0 -90
  183. package/lib/attr-spacing/index.d.ts +0 -6
  184. package/lib/attr-spacing/index.js +0 -100
  185. package/lib/helper/aria/get-aria.d.ts +0 -7
  186. package/lib/helper/aria/get-aria.js +0 -53
  187. package/lib/helper/aria/get-computed-role.d.ts +0 -10
  188. package/lib/helper/aria/get-computed-role.js +0 -24
  189. package/lib/helper/aria/get-implicit-role.d.ts +0 -7
  190. package/lib/helper/aria/get-implicit-role.js +0 -12
  191. package/lib/helper/aria/get-permitted-roles.d.ts +0 -14
  192. package/lib/helper/aria/get-permitted-roles.js +0 -26
  193. package/lib/helper/aria/resolve-version.d.ts +0 -2
  194. package/lib/helper/aria/resolve-version.js +0 -21
  195. package/lib/helper/spec/aria-spec.d.ts +0 -5
  196. package/lib/helper/spec/aria-spec.js +0 -12
  197. package/lib/helper/spec/get-role-spec.d.ts +0 -11
  198. package/lib/helper/spec/get-role-spec.js +0 -39
  199. package/lib/helper/spec/html-spec.d.ts +0 -2
  200. package/lib/helper/spec/html-spec.js +0 -14
  201. package/lib/indentation/index.d.ts +0 -7
  202. package/lib/indentation/index.js +0 -208
  203. package/lib/permitted-contents/array.combination.d.ts +0 -1
  204. package/lib/permitted-contents/array.combination.js +0 -33
  205. package/lib/permitted-contents/permitted-content.spec-to-regexp.d.ts +0 -11
  206. package/lib/permitted-contents/permitted-content.spec-to-regexp.js +0 -230
  207. package/lib/permitted-contents/unfold-content-models-to-tags.d.ts +0 -2
  208. package/lib/permitted-contents/unfold-content-models-to-tags.js +0 -8
  209. package/lib/wai-aria/checkings/checking-required-owned-elements.js +0 -63
  210. package/tsconfig.test.json +0 -3
  211. package/tsconfig.tsbuildinfo +0 -1
@@ -1,27 +1,50 @@
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");
5
+ const shared_1 = require("@markuplint/shared");
6
+ const HYPERLINK_SELECTOR = 'a[href], area[href]';
4
7
  exports.default = (0, ml_core_1.createRule)({
5
8
  defaultOptions: {
6
- ariaVersion: '1.2',
9
+ ariaVersion: ml_spec_1.ARIA_RECOMMENDED_VERSION,
10
+ fragmentRefersNameAttr: false,
7
11
  },
8
12
  async verify({ document, report, t }) {
9
13
  const idList = new Set();
14
+ const nameList = new Set();
10
15
  let hasDynamicId = false;
11
- await document.walkOn('Attr', attr => {
12
- if (attr.name.toLowerCase() !== 'id') {
16
+ let hasDynamicName = false;
17
+ const isMutable = document.nodeList.some(node => node.is(node.MARKUPLINT_PREPROCESSOR_BLOCK));
18
+ if (isMutable) {
19
+ return;
20
+ }
21
+ document.querySelectorAll('[id]').forEach(el => {
22
+ const attr = el.getAttributeNode('id');
23
+ if (!attr) {
13
24
  return;
14
25
  }
15
26
  if (attr.isDynamicValue) {
16
27
  hasDynamicId = true;
17
28
  }
18
29
  if (attr.valueType !== 'code') {
19
- idList.add(attr.value);
30
+ idList.add((0, shared_1.decodeEntities)(attr.value));
20
31
  }
21
32
  });
22
33
  if (hasDynamicId) {
23
34
  return;
24
35
  }
36
+ document.querySelectorAll('[name]').forEach(el => {
37
+ const attr = el.getAttributeNode('name');
38
+ if (!attr) {
39
+ return;
40
+ }
41
+ if (attr.isDynamicValue) {
42
+ hasDynamicName = true;
43
+ }
44
+ if (attr.valueType !== 'code') {
45
+ nameList.add((0, shared_1.decodeEntities)(attr.value));
46
+ }
47
+ });
25
48
  await document.walkOn('Attr', attr => {
26
49
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
27
50
  const attrSpec = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
@@ -69,7 +92,7 @@ exports.default = (0, ml_core_1.createRule)({
69
92
  }
70
93
  }
71
94
  }
72
- const { props } = (0, ml_core_1.ariaSpecs)(document.specs, attr.rule.option.ariaVersion);
95
+ const { props } = (0, ml_core_1.ariaSpecs)(document.specs, attr.rule.options.ariaVersion);
73
96
  const aria = props.find(prop => prop.name === name);
74
97
  if (aria) {
75
98
  if (aria.value === 'ID reference' && !idList.has(value)) {
@@ -100,5 +123,42 @@ exports.default = (0, ml_core_1.createRule)({
100
123
  }
101
124
  }
102
125
  });
126
+ /**
127
+ * @see https://html.spec.whatwg.org/multipage/browsing-the-web.html#scrolling-to-a-fragment
128
+ */
129
+ await document.walkOn('Element', el => {
130
+ var _a, _b, _c, _d;
131
+ if (el.rule.options.fragmentRefersNameAttr && hasDynamicName) {
132
+ return;
133
+ }
134
+ if (!el.matches(HYPERLINK_SELECTOR)) {
135
+ return;
136
+ }
137
+ const href = el.getAttributeNode('href');
138
+ if (!href) {
139
+ return;
140
+ }
141
+ const rawFragment = (_a = href.value.match(/^#(.+)/)) === null || _a === void 0 ? void 0 : _a[1];
142
+ if (rawFragment == null) {
143
+ return;
144
+ }
145
+ const decodedFragment = (0, shared_1.decodeHref)(rawFragment);
146
+ // > 2. If fragment is the empty string, then return the special value top of the document.
147
+ // >
148
+ // > 9. If decodedFragment is an ASCII case-insensitive match for the string top, then return the top of the document.
149
+ if (decodedFragment === '' || /^top$/i.test(decodedFragment)) {
150
+ return;
151
+ }
152
+ if (!idList.has(decodedFragment) &&
153
+ (el.rule.options.fragmentRefersNameAttr ? !nameList.has(decodedFragment) : true)) {
154
+ report({
155
+ scope: href,
156
+ line: (_b = href.valueNode) === null || _b === void 0 ? void 0 : _b.startLine,
157
+ col: (_c = href.valueNode) === null || _c === void 0 ? void 0 : _c.startCol,
158
+ raw: (_d = href.valueNode) === null || _d === void 0 ? void 0 : _d.raw,
159
+ message: t('Missing {0}', t('"{0*}" ID', decodedFragment)),
160
+ });
161
+ }
162
+ });
103
163
  },
104
164
  });
@@ -1,5 +1,5 @@
1
- declare type Options = {
2
- ignore?: string | string[];
1
+ type Options = {
2
+ ignore?: string | string[];
3
3
  };
4
- declare const _default: import("@markuplint/ml-core").RuleSeed<boolean, Options>;
4
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Options>>;
5
5
  export default _default;
@@ -3,17 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
4
  const helpers_1 = require("../helpers");
5
5
  exports.default = (0, ml_core_1.createRule)({
6
- defaultServerity: 'warning',
6
+ defaultSeverity: 'warning',
7
7
  defaultOptions: {},
8
8
  async verify({ document, report, t }) {
9
9
  await document.walkOn('Attr', attr => {
10
- if (attr.ownerElement.isCustomElement) {
10
+ if (attr.ownerElement.elementType !== 'html') {
11
11
  return;
12
12
  }
13
- const ignoreList = Array.isArray(attr.rule.option.ignore)
14
- ? attr.rule.option.ignore
15
- : attr.rule.option.ignore
16
- ? [attr.rule.option.ignore]
13
+ const ignoreList = Array.isArray(attr.rule.options.ignore)
14
+ ? attr.rule.options.ignore
15
+ : attr.rule.options.ignore
16
+ ? [attr.rule.options.ignore]
17
17
  : [];
18
18
  const name = attr.name;
19
19
  for (const ignore of ignoreList) {
@@ -0,0 +1,10 @@
1
+ import type { ChildNode, Options, Result, Specs } from './types';
2
+ import type { PermittedContentChoice } from '@markuplint/ml-spec';
3
+ import type { ReadonlyDeep } from 'type-fest';
4
+ export declare function choice(
5
+ pattern: ReadonlyDeep<PermittedContentChoice>,
6
+ elements: readonly ChildNode[],
7
+ specs: Specs,
8
+ options: Options,
9
+ depth: number,
10
+ ): Result;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.choice = void 0;
4
+ const debug_1 = require("./debug");
5
+ const order_1 = require("./order");
6
+ const utils_1 = require("./utils");
7
+ const indexes = new WeakMap();
8
+ function choice(pattern,
9
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
10
+ elements, specs, options, depth) {
11
+ const choiceLog = debug_1.cmLog.extend(`choice#${depth}`);
12
+ const collection = new utils_1.Collection(elements);
13
+ const unmatchedResults = [];
14
+ let i = 0;
15
+ for (const some of pattern.choice) {
16
+ choiceLog('Patterns[%s]: %s', i, (0, utils_1.modelLog)(some, ''));
17
+ const result = (0, order_1.order)(some, collection.unmatched, specs, options, depth + 1);
18
+ if (result.type === 'UNEXPECTED_EXTRA_NODE' || result.type === 'MATCHED' || result.type === 'MATCHED_ZERO') {
19
+ choiceLog('Results[%s]: %s', i, choiceLogString(pattern.choice, i));
20
+ collection.addMatched(result.matched);
21
+ return {
22
+ type: result.type,
23
+ matched: collection.matched,
24
+ unmatched: collection.unmatched,
25
+ zeroMatch: result.zeroMatch,
26
+ query: result.query,
27
+ hint: result.hint,
28
+ };
29
+ }
30
+ unmatchedResults.push(result);
31
+ indexes.set(result, i);
32
+ i++;
33
+ }
34
+ const barelyMatchedResult = unmatchedResults.sort((a, b) => {
35
+ var _c, _d, _e, _f;
36
+ const computed1 = b.matched.length - a.matched.length;
37
+ if (computed1 !== 0) {
38
+ return computed1;
39
+ }
40
+ const _a = (_d = (_c = a.hint.missing) === null || _c === void 0 ? void 0 : _c.barelyMatchedElements) !== null && _d !== void 0 ? _d : 0;
41
+ const _b = (_f = (_e = b.hint.missing) === null || _e === void 0 ? void 0 : _e.barelyMatchedElements) !== null && _f !== void 0 ? _f : 0;
42
+ const computed2 = _b - _a;
43
+ return computed2;
44
+ })[0];
45
+ if (!barelyMatchedResult) {
46
+ throw new Error('Unreachable code');
47
+ }
48
+ const index = indexes.get(barelyMatchedResult);
49
+ if (index != null) {
50
+ choiceLog('Results[%s]: %s', index, choiceLogString(pattern.choice, index, true));
51
+ }
52
+ return {
53
+ type: barelyMatchedResult.type,
54
+ matched: collection.matched,
55
+ unmatched: collection.unmatched,
56
+ zeroMatch: barelyMatchedResult.zeroMatch,
57
+ query: barelyMatchedResult.query,
58
+ hint: barelyMatchedResult.hint,
59
+ };
60
+ }
61
+ exports.choice = choice;
62
+ function choiceLogString(choice, index, barely = false) {
63
+ const colorFn = barely ? debug_1.bgBlue : debug_1.bgGreen;
64
+ return choice
65
+ .map((pattern, i) => {
66
+ if (i === index) {
67
+ return colorFn((0, utils_1.modelLog)(pattern, ''));
68
+ }
69
+ return (0, utils_1.modelLog)(pattern, '');
70
+ })
71
+ .join(', ');
72
+ }
@@ -0,0 +1,20 @@
1
+ import type { ChildNode, Options, Result, Specs } from './types';
2
+ import type { PermittedContentPattern } from '@markuplint/ml-spec';
3
+ import type { ReadonlyDeep } from 'type-fest';
4
+ /**
5
+ * Check content condition
6
+ *
7
+ * @param pattern
8
+ * @param elements
9
+ * @param specs
10
+ * @param options
11
+ * @param depth
12
+ * @returns
13
+ */
14
+ export declare function complexBranch(
15
+ pattern: ReadonlyDeep<PermittedContentPattern>,
16
+ elements: readonly ChildNode[],
17
+ specs: Specs,
18
+ options: Options,
19
+ depth: number,
20
+ ): Result;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.complexBranch = void 0;
4
+ const choice_1 = require("./choice");
5
+ const count_pattern_1 = require("./count-pattern");
6
+ const transparent_1 = require("./transparent");
7
+ const utils_1 = require("./utils");
8
+ /**
9
+ * Check content condition
10
+ *
11
+ * @param pattern
12
+ * @param elements
13
+ * @param specs
14
+ * @param options
15
+ * @param depth
16
+ * @returns
17
+ */
18
+ function complexBranch(pattern,
19
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
20
+ elements, specs, options, depth) {
21
+ if ((0, utils_1.isChoice)(pattern)) {
22
+ return (0, choice_1.choice)(pattern, elements, specs, options, depth);
23
+ }
24
+ if ((0, utils_1.isTransparent)(pattern)) {
25
+ return (0, transparent_1.transparent)(elements);
26
+ }
27
+ return (0, count_pattern_1.countPattern)(pattern, elements, specs, options, depth);
28
+ }
29
+ exports.complexBranch = complexBranch;
@@ -0,0 +1,2 @@
1
+ import type { ContentModelResult, Element, Options, TagRule } from './types';
2
+ export declare function contentModel(el: Element, rules: readonly TagRule[], options: Options): ContentModelResult[];
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.contentModel = void 0;
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
5
+ const start_1 = require("./start");
6
+ function contentModel(
7
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
8
+ el, rules, options) {
9
+ const model = createModel(el, rules);
10
+ if (model == null) {
11
+ return [
12
+ {
13
+ type: 'MATCHED',
14
+ scope: el,
15
+ query: '*',
16
+ hint: {},
17
+ },
18
+ ];
19
+ }
20
+ const result = (0, start_1.start)(model, el, el.ownerMLDocument.specs, options);
21
+ return result;
22
+ }
23
+ exports.contentModel = contentModel;
24
+ function createModel(
25
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
26
+ el, rules) {
27
+ const specs = cachedSpecs(el.ownerMLDocument.specs, rules);
28
+ const model = (0, ml_spec_1.getContentModel)(el, specs.specs);
29
+ return model;
30
+ }
31
+ const caches = new Map();
32
+ function cachedSpecs(specs, rules) {
33
+ if (rules.length === 0) {
34
+ return specs;
35
+ }
36
+ const key = JSON.stringify(rules);
37
+ const cached = caches.get(key);
38
+ if (cached) {
39
+ return cached;
40
+ }
41
+ const merged = {
42
+ ...specs,
43
+ specs: [
44
+ ...specs.specs,
45
+ ...rules.map(tag => ({
46
+ name: tag.tag,
47
+ contentModel: tag,
48
+ })),
49
+ ],
50
+ };
51
+ caches.set(key, merged);
52
+ return merged;
53
+ }
@@ -0,0 +1,29 @@
1
+ import type { ChildNode, Options, Result, Specs } from './types';
2
+ import type {
3
+ PermittedContentOneOrMore,
4
+ PermittedContentOptional,
5
+ PermittedContentRequire,
6
+ PermittedContentZeroOrMore,
7
+ } from '@markuplint/ml-spec';
8
+ import type { ReadonlyDeep } from 'type-fest';
9
+ /**
10
+ * Check count
11
+ *
12
+ * @param pattern
13
+ * @param elements
14
+ * @param specs
15
+ * @param options
16
+ * @param depth
17
+ * @returns
18
+ */
19
+ export declare function countPattern(
20
+ pattern:
21
+ | ReadonlyDeep<PermittedContentOneOrMore>
22
+ | ReadonlyDeep<PermittedContentOptional>
23
+ | ReadonlyDeep<PermittedContentRequire>
24
+ | ReadonlyDeep<PermittedContentZeroOrMore>,
25
+ elements: readonly ChildNode[],
26
+ specs: Specs,
27
+ options: Options,
28
+ depth: number,
29
+ ): Result;
@@ -0,0 +1,162 @@
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,
18
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
19
+ elements, specs, options, depth) {
20
+ const ptLog = debug_1.cmLog.extend(`countPattern#${depth}`);
21
+ const collection = new utils_1.Collection(elements);
22
+ const { model, min, max, repeat, missingType } = (0, utils_1.normalizeModel)(pattern);
23
+ ptLog('Model:\n RegEx: %s\n Schema: %o', (0, utils_1.modelLog)(model, repeat), pattern);
24
+ let prevResult = null;
25
+ let barelyResult = null;
26
+ let loopCount = 0;
27
+ // eslint-disable-next-line no-constant-condition
28
+ while (true) {
29
+ loopCount++;
30
+ ptLog('Check#%s: %s', loopCount, collection);
31
+ const result = (0, recursive_branch_1.recursiveBranch)(model, collection.unmatched, specs, options, depth);
32
+ const added = collection.addMatched(result.matched);
33
+ const { matchedCount } = collection;
34
+ if (result.type === 'UNMATCHED_SELECTOR_BUT_MAY_EMPTY') {
35
+ ptLog('MATCHED_ZERO:\n model: %s\n max: %s\n collection: %s\n matched element: %s', (0, utils_1.modelLog)(model, repeat), max, collection, matchedCount);
36
+ return compereResult({
37
+ type: 'MATCHED_ZERO',
38
+ matched: collection.matched,
39
+ unmatched: collection.unmatched,
40
+ zeroMatch: true,
41
+ query: result.query,
42
+ hint: result.hint,
43
+ }, barelyResult);
44
+ }
45
+ if (max < collection.matchedCount) {
46
+ collection.max(max);
47
+ ptLog('UNEXPECTED_EXTRA_NODE:\n model: %s\n max: %s\n collection: %s\n matched element: %s', (0, utils_1.modelLog)(model, repeat), max, collection, matchedCount);
48
+ return compereResult({
49
+ type: 'UNEXPECTED_EXTRA_NODE',
50
+ matched: collection.matched,
51
+ unmatched: collection.unmatched,
52
+ zeroMatch: result.zeroMatch,
53
+ query: result.query,
54
+ hint: (0, utils_1.mergeHints)(result.hint, { max }),
55
+ }, barelyResult);
56
+ }
57
+ if (prevResult) {
58
+ if (result.type === 'MISSING_NODE_ONE_OR_MORE' ||
59
+ result.type === 'MISSING_NODE_REQUIRED' ||
60
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS') {
61
+ ptLog('%s(continued): %s; Needs', result.type, collection, result.query);
62
+ return compereResult({
63
+ type: result.type,
64
+ matched: collection.matched,
65
+ unmatched: collection.unmatched,
66
+ zeroMatch: result.zeroMatch,
67
+ query: result.query,
68
+ hint: result.hint,
69
+ }, barelyResult);
70
+ }
71
+ ptLog('%s(continued): %s', prevResult.type, collection);
72
+ return compereResult(prevResult, barelyResult);
73
+ }
74
+ if (added && collection.unmatched.length > 0) {
75
+ if (result.type !== 'MISSING_NODE' && result.type !== 'UNMATCHED_SELECTORS') {
76
+ barelyResult = {
77
+ type: result.type,
78
+ matched: collection.matched,
79
+ unmatched: collection.unmatched,
80
+ zeroMatch: result.zeroMatch,
81
+ query: result.query,
82
+ hint: result.hint,
83
+ };
84
+ }
85
+ ptLog('continue⤴️');
86
+ continue;
87
+ }
88
+ if (collection.matchedCount + (result.zeroMatch ? 1 : 0) < min) {
89
+ const resultType = result.type === 'MISSING_NODE_REQUIRED' ||
90
+ result.type === 'MISSING_NODE_ONE_OR_MORE' ||
91
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS'
92
+ ? result.type
93
+ : missingType !== null && missingType !== void 0 ? missingType : 'MISSING_NODE_REQUIRED';
94
+ ptLog('%s(in %s); Needs %s', resultType, missingType, result.query);
95
+ return compereResult({
96
+ type: resultType,
97
+ matched: collection.matched,
98
+ unmatched: collection.unmatched,
99
+ zeroMatch: result.zeroMatch,
100
+ query: result.query,
101
+ hint: (0, utils_1.mergeHints)(result.hint, {
102
+ missing: {
103
+ barelyMatchedElements: collection.matched.length,
104
+ need: result.query,
105
+ },
106
+ }),
107
+ }, barelyResult);
108
+ }
109
+ const resultType = collection.matched.length === 0 ? 'MATCHED_ZERO' : 'MATCHED';
110
+ const zeroMatch = result.zeroMatch || min === 0 || resultType === 'MATCHED_ZERO';
111
+ const matchedResult = {
112
+ type: resultType,
113
+ matched: collection.matched,
114
+ unmatched: collection.unmatched,
115
+ zeroMatch,
116
+ query: result.query,
117
+ hint: (0, utils_1.mergeHints)(result.hint, {
118
+ missing: {
119
+ barelyMatchedElements: collection.matched.length,
120
+ need: result.query,
121
+ },
122
+ }),
123
+ };
124
+ if (collection.unmatched.length > 0) {
125
+ prevResult = matchedResult;
126
+ ptLog('continue⤴️ (add prev)');
127
+ continue;
128
+ }
129
+ ptLog('%s:\n model: %s\n max: %s\n collection: %s\n matched element: %s', resultType, (0, utils_1.modelLog)(model, repeat), max, collection, matchedCount);
130
+ if (result.type === 'MISSING_NODE_REQUIRED' ||
131
+ result.type === 'MISSING_NODE_ONE_OR_MORE' ||
132
+ result.type === 'TRANSPARENT_MODEL_DISALLOWS') {
133
+ return compereResult({
134
+ type: result.type,
135
+ matched: collection.matched,
136
+ unmatched: collection.unmatched,
137
+ zeroMatch: result.zeroMatch,
138
+ query: result.query,
139
+ hint: result.hint,
140
+ }, barelyResult);
141
+ }
142
+ return compereResult(matchedResult, barelyResult);
143
+ }
144
+ }
145
+ exports.countPattern = countPattern;
146
+ const cLog = debug_1.cmLog.extend('countCompereResult');
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) {
152
+ var _a;
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);
154
+ if (b == null) {
155
+ return a;
156
+ }
157
+ if (a.type === 'MATCHED' || a.type === 'MATCHED_ZERO' || a.type === 'UNEXPECTED_EXTRA_NODE') {
158
+ return a;
159
+ }
160
+ const result = (_a = [a, b].sort((a, b) => { var _a, _b, _c, _d; return ((_b = (_a = b.hint.missing) === null || _a === void 0 ? void 0 : _a.barelyMatchedElements) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = a.hint.missing) === null || _c === void 0 ? void 0 : _c.barelyMatchedElements) !== null && _d !== void 0 ? _d : 0); })[0]) !== null && _a !== void 0 ? _a : a;
161
+ return result;
162
+ }
@@ -0,0 +1,30 @@
1
+ /// <reference types="debug" />
2
+ export declare const cmLog: import('debug').Debugger;
3
+ export declare const bgGreen: {
4
+ (): void;
5
+ bold(): void;
6
+ };
7
+ export declare const green: {
8
+ (): void;
9
+ bold(): void;
10
+ };
11
+ export declare const bgRed: {
12
+ (): void;
13
+ bold(): void;
14
+ };
15
+ export declare const bgBlue: {
16
+ (): void;
17
+ bold(): void;
18
+ };
19
+ export declare const blue: {
20
+ (): void;
21
+ bold(): void;
22
+ };
23
+ export declare const bgMagenta: {
24
+ (): void;
25
+ bold(): void;
26
+ };
27
+ export declare const cyan: {
28
+ (): void;
29
+ bold(): void;
30
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cyan = exports.bgMagenta = exports.blue = exports.bgBlue = exports.bgRed = exports.green = exports.bgGreen = exports.cmLog = void 0;
4
+ const debug_1 = require("../debug");
5
+ exports.cmLog = debug_1.log.extend('content-model');
6
+ const fn = () => { };
7
+ fn.bold = () => { };
8
+ exports.bgGreen = fn;
9
+ exports.green = fn;
10
+ exports.bgRed = fn;
11
+ exports.bgBlue = fn;
12
+ exports.blue = fn;
13
+ exports.bgMagenta = fn;
14
+ exports.cyan = fn;
@@ -0,0 +1,3 @@
1
+ /// <reference types="debug" />
2
+ export declare const cmLog: import('debug').Debugger;
3
+ export { bgGreen, green, bgRed, bgBlue, blue, bgMagenta, cyan } from 'ansi-colors';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cyan = exports.bgMagenta = exports.blue = exports.bgBlue = exports.bgRed = exports.green = exports.bgGreen = exports.cmLog = void 0;
4
+ const debug_1 = require("../debug");
5
+ exports.cmLog = debug_1.log.extend('content-model');
6
+ var ansi_colors_1 = require("ansi-colors");
7
+ Object.defineProperty(exports, "bgGreen", { enumerable: true, get: function () { return ansi_colors_1.bgGreen; } });
8
+ Object.defineProperty(exports, "green", { enumerable: true, get: function () { return ansi_colors_1.green; } });
9
+ Object.defineProperty(exports, "bgRed", { enumerable: true, get: function () { return ansi_colors_1.bgRed; } });
10
+ Object.defineProperty(exports, "bgBlue", { enumerable: true, get: function () { return ansi_colors_1.bgBlue; } });
11
+ Object.defineProperty(exports, "blue", { enumerable: true, get: function () { return ansi_colors_1.blue; } });
12
+ Object.defineProperty(exports, "bgMagenta", { enumerable: true, get: function () { return ansi_colors_1.bgMagenta; } });
13
+ Object.defineProperty(exports, "cyan", { enumerable: true, get: function () { return ansi_colors_1.cyan; } });
@@ -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
- };
8
- declare const _default: import("@markuplint/ml-core").RuleSeed<TagRule[], Options>;
1
+ import type { Options, TagRule } from './types';
2
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<TagRule[], Options>>;
9
3
  export default _default;