@markuplint/ml-core 4.13.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 (92) hide show
  1. package/ARCHITECTURE.ja.md +524 -0
  2. package/ARCHITECTURE.md +524 -0
  3. package/CHANGELOG.md +52 -2
  4. package/README.md +5 -0
  5. package/SKILL.md +61 -0
  6. package/docs/linting-pipeline.ja.md +307 -0
  7. package/docs/linting-pipeline.md +307 -0
  8. package/docs/maintenance.ja.md +210 -0
  9. package/docs/maintenance.md +210 -0
  10. package/docs/ml-dom/attr.ja.md +103 -0
  11. package/docs/ml-dom/attr.md +103 -0
  12. package/docs/ml-dom/block.ja.md +272 -0
  13. package/docs/ml-dom/block.md +272 -0
  14. package/docs/ml-dom/document.ja.md +141 -0
  15. package/docs/ml-dom/document.md +141 -0
  16. package/docs/ml-dom/element.ja.md +176 -0
  17. package/docs/ml-dom/element.md +176 -0
  18. package/docs/ml-dom/helpers.ja.md +203 -0
  19. package/docs/ml-dom/helpers.md +203 -0
  20. package/docs/ml-dom/node.ja.md +199 -0
  21. package/docs/ml-dom/node.md +199 -0
  22. package/docs/ml-dom/others.ja.md +120 -0
  23. package/docs/ml-dom/others.md +120 -0
  24. package/docs/ml-dom/overview.ja.md +102 -0
  25. package/docs/ml-dom/overview.md +102 -0
  26. package/docs/ml-dom/pretender.ja.md +269 -0
  27. package/docs/ml-dom/pretender.md +269 -0
  28. package/docs/ml-dom/rule-mapping.ja.md +371 -0
  29. package/docs/ml-dom/rule-mapping.md +371 -0
  30. package/docs/ml-dom.ja.md +18 -0
  31. package/docs/ml-dom.md +18 -0
  32. package/docs/rule-system.ja.md +287 -0
  33. package/docs/rule-system.md +287 -0
  34. package/lib/convert-ruleset.d.ts +7 -0
  35. package/lib/convert-ruleset.js +7 -0
  36. package/lib/debug.d.ts +4 -0
  37. package/lib/debug.js +4 -0
  38. package/lib/index.d.ts +4 -3
  39. package/lib/index.js +1 -1
  40. package/lib/ml-core.d.ts +37 -1
  41. package/lib/ml-core.js +171 -82
  42. package/lib/ml-dom/helper/accname.d.ts +8 -0
  43. package/lib/ml-dom/helper/accname.js +71 -55
  44. package/lib/ml-dom/helper/create-node.js +1 -0
  45. package/lib/ml-dom/helper/get-indent.d.ts +4 -1
  46. package/lib/ml-dom/helper/get-indent.js +21 -30
  47. package/lib/ml-dom/node/attr.d.ts +65 -4
  48. package/lib/ml-dom/node/attr.js +151 -53
  49. package/lib/ml-dom/node/block.d.ts +23 -2
  50. package/lib/ml-dom/node/block.js +24 -1
  51. package/lib/ml-dom/node/child-node.d.ts +9 -0
  52. package/lib/ml-dom/node/child-node.js +9 -0
  53. package/lib/ml-dom/node/comment.d.ts +7 -0
  54. package/lib/ml-dom/node/comment.js +7 -0
  55. package/lib/ml-dom/node/document-fragment.d.ts +8 -0
  56. package/lib/ml-dom/node/document-fragment.js +8 -0
  57. package/lib/ml-dom/node/document-type.d.ts +22 -0
  58. package/lib/ml-dom/node/document-type.js +25 -0
  59. package/lib/ml-dom/node/document.d.ts +88 -7
  60. package/lib/ml-dom/node/document.js +128 -32
  61. package/lib/ml-dom/node/dom-token-list.js +17 -30
  62. package/lib/ml-dom/node/element-close-tag.js +1 -0
  63. package/lib/ml-dom/node/element.d.ts +151 -5
  64. package/lib/ml-dom/node/element.js +242 -50
  65. package/lib/ml-dom/node/node-store.js +6 -15
  66. package/lib/ml-dom/node/node.d.ts +19 -1
  67. package/lib/ml-dom/node/node.js +175 -166
  68. package/lib/ml-dom/node/parent-node.js +14 -30
  69. package/lib/ml-dom/node/rule-mapper.js +7 -20
  70. package/lib/ml-dom/node/text.d.ts +19 -0
  71. package/lib/ml-dom/node/text.js +21 -0
  72. package/lib/ml-dom/node/types.d.ts +68 -0
  73. package/lib/ml-dom/token/token.d.ts +42 -0
  74. package/lib/ml-dom/token/token.js +59 -39
  75. package/lib/ml-rule/create-rule.d.ts +17 -1
  76. package/lib/ml-rule/ml-rule-context.js +7 -11
  77. package/lib/ml-rule/ml-rule.d.ts +66 -1
  78. package/lib/ml-rule/ml-rule.js +95 -25
  79. package/lib/ml-rule/types.d.ts +41 -0
  80. package/lib/plugin/plugin.d.ts +8 -0
  81. package/lib/plugin/plugin.js +8 -0
  82. package/lib/plugin/types.d.ts +21 -0
  83. package/lib/ruleset/index.d.ts +10 -0
  84. package/lib/ruleset/index.js +13 -0
  85. package/lib/test/index.d.ts +42 -1
  86. package/lib/test/index.js +39 -2
  87. package/lib/types.d.ts +10 -1
  88. package/lib/violation-collector.d.ts +33 -0
  89. package/lib/violation-collector.js +48 -28
  90. package/lib/virtual-rule.d.ts +72 -0
  91. package/lib/virtual-rule.js +233 -0
  92. package/package.json +16 -13
