@markuplint/rules 4.11.2 → 5.0.0-alpha.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.
Files changed (266) hide show
  1. package/CHANGELOG.md +63 -2
  2. package/SKILL.md +76 -0
  3. package/lib/attr-check.d.ts +46 -7
  4. package/lib/attr-check.js +42 -8
  5. package/lib/attr-duplication/index.d.ts +7 -0
  6. package/lib/attr-duplication/index.js +7 -0
  7. package/lib/attr-duplication/meta.d.ts +1 -0
  8. package/lib/attr-duplication/meta.js +1 -0
  9. package/lib/attr-value-quotes/index.d.ts +10 -0
  10. package/lib/attr-value-quotes/index.js +10 -0
  11. package/lib/attr-value-quotes/meta.d.ts +1 -0
  12. package/lib/attr-value-quotes/meta.js +1 -0
  13. package/lib/case-sensitive-attr-name/index.d.ts +9 -0
  14. package/lib/case-sensitive-attr-name/index.js +8 -0
  15. package/lib/case-sensitive-attr-name/meta.d.ts +1 -0
  16. package/lib/case-sensitive-attr-name/meta.js +1 -0
  17. package/lib/case-sensitive-tag-name/index.d.ts +9 -0
  18. package/lib/case-sensitive-tag-name/index.js +8 -0
  19. package/lib/case-sensitive-tag-name/meta.d.ts +1 -0
  20. package/lib/case-sensitive-tag-name/meta.js +1 -0
  21. package/lib/character-reference/index.d.ts +9 -0
  22. package/lib/character-reference/index.js +20 -0
  23. package/lib/character-reference/meta.d.ts +1 -0
  24. package/lib/character-reference/meta.js +1 -0
  25. package/lib/class-naming/index.d.ts +9 -0
  26. package/lib/class-naming/index.js +8 -0
  27. package/lib/class-naming/meta.d.ts +1 -0
  28. package/lib/class-naming/meta.js +1 -0
  29. package/lib/correct-aspect-ratio/index.d.ts +5 -0
  30. package/lib/correct-aspect-ratio/index.js +80 -0
  31. package/lib/correct-aspect-ratio/meta.d.ts +4 -0
  32. package/lib/correct-aspect-ratio/meta.js +3 -0
  33. package/lib/correct-aspect-ratio/resolve-image-size.d.ts +24 -0
  34. package/lib/correct-aspect-ratio/resolve-image-size.js +165 -0
  35. package/lib/create-message.d.ts +29 -2
  36. package/lib/create-message.js +60 -2
  37. package/lib/debug.d.ts +9 -0
  38. package/lib/debug.js +5 -0
  39. package/lib/deprecated-attr/index.d.ts +6 -0
  40. package/lib/deprecated-attr/index.js +6 -0
  41. package/lib/deprecated-attr/meta.d.ts +1 -0
  42. package/lib/deprecated-attr/meta.js +1 -0
  43. package/lib/deprecated-element/index.d.ts +6 -0
  44. package/lib/deprecated-element/index.js +8 -2
  45. package/lib/deprecated-element/meta.d.ts +1 -0
  46. package/lib/deprecated-element/meta.js +1 -0
  47. package/lib/disallowed-element/index.d.ts +7 -0
  48. package/lib/disallowed-element/index.js +7 -0
  49. package/lib/disallowed-element/meta.d.ts +1 -0
  50. package/lib/disallowed-element/meta.js +1 -0
  51. package/lib/doctype/index.d.ts +10 -0
  52. package/lib/doctype/index.js +8 -0
  53. package/lib/doctype/meta.d.ts +1 -0
  54. package/lib/doctype/meta.js +1 -0
  55. package/lib/end-tag/index.d.ts +7 -0
  56. package/lib/end-tag/index.js +8 -1
  57. package/lib/end-tag/meta.d.ts +1 -0
  58. package/lib/end-tag/meta.js +1 -0
  59. package/lib/heading-levels/index.d.ts +6 -0
  60. package/lib/heading-levels/index.js +6 -1
  61. package/lib/heading-levels/meta.d.ts +1 -0
  62. package/lib/heading-levels/meta.js +1 -0
  63. package/lib/helpers.d.ts +105 -0
  64. package/lib/helpers.js +112 -16
  65. package/lib/id-duplication/index.d.ts +7 -0
  66. package/lib/id-duplication/index.js +7 -0
  67. package/lib/id-duplication/meta.d.ts +1 -0
  68. package/lib/id-duplication/meta.js +1 -0
  69. package/lib/index.d.ts +43 -41
  70. package/lib/index.js +24 -0
  71. package/lib/ineffective-attr/index.d.ts +7 -0
  72. package/lib/ineffective-attr/index.js +7 -0
  73. package/lib/ineffective-attr/meta.d.ts +1 -0
  74. package/lib/ineffective-attr/meta.js +1 -0
  75. package/lib/invalid-attr/index.d.ts +29 -21
  76. package/lib/invalid-attr/index.js +60 -109
  77. package/lib/invalid-attr/meta.d.ts +1 -0
  78. package/lib/invalid-attr/meta.js +1 -0
  79. package/lib/label-has-control/index.d.ts +7 -0
  80. package/lib/label-has-control/index.js +11 -0
  81. package/lib/label-has-control/meta.d.ts +1 -0
  82. package/lib/label-has-control/meta.js +1 -0
  83. package/lib/landmark-roles/index.d.ts +14 -0
  84. package/lib/landmark-roles/index.js +21 -0
  85. package/lib/landmark-roles/meta.d.ts +1 -0
  86. package/lib/landmark-roles/meta.js +1 -0
  87. package/lib/link-types/index.d.ts +10 -0
  88. package/lib/link-types/index.js +180 -0
  89. package/lib/link-types/meta.d.ts +5 -0
  90. package/lib/link-types/meta.js +4 -0
  91. package/lib/neighbor-popovers/index.d.ts +8 -0
  92. package/lib/neighbor-popovers/index.js +28 -6
  93. package/lib/neighbor-popovers/meta.d.ts +1 -0
  94. package/lib/neighbor-popovers/meta.js +1 -0
  95. package/lib/no-ambiguous-navigable-target-names/index.d.ts +8 -0
  96. package/lib/no-ambiguous-navigable-target-names/index.js +8 -0
  97. package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -0
  98. package/lib/no-ambiguous-navigable-target-names/meta.js +1 -0
  99. package/lib/no-boolean-attr-value/index.d.ts +7 -0
  100. package/lib/no-boolean-attr-value/index.js +7 -0
  101. package/lib/no-boolean-attr-value/meta.d.ts +1 -0
  102. package/lib/no-boolean-attr-value/meta.js +1 -0
  103. package/lib/no-consecutive-br/index.d.ts +8 -0
  104. package/lib/no-consecutive-br/index.js +8 -0
  105. package/lib/no-consecutive-br/meta.d.ts +1 -0
  106. package/lib/no-consecutive-br/meta.js +1 -0
  107. package/lib/no-default-value/index.d.ts +7 -0
  108. package/lib/no-default-value/index.js +7 -0
  109. package/lib/no-default-value/meta.d.ts +1 -0
  110. package/lib/no-default-value/meta.js +1 -0
  111. package/lib/no-duplicate-dt/index.d.ts +6 -0
  112. package/lib/no-duplicate-dt/index.js +6 -0
  113. package/lib/no-duplicate-dt/meta.d.ts +1 -0
  114. package/lib/no-duplicate-dt/meta.js +1 -0
  115. package/lib/no-empty-palpable-content/index.d.ts +13 -0
  116. package/lib/no-empty-palpable-content/index.js +12 -0
  117. package/lib/no-empty-palpable-content/meta.d.ts +1 -0
  118. package/lib/no-empty-palpable-content/meta.js +1 -0
  119. package/lib/no-hard-code-id/index.d.ts +8 -0
  120. package/lib/no-hard-code-id/index.js +8 -0
  121. package/lib/no-hard-code-id/meta.d.ts +1 -0
  122. package/lib/no-hard-code-id/meta.js +1 -0
  123. package/lib/no-orphaned-end-tag/index.d.ts +7 -0
  124. package/lib/no-orphaned-end-tag/index.js +8 -2
  125. package/lib/no-orphaned-end-tag/meta.d.ts +1 -0
  126. package/lib/no-orphaned-end-tag/meta.js +1 -0
  127. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -1
  128. package/lib/no-refer-to-non-existent-id/index.js +11 -2
  129. package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -0
  130. package/lib/no-refer-to-non-existent-id/meta.js +1 -0
  131. package/lib/no-unsupported-features/compat-data.d.ts +71 -0
  132. package/lib/no-unsupported-features/compat-data.js +204 -0
  133. package/lib/no-unsupported-features/index.d.ts +24 -0
  134. package/lib/no-unsupported-features/index.js +139 -0
  135. package/lib/no-unsupported-features/meta.d.ts +5 -0
  136. package/lib/no-unsupported-features/meta.js +4 -0
  137. package/lib/no-unsupported-features/resolve-browsers.d.ts +30 -0
  138. package/lib/no-unsupported-features/resolve-browsers.js +125 -0
  139. package/lib/no-use-event-handler-attr/index.d.ts +10 -0
  140. package/lib/no-use-event-handler-attr/index.js +8 -0
  141. package/lib/no-use-event-handler-attr/meta.d.ts +1 -0
  142. package/lib/no-use-event-handler-attr/meta.js +1 -0
  143. package/lib/permitted-contents/choice.d.ts +17 -0
  144. package/lib/permitted-contents/choice.js +31 -1
  145. package/lib/permitted-contents/complex-branch.d.ts +11 -7
  146. package/lib/permitted-contents/complex-branch.js +11 -7
  147. package/lib/permitted-contents/content-model.d.ts +11 -0
  148. package/lib/permitted-contents/content-model.js +32 -0
  149. package/lib/permitted-contents/count-pattern.d.ts +13 -7
  150. package/lib/permitted-contents/count-pattern.js +24 -8
  151. package/lib/permitted-contents/debug.browser.d.ts +12 -0
  152. package/lib/permitted-contents/debug.browser.js +12 -0
  153. package/lib/permitted-contents/debug.d.ts +12 -0
  154. package/lib/permitted-contents/debug.js +12 -0
  155. package/lib/permitted-contents/index.d.ts +12 -0
  156. package/lib/permitted-contents/index.js +21 -0
  157. package/lib/permitted-contents/matches-selector.d.ts +19 -0
  158. package/lib/permitted-contents/matches-selector.js +33 -0
  159. package/lib/permitted-contents/meta.d.ts +1 -0
  160. package/lib/permitted-contents/meta.js +1 -0
  161. package/lib/permitted-contents/order.d.ts +14 -7
  162. package/lib/permitted-contents/order.js +15 -8
  163. package/lib/permitted-contents/recursive-branch.d.ts +17 -0
  164. package/lib/permitted-contents/recursive-branch.js +17 -0
  165. package/lib/permitted-contents/represent-transparent-nodes.d.ts +54 -0
  166. package/lib/permitted-contents/represent-transparent-nodes.js +119 -12
  167. package/lib/permitted-contents/start.d.ts +12 -6
  168. package/lib/permitted-contents/start.js +12 -6
  169. package/lib/permitted-contents/transparent.d.ts +12 -0
  170. package/lib/permitted-contents/transparent.js +12 -0
  171. package/lib/permitted-contents/types.d.ts +67 -0
  172. package/lib/permitted-contents/utils.d.ts +160 -0
  173. package/lib/permitted-contents/utils.js +216 -35
  174. package/lib/placeholder-label-option/index.d.ts +7 -0
  175. package/lib/placeholder-label-option/index.js +19 -15
  176. package/lib/placeholder-label-option/meta.d.ts +1 -0
  177. package/lib/placeholder-label-option/meta.js +1 -0
  178. package/lib/redundant-accessible-name/index.d.ts +10 -0
  179. package/lib/redundant-accessible-name/index.js +123 -0
  180. package/lib/redundant-accessible-name/meta.d.ts +5 -0
  181. package/lib/redundant-accessible-name/meta.js +4 -0
  182. package/lib/require-accessible-name/index.d.ts +10 -4
  183. package/lib/require-accessible-name/index.js +13 -5
  184. package/lib/require-accessible-name/meta.d.ts +1 -0
  185. package/lib/require-accessible-name/meta.js +1 -0
  186. package/lib/require-datetime/index.d.ts +12 -0
  187. package/lib/require-datetime/index.js +8 -0
  188. package/lib/require-datetime/meta.d.ts +1 -0
  189. package/lib/require-datetime/meta.js +1 -0
  190. package/lib/require-datetime/types.d.ts +7 -0
  191. package/lib/require-datetime/utils.d.ts +18 -5
  192. package/lib/require-datetime/utils.js +53 -9
  193. package/lib/require-dialog-autofocus/index.d.ts +22 -0
  194. package/lib/require-dialog-autofocus/index.js +62 -0
  195. package/lib/require-dialog-autofocus/meta.d.ts +5 -0
  196. package/lib/require-dialog-autofocus/meta.js +4 -0
  197. package/lib/required-attr/index.d.ts +21 -1
  198. package/lib/required-attr/index.js +34 -4
  199. package/lib/required-attr/meta.d.ts +1 -0
  200. package/lib/required-attr/meta.js +1 -0
  201. package/lib/required-element/index.d.ts +14 -0
  202. package/lib/required-element/index.js +14 -2
  203. package/lib/required-element/meta.d.ts +1 -0
  204. package/lib/required-element/meta.js +1 -0
  205. package/lib/required-h1/index.d.ts +12 -0
  206. package/lib/required-h1/index.js +7 -0
  207. package/lib/required-h1/meta.d.ts +1 -0
  208. package/lib/required-h1/meta.js +1 -0
  209. package/lib/srcset-sizes-constraint/index.d.ts +6 -0
  210. package/lib/srcset-sizes-constraint/index.js +108 -0
  211. package/lib/srcset-sizes-constraint/meta.d.ts +5 -0
  212. package/lib/srcset-sizes-constraint/meta.js +4 -0
  213. package/lib/srcset-sizes-constraint/parse-srcset.d.ts +40 -0
  214. package/lib/srcset-sizes-constraint/parse-srcset.js +56 -0
  215. package/lib/table-row-column-alignment/find-children.d.ts +10 -0
  216. package/lib/table-row-column-alignment/find-children.js +11 -0
  217. package/lib/table-row-column-alignment/grid.d.ts +60 -0
  218. package/lib/table-row-column-alignment/grid.js +104 -26
  219. package/lib/table-row-column-alignment/index.d.ts +8 -0
  220. package/lib/table-row-column-alignment/index.js +8 -0
  221. package/lib/table-row-column-alignment/meta.d.ts +1 -0
  222. package/lib/table-row-column-alignment/meta.js +1 -0
  223. package/lib/table-row-column-alignment/types.d.ts +10 -0
  224. package/lib/use-list/index.d.ts +16 -0
  225. package/lib/use-list/index.js +20 -0
  226. package/lib/use-list/meta.d.ts +1 -0
  227. package/lib/use-list/meta.js +1 -0
  228. package/lib/wai-aria/checkings/abstract-role.d.ts +9 -0
  229. package/lib/wai-aria/checkings/abstract-role.js +14 -2
  230. package/lib/wai-aria/checkings/default-value.d.ts +11 -0
  231. package/lib/wai-aria/checkings/default-value.js +11 -0
  232. package/lib/wai-aria/checkings/deprecated-props.d.ts +11 -0
  233. package/lib/wai-aria/checkings/deprecated-props.js +11 -0
  234. package/lib/wai-aria/checkings/deprecated-role.d.ts +10 -0
  235. package/lib/wai-aria/checkings/deprecated-role.js +10 -0
  236. package/lib/wai-aria/checkings/disallowed-prop.d.ts +14 -0
  237. package/lib/wai-aria/checkings/disallowed-prop.js +19 -2
  238. package/lib/wai-aria/checkings/implicit-props.d.ts +13 -0
  239. package/lib/wai-aria/checkings/implicit-props.js +13 -0
  240. package/lib/wai-aria/checkings/implicit-role.d.ts +9 -0
  241. package/lib/wai-aria/checkings/implicit-role.js +14 -2
  242. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +9 -0
  243. package/lib/wai-aria/checkings/interaction-in-hidden.js +15 -4
  244. package/lib/wai-aria/checkings/no-global-prop.d.ts +10 -0
  245. package/lib/wai-aria/checkings/no-global-prop.js +10 -0
  246. package/lib/wai-aria/checkings/non-existent-role.d.ts +11 -0
  247. package/lib/wai-aria/checkings/non-existent-role.js +19 -2
  248. package/lib/wai-aria/checkings/permitted-roles.d.ts +10 -0
  249. package/lib/wai-aria/checkings/permitted-roles.js +15 -2
  250. package/lib/wai-aria/checkings/presentational-children.d.ts +7 -1
  251. package/lib/wai-aria/checkings/presentational-children.js +17 -3
  252. package/lib/wai-aria/checkings/required-accessibility-parent-role.d.ts +25 -0
  253. package/lib/wai-aria/checkings/required-accessibility-parent-role.js +56 -0
  254. package/lib/wai-aria/checkings/required-owned-elements.d.ts +10 -1
  255. package/lib/wai-aria/checkings/required-owned-elements.js +69 -25
  256. package/lib/wai-aria/checkings/required-prop.d.ts +13 -0
  257. package/lib/wai-aria/checkings/required-prop.js +18 -2
  258. package/lib/wai-aria/checkings/value.d.ts +23 -0
  259. package/lib/wai-aria/checkings/value.js +32 -0
  260. package/lib/wai-aria/index.d.ts +10 -0
  261. package/lib/wai-aria/index.js +22 -4
  262. package/lib/wai-aria/meta.d.ts +1 -0
  263. package/lib/wai-aria/meta.js +1 -0
  264. package/lib/wai-aria/types.d.ts +25 -1
  265. package/package.json +16 -11
  266. package/schema.json +18 -0
