@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.
- package/ARCHITECTURE.ja.md +524 -0
- package/ARCHITECTURE.md +524 -0
- package/CHANGELOG.md +52 -2
- package/README.md +5 -0
- package/SKILL.md +61 -0
- package/docs/linting-pipeline.ja.md +307 -0
- package/docs/linting-pipeline.md +307 -0
- package/docs/maintenance.ja.md +210 -0
- package/docs/maintenance.md +210 -0
- package/docs/ml-dom/attr.ja.md +103 -0
- package/docs/ml-dom/attr.md +103 -0
- package/docs/ml-dom/block.ja.md +272 -0
- package/docs/ml-dom/block.md +272 -0
- package/docs/ml-dom/document.ja.md +141 -0
- package/docs/ml-dom/document.md +141 -0
- package/docs/ml-dom/element.ja.md +176 -0
- package/docs/ml-dom/element.md +176 -0
- package/docs/ml-dom/helpers.ja.md +203 -0
- package/docs/ml-dom/helpers.md +203 -0
- package/docs/ml-dom/node.ja.md +199 -0
- package/docs/ml-dom/node.md +199 -0
- package/docs/ml-dom/others.ja.md +120 -0
- package/docs/ml-dom/others.md +120 -0
- package/docs/ml-dom/overview.ja.md +102 -0
- package/docs/ml-dom/overview.md +102 -0
- package/docs/ml-dom/pretender.ja.md +269 -0
- package/docs/ml-dom/pretender.md +269 -0
- package/docs/ml-dom/rule-mapping.ja.md +371 -0
- package/docs/ml-dom/rule-mapping.md +371 -0
- package/docs/ml-dom.ja.md +18 -0
- package/docs/ml-dom.md +18 -0
- package/docs/rule-system.ja.md +287 -0
- package/docs/rule-system.md +287 -0
- package/lib/convert-ruleset.d.ts +7 -0
- package/lib/convert-ruleset.js +7 -0
- package/lib/debug.d.ts +4 -0
- package/lib/debug.js +4 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.js +1 -1
- package/lib/ml-core.d.ts +37 -1
- package/lib/ml-core.js +171 -82
- package/lib/ml-dom/helper/accname.d.ts +8 -0
- package/lib/ml-dom/helper/accname.js +71 -55
- package/lib/ml-dom/helper/create-node.js +1 -0
- package/lib/ml-dom/helper/get-indent.d.ts +4 -1
- package/lib/ml-dom/helper/get-indent.js +21 -30
- package/lib/ml-dom/node/attr.d.ts +65 -4
- package/lib/ml-dom/node/attr.js +151 -53
- package/lib/ml-dom/node/block.d.ts +23 -2
- package/lib/ml-dom/node/block.js +24 -1
- package/lib/ml-dom/node/child-node.d.ts +9 -0
- package/lib/ml-dom/node/child-node.js +9 -0
- package/lib/ml-dom/node/comment.d.ts +7 -0
- package/lib/ml-dom/node/comment.js +7 -0
- package/lib/ml-dom/node/document-fragment.d.ts +8 -0
- package/lib/ml-dom/node/document-fragment.js +8 -0
- package/lib/ml-dom/node/document-type.d.ts +22 -0
- package/lib/ml-dom/node/document-type.js +25 -0
- package/lib/ml-dom/node/document.d.ts +88 -7
- package/lib/ml-dom/node/document.js +128 -32
- package/lib/ml-dom/node/dom-token-list.js +17 -30
- package/lib/ml-dom/node/element-close-tag.js +1 -0
- package/lib/ml-dom/node/element.d.ts +151 -5
- package/lib/ml-dom/node/element.js +242 -50
- package/lib/ml-dom/node/node-store.js +6 -15
- package/lib/ml-dom/node/node.d.ts +19 -1
- package/lib/ml-dom/node/node.js +175 -166
- package/lib/ml-dom/node/parent-node.js +14 -30
- package/lib/ml-dom/node/rule-mapper.js +7 -20
- package/lib/ml-dom/node/text.d.ts +19 -0
- package/lib/ml-dom/node/text.js +21 -0
- package/lib/ml-dom/node/types.d.ts +68 -0
- package/lib/ml-dom/token/token.d.ts +42 -0
- package/lib/ml-dom/token/token.js +59 -39
- package/lib/ml-rule/create-rule.d.ts +17 -1
- package/lib/ml-rule/ml-rule-context.js +7 -11
- package/lib/ml-rule/ml-rule.d.ts +66 -1
- package/lib/ml-rule/ml-rule.js +95 -25
- package/lib/ml-rule/types.d.ts +41 -0
- package/lib/plugin/plugin.d.ts +8 -0
- package/lib/plugin/plugin.js +8 -0
- package/lib/plugin/types.d.ts +21 -0
- package/lib/ruleset/index.d.ts +10 -0
- package/lib/ruleset/index.js +13 -0
- package/lib/test/index.d.ts +42 -1
- package/lib/test/index.js +39 -2
- package/lib/types.d.ts +10 -1
- package/lib/violation-collector.d.ts +33 -0
- package/lib/violation-collector.js +48 -28
- package/lib/virtual-rule.d.ts +72 -0
- package/lib/virtual-rule.js +233 -0
- 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
|
-
*
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 (
|
|
2029
|
-
return
|
|
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.
|
|
2039
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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 (
|
|
28
|
+
if (this.#set.has(token)) {
|
|
41
29
|
continue;
|
|
42
30
|
}
|
|
43
|
-
|
|
31
|
+
this.#set.add(token);
|
|
44
32
|
this.push(token);
|
|
45
33
|
}
|
|
46
|
-
|
|
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
|
|
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
|
|
109
|
+
for (const ownerAttr of this.#ownerAttrs) {
|
|
122
110
|
if (ownerAttr.isDynamicValue) {
|
|
123
111
|
continue;
|
|
124
112
|
}
|
|
125
|
-
const startOffset =
|
|
113
|
+
const startOffset = this.#origin.indexOf(token, _offset);
|
|
126
114
|
if (startOffset === -1) {
|
|
127
115
|
continue;
|
|
128
116
|
}
|
|
129
|
-
const position = getPosition(
|
|
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();
|