@markuplint/rules 4.11.2 → 4.12.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 (231) hide show
  1. package/CHANGELOG.md +6 -3
  2. package/SKILL.md +76 -0
  3. package/lib/attr-check.d.ts +41 -5
  4. package/lib/attr-check.js +29 -5
  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 +8 -0
  22. package/lib/character-reference/index.js +16 -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/create-message.d.ts +27 -0
  30. package/lib/create-message.js +56 -1
  31. package/lib/debug.d.ts +9 -0
  32. package/lib/debug.js +5 -0
  33. package/lib/deprecated-attr/index.d.ts +6 -0
  34. package/lib/deprecated-attr/index.js +6 -0
  35. package/lib/deprecated-attr/meta.d.ts +1 -0
  36. package/lib/deprecated-attr/meta.js +1 -0
  37. package/lib/deprecated-element/index.d.ts +8 -0
  38. package/lib/deprecated-element/index.js +8 -0
  39. package/lib/deprecated-element/meta.d.ts +1 -0
  40. package/lib/deprecated-element/meta.js +1 -0
  41. package/lib/disallowed-element/index.d.ts +7 -0
  42. package/lib/disallowed-element/index.js +7 -0
  43. package/lib/disallowed-element/meta.d.ts +1 -0
  44. package/lib/disallowed-element/meta.js +1 -0
  45. package/lib/doctype/index.d.ts +10 -0
  46. package/lib/doctype/index.js +8 -0
  47. package/lib/doctype/meta.d.ts +1 -0
  48. package/lib/doctype/meta.js +1 -0
  49. package/lib/end-tag/index.d.ts +7 -0
  50. package/lib/end-tag/index.js +7 -0
  51. package/lib/end-tag/meta.d.ts +1 -0
  52. package/lib/end-tag/meta.js +1 -0
  53. package/lib/heading-levels/index.d.ts +6 -0
  54. package/lib/heading-levels/index.js +6 -0
  55. package/lib/heading-levels/meta.d.ts +1 -0
  56. package/lib/heading-levels/meta.js +1 -0
  57. package/lib/helpers.d.ts +104 -0
  58. package/lib/helpers.js +105 -2
  59. package/lib/id-duplication/index.d.ts +7 -0
  60. package/lib/id-duplication/index.js +7 -0
  61. package/lib/id-duplication/meta.d.ts +1 -0
  62. package/lib/id-duplication/meta.js +1 -0
  63. package/lib/index.d.ts +13 -0
  64. package/lib/index.js +12 -0
  65. package/lib/ineffective-attr/index.d.ts +7 -0
  66. package/lib/ineffective-attr/index.js +7 -0
  67. package/lib/ineffective-attr/meta.d.ts +1 -0
  68. package/lib/ineffective-attr/meta.js +1 -0
  69. package/lib/invalid-attr/index.d.ts +24 -0
  70. package/lib/invalid-attr/index.js +17 -0
  71. package/lib/invalid-attr/meta.d.ts +1 -0
  72. package/lib/invalid-attr/meta.js +1 -0
  73. package/lib/label-has-control/index.d.ts +7 -0
  74. package/lib/label-has-control/index.js +11 -0
  75. package/lib/label-has-control/meta.d.ts +1 -0
  76. package/lib/label-has-control/meta.js +1 -0
  77. package/lib/landmark-roles/index.d.ts +14 -0
  78. package/lib/landmark-roles/index.js +21 -0
  79. package/lib/landmark-roles/meta.d.ts +1 -0
  80. package/lib/landmark-roles/meta.js +1 -0
  81. package/lib/neighbor-popovers/index.d.ts +8 -0
  82. package/lib/neighbor-popovers/index.js +26 -2
  83. package/lib/neighbor-popovers/meta.d.ts +1 -0
  84. package/lib/neighbor-popovers/meta.js +1 -0
  85. package/lib/no-ambiguous-navigable-target-names/index.d.ts +8 -0
  86. package/lib/no-ambiguous-navigable-target-names/index.js +8 -0
  87. package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -0
  88. package/lib/no-ambiguous-navigable-target-names/meta.js +1 -0
  89. package/lib/no-boolean-attr-value/index.d.ts +7 -0
  90. package/lib/no-boolean-attr-value/index.js +7 -0
  91. package/lib/no-boolean-attr-value/meta.d.ts +1 -0
  92. package/lib/no-boolean-attr-value/meta.js +1 -0
  93. package/lib/no-consecutive-br/index.d.ts +8 -0
  94. package/lib/no-consecutive-br/index.js +8 -0
  95. package/lib/no-consecutive-br/meta.d.ts +1 -0
  96. package/lib/no-consecutive-br/meta.js +1 -0
  97. package/lib/no-default-value/index.d.ts +7 -0
  98. package/lib/no-default-value/index.js +7 -0
  99. package/lib/no-default-value/meta.d.ts +1 -0
  100. package/lib/no-default-value/meta.js +1 -0
  101. package/lib/no-duplicate-dt/index.d.ts +6 -0
  102. package/lib/no-duplicate-dt/index.js +6 -0
  103. package/lib/no-duplicate-dt/meta.d.ts +1 -0
  104. package/lib/no-duplicate-dt/meta.js +1 -0
  105. package/lib/no-empty-palpable-content/index.d.ts +13 -0
  106. package/lib/no-empty-palpable-content/index.js +12 -0
  107. package/lib/no-empty-palpable-content/meta.d.ts +1 -0
  108. package/lib/no-empty-palpable-content/meta.js +1 -0
  109. package/lib/no-hard-code-id/index.d.ts +8 -0
  110. package/lib/no-hard-code-id/index.js +8 -0
  111. package/lib/no-hard-code-id/meta.d.ts +1 -0
  112. package/lib/no-hard-code-id/meta.js +1 -0
  113. package/lib/no-orphaned-end-tag/index.d.ts +7 -0
  114. package/lib/no-orphaned-end-tag/index.js +7 -0
  115. package/lib/no-orphaned-end-tag/meta.d.ts +1 -0
  116. package/lib/no-orphaned-end-tag/meta.js +1 -0
  117. package/lib/no-refer-to-non-existent-id/index.d.ts +8 -0
  118. package/lib/no-refer-to-non-existent-id/index.js +9 -0
  119. package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -0
  120. package/lib/no-refer-to-non-existent-id/meta.js +1 -0
  121. package/lib/no-use-event-handler-attr/index.d.ts +10 -0
  122. package/lib/no-use-event-handler-attr/index.js +8 -0
  123. package/lib/no-use-event-handler-attr/meta.d.ts +1 -0
  124. package/lib/no-use-event-handler-attr/meta.js +1 -0
  125. package/lib/permitted-contents/choice.d.ts +17 -0
  126. package/lib/permitted-contents/choice.js +30 -0
  127. package/lib/permitted-contents/complex-branch.d.ts +11 -7
  128. package/lib/permitted-contents/complex-branch.js +11 -7
  129. package/lib/permitted-contents/content-model.d.ts +11 -0
  130. package/lib/permitted-contents/content-model.js +32 -0
  131. package/lib/permitted-contents/count-pattern.d.ts +13 -7
  132. package/lib/permitted-contents/count-pattern.js +23 -7
  133. package/lib/permitted-contents/debug.browser.d.ts +12 -0
  134. package/lib/permitted-contents/debug.browser.js +12 -0
  135. package/lib/permitted-contents/debug.d.ts +12 -0
  136. package/lib/permitted-contents/debug.js +12 -0
  137. package/lib/permitted-contents/index.d.ts +12 -0
  138. package/lib/permitted-contents/index.js +21 -0
  139. package/lib/permitted-contents/matches-selector.d.ts +19 -0
  140. package/lib/permitted-contents/matches-selector.js +33 -0
  141. package/lib/permitted-contents/meta.d.ts +1 -0
  142. package/lib/permitted-contents/meta.js +1 -0
  143. package/lib/permitted-contents/order.d.ts +14 -7
  144. package/lib/permitted-contents/order.js +14 -7
  145. package/lib/permitted-contents/recursive-branch.d.ts +17 -0
  146. package/lib/permitted-contents/recursive-branch.js +17 -0
  147. package/lib/permitted-contents/represent-transparent-nodes.d.ts +29 -0
  148. package/lib/permitted-contents/represent-transparent-nodes.js +24 -0
  149. package/lib/permitted-contents/start.d.ts +12 -6
  150. package/lib/permitted-contents/start.js +12 -6
  151. package/lib/permitted-contents/transparent.d.ts +12 -0
  152. package/lib/permitted-contents/transparent.js +12 -0
  153. package/lib/permitted-contents/types.d.ts +67 -0
  154. package/lib/permitted-contents/utils.d.ts +161 -1
  155. package/lib/permitted-contents/utils.js +194 -0
  156. package/lib/placeholder-label-option/index.d.ts +7 -0
  157. package/lib/placeholder-label-option/index.js +19 -15
  158. package/lib/placeholder-label-option/meta.d.ts +1 -0
  159. package/lib/placeholder-label-option/meta.js +1 -0
  160. package/lib/require-accessible-name/index.d.ts +11 -0
  161. package/lib/require-accessible-name/index.js +7 -0
  162. package/lib/require-accessible-name/meta.d.ts +1 -0
  163. package/lib/require-accessible-name/meta.js +1 -0
  164. package/lib/require-datetime/index.d.ts +12 -0
  165. package/lib/require-datetime/index.js +8 -0
  166. package/lib/require-datetime/meta.d.ts +1 -0
  167. package/lib/require-datetime/meta.js +1 -0
  168. package/lib/require-datetime/types.d.ts +7 -0
  169. package/lib/require-datetime/utils.d.ts +18 -5
  170. package/lib/require-datetime/utils.js +53 -9
  171. package/lib/required-attr/index.d.ts +13 -0
  172. package/lib/required-attr/index.js +7 -0
  173. package/lib/required-attr/meta.d.ts +1 -0
  174. package/lib/required-attr/meta.js +1 -0
  175. package/lib/required-element/index.d.ts +14 -0
  176. package/lib/required-element/index.js +14 -2
  177. package/lib/required-element/meta.d.ts +1 -0
  178. package/lib/required-element/meta.js +1 -0
  179. package/lib/required-h1/index.d.ts +12 -0
  180. package/lib/required-h1/index.js +7 -0
  181. package/lib/required-h1/meta.d.ts +1 -0
  182. package/lib/required-h1/meta.js +1 -0
  183. package/lib/table-row-column-alignment/find-children.d.ts +10 -0
  184. package/lib/table-row-column-alignment/find-children.js +11 -0
  185. package/lib/table-row-column-alignment/grid.d.ts +60 -0
  186. package/lib/table-row-column-alignment/grid.js +85 -0
  187. package/lib/table-row-column-alignment/index.d.ts +8 -0
  188. package/lib/table-row-column-alignment/index.js +8 -0
  189. package/lib/table-row-column-alignment/meta.d.ts +1 -0
  190. package/lib/table-row-column-alignment/meta.js +1 -0
  191. package/lib/table-row-column-alignment/types.d.ts +10 -0
  192. package/lib/use-list/index.d.ts +16 -0
  193. package/lib/use-list/index.js +20 -0
  194. package/lib/use-list/meta.d.ts +1 -0
  195. package/lib/use-list/meta.js +1 -0
  196. package/lib/wai-aria/checkings/abstract-role.d.ts +9 -0
  197. package/lib/wai-aria/checkings/abstract-role.js +9 -0
  198. package/lib/wai-aria/checkings/default-value.d.ts +11 -0
  199. package/lib/wai-aria/checkings/default-value.js +11 -0
  200. package/lib/wai-aria/checkings/deprecated-props.d.ts +11 -0
  201. package/lib/wai-aria/checkings/deprecated-props.js +11 -0
  202. package/lib/wai-aria/checkings/deprecated-role.d.ts +10 -0
  203. package/lib/wai-aria/checkings/deprecated-role.js +10 -0
  204. package/lib/wai-aria/checkings/disallowed-prop.d.ts +14 -0
  205. package/lib/wai-aria/checkings/disallowed-prop.js +14 -0
  206. package/lib/wai-aria/checkings/implicit-props.d.ts +13 -0
  207. package/lib/wai-aria/checkings/implicit-props.js +13 -0
  208. package/lib/wai-aria/checkings/implicit-role.d.ts +9 -0
  209. package/lib/wai-aria/checkings/implicit-role.js +9 -0
  210. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +9 -0
  211. package/lib/wai-aria/checkings/interaction-in-hidden.js +15 -4
  212. package/lib/wai-aria/checkings/no-global-prop.d.ts +10 -0
  213. package/lib/wai-aria/checkings/no-global-prop.js +10 -0
  214. package/lib/wai-aria/checkings/non-existent-role.d.ts +10 -0
  215. package/lib/wai-aria/checkings/non-existent-role.js +10 -0
  216. package/lib/wai-aria/checkings/permitted-roles.d.ts +10 -0
  217. package/lib/wai-aria/checkings/permitted-roles.js +10 -0
  218. package/lib/wai-aria/checkings/presentational-children.d.ts +7 -1
  219. package/lib/wai-aria/checkings/presentational-children.js +14 -1
  220. package/lib/wai-aria/checkings/required-owned-elements.d.ts +9 -1
  221. package/lib/wai-aria/checkings/required-owned-elements.js +16 -1
  222. package/lib/wai-aria/checkings/required-prop.d.ts +13 -0
  223. package/lib/wai-aria/checkings/required-prop.js +13 -0
  224. package/lib/wai-aria/checkings/value.d.ts +23 -0
  225. package/lib/wai-aria/checkings/value.js +32 -0
  226. package/lib/wai-aria/index.d.ts +10 -0
  227. package/lib/wai-aria/index.js +10 -0
  228. package/lib/wai-aria/meta.d.ts +1 -0
  229. package/lib/wai-aria/meta.js +1 -0
  230. package/lib/wai-aria/types.d.ts +17 -0
  231. package/package.json +9 -9