@@ -2,13 +2,17 @@ import type { ChildNode, Options, Result, Specs } from './types.js';
2
2
  import type { PermittedContentPattern } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
4
  /**
5
- * Check content condition
5
+ * Dispatches a single content model pattern to the appropriate handler based on its type.
6
+ * Acts as a routing layer in the content model validation pipeline:
7
+ * - Choice patterns (alternation) are delegated to `choice`.
8
+ * - Transparent patterns are delegated to `transparent`.
9
+ * - All other quantified patterns (require, optional, oneOrMore, zeroOrMore) are delegated to `countPattern`.
6
10
  *
7
- * @param pattern
8
- * @param childNodes
9
- * @param specs
10
- * @param options
11
- * @param depth
12
- * @returns
11
+ * @param pattern - A single content model pattern to evaluate.
12
+ * @param childNodes - The child nodes to validate against the pattern.
13
+ * @param specs - The resolved spec data for content model lookups.
14
+ * @param options - Validation behavior options.
15
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
16
+ * @returns A result indicating whether the child nodes match the pattern.
13
17
  */
14
18
  export declare function complexBranch(pattern: ReadonlyDeep<PermittedContentPattern>, childNodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): Result;
@@ -3,14 +3,18 @@ import { countPattern } from './count-pattern.js';
3
3
  import { transparent } from './transparent.js';