@@ -4,10 +4,32 @@ import type { DocumentTypeNodeType } from './types.js';
4
4
  import type { MLASTDoctype } from '@markuplint/ml-ast';
5
5
  import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
6
6
  import { MLNode } from './node.js';
7
+ /**
8
+ * Represents a DOM DocumentType node wrapper in the markuplint DOM tree.
9
+ * Wraps the `<!DOCTYPE ...>` declaration and implements the standard DOM `DocumentType` interface.
10
+ *
11
+ * @template T - The rule configuration value type
12
+ * @template O - The rule options type
13
+ */
7
14
  export declare class MLDocumentType<T extends RuleConfigValue, O extends PlainData = undefined> extends MLNode<T, O, MLASTDoctype> implements DocumentType {
15
+ /**
16
+ * The name of the document type (e.g., `"html"`).
17
+ */
8
18
  readonly name: string;
19
+ /**
20
+ * The public identifier of the document type, or an empty string if not specified.
21
+ */
9
22
  readonly publicId: string;
23
+ /**
24
+ * The system identifier of the document type, or an empty string if not specified.
25
+ */
10
26
  readonly systemId: string;
27
+ /**
28
+ * Creates a new MLDocumentType instance.
29
+ *
30
+ * @param astNode - The AST doctype node to wrap
31
+ * @param document - The owning document
32
+ */
11
33
  constructor(astNode: MLASTDoctype, document: MLDocument<T, O>);
12
34
  /**
13
35
  * Returns a string appropriate for the type of node as `DocumentType`
@@ -1,6 +1,31 @@
1
1
  import { after, before, remove, replaceWith } from '../manipulations/child-node-methods.js';
2
2
  import { MLNode } from './node.js';
3
+ /**
4
+ * Represents a DOM DocumentType node wrapper in the markuplint DOM tree.
5
+ * Wraps the `<!DOCTYPE ...>` declaration and implements the standard DOM `DocumentType` interface.
6
+ *
7
+ * @template T - The rule configuration value type
8
+ * @template O - The rule options type
9
+ */
3
10
  export class MLDocumentType extends MLNode {
11
+ /**
12
+ * The name of the document type (e.g., `"html"`).
13
+ */
14
+ name;
15
+ /**
16
+ * The public identifier of the document type, or an empty string if not specified.
17
+ */
18
+ publicId;
19
+ /**
20
+ * The system identifier of the document type, or an empty string if not specified.
21
+ */
22
+ systemId;
23
+ /**
24
+ * Creates a new MLDocumentType instance.
25
+ *
26
+ * @param astNode - The AST doctype node to wrap
27
+ * @param document - The owning document
28
+ */
4
29
  constructor(astNode,
5
30
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
6
31
  document) {
@@ -11,9 +11,18 @@ import type { MLSchema } from '../../types.js';
11
11
  import type { Walker } from '../helper/walkers.js';
12
12
  import type { MLToken } from '../token/token.js';
13
13
  import type { EndTagType, MLASTDocument } from '@markuplint/ml-ast';
14
- import type { PlainData, Pretender, RuleConfigValue } from '@markuplint/ml-config';
14
+ import type { PlainData, Pretender, RuleCommonSettings, RuleConfigValue } from '@markuplint/ml-config';
15
15
  import type { ARIAVersion, MLMLSpec } from '@markuplint/ml-spec';
16
16
  import { MLParentNode } from './parent-node.js';
17
+ /**
18
+ * Represents a DOM Document node wrapper in the markuplint DOM tree.
19
+ * Serves as the root node of the parsed document, managing the node list,
20
+ * rule mappings, pretender initialization, accessibility computation,
21
+ * and document-level configuration (end tag handling, booleanish values, etc.).
22
+ *
23
+ * @template T - The rule configuration value type
24
+ * @template O - The rule options type
25
+ */
17
26
  export declare class MLDocument<T extends RuleConfigValue, O extends PlainData = undefined> extends MLParentNode<T, O> implements Document {
18
27
  #private;
19
28
  /**
@@ -30,7 +39,9 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
30
39
  */
31
40
  readonly booleanish: boolean;
32
41
  /**
33
- *
42
+ * The rule currently being evaluated during a lint pass.
43
+ * Set by the linting engine before rule evaluation begins and used by nodes
44
+ * to retrieve their rule configuration. Null when no rule is being evaluated.
34
45
  */
35
46
  currentRule: Readonly<MLRule<T, O>> | null;
36
47
  /**
@@ -40,11 +51,13 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
40
51
  */
41
52
  readonly endTag: EndTagType;
42
53
  /**
43
- *
54
+ * Whether this document represents a fragment rather than a complete document.
55
+ * Fragment documents may lack root-level elements like `<html>`, `<head>`, or `<body>`.
44
56
  */
45
57
  readonly isFragment: boolean;
46
58
  /**
47
- * An array of markuplint DOM nodes
59
+ * A flat, ordered array of all markuplint DOM nodes in the document,
60
+ * used for sequential traversal and token-level operations.
48
61
  */
49
62
  readonly nodeList: ReadonlyArray<MLNode<T, O>>;
50
63
  readonly ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
@@ -52,16 +65,28 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
52
65
  readonly ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
53
66
  readonly ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
54
67
  /**
55
- *
68
+ * The ML specification data used for element/attribute lookups, ARIA role resolution,
69
+ * and other spec-driven computations.
56
70
  */
57
71
  readonly specs: MLMLSpec;
72
+ /**
73
+ * Whether tag name comparisons should be case-sensitive.
74
+ * When false (default for HTML), tag names are compared case-insensitively.
75
+ */
58
76
  readonly tagNameCaseSensitive: boolean;
59
77
  /**
60
- *
78
+ * Common settings applied globally to all rules, such as the ARIA version.
79
+ * Rules use this as a fallback when their own options do not specify a value.
80
+ */
81
+ readonly ruleCommonSettings: RuleCommonSettings;
82
+ /**
61
83
  * @param ast node list of markuplint AST
62
84
  * @param ruleset ruleset object
85
+ * @param schemas base HTML/ARIA spec with optional framework-specific extensions
86
+ * @param ruleCommonSettings common settings applied globally to all rules
87
+ * @param options optional configuration for document behavior
63
88
  */
64
- constructor(ast: MLASTDocument, ruleset: Ruleset, schemas: MLSchema, options?: {
89
+ constructor(ast: MLASTDocument, ruleset: Ruleset, schemas: MLSchema, ruleCommonSettings: RuleCommonSettings, options?: {
65
90
  readonly filename?: string;
66
91
  readonly endTag?: 'xml' | 'omittable' | 'never';
67
92
  readonly booleanish?: boolean;
@@ -1435,7 +1460,11 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1435
1460
  */
1436
1461
  createTreeWalker(root: Node, whatToShow?: number, filter?: NodeFilter | null): TreeWalker;
1437
1462
  /**
1463
+ * Returns a debug-friendly string array representing the structure of the document's
1464
+ * node list, useful for debugging and test assertions.
1465
+ *
1438
1466
  * @implements `@markuplint/ml-core` API: `MLDocument`
1467
+ * @returns An array of strings describing each node in the document
1439
1468
  */
1440
1469
  debugMap(): string[];
1441
1470
  /**
@@ -1488,6 +1517,19 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1488
1517
  * @implements DOM API: `Document`
1489
1518
  */
1490
1519
  exitPointerLock(): void;
1520
+ /**
1521
+ * Computes the accessibility properties for the given node, including its
1522
+ * ARIA role, accessible name, focusability, and ARIA property values.
1523
+ * Returns null for non-element nodes.
1524
+ *
1525
+ * The accessible name is obtained via `node.getAccessibleName()` so that
1526
+ * the per-element memoization cache is shared with other consumers
1527
+ * (rules, selectors). See {@link MLElement.getAccessibleName}.
1528
+ *
1529
+ * @param node - The node to compute accessibility properties for
1530
+ * @param ariaVersion - The ARIA specification version to use for computation
1531
+ * @returns The computed accessibility properties, or null for non-element nodes
1532
+ */
1491
1533
  getAccessibilityProp(node: MLNode<T, O>, ariaVersion?: ARIAVersion): AccessibilityProperties | null;
1492
1534
  /**
1493
1535
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -1536,7 +1578,11 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1536
1578
  */
1537
1579
  getSelection(): Selection | null;
1538
1580
  /**
1581
+ * Returns a flat, offset-sorted list of all tokens in the document,
1582
+ * including element close tags. The result is cached after the first call.
1583
+ *
1539
1584
  * @implements `@markuplint/ml-core` API: `MLDocument`
1585
+ * @returns A frozen array of tokens sorted by their starting offset
1540
1586
  */
1541
1587
  getTokenList(): readonly MLToken<import("@markuplint/ml-ast").MLASTToken>[];
1542
1588
  /**
@@ -1623,11 +1669,20 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1623
1669
  */
1624
1670
  requestStorageAccess(): Promise<void>;
1625
1671
  /**
1672
+ * Searches for a node at the given source location (line and column).
1673
+ *
1626
1674
  * @implements `@markuplint/ml-core` API: `MLDocument`
1675
+ * @param line - The 1-based line number to search at
1676
+ * @param col - The 1-based column number to search at
1677
+ * @returns The node at the given location, or null if not found
1627
1678
  */
1628
1679
  searchNodeByLocation(line: number, col: number): MLNode<T, O, import("@markuplint/ml-ast").MLASTNode> | null;
1629
1680
  /**
1681
+ * Sets the currently active rule for this document. Called by the linting engine
1682
+ * before each rule evaluation pass.
1683
+ *
1630
1684
  * @implements `@markuplint/ml-core` API: `MLDocument`
1685
+ * @param rule - The rule to set as current, or null to clear
1631
1686
  */
1632
1687
  setRule(rule: Readonly<MLRule<T, O>> | null): void;
1633
1688
  /**
@@ -1638,11 +1693,25 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1638
1693
  */
1639
1694
  startViewTransition(callbackOptions?: ViewTransitionUpdateCallback): ViewTransition;
1640
1695
  /**
1696
+ * Returns a string representation of the entire document. When `fixed` is true,
1697
+ * returns the document with all lint fixes applied by substituting
1698
+ * fixed token content at the appropriate offsets.
1699
+ *
1641
1700
  * @implements `@markuplint/ml-core` API: `MLDocument`
1701
+ * @param fixed - When true, returns the fixed content; otherwise returns the original raw content
1702
+ * @returns The string content of the document
1642
1703
  */
1643
1704
  toString(fixed?: boolean): string;
1644
1705
  /**
1706
+ * Walks the document tree, visiting nodes of the specified type and invoking
1707
+ * the walker callback for each one. Supports walking Element, Text, Comment,
1708
+ * Attr, and ElementCloseTag node types.
1709
+ *
1645
1710
  * @implements `@markuplint/ml-core` API: `MLDocument`
1711
+ * @param type - The node type to walk over
1712
+ * @param walker - The callback to invoke for each matching node
1713
+ * @param skipWhenRuleIsDisabled - When true, skips nodes where the current rule is disabled
1714
+ * @returns A promise that resolves when all matching nodes have been visited
1646
1715
  */
1647
1716
  walkOn(type: 'Element', walker: Walker<T, O, MLElement<T, O>>, skipWhenRuleIsDisabled?: boolean): Promise<void>;
1648
1717
  walkOn(type: 'Text', walker: Walker<T, O, MLText<T, O>>, skipWhenRuleIsDisabled?: boolean): Promise<void>;
@@ -1663,6 +1732,18 @@ export declare class MLDocument<T extends RuleConfigValue, O extends PlainData =
1663
1732
  * @implements DOM API: `Document`
1664
1733
  */
1665
1734
  writeln(...text: readonly string[]): void;
1735
+ /**
1736
+ * Initializes pretender contexts for all element nodes in the document.
1737
+ *
1738
+ * @param pretenders - Optional pretender configurations from the document options
1739
+ */
1666
1740
  private _pretending;
1741
+ /**
1742
+ * Maps the ruleset configuration to each node in the document.
1743
+ * Applies global rules, node-specific rules (by selector), and
1744
+ * child-node rules to build the per-node rule configuration.
1745
+ *
1746
+ * @param ruleset - The ruleset containing rules, nodeRules, and childNodeRules
1747
+ */
1667
1748
  private _ruleMapping;
1668
1749
  }
@@ -1,17 +1,5 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _MLDocument_filename, _MLDocument_tokenList;
13
1
  import { exchangeValueOnRule, mergeRule } from '@markuplint/ml-config';
14
- import { schemaToSpec, getAccname, getComputedRole, mayBeFocusable, getComputedAriaProps, isExposed, ARIA_RECOMMENDED_VERSION, } from '@markuplint/ml-spec';
2
+ import { schemaToSpec, getComputedRole, mayBeFocusable, getComputedAriaProps, isExposed, ARIA_RECOMMENDED_VERSION, } from '@markuplint/ml-spec';
15
3
  import { ConfigParserError } from '@markuplint/parser-utils';
16
4
  import { InvalidSelectorError } from '@markuplint/selector';
17
5
  import { log as coreLog } from '../../debug.js';
@@ -25,30 +13,92 @@ import { UnexpectedCallError } from './unexpected-call-error.js';
25
13
  const log = coreLog.extend('ml-dom');
26
14
  const docLog = log.extend('document');
27
15
  const ruleLog = docLog.extend('rule');
16
+ /**
17
+ * Represents a DOM Document node wrapper in the markuplint DOM tree.
18
+ * Serves as the root node of the parsed document, managing the node list,
19
+ * rule mappings, pretender initialization, accessibility computation,
20
+ * and document-level configuration (end tag handling, booleanish values, etc.).
21
+ *
22
+ * @template T - The rule configuration value type
23
+ * @template O - The rule options type
24
+ */
28
25
  export class MLDocument extends MLParentNode {
29
26
  /**
27
+ * Detect value as a true if its attribute is booleanish value and omitted.
30
28
  *
29
+ * Ex:
30
+ * ```jsx
31
+ * <Component aria-hidden />
32
+ * ```
33
+ *
34
+ * In the above, the `aria-hidden` is `true`.
35
+ *
36
+ * @default false
37
+ */
38
+ booleanish;
39
+ /**
40
+ * The rule currently being evaluated during a lint pass.
41
+ * Set by the linting engine before rule evaluation begins and used by nodes
42
+ * to retrieve their rule configuration. Null when no rule is being evaluated.
43
+ */
44
+ currentRule = null;
45
+ /**
46
+ * This is defined by the parser.
47
+ *
48
+ * @default "omittable"
49
+ */
50
+ endTag;
51
+ /**
52
+ * The file path of the source document, if available.
53
+ */
54
+ #filename;
55
+ /**
56
+ * Whether this document represents a fragment rather than a complete document.
57
+ * Fragment documents may lack root-level elements like `<html>`, `<head>`, or `<body>`.
58
+ */
59
+ isFragment;
60
+ /**
61
+ * A flat, ordered array of all markuplint DOM nodes in the document,
62
+ * used for sequential traversal and token-level operations.
63
+ */
64
+ nodeList;
65
+ ontouchcancel;
66
+ ontouchend;
67
+ ontouchmove;
68
+ ontouchstart;
69
+ /**
70
+ * The ML specification data used for element/attribute lookups, ARIA role resolution,
71
+ * and other spec-driven computations.
72
+ */
73
+ specs;
74
+ /**
75
+ * Whether tag name comparisons should be case-sensitive.
76
+ * When false (default for HTML), tag names are compared case-insensitively.
77
+ */
78
+ tagNameCaseSensitive;
79
+ /**
80
+ * Common settings applied globally to all rules, such as the ARIA version.
81
+ * Rules use this as a fallback when their own options do not specify a value.
82
+ */
83
+ ruleCommonSettings;
84
+ #tokenList = null;
85
+ /**
31
86
  * @param ast node list of markuplint AST
32
87
  * @param ruleset ruleset object
88
+ * @param schemas base HTML/ARIA spec with optional framework-specific extensions
89
+ * @param ruleCommonSettings common settings applied globally to all rules
90
+ * @param options optional configuration for document behavior
33
91
  */
34
- constructor(ast, ruleset, schemas, options) {
92
+ constructor(ast, ruleset, schemas, ruleCommonSettings, options) {
35
93
  // @ts-ignore
36
94
  super(ast, null);
37
- /**
38
- *
39
- */
40
- this.currentRule = null;
41
- /**
42
- *
43
- */
44
- _MLDocument_filename.set(this, void 0);
45
- _MLDocument_tokenList.set(this, null);
46
95
  this.isFragment = ast.isFragment;
47
96
  this.specs = schemaToSpec(schemas);
48
97
  this.booleanish = options?.booleanish ?? false;
49
98
  this.endTag = options?.endTag ?? 'omittable';
50
- __classPrivateFieldSet(this, _MLDocument_filename, options?.filename, "f");
99
+ this.#filename = options?.filename;
51
100
  this.tagNameCaseSensitive = options?.tagNameCaseSensitive ?? false;
101
+ this.ruleCommonSettings = ruleCommonSettings;
52
102
  // console.log(ast.nodeList.map((n, i) => `${i}: ${n.uuid} "${n.raw.trim()}"(${n.type})`));
53
103
  this.nodeList = Object.freeze(ast.nodeList
54
104
  .map(astNode => {
@@ -314,7 +364,7 @@ export class MLDocument extends MLParentNode {
314
364
  * @implements `@markuplint/ml-core` API: `MLDOMDocument`
315
365
  */
316
366
  get filename() {
317
- return __classPrivateFieldGet(this, _MLDocument_filename, "f");
367
+ return this.#filename;
318
368
  }
319
369
  /**
320
370
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -1833,7 +1883,11 @@ export class MLDocument extends MLParentNode {
1833
1883
  throw new UnexpectedCallError('Not supported "createTreeWalker" method');
1834
1884
  }
1835
1885
  /**
1886
+ * Returns a debug-friendly string array representing the structure of the document's
1887
+ * node list, useful for debugging and test assertions.
1888
+ *
1836
1889
  * @implements `@markuplint/ml-core` API: `MLDocument`
1890
+ * @returns An array of strings describing each node in the document
1837
1891
  */
1838
1892
  debugMap() {
1839
1893
  return nodeListToDebugMaps(this.nodeList, true);
@@ -1908,6 +1962,19 @@ export class MLDocument extends MLParentNode {
1908
1962
  exitPointerLock() {
1909
1963
  throw new UnexpectedCallError('Not supported "exitPointerLock" method');
1910
1964
  }
1965
+ /**
1966
+ * Computes the accessibility properties for the given node, including its
1967
+ * ARIA role, accessible name, focusability, and ARIA property values.
1968
+ * Returns null for non-element nodes.
1969
+ *
1970
+ * The accessible name is obtained via `node.getAccessibleName()` so that
1971
+ * the per-element memoization cache is shared with other consumers
1972
+ * (rules, selectors). See {@link MLElement.getAccessibleName}.
1973
+ *
1974
+ * @param node - The node to compute accessibility properties for
1975
+ * @param ariaVersion - The ARIA specification version to use for computation
1976
+ * @returns The computed accessibility properties, or null for non-element nodes
1977
+ */
1911
1978
  getAccessibilityProp(
1912
1979
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
1913
1980
  node, ariaVersion = ARIA_RECOMMENDED_VERSION) {
@@ -1931,7 +1998,7 @@ export class MLDocument extends MLParentNode {
1931
1998
  exposedToTree: true,
1932
1999
  };
1933
2000
  const role = getComputedRole(node.ownerMLDocument.specs, node, ariaVersion);
1934
- const name = getAccname(node).trim();
2001
+ const name = node.getAccessibleName(ariaVersion).trim();
1935
2002
  const focusable = mayBeFocusable(node, node.ownerMLDocument.specs);
1936
2003
  const nameRequired = role.role?.accessibleNameRequired ?? false;
1937
2004
  const nameProhibited = role.role?.accessibleNameProhibited ?? false;
@@ -2022,11 +2089,15 @@ export class MLDocument extends MLParentNode {
2022
2089
  throw new UnexpectedCallError('Not supported "getSelection" method');
2023
2090
  }
2024
2091
  /**
2092
+ * Returns a flat, offset-sorted list of all tokens in the document,
2093
+ * including element close tags. The result is cached after the first call.
2094
+ *
2025
2095
  * @implements `@markuplint/ml-core` API: `MLDocument`
2096
+ * @returns A frozen array of tokens sorted by their starting offset
2026
2097
  */
2027
2098
  getTokenList() {
2028
- if (__classPrivateFieldGet(this, _MLDocument_tokenList, "f")) {
2029
- return __classPrivateFieldGet(this, _MLDocument_tokenList, "f");
2099
+ if (this.#tokenList) {
2100
+ return this.#tokenList;
2030
2101
  }
2031
2102
  const tokens = [];
2032
2103
  for (const node of this.nodeList) {
@@ -2035,9 +2106,8 @@ export class MLDocument extends MLParentNode {
2035
2106
  tokens.push(node.closeTag);
2036
2107
  }
2037
2108
  }
2038
- tokens.sort((a, b) => a.startOffset - b.startOffset);
2039
- __classPrivateFieldSet(this, _MLDocument_tokenList, Object.freeze(tokens), "f");
2040
- return __classPrivateFieldGet(this, _MLDocument_tokenList, "f");
2109
+ this.#tokenList = Object.freeze(tokens.toSorted((a, b) => a.startOffset - b.startOffset));
2110
+ return this.#tokenList;
2041
2111
  }
2042
2112
  /**
2043
2113
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -2145,7 +2215,12 @@ export class MLDocument extends MLParentNode {
2145
2215
  throw new UnexpectedCallError('Not supported "requestStorageAccess" method');
2146
2216
  }
2147
2217
  /**
2218
+ * Searches for a node at the given source location (line and column).
2219
+ *
2148
2220
  * @implements `@markuplint/ml-core` API: `MLDocument`
2221
+ * @param line - The 1-based line number to search at
2222
+ * @param col - The 1-based column number to search at
2223
+ * @returns The node at the given location, or null if not found
2149
2224
  */
2150
2225
  searchNodeByLocation(line, col) {
2151
2226
  for (const node of this.nodeList) {
@@ -2156,7 +2231,11 @@ export class MLDocument extends MLParentNode {
2156
2231
  return null;
2157
2232
  }
2158
2233
  /**
2234
+ * Sets the currently active rule for this document. Called by the linting engine
2235
+ * before each rule evaluation pass.
2236
+ *
2159
2237
  * @implements `@markuplint/ml-core` API: `MLDocument`
2238
+ * @param rule - The rule to set as current, or null to clear
2160
2239
  */
2161
2240
  setRule(rule) {
2162
2241
  this.currentRule = rule;
@@ -2171,7 +2250,13 @@ export class MLDocument extends MLParentNode {
2171
2250
  throw new UnexpectedCallError('Not supported "startViewTransition" method');
2172
2251
  }
2173
2252
  /**
2253
+ * Returns a string representation of the entire document. When `fixed` is true,
2254
+ * returns the document with all lint fixes applied by substituting
2255
+ * fixed token content at the appropriate offsets.
2256
+ *
2174
2257
  * @implements `@markuplint/ml-core` API: `MLDocument`
2258
+ * @param fixed - When true, returns the fixed content; otherwise returns the original raw content
2259
+ * @returns The string content of the document
2175
2260
  */
2176
2261
  toString(fixed = false) {
2177
2262
  if (!fixed) {
@@ -2229,6 +2314,11 @@ export class MLDocument extends MLParentNode {
2229
2314
  writeln(...text) {
2230
2315
  throw new UnexpectedCallError('Not supported "writeln" method');
2231
2316
  }
2317
+ /**
2318
+ * Initializes pretender contexts for all element nodes in the document.
2319
+ *
2320
+ * @param pretenders - Optional pretender configurations from the document options
2321
+ */
2232
2322
  _pretending(pretenders) {
2233
2323
  if (docLog.enabled) {
2234
2324
  docLog('Pretending: %O', pretenders);
@@ -2239,6 +2329,13 @@ export class MLDocument extends MLParentNode {
2239
2329
  }
2240
2330
  }
2241
2331
  }
2332
+ /**
2333
+ * Maps the ruleset configuration to each node in the document.
2334
+ * Applies global rules, node-specific rules (by selector), and
2335
+ * child-node rules to build the per-node rule configuration.
2336
+ *
2337
+ * @param ruleset - The ruleset containing rules, nodeRules, and childNodeRules
2338
+ */
2242
2339
  _ruleMapping(ruleset) {
2243
2340
  if (docLog.enabled) {
2244
2341
  docLog('Rule Mapping: %O', Object.keys(ruleset.rules));
@@ -2363,4 +2460,3 @@ export class MLDocument extends MLParentNode {
2363
2460
  ruleMapper.apply();
2364
2461
  }
2365
2462
  }
2366
- _MLDocument_filename = new WeakMap(), _MLDocument_tokenList = new WeakMap();
@@ -1,18 +1,13 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _MLDomTokenList_origin, _MLDomTokenList_ownerAttrs, _MLDomTokenList_set;
13
1
  import { getPosition } from '@markuplint/parser-utils/location';
14
2
  import { UnexpectedCallError } from './unexpected-call-error.js';
15
3
  export class MLDomTokenList extends Array {
4
+ #origin;
5
+ /**
6
+ * In some cases, an author specifies multiple attributes or directives.
7
+ * The reference is not always one.
8
+ */
9
+ #ownerAttrs;
10
+ #set;
16
11
  constructor(tokens,
17
12
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
18
13
  ownerAttrs) {
@@ -21,29 +16,22 @@ export class MLDomTokenList extends Array {
21
16
  .map(t => t.trim())
22
17
  .filter(t => !!t);
23
18
  super(...list);
24
- _MLDomTokenList_origin.set(this, void 0);
25
- /**
26
- * In some cases, an author specifies multiple attributes or directives.
27
- * The reference is not always one.
28
- */
29
- _MLDomTokenList_ownerAttrs.set(this, void 0);
30
- _MLDomTokenList_set.set(this, void 0);
31
- __classPrivateFieldSet(this, _MLDomTokenList_origin, tokens, "f");
32
- __classPrivateFieldSet(this, _MLDomTokenList_ownerAttrs, ownerAttrs, "f");
33
- __classPrivateFieldSet(this, _MLDomTokenList_set, new Set(list), "f");
19
+ this.#origin = tokens;
20
+ this.#ownerAttrs = ownerAttrs;
21
+ this.#set = new Set(list);
34
22
  }
35
23
  get value() {
36
24
  return this.join(' ');
37
25
  }
38
26
  add(...tokens) {
39
27
  for (const token of tokens) {
40
- if (__classPrivateFieldGet(this, _MLDomTokenList_set, "f").has(token)) {
28
+ if (this.#set.has(token)) {
41
29
  continue;
42
30
  }
43
- __classPrivateFieldGet(this, _MLDomTokenList_set, "f").add(token);
31
+ this.#set.add(token);
44
32
  this.push(token);
45
33
  }
46
- __classPrivateFieldSet(this, _MLDomTokenList_origin, __classPrivateFieldGet(this, _MLDomTokenList_origin, "f") + tokens.join(' '), "f");
34
+ this.#origin += tokens.join(' ');
47
35
  }
48
36
  /**
49
37
  * @implements `@markuplint/ml-core` API: `MLDomTokenList`
@@ -74,7 +62,7 @@ export class MLDomTokenList extends Array {
74
62
  return locs;
75
63
  }
76
64
  contains(token) {
77
- return __classPrivateFieldGet(this, _MLDomTokenList_set, "f").has(token);
65
+ return this.#set.has(token);
78
66
  }
79
67
  forEach(callbackfn, thisArg) {
80
68
  this.forEach.bind(this)((v, i) => callbackfn(v, i, thisArg ?? this));
@@ -118,15 +106,15 @@ export class MLDomTokenList extends Array {
118
106
  if (!token) {
119
107
  return null;
120
108
  }
121
- for (const ownerAttr of __classPrivateFieldGet(this, _MLDomTokenList_ownerAttrs, "f")) {
109
+ for (const ownerAttr of this.#ownerAttrs) {
122
110
  if (ownerAttr.isDynamicValue) {
123
111
  continue;
124
112
  }
125
- const startOffset = __classPrivateFieldGet(this, _MLDomTokenList_origin, "f").indexOf(token, _offset);
113
+ const startOffset = this.#origin.indexOf(token, _offset);
126
114
  if (startOffset === -1) {
127
115
  continue;
128
116
  }
129
- const position = getPosition(__classPrivateFieldGet(this, _MLDomTokenList_origin, "f"), startOffset);
117
+ const position = getPosition(this.#origin, startOffset);
130
118
  const startLine = position.line;
131
119
  const startCol = position.column;
132
120
  return {
@@ -141,4 +129,3 @@ export class MLDomTokenList extends Array {
141
129
  return null;
142
130
  }
143
131
  }
144
- _MLDomTokenList_origin = new WeakMap(), _MLDomTokenList_ownerAttrs = new WeakMap(), _MLDomTokenList_set = new WeakMap();
@@ -1,5 +1,6 @@
1
1
  import { MLNode } from './node.js';
2
2
  export class MLElementCloseTag extends MLNode {
3
+ pair;
3
4
  constructor(astNode,
4
5
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
6
  document,