@@ -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,37 @@
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. Uses `branchesToPatterns` to handle branching when multiple resolutions are possible.
30
+ *
31
+ * @param childNodes - The child nodes of the element being validated, some of which may be transparent.
32
+ * @param specs - The resolved spec data for content model lookups.
33
+ * @param options - Validation behavior options.
34
+ * @returns An array of possible transparent node resolutions, each with flattened nodes and accumulated errors.
35
+ */
7
36
  export declare function representTransparentNodes(childNodes: readonly ChildNode[], specs: Specs, options: Options): TransparentNode[];
8
37
  export {};
@@ -2,7 +2,31 @@ import { getContentModel } from '@markuplint/ml-spec';
2
2
  import { branchesToPatterns } from '@markuplint/shared';
3
3
  import { order } from './order.js';
4
4
  import { Collection, isTransparent, matches } from './utils.js';
5
+ /**
6
+ * A map tracking child nodes that are currently being evaluated through
7
+ * a transparent content model. Used to prevent infinite recursion and
8
+ * to enable special handling in error messages and debug output.
9
+ */
5
10
  export const transparentMode = new Map();
11
+ /**
12
+ * Resolves transparent content model elements by replacing them with their
13
+ * children for validation purposes. In HTML, elements like `<a>`, `<ins>`, and `<del>`
14
+ * have transparent content models, meaning their children must be valid in the
15
+ * parent's content model as if the transparent element were not present.
16
+ *
17
+ * This function:
18
+ * 1. Identifies child elements with transparent content models.
19
+ * 2. Filters out children that match non-transparent parts of the element's content model.
20
+ * 3. Replaces the transparent element with its remaining (unmatched) children.
21
+ * 4. Validates that each remaining child satisfies the transparent model's condition selector.
22
+ * 5. Recursively resolves parent-level transparent nodes to propagate errors up the tree.
23
+ * 6. Uses `branchesToPatterns` to handle branching when multiple resolutions are possible.
24
+ *
25
+ * @param childNodes - The child nodes of the element being validated, some of which may be transparent.
26
+ * @param specs - The resolved spec data for content model lookups.
27
+ * @param options - Validation behavior options.
28
+ * @returns An array of possible transparent node resolutions, each with flattened nodes and accumulated errors.
29
+ */
6
30
  export function representTransparentNodes(
7
31
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
8
32
  childNodes, specs, options) {
@@ -2,12 +2,18 @@ import type { ContentModelResult, Element, Options, Specs } from './types.js';
2
2
  import type { ContentModel } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
4
  /**
5
- * Check start
5
+ * Entry point for validating an element's child nodes against a content model definition.
6
+ * Handles the three forms of content model: `false` (no content allowed), `true` (any content
7
+ * allowed), or an ordered pattern array. For pattern arrays, transparent content model nodes
8
+ * are first resolved, then each resulting pattern of child nodes is validated via `order`.
6
9
  *
7
- * @param contents
8
- * @param el
9
- * @param specs
10
- * @param options
11
- * @returns
10
+ * When `options.evaluateConditionalChildNodes` is enabled, all conditional branches
11
+ * (e.g., from template directives) are evaluated independently.
12
+ *
13
+ * @param contents - The content model definition: `false` for empty, `true` for any, or an array of patterns.
14
+ * @param el - The parent element whose children are being validated.
15
+ * @param specs - The resolved spec data for content model lookups.
16
+ * @param options - Validation behavior options.
17
+ * @returns An array of content model results describing any violations found.
12
18
  */
13
19
  export declare function start(contents: ReadonlyDeep<ContentModel['contents']>, el: Element, specs: Specs, options: Options): ContentModelResult[];
@@ -1,13 +1,19 @@
1
1
  import { order } from './order.js';
2
2
  import { representTransparentNodes } from './represent-transparent-nodes.js';
3
3
  /**
4
- * Check start
4
+ * Entry point for validating an element's child nodes against a content model definition.
5
+ * Handles the three forms of content model: `false` (no content allowed), `true` (any content
6
+ * allowed), or an ordered pattern array. For pattern arrays, transparent content model nodes
7
+ * are first resolved, then each resulting pattern of child nodes is validated via `order`.
5
8
  *
6
- * @param contents
7
- * @param el
8
- * @param specs
9
- * @param options
10
- * @returns
9
+ * When `options.evaluateConditionalChildNodes` is enabled, all conditional branches
10
+ * (e.g., from template directives) are evaluated independently.
11
+ *
12
+ * @param contents - The content model definition: `false` for empty, `true` for any, or an array of patterns.
13
+ * @param el - The parent element whose children are being validated.
14
+ * @param specs - The resolved spec data for content model lookups.
15
+ * @param options - Validation behavior options.
16
+ * @returns An array of content model results describing any violations found.
11
17
  */
12
18
  export function start(contents,
13
19
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -1,2 +1,14 @@
1
1
  import type { ChildNode, Result } from './types.js';
2
+ /**
3
+ * Handles the transparent content model pattern by passing all child nodes
4
+ * through as matched. In HTML, a transparent element inherits the content model
5
+ * of its parent, so its children are validated against the parent's model instead.
6
+ *
7
+ * If the element is a component root (has no grandparent element), all children
8
+ * are treated as matched. Otherwise, validation is deferred to the parent's
9
+ * content model processing.
10
+ *
11
+ * @param childNodes - The child nodes to evaluate under the transparent model.
12
+ * @returns A result indicating all children are matched (validation deferred to parent).
13
+ */
2
14
  export declare function transparent(childNodes: readonly ChildNode[]): Result;
@@ -1,5 +1,17 @@
1
1
  import { cmLog } from './debug.js';
2
2
  const transparentLog = cmLog.extend('transparent');
3
+ /**
4
+ * Handles the transparent content model pattern by passing all child nodes
5
+ * through as matched. In HTML, a transparent element inherits the content model
6
+ * of its parent, so its children are validated against the parent's model instead.
7
+ *
8
+ * If the element is a component root (has no grandparent element), all children
9
+ * are treated as matched. Otherwise, validation is deferred to the parent's
10
+ * content model processing.
11
+ *
12
+ * @param childNodes - The child nodes to evaluate under the transparent model.
13
+ * @returns A result indicating all children are matched (validation deferred to parent).
14
+ */
3
15
  export function transparent(
4
16
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
17
  childNodes) {
@@ -1,8 +1,19 @@
1
1
  import type { Element as _Element, ChildNode as _ChildNode } from '@markuplint/ml-core';
2
2
  import type { ContentModel, MLMLSpec } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
+ /**
5
+ * An element node parameterized with the permitted-contents rule's TagRule and Options.
6
+ */
4
7
  export type Element = _Element<TagRule[], Options>;
8
+ /**
9
+ * A child node parameterized with the permitted-contents rule's TagRule and Options.
10
+ */
5
11
  export type ChildNode = _ChildNode<TagRule[], Options>;
12
+ /**
13
+ * A subset of the full ML spec containing only the fields needed
14
+ * for content model validation: citation references, global definitions,
15
+ * and per-element content model specifications.
16
+ */
6
17
  export type Specs = {
7
18
  readonly cites: MLMLSpec['cites'];
8
19
  readonly def: MLMLSpec['def'];
@@ -13,12 +24,24 @@ export type Specs = {
13
24
  };
14
25
  }[];
15
26
  };
27
+ /**
28
+ * The final result of content model validation for a single child node,
29
+ * indicating whether the node is permitted, missing, or unexpected
30
+ * within its parent element's content model.
31
+ */
16
32
  export type ContentModelResult = {
17
33
  type: MatchedReason | UnmatchedReason;
18
34
  scope: ChildNode;
19
35
  query: Result['query'];
20
36
  hint: Result['hint'];
21
37
  };
38
+ /**
39
+ * An intermediate result produced during content model pattern matching.
40
+ * Tracks which child nodes were matched, which were unmatched, and
41
+ * provides diagnostic hints about the nature of a mismatch.
42
+ *
43
+ * @template T - Additional result type strings beyond the standard matched/unmatched reasons.
44
+ */
22
45
  export type Result<T extends string = MatchedReason> = {
23
46
  type: MatchedReason | UnmatchedReason | T;
24
47
  matched: ChildNode[];
@@ -27,6 +50,11 @@ export type Result<T extends string = MatchedReason> = {
27
50
  query: string;
28
51
  hint: Hints;
29
52
  };
53
+ /**
54
+ * Diagnostic hints attached to a content model result, providing additional
55
+ * context for error reporting such as maximum allowed count, the offending
56
+ * node, or information about transparent model violations.
57
+ */
30
58
  export type Hints = {
31
59
  max?: number;
32
60
  not?: ChildNode;
@@ -36,21 +64,60 @@ export type Hints = {
36
64
  need?: string;
37
65
  };
38
66
  };
67
+ /**
68
+ * Reasons indicating that a content model pattern successfully matched.
69
+ * `MATCHED` means one or more nodes matched; `MATCHED_ZERO` means the pattern
70
+ * matched vacuously (zero nodes consumed, but the pattern allows it).
71
+ */
39
72
  export type MatchedReason = 'MATCHED' | 'MATCHED_ZERO';
73
+ /**
74
+ * Reasons indicating that a content model pattern did not match.
75
+ * Includes cases where content is disallowed entirely, an unexpected node
76
+ * was found, a transparent model forbids the node, or a required node is missing.
77
+ */
40
78
  export type UnmatchedReason = 'NOTHING' | 'UNEXPECTED_EXTRA_NODE' | 'TRANSPARENT_MODEL_DISALLOWS' | MissingNodeReason;
79
+ /**
80
+ * Specific reasons for a missing node: either a required element is absent,
81
+ * or one-or-more occurrences are expected but none were found.
82
+ */
41
83
  export type MissingNodeReason = 'MISSING_NODE_REQUIRED' | 'MISSING_NODE_ONE_OR_MORE';
84
+ /**
85
+ * A regular-expression-like repeat sign used to describe the quantifier
86
+ * of a content model pattern (e.g., `?` for optional, `+` for one-or-more,
87
+ * `*` for zero-or-more, or `{min,max}` for a specific range).
88
+ */
42
89
  export type RepeatSign = '' | '?' | '+' | '*' | `{${number},${number}}`;
90
+ /**
91
+ * Describes a transparent content model element along with any additional
92
+ * CSS selector condition that must be satisfied for the transparency to apply.
93
+ */
43
94
  export type TransparentModel = {
44
95
  el: Element;
45
96
  additionalCondition: string;
46
97
  };
98
+ /**
99
+ * A user-defined tag rule that associates an element tag name with
100
+ * its permitted content model definition, used to override or extend
101
+ * the built-in HTML spec content models.
102
+ */
47
103
  export type TagRule = {
48
104
  readonly tag: string;
49
105
  } & ReadonlyDeep<ContentModel>;
106
+ /**
107
+ * Options for the permitted-contents rule that control validation behavior.
108
+ */
50
109
  export type Options = {
110
+ /**
111
+ * When true, skips reporting missing-node errors on elements that
112
+ * have mutable children (e.g., elements whose children may be
113
+ * dynamically injected by a framework or template engine).
114
+ */
51
115
  readonly ignoreHasMutableChildren: boolean;
52
116
  /**
53
117
  * @experimental
118
+ * When true, evaluates conditional child node branches (e.g., from
119
+ * template directives like `v-if`) to validate each possible branch
120
+ * against the content model.
54
121
  */
55
122
  readonly evaluateConditionalChildNodes: boolean;
56
123
  };
@@ -1,7 +1,26 @@
1
1
  import type { ChildNode, Hints, MissingNodeReason, RepeatSign, Specs } from './types.js';
2
2
  import type { PermittedContentPattern, PermittedContentChoice, PermittedContentOneOrMore, PermittedContentOptional, PermittedContentRequire, PermittedContentTransparent, PermittedContentZeroOrMore, Model } from '@markuplint/ml-spec';
3
3
  import type { ReadonlyDeep } from 'type-fest';
4
+ /**
5
+ * Determines whether a given value is a terminal model (a selector string or an array
6
+ * of selector strings) rather than a nested array of content model patterns.
7
+ * Distinguishes between `Model` (leaf-level selectors) and `PermittedContentPattern[]`
8
+ * (structural pattern arrays that require further recursive evaluation).
9
+ *
10
+ * @param model - The value to check, either a terminal model or a nested pattern array.
11
+ * @returns True if the value is a terminal model (string or string array), false if it is a pattern array.
12
+ */
4
13
  export declare function isModel(model: ReadonlyDeep<Model | PermittedContentPattern[]>): model is ReadonlyDeep<Model>;
14
+ /**
15
+ * Tests whether a child node matches a CSS selector string using the markuplint
16
+ * selector engine. Returns whether the node matched and, if not, the deepest
17
+ * unmatched descendant node for diagnostic purposes.
18
+ *
19
+ * @param selector - The CSS selector string to test against.
20
+ * @param node - The child node to test.
21
+ * @param specs - The spec data passed to the selector engine for attribute resolution.
22
+ * @returns An object with `matched: true` if the node matches, or `matched: false` with an optional `not` node.
23
+ */
5
24
  export declare function matches(selector: string, node: ChildNode, specs: Specs): {
6
25
  matched: boolean;
7
26
  not?: undefined;
@@ -9,19 +28,78 @@ export declare function matches(selector: string, node: ChildNode, specs: Specs)
9
28
  matched: boolean;
10
29
  not: ChildNode | undefined;
11
30
  };
31
+ /**
32
+ * Type guard that checks whether a content model pattern is a "require" pattern,
33
+ * indicating one or more required occurrences of a specific element or model.
34
+ *
35
+ * @param content - The content model pattern to check.
36
+ * @returns True if the pattern has a `require` property.
37
+ */
12
38
  export declare function isRequire(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentRequire>;
39
+ /**
40
+ * Type guard that checks whether a content model pattern is an "optional" pattern,
41
+ * indicating zero or one occurrences of a specific element or model.
42
+ *
43
+ * @param content - The content model pattern to check.
44
+ * @returns True if the pattern has an `optional` property.
45
+ */
13
46
  export declare function isOptional(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentOptional>;
47
+ /**
48
+ * Type guard that checks whether a content model pattern is a "oneOrMore" pattern,
49
+ * indicating one or more occurrences of a specific element or model.
50
+ *
51
+ * @param content - The content model pattern to check.
52
+ * @returns True if the pattern has a `oneOrMore` property.
53
+ */
14
54
  export declare function isOneOrMore(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentOneOrMore>;
55
+ /**
56
+ * Type guard that checks whether a content model pattern is a "zeroOrMore" pattern,
57
+ * indicating zero or more occurrences of a specific element or model.
58
+ *
59
+ * @param content - The content model pattern to check.
60
+ * @returns True if the pattern has a `zeroOrMore` property.
61
+ */
15
62
  export declare function isZeroOrMore(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentZeroOrMore>;
63
+ /**
64
+ * Type guard that checks whether a content model pattern is a "choice" pattern,
65
+ * representing an alternation between multiple possible content model branches.
66
+ *
67
+ * @param content - The content model pattern to check.
68
+ * @returns True if the pattern has a `choice` property.
69
+ */
16
70
  export declare function isChoice(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentChoice>;
71
+ /**
72
+ * Type guard that checks whether a content model pattern is a "transparent" pattern,
73
+ * indicating the element inherits its parent's content model.
74
+ *
75
+ * @param content - The content model pattern to check.
76
+ * @returns True if the pattern has a `transparent` property.
77
+ */
17
78
  export declare function isTransparent(content: ReadonlyDeep<PermittedContentPattern>): content is ReadonlyDeep<PermittedContentTransparent>;
79
+ /**
80
+ * Normalizes a quantified content model pattern (require, optional, oneOrMore, or zeroOrMore)
81
+ * into a uniform representation with the inner model, minimum count, maximum count,
82
+ * a regex-like repeat sign for debug display, and the appropriate missing-node error type.
83
+ *
84
+ * @param pattern - A quantified content model pattern to normalize.
85
+ * @returns An object with `model`, `min`, `max`, `repeat` sign, and optional `missingType`.
86
+ */
18
87
  export declare function normalizeModel(pattern: ReadonlyDeep<PermittedContentRequire> | ReadonlyDeep<PermittedContentOptional> | ReadonlyDeep<PermittedContentOneOrMore> | ReadonlyDeep<PermittedContentZeroOrMore>): {
19
- model: ReadonlyDeep<PermittedContentPattern[] | Model>;
88
+ model: ReadonlyDeep<Model | PermittedContentPattern[]>;
20
89
  min: number;
21
90
  max: number;
22
91
  repeat: RepeatSign;
23
92
  missingType: MissingNodeReason | undefined;
24
93
  };
94
+ /**
95
+ * Merges two Hints objects, combining their properties and selecting the
96
+ * `missing` hint with the higher `barelyMatchedElements` count (i.e., the
97
+ * one closest to a successful match) for the most useful error diagnostics.
98
+ *
99
+ * @param a - The first hints object.
100
+ * @param b - The second hints object.
101
+ * @returns A merged hints object with undefined properties removed.
102
+ */
25
103
  export declare function mergeHints(a: Readonly<Hints>, b: Readonly<Hints>): Partial<{
26
104
  missing: Partial<{
27
105
  barelyMatchedElements?: number;
@@ -31,20 +109,102 @@ export declare function mergeHints(a: Readonly<Hints>, b: Readonly<Hints>): Part
31
109
  not?: ChildNode;
32
110
  transparent?: import("./types.js").Element;
33
111
  }>;
112
+ /**
113
+ * Creates a shallow copy of an object with all `undefined` values removed.
114
+ * Used to produce clean hint objects for result reporting without
115
+ * extraneous undefined properties.
116
+ *
117
+ * @template T - The object type.
118
+ * @param object - The source object to clean.
119
+ * @returns A new object containing only the defined properties of the input.
120
+ */
34
121
  export declare function cleanObject<T extends object>(object: T): Partial<T>;
122
+ /**
123
+ * Tracks matched and unmatched child nodes during content model validation.
124
+ * Provides operations for adding matched nodes, backtracking to a locked state,
125
+ * capping matches at a maximum count, and generating colored debug output.
126
+ *
127
+ * The collection maintains an ordered set of original nodes and partitions them
128
+ * into matched and unmatched sets as the validation algorithm progresses.
129
+ */
35
130
  export declare class Collection {
36
131
  #private;
132
+ /**
133
+ * Creates a new Collection from the given child nodes.
134
+ *
135
+ * @param origin - The initial list of child nodes to track.
136
+ */
37
137
  constructor(origin: readonly ChildNode[]);
138
+ /**
139
+ * Returns a copy of the currently matched nodes in insertion order.
140
+ */
38
141
  get matched(): ChildNode[];
142
+ /**
143
+ * Returns the number of currently matched nodes.
144
+ */
39
145
  get matchedCount(): number;
146
+ /**
147
+ * Returns a copy of all original nodes in their original order.
148
+ */
40
149
  get nodes(): ChildNode[];
150
+ /**
151
+ * Returns the nodes that have not yet been matched, preserving original order.
152
+ */
41
153
  get unmatched(): ChildNode[];
154
+ /**
155
+ * Adds nodes to the matched set. All nodes must belong to the original
156
+ * collection; external nodes will cause a ReferenceError.
157
+ *
158
+ * @param nodes - The child nodes to mark as matched.
159
+ * @returns True if the matched set grew (new nodes were added), false otherwise.
160
+ */
42
161
  addMatched(nodes: ChildNode[]): boolean;
162
+ /**
163
+ * Reverts the matched set to the last locked state, discarding
164
+ * any matches added since the last `lock()` call. Used for backtracking
165
+ * when a pattern match attempt fails after a zero-match.
166
+ */
43
167
  back(): void;
168
+ /**
169
+ * Saves the current matched set as a checkpoint that `back()` can
170
+ * revert to. Called after a successful backtrack recovery to preserve
171
+ * the known-good state.
172
+ */
44
173
  lock(): void;
174
+ /**
175
+ * Trims the matched set to at most `max` entries by removing
176
+ * the most recently added nodes beyond the limit. Used when the
177
+ * maximum occurrence count for a pattern is exceeded.
178
+ *
179
+ * @param max - The maximum number of matched nodes to retain.
180
+ */
45
181
  max(max: number): void;
182
+ /**
183
+ * Returns a colored string representation of all nodes for debug logging.
184
+ * Matched nodes are shown in green, locked nodes in bold green, unmatched
185
+ * extra nodes in red (when highlighted), and transparent-mode nodes in
186
+ * blue/cyan/magenta variants.
187
+ *
188
+ * @param highlightExtraNodes - When true, unmatched nodes are highlighted in red/magenta.
189
+ * @returns A formatted string like `[ <div>, <span>, <p> ]` with ANSI colors.
190
+ */
46
191
  toString(highlightExtraNodes?: boolean): string;
47
192
  }
193
+ /**
194
+ * Error class representing an unsupported content model feature.
195
+ * Thrown when the validation engine encounters a pattern type or
196
+ * configuration that is not yet implemented.
197
+ */
48
198
  export declare class UnsupportedError extends Error {
49
199
  }
200
+ /**
201
+ * Formats a content model (terminal model or pattern array) and its repeat sign
202
+ * into a regex-like string for debug logging output. Terminal selectors are
203
+ * rendered as `<selector>`, arrays of selectors as `(<s1>|<s2>)`, and
204
+ * nested patterns are recursively formatted.
205
+ *
206
+ * @param model - The model or pattern array to format.
207
+ * @param repeat - The quantifier sign to append (e.g., `+`, `*`, `?`, or `{m,n}`).
208
+ * @returns A human-readable regex-like string representation of the model.
209
+ */
50
210
  export declare function modelLog(model: ReadonlyDeep<Model | PermittedContentPattern[]>, repeat: RepeatSign): string;