4
4
  import { isChoice, isTransparent } from './utils.js';
5
5
  /**
6
- * Check content condition
6
+ * Dispatches a single content model pattern to the appropriate handler based on its type.
7
+ * Acts as a routing layer in the content model validation pipeline:
8
+ * - Choice patterns (alternation) are delegated to `choice`.
9
+ * - Transparent patterns are delegated to `transparent`.
10
+ * - All other quantified patterns (require, optional, oneOrMore, zeroOrMore) are delegated to `countPattern`.
7
11
  *
8
- * @param pattern
9
- * @param childNodes
10
- * @param specs
11
- * @param options
12
- * @param depth
13
- * @returns
12
+ * @param pattern - A single content model pattern to evaluate.
13
+ * @param childNodes - The child nodes to validate against the pattern.
14
+ * @param specs - The resolved spec data for content model lookups.
15
+ * @param options - Validation behavior options.
16
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
17
+ * @returns A result indicating whether the child nodes match the pattern.
14
18
  */
15
19
  export function complexBranch(pattern,
16
20
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -1,2 +1,13 @@
1
1
  import type { ContentModelResult, Element, Options, TagRule } from './types.js';
2
+ /**
3
+ * Top-level entry point for content model validation of a single element.
4
+ * Resolves the element's content model from the spec (possibly augmented
5
+ * by user-defined tag rules), then delegates to `start` to validate
6
+ * the element's child nodes against that model.
7
+ *
8
+ * @param el - The element whose children are to be validated against its content model.
9
+ * @param rules - User-defined tag rules that can override or extend built-in content models.
10
+ * @param options - Validation behavior options (e.g., whether to ignore mutable children).
11
+ * @returns An array of content model results, one per child node issue found (empty if all valid).
12
+ */
2
13
  export declare function contentModel(el: Element, rules: readonly TagRule[], options: Options): ContentModelResult[];
@@ -1,5 +1,16 @@
1
1
  import { getContentModel } from '@markuplint/ml-spec';
2
2
  import { start } from './start.js';
3
+ /**
4
+ * Top-level entry point for content model validation of a single element.
5
+ * Resolves the element's content model from the spec (possibly augmented
6
+ * by user-defined tag rules), then delegates to `start` to validate
7
+ * the element's child nodes against that model.
8
+ *
9
+ * @param el - The element whose children are to be validated against its content model.
10
+ * @param rules - User-defined tag rules that can override or extend built-in content models.
11
+ * @param options - Validation behavior options (e.g., whether to ignore mutable children).
12
+ * @returns An array of content model results, one per child node issue found (empty if all valid).
13
+ */
3
14
  export function contentModel(
4
15
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
16
  el, rules, options) {
@@ -17,6 +28,15 @@ el, rules, options) {
17
28
  const result = start(model, el, specs, options);
18
29
  return result;
19
30
  }
31
+ /**
32
+ * Builds the content model and merged specs for a given element.
33
+ * Combines the element's document-level specs with any user-defined
34
+ * tag rules, then looks up the content model for the element.
35
+ *
36
+ * @param el - The element to look up the content model for.
37
+ * @param rules - User-defined tag rules to merge into the spec.
38
+ * @returns An object containing the resolved content model and merged specs.
39
+ */
20
40
  function createModel(
21
41
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
22
42
  el, rules) {
@@ -27,7 +47,19 @@ el, rules) {
27
47
  specs,
28
48
  };
29
49
  }
50
+ /**
51
+ * Cache for merged specs keyed by the JSON-serialized tag rules.
52
+ * Avoids re-merging the same set of user-defined tag rules on every element check.
53
+ */
30
54
  const caches = new Map();
55
+ /**
56
+ * Returns a Specs object that merges the base ML spec with user-defined
57
+ * tag rules. Results are cached by the serialized rules to avoid redundant merging.
58
+ *
59
+ * @param specs - The base ML spec from the document.
60
+ * @param rules - User-defined tag rules to merge.
61
+ * @returns The merged Specs, either from cache or freshly computed.
62
+ */
31
63
  function cachedSpecs(specs, rules) {
32
64
  if (rules.length === 0) {
33
65
  return specs;
@@ -2,13 +2,19 @@ import type { ChildNode, Options, Result, Specs } from './types.js';
2
2
  import type { PermittedContentOneOrMore, PermittedContentOptional, PermittedContentRequire, PermittedContentZeroOrMore } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
4
  /**
5
- * Check count
5
+ * Validates a quantified content model pattern (require, optional, oneOrMore, or zeroOrMore)
6
+ * against a list of child nodes. Repeatedly applies the inner pattern via `recursiveBranch`
7
+ * until the minimum count is satisfied and no more nodes match, or until the maximum count
8
+ * is exceeded.
6
9
  *
7
- * @param pattern
8
- * @param childNodes
9
- * @param specs
10
- * @param options
11
- * @param depth
12
- * @returns
10
+ * Implements the repetition/quantifier semantics of content models (e.g., "one or more
11
+ * flow content elements", "optionally a `<caption>`", "exactly one `<tbody>`").
12
+ *
13
+ * @param pattern - A quantified content model pattern (require, optional, oneOrMore, or zeroOrMore).
14
+ * @param childNodes - The child nodes to validate against the repeated pattern.
15
+ * @param specs - The resolved spec data for content model lookups.
16
+ * @param options - Validation behavior options.
17
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
18
+ * @returns A result indicating whether the required count of matches was achieved.
13
19
  */
14
20
  export declare function countPattern(pattern: ReadonlyDeep<PermittedContentOneOrMore> | ReadonlyDeep<PermittedContentOptional> | ReadonlyDeep<PermittedContentRequire> | ReadonlyDeep<PermittedContentZeroOrMore>, childNodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): Result;
@@ -3,14 +3,20 @@ import { recursiveBranch } from './recursive-branch.js';
3
3
  import { Collection, mergeHints, modelLog, normalizeModel } from './utils.js';
4
4
  const cLog = cmLog.extend('countCompereResult');
5
5
  /**
6
- * Check count
6
+ * Validates a quantified content model pattern (require, optional, oneOrMore, or zeroOrMore)
7
+ * against a list of child nodes. Repeatedly applies the inner pattern via `recursiveBranch`
8
+ * until the minimum count is satisfied and no more nodes match, or until the maximum count
9
+ * is exceeded.
7
10
  *
8
- * @param pattern
9
- * @param childNodes
10
- * @param specs
11
- * @param options
12
- * @param depth
13
- * @returns
11
+ * Implements the repetition/quantifier semantics of content models (e.g., "one or more
12
+ * flow content elements", "optionally a `<caption>`", "exactly one `<tbody>`").
13
+ *
14
+ * @param pattern - A quantified content model pattern (require, optional, oneOrMore, or zeroOrMore).
15
+ * @param childNodes - The child nodes to validate against the repeated pattern.
16
+ * @param specs - The resolved spec data for content model lookups.
17
+ * @param options - Validation behavior options.
18
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
19
+ * @returns A result indicating whether the required count of matches was achieved.
14
20
  */
15
21
  export function countPattern(pattern,
16
22
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -139,6 +145,16 @@ childNodes, specs, options, depth) {
139
145
  return compereResult(matchedResult, barelyResult);
140
146
  }
141
147
  }
148
+ /**
149
+ * Compares two results and returns the one that represents the best diagnostic outcome.
150
+ * When the primary result is a match or an unexpected-extra-node, it is preferred.
151
+ * Otherwise, the result with more barely-matched elements (closer to success) is chosen
152
+ * to provide the most helpful error message.
153
+ *
154
+ * @param a - The primary (current iteration) result.
155
+ * @param b - The barely-matched result from a previous successful partial match, or null.
156
+ * @returns The result that should be reported to the user.
157
+ */
142
158
  function compereResult(
143
159
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
144
160
  a,
@@ -151,6 +167,6 @@ b) {
151
167
  if (a.type === 'MATCHED' || a.type === 'MATCHED_ZERO' || a.type === 'UNEXPECTED_EXTRA_NODE') {
152
168
  return a;
153
169
  }
154
- const result = [a, b].sort((a, b) => (b.hint.missing?.barelyMatchedElements ?? 0) - (a.hint.missing?.barelyMatchedElements ?? 0))[0] ?? a;
170
+ const result = [a, b].toSorted((a, b) => (b.hint.missing?.barelyMatchedElements ?? 0) - (a.hint.missing?.barelyMatchedElements ?? 0))[0] ?? a;
155
171
  return result;
156
172
  }
@@ -1,29 +1,41 @@
1
1
  import type { Log } from '../debug.js';
2
+ /**
3
+ * Debug logger scoped to the content-model validation module (browser build).
4
+ * Extends the parent rule logger with a `content-model` namespace.
5
+ * In the browser environment, color helpers are no-op stubs.
6
+ */
2
7
  export declare const cmLog: Log;
8
+ /** No-op color stub for browser environments: green background. */
3
9
  export declare const bgGreen: {
4
10
  (): void;
5
11
  bold(): void;
6
12
  };
13
+ /** No-op color stub for browser environments: green foreground. */
7
14
  export declare const green: {
8
15
  (): void;
9
16
  bold(): void;
10
17
  };
18
+ /** No-op color stub for browser environments: red background. */
11
19
  export declare const bgRed: {
12
20
  (): void;
13
21
  bold(): void;
14
22
  };
23
+ /** No-op color stub for browser environments: blue background. */
15
24
  export declare const bgBlue: {
16
25
  (): void;
17
26
  bold(): void;
18
27
  };
28
+ /** No-op color stub for browser environments: blue foreground. */
19
29
  export declare const blue: {
20
30
  (): void;
21
31
  bold(): void;
22
32
  };
33
+ /** No-op color stub for browser environments: magenta background. */
23
34
  export declare const bgMagenta: {
24
35
  (): void;
25
36
  bold(): void;
26
37
  };
38
+ /** No-op color stub for browser environments: cyan foreground. */
27
39
  export declare const cyan: {
28
40
  (): void;
29
41
  bold(): void;
@@ -1,11 +1,23 @@
1
1
  import { log } from '../debug.js';
2
+ /**
3
+ * Debug logger scoped to the content-model validation module (browser build).
4
+ * Extends the parent rule logger with a `content-model` namespace.
5
+ * In the browser environment, color helpers are no-op stubs.
6
+ */
2
7
  export const cmLog = log.extend('content-model');
3
8
  const fn = () => { };
4
9
  fn.bold = () => { };
10
+ /** No-op color stub for browser environments: green background. */
5
11
  export const bgGreen = fn;
12
+ /** No-op color stub for browser environments: green foreground. */
6
13
  export const green = fn;
14
+ /** No-op color stub for browser environments: red background. */
7
15
  export const bgRed = fn;
16
+ /** No-op color stub for browser environments: blue background. */
8
17
  export const bgBlue = fn;
18
+ /** No-op color stub for browser environments: blue foreground. */
9
19
  export const blue = fn;
20
+ /** No-op color stub for browser environments: magenta background. */
10
21
  export const bgMagenta = fn;
22
+ /** No-op color stub for browser environments: cyan foreground. */
11
23
  export const cyan = fn;
@@ -1,10 +1,22 @@
1
1
  import type { Log } from '../debug.js';
2
2
  import color from 'ansi-colors';
3
+ /**
4
+ * Debug logger scoped to the content-model validation module.
5
+ * Extends the parent rule logger with a `content-model` namespace
6
+ * for structured debug output during content model evaluation.
7
+ */
3
8
  export declare const cmLog: Log;
9
+ /** ANSI color helper: green background for highlighting locked-and-matched nodes in debug output. */
4
10
  export declare const bgGreen: color.StyleFunction;
11
+ /** ANSI color helper: green foreground for highlighting matched nodes in debug output. */
5
12
  export declare const green: color.StyleFunction;
13
+ /** ANSI color helper: red background for highlighting unexpected/extra nodes in debug output. */
6
14
  export declare const bgRed: color.StyleFunction;
15
+ /** ANSI color helper: blue background for highlighting locked-and-matched transparent nodes in debug output. */
7
16
  export declare const bgBlue: color.StyleFunction;
17
+ /** ANSI color helper: blue foreground for highlighting matched transparent nodes in debug output. */
8
18
  export declare const blue: color.StyleFunction;
19
+ /** ANSI color helper: magenta background for highlighting unexpected transparent nodes in debug output. */
9
20
  export declare const bgMagenta: color.StyleFunction;
21
+ /** ANSI color helper: cyan foreground for highlighting unmatched transparent nodes in debug output. */
10
22
  export declare const cyan: color.StyleFunction;
@@ -1,10 +1,22 @@
1
1
  import color from 'ansi-colors';
2
2
  import { log } from '../debug.js';
3
+ /**
4
+ * Debug logger scoped to the content-model validation module.
5
+ * Extends the parent rule logger with a `content-model` namespace
6
+ * for structured debug output during content model evaluation.
7
+ */
3
8
  export const cmLog = log.extend('content-model');
9
+ /** ANSI color helper: green background for highlighting locked-and-matched nodes in debug output. */
4
10
  export const bgGreen = color.bgGreen;
11
+ /** ANSI color helper: green foreground for highlighting matched nodes in debug output. */
5
12
  export const green = color.green;
13
+ /** ANSI color helper: red background for highlighting unexpected/extra nodes in debug output. */
6
14
  export const bgRed = color.bgRed;
15
+ /** ANSI color helper: blue background for highlighting locked-and-matched transparent nodes in debug output. */
7
16
  export const bgBlue = color.bgBlue;
17
+ /** ANSI color helper: blue foreground for highlighting matched transparent nodes in debug output. */
8
18
  export const blue = color.blue;
19
+ /** ANSI color helper: magenta background for highlighting unexpected transparent nodes in debug output. */
9
20
  export const bgMagenta = color.bgMagenta;
21
+ /** ANSI color helper: cyan foreground for highlighting unmatched transparent nodes in debug output. */
10
22
  export const cyan = color.cyan;
@@ -1,3 +1,15 @@
1
1
  import type { Options, TagRule } from './types.js';
2
+ /**
3
+ * The `permitted-contents` rule validates that each element's child nodes conform
4
+ * to the HTML content model specification. It is the most complex rule in markuplint,
5
+ * implementing a full content model validation engine that handles ordered sequences,
6
+ * quantified patterns (require, optional, oneOrMore, zeroOrMore), choice alternations,
7
+ * transparent content models, and conditional child node branches.
8
+ *
9
+ * For each element, it resolves the applicable content model (from the HTML spec or
10
+ * user-defined tag rules), evaluates the element's children against that model, and
11
+ * reports violations such as unexpected elements, missing required elements, or
12
+ * disallowed content through transparent models.
13
+ */
2
14
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<TagRule[], Options>>;
3
15
  export default _default;
@@ -2,6 +2,18 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { contentModel } from './content-model.js';
3
3
  import meta from './meta.js';
4
4
  import { transparentMode } from './represent-transparent-nodes.js';
5
+ /**
6
+ * The `permitted-contents` rule validates that each element's child nodes conform
7
+ * to the HTML content model specification. It is the most complex rule in markuplint,
8
+ * implementing a full content model validation engine that handles ordered sequences,
9
+ * quantified patterns (require, optional, oneOrMore, zeroOrMore), choice alternations,
10
+ * transparent content models, and conditional child node branches.
11
+ *
12
+ * For each element, it resolves the applicable content model (from the HTML spec or
13
+ * user-defined tag rules), evaluates the element's children against that model, and
14
+ * reports violations such as unexpected elements, missing required elements, or
15
+ * disallowed content through transparent models.
16
+ */
5
17
  export default createRule({
6
18
  meta: meta,
7
19
  defaultValue: [],
@@ -91,6 +103,15 @@ export default createRule({
91
103
  });
92
104
  },
93
105
  });
106
+ /**
107
+ * Generates a localized, human-readable name for a child node based on its type.
108
+ * Used in error messages to describe the offending node (e.g., 'the "div" element',
109
+ * 'the text node', 'the comment', 'the doctype', 'the code block').
110
+ *
111
+ * @param scope - The child node to generate a name for.
112
+ * @param t - The translator function for localized message formatting.
113
+ * @returns A localized string describing the node.
114
+ */
94
115
  function name(
95
116
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
96
117
  scope, t) {
@@ -1,3 +1,22 @@
1
1
  import type { ChildNode, Result, Specs } from './types.js';
2
+ /**
3
+ * Extended result type for selector matching that includes additional
4
+ * intermediate states: a selector that did not match but allows empty content,
5
+ * a missing node, or unmatched selectors with partial matches.
6
+ */
2
7
  export type SelectorResult = Result<'UNMATCHED_SELECTOR_BUT_MAY_EMPTY' | 'MISSING_NODE' | 'UNMATCHED_SELECTORS'>;
8
+ /**
9
+ * Tests whether a single child node matches a content model query selector.
10
+ * Handles special node types (text nodes, preprocessor blocks, custom elements)
11
+ * and delegates standard element matching to the CSS selector engine.
12
+ *
13
+ * The query string may reference content model categories (e.g., `#phrasing`)
14
+ * which are expanded to concrete tag selectors via `optCondition`.
15
+ *
16
+ * @param query - The content model query string (e.g., `"div"`, `"#phrasing"`, `":model(flow)"`).
17
+ * @param childNode - The child node to test, or undefined if no node is available.
18
+ * @param specs - The resolved spec data for category-to-tag-name expansion.
19
+ * @param depth - The current recursion depth, used for debug logging namespacing.
20
+ * @returns A selector result indicating match status with diagnostic hints.
21
+ */
3
22
  export declare function matchesSelector(query: string, childNode: ChildNode | undefined, specs: Specs, depth: number): SelectorResult;
@@ -1,6 +1,20 @@
1
1
  import { contentModelCategoryToTagNames } from '@markuplint/ml-spec';
2
2
  import { cmLog } from './debug.js';
3
3
  import { cleanObject, matches } from './utils.js';
4
+ /**
5
+ * Tests whether a single child node matches a content model query selector.
6
+ * Handles special node types (text nodes, preprocessor blocks, custom elements)
7
+ * and delegates standard element matching to the CSS selector engine.
8
+ *
9
+ * The query string may reference content model categories (e.g., `#phrasing`)
10
+ * which are expanded to concrete tag selectors via `optCondition`.
11
+ *
12
+ * @param query - The content model query string (e.g., `"div"`, `"#phrasing"`, `":model(flow)"`).
13
+ * @param childNode - The child node to test, or undefined if no node is available.
14
+ * @param specs - The resolved spec data for category-to-tag-name expansion.
15
+ * @param depth - The current recursion depth, used for debug logging namespacing.
16
+ * @returns A selector result indicating match status with diagnostic hints.
17
+ */
4
18
  export function matchesSelector(query,
5
19
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
6
20
  childNode, specs, depth) {
@@ -127,6 +141,9 @@ childNode, specs, depth) {
127
141
  hint: {},
128
142
  };
129
143
  }
144
+ /**
145
+ * Pre-computed conditions for well-known queries that do not depend on specs.
146
+ */
130
147
  const conditionWithoutSpecs = {
131
148
  '#custom': {
132
149
  selector: '#custom',
@@ -139,7 +156,23 @@ const conditionWithoutSpecs = {
139
156
  hasText: true,
140
157
  },
141
158
  };
159
+ /**
160
+ * Cache of parsed conditions keyed by specs instance and query string.
161
+ * Prevents redundant category expansion for the same query across multiple elements.
162
+ */
142
163
  const optConditionSpecsBaseCaches = new Map();
164
+ /**
165
+ * Parses a content model query string into a Condition object by expanding
166
+ * content model category references (e.g., `#phrasing`, `:model(flow)`) into
167
+ * concrete CSS `:is(...)` selectors. Also detects whether the query implicitly
168
+ * includes custom elements or text nodes.
169
+ *
170
+ * Results are cached per specs instance and query string.
171
+ *
172
+ * @param query - The raw content model query string to parse.
173
+ * @param specs - The spec data used to resolve category names to tag lists.
174
+ * @returns A readonly Condition with the resolved selector and flags.
175
+ */
143
176
  function optCondition(query, specs) {
144
177
  const condWithoutSpecs = conditionWithoutSpecs[query];
145
178
  if (condWithoutSpecs) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `permitted-contents` validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `permitted-contents` validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -2,13 +2,20 @@ import type { ChildNode, Options, Result, Specs } from './types.js';
2
2
  import type { PermittedContentPattern } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
4
  /**
5
- * Check ordered array
5
+ * Validates an ordered sequence of content model patterns against a list of child nodes.
6
+ * Each pattern in the `contents` array is matched in order against the remaining unmatched
7
+ * child nodes, consuming nodes as they match. This implements the sequential composition
8
+ * semantics of HTML content models (e.g., "a `<caption>` followed by zero or more `<colgroup>`s
9
+ * followed by a `<thead>`...").
6
10
  *
7
- * @param contents
8
- * @param childNodes
9
- * @param specs
10
- * @param options
11
- * @param depth
12
- * @returns
11
+ * Supports backtracking: when a pattern matches zero nodes (zeroMatch), the algorithm
12
+ * can backtrack to try the next pattern from the previous position if the current pattern fails.
13
+ *
14
+ * @param contents - An ordered array of content model patterns to match sequentially.
15
+ * @param childNodes - The child nodes to validate against the patterns.
16
+ * @param specs - The resolved spec data for content model lookups.
17
+ * @param options - Validation behavior options.
18
+ * @param depth - The current recursion depth, used for debug logging and nested pattern matching.
19
+ * @returns A result indicating overall match status and the matched/unmatched node partitioning.
13
20
  */
14
21
  export declare function order(contents: ReadonlyDeep<PermittedContentPattern[]>, childNodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): Result;
@@ -3,14 +3,21 @@ import { complexBranch } from './complex-branch.js';
3
3
  import { cmLog } from './debug.js';
4
4
  import { Collection, mergeHints, modelLog } from './utils.js';
5
5
  /**
6
- * Check ordered array
6
+ * Validates an ordered sequence of content model patterns against a list of child nodes.
7
+ * Each pattern in the `contents` array is matched in order against the remaining unmatched
8
+ * child nodes, consuming nodes as they match. This implements the sequential composition
9
+ * semantics of HTML content models (e.g., "a `<caption>` followed by zero or more `<colgroup>`s
10
+ * followed by a `<thead>`...").
7
11
  *
8
- * @param contents
9
- * @param childNodes
10
- * @param specs
11
- * @param options
12
- * @param depth
13
- * @returns
12
+ * Supports backtracking: when a pattern matches zero nodes (zeroMatch), the algorithm
13
+ * can backtrack to try the next pattern from the previous position if the current pattern fails.
14
+ *
15
+ * @param contents - An ordered array of content model patterns to match sequentially.
16
+ * @param childNodes - The child nodes to validate against the patterns.
17
+ * @param specs - The resolved spec data for content model lookups.
18
+ * @param options - Validation behavior options.
19
+ * @param depth - The current recursion depth, used for debug logging and nested pattern matching.
20
+ * @returns A result indicating overall match status and the matched/unmatched node partitioning.
14
21
  */
15
22
  export function order(contents,
16
23
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -37,7 +44,7 @@ childNodes, specs, options, depth) {
37
44
  afterBacktrack = true;
38
45
  continue;
39
46
  }
40
- const barelyMatchedResult = unmatchedResults.sort((a, b) => b.matched.length - a.matched.length)[0];
47
+ const barelyMatchedResult = unmatchedResults.toSorted((a, b) => b.matched.length - a.matched.length)[0];
41
48
  if (!barelyMatchedResult) {
42
49
  throw new Error('Unreachable code');
43
50
  }
@@ -2,4 +2,21 @@ import type { SelectorResult } from './matches-selector.js';
2
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
+ /**
6
+ * Evaluates a model or nested pattern array against child nodes at the leaf level
7
+ * of the content model tree. If the input is a nested pattern array (not a terminal model),
8
+ * it recurses back into `order` for sequential evaluation. If it is a terminal model
9
+ * (a single selector string or an array of selector strings representing alternatives),
10
+ * it tests the first unmatched child node against each selector via `matchesSelector`.
11
+ *
12
+ * For array-of-selectors models, the selectors act as alternatives (logical OR): the first
13
+ * selector to match the child node produces the result.
14
+ *
15
+ * @param model - Either a terminal model (selector string or array of selector strings) or a nested pattern array.
16
+ * @param childNodes - The child nodes to validate against the model.
17
+ * @param specs - The resolved spec data for content model lookups.
18
+ * @param options - Validation behavior options.
19
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
20
+ * @returns A selector result indicating whether the first unmatched child node matches the model.
21
+ */
5
22
  export declare function recursiveBranch(model: ReadonlyDeep<Model | PermittedContentPattern[]>, childNodes: readonly ChildNode[], specs: Specs, options: Options, depth: number): SelectorResult;
@@ -1,6 +1,23 @@
1
1
  import { matchesSelector } from './matches-selector.js';
2
2
  import { order } from './order.js';
3
3
  import { Collection, isModel } from './utils.js';
4
+ /**
5
+ * Evaluates a model or nested pattern array against child nodes at the leaf level
6
+ * of the content model tree. If the input is a nested pattern array (not a terminal model),
7
+ * it recurses back into `order` for sequential evaluation. If it is a terminal model
8
+ * (a single selector string or an array of selector strings representing alternatives),
9
+ * it tests the first unmatched child node against each selector via `matchesSelector`.
10
+ *
11
+ * For array-of-selectors models, the selectors act as alternatives (logical OR): the first
12
+ * selector to match the child node produces the result.
13
+ *
14
+ * @param model - Either a terminal model (selector string or array of selector strings) or a nested pattern array.
15
+ * @param childNodes - The child nodes to validate against the model.
16
+ * @param specs - The resolved spec data for content model lookups.
17
+ * @param options - Validation behavior options.
18
+ * @param depth - The current recursion depth, used for debug logging and nested evaluation.
19
+ * @returns A selector result indicating whether the first unmatched child node matches the model.
20
+ */
4
21
  export function recursiveBranch(model,
5
22
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
6
23
  childNodes, specs, options, depth) {
@@ -1,8 +1,62 @@
1
1
  import type { ChildNode, Options, Result, Specs } from './types.js';
2
+ /**
3
+ * A map tracking child nodes that are currently being evaluated through
4
+ * a transparent content model. Used to prevent infinite recursion and
5
+ * to enable special handling in error messages and debug output.
6
+ */
2
7
  export declare const transparentMode: Map<ChildNode, true>;
8
+ /**
9
+ * Represents a possible resolution of transparent content model nodes,
10
+ * containing the flattened list of child nodes to validate and any
11
+ * errors detected during transparent model resolution.
12
+ */
3
13
  type TransparentNode = {
4
14
  nodes: ChildNode[];
5
15
  errors: Result[];
6
16
  };
17
+ /**
18
+ * Resolves transparent content model elements by replacing them with their
19
+ * children for validation purposes. In HTML, elements like `<a>`, `<ins>`, and `<del>`
20
+ * have transparent content models, meaning their children must be valid in the
21
+ * parent's content model as if the transparent element were not present.
22
+ *
23
+ * This function:
24
+ * 1. Identifies child elements with transparent content models.
25
+ * 2. Filters out children that match non-transparent parts of the element's content model.
26
+ * 3. Replaces the transparent element with its remaining (unmatched) children.
27
+ * 4. Validates that each remaining child satisfies the transparent model's condition selector.
28
+ * 5. Recursively resolves parent-level transparent nodes to propagate errors up the tree.
29
+ * 6. Builds patterns incrementally, capping cross-products to avoid exponential blowup.
30
+ *
31
+ * ### Algorithm — incremental pattern building
32
+ *
33
+ * Patterns are built incrementally as each child node is visited:
34
+ *
35
+ * - **Non-transparent child**: appended to every existing pattern.
36
+ * Pattern count stays the same.
37
+ * - **Single-branch transparent child** (non-conditional, or
38
+ * `evaluateConditionalChildNodes` disabled): all unmatched children
39
+ * are spread into every pattern. Pattern count stays the same.
40
+ * - **Multi-branch transparent child** (conditional, e.g. `v-if`/`v-else`):
41
+ * a cross-product of existing patterns × branch groups is computed,
42
+ * capped at {@link MAX_PATTERNS}. If the cap would be exceeded, a
43
+ * conservative fallback merges all branch children into every pattern.
44
+ *
45
+ * ### Complexity
46
+ *
47
+ * - **Previous algorithm** (`branchesToPatterns` Cartesian product):
48
+ * O(K^N) time and space, where N = number of transparent elements,
49
+ * K = average branch count per element. 12 elements with 2 children
50
+ * each produced 4096 patterns and took 30+ seconds.
51
+ * - **Current algorithm**: O(N × K × min(|patterns|, MAX_PATTERNS))
52
+ * time; O(MAX_PATTERNS × P) space where P = average pattern length.
53
+ * The same 12-element case now produces 1 pattern in <100 ms.
54
+ *
55
+ * @param childNodes - The child nodes of the element being validated, some of which may be transparent.
56
+ * @param specs - The resolved spec data for content model lookups.
57
+ * @param options - Validation behavior options.
58
+ * @returns An array of possible transparent node resolutions, each with flattened nodes and accumulated errors.
59
+ * @see https://github.com/markuplint/markuplint/issues/3249
60
+ */
7
61
  export declare function representTransparentNodes(childNodes: readonly ChildNode[], specs: Specs, options: Options): TransparentNode[];
8
62
  export {};