@markuplint/ml-core 4.0.0-dev.28 → 4.0.0-rc.1

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 (50) hide show
  1. package/LICENSE +1 -1
  2. package/lib/configs.browser.js +10 -8
  3. package/lib/convert-ruleset.d.ts +1 -1
  4. package/lib/convert-ruleset.js +1 -1
  5. package/lib/index.d.ts +1 -2
  6. package/lib/index.js +1 -2
  7. package/lib/ml-core.js +1 -0
  8. package/lib/ml-dom/helper/create-node.d.ts +2 -2
  9. package/lib/ml-dom/helper/create-node.js +32 -7
  10. package/lib/ml-dom/helper/get-indent.js +1 -1
  11. package/lib/ml-dom/manipulations/child-node-methods.js +1 -1
  12. package/lib/ml-dom/node/attr.d.ts +18 -0
  13. package/lib/ml-dom/node/attr.js +69 -31
  14. package/lib/ml-dom/node/block.js +1 -3
  15. package/lib/ml-dom/node/character-data.d.ts +2 -2
  16. package/lib/ml-dom/node/character-data.js +1 -1
  17. package/lib/ml-dom/node/child-node.d.ts +2 -2
  18. package/lib/ml-dom/node/document-fragment.d.ts +2 -2
  19. package/lib/ml-dom/node/document-fragment.js +1 -1
  20. package/lib/ml-dom/node/document-type.js +1 -3
  21. package/lib/ml-dom/node/document.d.ts +6 -4
  22. package/lib/ml-dom/node/document.js +13 -11
  23. package/lib/ml-dom/node/dom-token-list.js +3 -3
  24. package/lib/ml-dom/node/element-close-tag.d.ts +20 -0
  25. package/lib/ml-dom/node/element-close-tag.js +39 -0
  26. package/lib/ml-dom/node/element.d.ts +14 -6
  27. package/lib/ml-dom/node/element.js +62 -46
  28. package/lib/ml-dom/node/named-node-map.js +1 -1
  29. package/lib/ml-dom/node/node-store.d.ts +3 -3
  30. package/lib/ml-dom/node/node.d.ts +2 -2
  31. package/lib/ml-dom/node/node.js +18 -11
  32. package/lib/ml-dom/node/parent-node.d.ts +2 -2
  33. package/lib/ml-dom/node/parent-node.js +1 -1
  34. package/lib/ml-dom/node/text.js +1 -1
  35. package/lib/ml-dom/node/types.d.ts +2 -3
  36. package/lib/ml-dom/node/unexpected-call-error.d.ts +1 -1
  37. package/lib/ml-dom/node/unexpected-call-error.js +1 -1
  38. package/lib/ml-dom/token/token.d.ts +3 -3
  39. package/lib/ml-dom/token/token.js +5 -5
  40. package/lib/ml-rule/ml-rule.d.ts +1 -1
  41. package/lib/ml-rule/types.d.ts +3 -0
  42. package/lib/ruleset/index.d.ts +1 -1
  43. package/lib/ruleset/index.js +1 -1
  44. package/lib/test/index.d.ts +6 -4
  45. package/lib/test/index.js +6 -2
  46. package/lib/types.d.ts +3 -3
  47. package/lib/utils/get-location-from-chars.js +1 -1
  48. package/package.json +13 -13
  49. package/lib/configs.d.ts +0 -2
  50. package/lib/configs.js +0 -37
@@ -8,13 +8,19 @@ import type { ARIAVersion } from '@markuplint/ml-spec';
8
8
  import { MLToken } from '../token/token.js';
9
9
  import { MLAttr } from './attr.js';
10
10
  import { MLDomTokenList } from './dom-token-list.js';
11
+ import { MLElementCloseTag } from './element-close-tag.js';
11
12
  import { MLParentNode } from './parent-node.js';
12
13
  export declare class MLElement<T extends RuleConfigValue, O extends PlainData = undefined> extends MLParentNode<T, O, MLASTElement> implements Element, HTMLOrSVGElement, HTMLElement {
13
14
  #private;
14
- readonly closeTag: MLToken | null;
15
+ readonly closeTag: MLElementCloseTag<T, O> | null;
16
+ /**
17
+ * Element type
18
+ *
19
+ * - `html`: From native HTML Standard
20
+ * - `web-component`: As the Web Component according to HTML Standard
21
+ * - `authored`: Authored element (JSX Element etc.) through the view framework or the template engine.
22
+ */
15
23
  readonly elementType: ElementType;
16
- readonly endSpace: MLToken | null;
17
- readonly hasSpreadAttr: boolean;
18
24
  readonly isForeignElement: boolean;
19
25
  readonly isOmitted: boolean;
20
26
  readonly namespaceURI: NamespaceURI;
@@ -24,6 +30,8 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
24
30
  readonly ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;
25
31
  pretenderContext: PretenderContext<MLElement<T, O>, T, O> | null;
26
32
  readonly selfClosingSolidus: MLToken | null;
33
+ readonly tagCloseChar: string;
34
+ readonly tagOpenChar: string;
27
35
  constructor(astNode: MLASTElement, document: MLDocument<T, O>);
28
36
  /**
29
37
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -469,6 +477,7 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
469
477
  * @implements `@markuplint/ml-core` API: `MLElement`
470
478
  */
471
479
  get fixedNodeName(): string;
480
+ get hasSpreadAttr(): boolean;
472
481
  /**
473
482
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
474
483
  *
@@ -1398,7 +1407,6 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
1398
1407
  * @see https://dom.spec.whatwg.org/#ref-for-dom-nondocumenttypechildnode-previouselementsibling%E2%91%A1
1399
1408
  */
1400
1409
  get previousElementSibling(): MLElement<T, O> | null;
1401
- get raw(): string;
1402
1410
  /**
1403
1411
  * @implements `@markuplint/ml-core` API: `MLElement`
1404
1412
  */
@@ -1781,7 +1789,7 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
1781
1789
  /**
1782
1790
  * Pretenders Initialization
1783
1791
  */
1784
- pretending(pretenders: readonly Pretender[]): void;
1792
+ pretending(pretenders?: readonly Pretender[]): void;
1785
1793
  /**
1786
1794
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
1787
1795
  *
@@ -1925,7 +1933,7 @@ export declare class MLElement<T extends RuleConfigValue, O extends PlainData =
1925
1933
  /**
1926
1934
  * @implements `@markuplint/ml-core` API: `MLElement`
1927
1935
  */
1928
- toString(): string;
1936
+ toString(fixed?: boolean): string;
1929
1937
  /**
1930
1938
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
1931
1939
  *
@@ -10,24 +10,22 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _MLElement_attributes, _MLElement_fixedNodeName, _MLElement_getChildElementsAndTextNodeWithoutWhitespacesCache, _MLElement_localName, _MLElement_normalizedAttrs, _MLElement_normalizedString, _MLElement_tagOpenChar;
13
+ var _MLElement_attributes, _MLElement_fixedNodeName, _MLElement_getChildElementsAndTextNodeWithoutWhitespacesCache, _MLElement_localName, _MLElement_normalizedAttrs, _MLElement_normalizedString;
14
14
  import { resolveNamespace } from '@markuplint/ml-spec';
15
15
  import { createSelector } from '@markuplint/selector';
16
- import { stringSplice } from '../../utils/string-splice.js';
17
16
  import { getAccname } from '../helper/accname.js';
18
17
  import { after, before, nextElementSibling, previousElementSibling, remove, replaceWith, } from '../manipulations/child-node-methods.js';
19
18
  import { MLToken } from '../token/token.js';
20
19
  import { MLAttr } from './attr.js';
21
20
  import { MLDomTokenList } from './dom-token-list.js';
21
+ import { MLElementCloseTag } from './element-close-tag.js';
22
22
  import { toNamedNodeMap } from './named-node-map.js';
23
23
  import { toHTMLCollection } from './node-list.js';
24
24
  import { MLParentNode } from './parent-node.js';
25
- import UnexpectedCallError from './unexpected-call-error.js';
25
+ import { UnexpectedCallError } from './unexpected-call-error.js';
26
26
  const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
27
27
  export class MLElement extends MLParentNode {
28
- constructor(
29
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
30
- astNode,
28
+ constructor(astNode,
31
29
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
32
30
  document) {
33
31
  super(astNode, document);
@@ -38,12 +36,9 @@ export class MLElement extends MLParentNode {
38
36
  _MLElement_normalizedAttrs.set(this, new Map());
39
37
  _MLElement_normalizedString.set(this, null);
40
38
  this.pretenderContext = null;
41
- _MLElement_tagOpenChar.set(this, void 0);
42
39
  __classPrivateFieldSet(this, _MLElement_attributes, astNode.attributes.map(attr => new MLAttr(attr, this)), "f");
43
- this.hasSpreadAttr = astNode.hasSpreadAttr;
44
40
  this.selfClosingSolidus = astNode.selfClosingSolidus ? new MLToken(astNode.selfClosingSolidus) : null;
45
- this.endSpace = astNode.endSpace ? new MLToken(astNode.endSpace) : null;
46
- this.closeTag = astNode.pearNode ? new MLToken(astNode.pearNode) : null;
41
+ this.closeTag = astNode.pairNode ? new MLElementCloseTag(astNode.pairNode, document, this) : null;
47
42
  const ns = resolveNamespace(astNode.nodeName, astNode.namespace);
48
43
  this.namespaceURI = ns.namespaceURI;
49
44
  this.elementType = astNode.elementType;
@@ -51,7 +46,8 @@ export class MLElement extends MLParentNode {
51
46
  this.isForeignElement = this.namespaceURI !== HTML_NAMESPACE;
52
47
  __classPrivateFieldSet(this, _MLElement_fixedNodeName, astNode.nodeName, "f");
53
48
  this.isOmitted = astNode.isGhost;
54
- __classPrivateFieldSet(this, _MLElement_tagOpenChar, astNode.tagOpenChar, "f");
49
+ this.tagOpenChar = astNode.tagOpenChar;
50
+ this.tagCloseChar = astNode.tagCloseChar;
55
51
  }
56
52
  /**
57
53
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -634,6 +630,9 @@ export class MLElement extends MLParentNode {
634
630
  get fixedNodeName() {
635
631
  return __classPrivateFieldGet(this, _MLElement_fixedNodeName, "f");
636
632
  }
633
+ get hasSpreadAttr() {
634
+ return __classPrivateFieldGet(this, _MLElement_attributes, "f").some(attr => attr.localName === '#spread');
635
+ }
637
636
  /**
638
637
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
639
638
  *
@@ -1809,26 +1808,6 @@ export class MLElement extends MLParentNode {
1809
1808
  get previousElementSibling() {
1810
1809
  return previousElementSibling(this);
1811
1810
  }
1812
- get raw() {
1813
- if (this.pretenderContext?.type === 'pretender') {
1814
- return this.originRaw;
1815
- }
1816
- let fixed = this.originRaw;
1817
- let gap = 0;
1818
- if (this.nodeName !== this.fixedNodeName) {
1819
- fixed = stringSplice(fixed, __classPrivateFieldGet(this, _MLElement_tagOpenChar, "f").length, this.nodeName.length, this.fixedNodeName);
1820
- gap = gap + this.fixedNodeName.length - this.nodeName.length;
1821
- }
1822
- for (const attr of this.attributes) {
1823
- const startOffset = (attr.spacesBeforeName?.startOffset ?? attr.startOffset) - this.startOffset;
1824
- const fixedAttr = attr.toString();
1825
- if (attr.originRaw !== fixedAttr) {
1826
- fixed = stringSplice(fixed, startOffset + gap, attr.originRaw.length, fixedAttr);
1827
- gap = gap + fixedAttr.length - attr.originRaw.length;
1828
- }
1829
- }
1830
- return fixed;
1831
- }
1832
1811
  /**
1833
1812
  * @implements `@markuplint/ml-core` API: `MLElement`
1834
1813
  */
@@ -2293,7 +2272,7 @@ export class MLElement extends MLParentNode {
2293
2272
  return {
2294
2273
  offset: this.startOffset,
2295
2274
  line: this.startLine,
2296
- col: this.startCol + __classPrivateFieldGet(this, _MLElement_tagOpenChar, "f").length,
2275
+ col: this.startCol + this.tagOpenChar.length,
2297
2276
  };
2298
2277
  }
2299
2278
  /**
@@ -2454,24 +2433,32 @@ export class MLElement extends MLParentNode {
2454
2433
  */
2455
2434
  pretending(pretenders) {
2456
2435
  const pretenderConfig = pretenders?.find(option => this.matches(option.selector));
2457
- if (!pretenderConfig) {
2436
+ const asAttrValue = this.getAttribute('as');
2437
+ const pretenderElement = pretenderConfig?.as ??
2438
+ (this.elementType === 'html' || !asAttrValue
2439
+ ? null
2440
+ : {
2441
+ element: asAttrValue,
2442
+ inheritAttrs: true,
2443
+ });
2444
+ if (pretenderElement == null) {
2458
2445
  return;
2459
2446
  }
2460
2447
  let nodeName;
2461
2448
  let namespace = 'html';
2462
2449
  const attributes = [];
2463
2450
  let aria;
2464
- if (typeof pretenderConfig.as === 'string') {
2465
- nodeName = pretenderConfig.as;
2451
+ if (typeof pretenderElement === 'string') {
2452
+ nodeName = pretenderElement;
2466
2453
  }
2467
2454
  else {
2468
- nodeName = pretenderConfig.as.element;
2469
- namespace = pretenderConfig.as.namespace ?? namespace;
2470
- if (pretenderConfig.as.inheritAttrs) {
2455
+ nodeName = pretenderElement.element;
2456
+ namespace = pretenderElement.namespace ?? namespace;
2457
+ if (pretenderElement.inheritAttrs) {
2471
2458
  attributes.push(...this._astToken.attributes);
2472
2459
  }
2473
- if (pretenderConfig.as.attrs) {
2474
- attributes.push(...pretenderConfig.as.attrs.map(({ name, value }, i) => {
2460
+ if (pretenderElement.attrs) {
2461
+ attributes.push(...pretenderElement.attrs.map(({ name, value }, i) => {
2475
2462
  const _value = value == null
2476
2463
  ? ''
2477
2464
  : typeof value === 'string'
@@ -2480,7 +2467,7 @@ export class MLElement extends MLParentNode {
2480
2467
  return {
2481
2468
  ...this._astToken,
2482
2469
  uuid: `${this.uuid}_attr_${i}`,
2483
- type: 'html-attr',
2470
+ type: 'attr',
2484
2471
  nodeName: name,
2485
2472
  spacesBeforeName: {
2486
2473
  ...this._astToken,
@@ -2523,7 +2510,7 @@ export class MLElement extends MLParentNode {
2523
2510
  };
2524
2511
  }));
2525
2512
  }
2526
- aria = pretenderConfig.as.aria;
2513
+ aria = pretenderElement.aria;
2527
2514
  }
2528
2515
  const as = new MLElement({
2529
2516
  ...this._astToken,
@@ -2744,7 +2731,7 @@ export class MLElement extends MLParentNode {
2744
2731
  if (node.is(node.ELEMENT_NODE)) {
2745
2732
  return node.toNormalizeString();
2746
2733
  }
2747
- return node.originRaw;
2734
+ return node.raw;
2748
2735
  });
2749
2736
  const endTag = `</${this.nodeName}>`;
2750
2737
  const normalizedString = `${startTag}${childNodes.join('')}${endTag}`;
@@ -2754,8 +2741,37 @@ export class MLElement extends MLParentNode {
2754
2741
  /**
2755
2742
  * @implements `@markuplint/ml-core` API: `MLElement`
2756
2743
  */
2757
- toString() {
2758
- return this.raw;
2744
+ toString(fixed = false) {
2745
+ if (!fixed) {
2746
+ return this.raw;
2747
+ }
2748
+ if (this.pretenderContext?.type === 'pretender') {
2749
+ return this.raw;
2750
+ }
2751
+ if (this.nodeName.startsWith('#')) {
2752
+ return this.raw;
2753
+ }
2754
+ if (this.isOmitted) {
2755
+ return this.raw;
2756
+ }
2757
+ let raw = this.raw;
2758
+ let offset = 0;
2759
+ const nodes = [
2760
+ {
2761
+ toString: () => this.tagOpenChar + this.fixedNodeName,
2762
+ startOffset: this.startOffset,
2763
+ endOffset: this.startOffset + this.tagOpenChar.length + this.nodeName.length,
2764
+ },
2765
+ ...this.attributes,
2766
+ ];
2767
+ for (const node of nodes) {
2768
+ const before = raw.slice(0, node.startOffset + offset - this.startOffset);
2769
+ const rawCode = node.toString(true);
2770
+ const after = raw.slice(node.endOffset + offset - this.startOffset);
2771
+ raw = before + rawCode + after;
2772
+ offset += rawCode.length - (node.endOffset - node.startOffset);
2773
+ }
2774
+ return raw;
2759
2775
  }
2760
2776
  /**
2761
2777
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -2788,4 +2804,4 @@ export class MLElement extends MLParentNode {
2788
2804
  throw new UnexpectedCallError('Not supported "webkitMatchesSelector" method');
2789
2805
  }
2790
2806
  }
2791
- _MLElement_attributes = new WeakMap(), _MLElement_fixedNodeName = new WeakMap(), _MLElement_getChildElementsAndTextNodeWithoutWhitespacesCache = new WeakMap(), _MLElement_localName = new WeakMap(), _MLElement_normalizedAttrs = new WeakMap(), _MLElement_normalizedString = new WeakMap(), _MLElement_tagOpenChar = new WeakMap();
2807
+ _MLElement_attributes = new WeakMap(), _MLElement_fixedNodeName = new WeakMap(), _MLElement_getChildElementsAndTextNodeWithoutWhitespacesCache = new WeakMap(), _MLElement_localName = new WeakMap(), _MLElement_normalizedAttrs = new WeakMap(), _MLElement_normalizedString = new WeakMap();
@@ -1,4 +1,4 @@
1
- import UnexpectedCallError from './unexpected-call-error.js';
1
+ import { UnexpectedCallError } from './unexpected-call-error.js';
2
2
  export class MLNamedNodeMap extends Array {
3
3
  getNamedItem(qualifiedName) {
4
4
  return this.find(attr => attr.name === qualifiedName) ?? null;
@@ -1,11 +1,11 @@
1
1
  import type { MLNode } from './node.js';
2
2
  import type { MappedNode } from './types.js';
3
- import type { MLASTAbstractNode } from '@markuplint/ml-ast';
3
+ import type { MLASTNode } from '@markuplint/ml-ast';
4
4
  import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
5
5
  declare class NodeStore {
6
6
  #private;
7
- getNode<N extends MLASTAbstractNode, T extends RuleConfigValue, O extends PlainData = undefined>(astNode: N): MappedNode<N, T, O>;
8
- setNode<A extends MLASTAbstractNode, T extends RuleConfigValue, O extends PlainData = undefined>(astNode: A, node: MLNode<T, O, A>): void;
7
+ getNode<N extends MLASTNode, T extends RuleConfigValue, O extends PlainData = undefined>(astNode: N): MappedNode<N, T, O>;
8
+ setNode<A extends MLASTNode, T extends RuleConfigValue, O extends PlainData = undefined>(astNode: A, node: MLNode<T, O, A>): void;
9
9
  }
10
10
  /**
11
11
  * `NodeStore` Singleton
@@ -5,10 +5,10 @@ import type { MLDocument } from './document.js';
5
5
  import type { MLElement } from './element.js';
6
6
  import type { MarkuplintPreprocessorBlockType, NodeType, NodeTypeOf } from './types.js';
7
7
  import type { RuleInfo } from '../../index.js';
8
- import type { MLASTAbstractNode } from '@markuplint/ml-ast';
8
+ import type { MLASTNode } from '@markuplint/ml-ast';
9
9
  import type { AnyRule, PlainData, RuleConfigValue } from '@markuplint/ml-config';
10
10
  import { MLToken } from '../token/token.js';
11
- export declare abstract class MLNode<T extends RuleConfigValue, O extends PlainData = undefined, A extends MLASTAbstractNode = MLASTAbstractNode> extends MLToken<A> implements Node {
11
+ export declare abstract class MLNode<T extends RuleConfigValue, O extends PlainData = undefined, A extends MLASTNode = MLASTNode> extends MLToken<A> implements Node {
12
12
  #private;
13
13
  /**
14
14
  * @implements DOM API: `Node`
@@ -14,7 +14,7 @@ import { MLToken } from '../token/token.js';
14
14
  import { isChildNode } from './child-node.js';
15
15
  import { toNodeList } from './node-list.js';
16
16
  import { nodeStore } from './node-store.js';
17
- import UnexpectedCallError from './unexpected-call-error.js';
17
+ import { UnexpectedCallError } from './unexpected-call-error.js';
18
18
  export class MLNode extends MLToken {
19
19
  constructor(astNode,
20
20
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -175,11 +175,17 @@ export class MLNode extends MLToken {
175
175
  if (this.is(this.DOCUMENT_FRAGMENT_NODE) ||
176
176
  this.is(this.ELEMENT_NODE) ||
177
177
  this.is(this.MARKUPLINT_PREPROCESSOR_BLOCK)) {
178
+ const astChildren =
178
179
  // @ts-ignore
179
- const astChildren = this._astToken.childNodes ?? [];
180
+ this._astToken?.childNodes?.filter(node => {
181
+ if (node.type === 'endtag' || node.type === 'invalid') {
182
+ return null;
183
+ }
184
+ return node;
185
+ }) ?? [];
180
186
  const childNodes = astChildren
181
187
  .map(node => nodeStore.getNode(node))
182
- .filter((node) => isChildNode(node));
188
+ .filter(node => isChildNode(node));
183
189
  // Cache
184
190
  __classPrivateFieldSet(this, _MLNode_childNodes, toNodeList(childNodes), "f");
185
191
  return __classPrivateFieldGet(this, _MLNode_childNodes, "f");
@@ -223,10 +229,9 @@ export class MLNode extends MLToken {
223
229
  * @implements `@markuplint/ml-core` API: `MLNode`
224
230
  */
225
231
  get nextNode() {
226
- if (!this._astToken.nextNode) {
227
- return null;
228
- }
229
- return nodeStore.getNode(this._astToken.nextNode);
232
+ const siblings = [...(this.syntacticalParentNode?.childNodes ?? __classPrivateFieldGet(this, _MLNode_ownerDocument, "f").nodeList)];
233
+ const index = siblings.findIndex(node => node.uuid === this.uuid);
234
+ return siblings[index + 1] ?? null;
230
235
  }
231
236
  /**
232
237
  * **IT THROWS AN ERROR WHEN CALLING THIS.**
@@ -368,10 +373,9 @@ export class MLNode extends MLToken {
368
373
  * @implements `@markuplint/ml-core` API: `MLNode`
369
374
  */
370
375
  get prevNode() {
371
- if (!this._astToken.prevNode) {
372
- return null;
373
- }
374
- return nodeStore.getNode(this._astToken.prevNode);
376
+ const siblings = [...(this.syntacticalParentNode?.childNodes ?? __classPrivateFieldGet(this, _MLNode_ownerDocument, "f").nodeList)];
377
+ const index = siblings.findIndex(node => node.uuid === this.uuid);
378
+ return siblings[index - 1] ?? null;
375
379
  }
376
380
  /**
377
381
  * @implements `@markuplint/ml-core` API: `MLNode`
@@ -466,6 +470,9 @@ export class MLNode extends MLToken {
466
470
  * @implements `@markuplint/ml-core` API: `MLNode`
467
471
  */
468
472
  get syntacticalParentNode() {
473
+ if (this._astToken.type === 'attr' || this._astToken.type === 'spread') {
474
+ return null;
475
+ }
469
476
  if (!this._astToken.parentNode) {
470
477
  return this.ownerMLDocument;
471
478
  }
@@ -1,12 +1,12 @@
1
1
  import type { MLElement } from './element.js';
2
- import type { MLASTAbstractNode } from '@markuplint/ml-ast';
2
+ import type { MLASTNode } from '@markuplint/ml-ast';
3
3
  import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
4
4
  import { MLNode } from './node.js';
5
5
  /**
6
6
  *
7
7
  * @see https://dom.spec.whatwg.org/#interface-parentnode
8
8
  */
9
- export declare abstract class MLParentNode<T extends RuleConfigValue, O extends PlainData = undefined, A extends MLASTAbstractNode = MLASTAbstractNode> extends MLNode<T, O, A> implements ParentNode {
9
+ export declare abstract class MLParentNode<T extends RuleConfigValue, O extends PlainData = undefined, A extends MLASTNode = MLASTNode> extends MLNode<T, O, A> implements ParentNode {
10
10
  #private;
11
11
  /**
12
12
  * @implements DOM API: `Element`, `Document`, `DocumentFragment`
@@ -14,7 +14,7 @@ import { syncWalk } from '../helper/walkers.js';
14
14
  import { getChildren } from '../manipulations/get-children.js';
15
15
  import { toNodeList } from './node-list.js';
16
16
  import { MLNode } from './node.js';
17
- import UnexpectedCallError from './unexpected-call-error.js';
17
+ import { UnexpectedCallError } from './unexpected-call-error.js';
18
18
  /**
19
19
  *
20
20
  * @see https://dom.spec.whatwg.org/#interface-parentnode
@@ -1,5 +1,5 @@
1
1
  import { MLCharacterData } from './character-data.js';
2
- import UnexpectedCallError from './unexpected-call-error.js';
2
+ import { UnexpectedCallError } from './unexpected-call-error.js';
3
3
  /**
4
4
  * Raw text elements
5
5
  *
@@ -5,12 +5,11 @@ import type { MLDocumentFragment } from './document-fragment.js';
5
5
  import type { MLDocumentType } from './document-type.js';
6
6
  import type { MLDocument } from './document.js';
7
7
  import type { MLElement } from './element.js';
8
- import type { MLNode } from './node.js';
9
8
  import type { MLText } from './text.js';
10
9
  import type { MLToken } from '../token/token.js';
11
- import type { MLASTAbstractNode, MLASTAttr, MLASTComment, MLASTDoctype, MLASTElement, MLASTParentNode, MLASTPreprocessorSpecificBlock, MLASTText, MLToken as MLASTToken } from '@markuplint/ml-ast/';
10
+ import type { MLASTAttr, MLASTComment, MLASTDoctype, MLASTElement, MLASTInvalid, MLASTParentNode, MLASTPreprocessorSpecificBlock, MLASTText, MLASTToken as MLASTToken } from '@markuplint/ml-ast/';
12
11
  import type { PlainData, PretenderARIA, RuleConfigValue } from '@markuplint/ml-config';
13
- export type MappedNode<N, T extends RuleConfigValue, O extends PlainData = undefined> = N extends MLASTElement ? MLElement<T, O> : N extends MLASTParentNode ? MLElement<T, O> : N extends MLASTComment ? MLComment<T, O> : N extends MLASTText ? MLText<T, O> : N extends MLASTDoctype ? MLDocumentType<T, O> : N extends MLASTPreprocessorSpecificBlock ? MLBlock<T, O> : N extends MLASTAbstractNode ? MLNode<T, O, MLASTAbstractNode> : N extends MLASTAttr ? MLAttr<T, O> : N extends MLASTToken ? MLToken : never;
12
+ export type MappedNode<N, T extends RuleConfigValue, O extends PlainData = undefined> = N extends MLASTElement ? MLElement<T, O> : N extends MLASTParentNode ? MLElement<T, O> : N extends MLASTComment ? MLComment<T, O> : N extends MLASTText ? MLText<T, O> : N extends MLASTDoctype ? MLDocumentType<T, O> : N extends MLASTPreprocessorSpecificBlock ? MLBlock<T, O> : N extends MLASTAttr ? MLAttr<T, O> : N extends MLASTInvalid ? MLText<T, O> : N extends MLASTToken ? MLToken : never;
14
13
  export type NodeTypeOf<NT extends NodeType, T extends RuleConfigValue, O extends PlainData = undefined> = NT extends ElementNodeType ? MLElement<T, O> : NT extends CommentNodeType ? MLComment<T, O> : NT extends TextNodeType ? MLText<T, O> : NT extends DocumentNodeType ? MLDocument<T, O> : NT extends DocumentTypeNodeType ? MLDocumentType<T, O> : NT extends DocumentFragmentNodeType ? MLDocumentFragment<T, O> : NT extends MarkuplintPreprocessorBlockType ? MLBlock<T, O> : NT extends AttributeNodeType ? MLAttr<T, O> : never;
15
14
  export type ElementNodeType = 1;
16
15
  export type AttributeNodeType = 2;
@@ -1,2 +1,2 @@
1
- export default class UnexpectedCallError extends Error {
1
+ export declare class UnexpectedCallError extends Error {
2
2
  }
@@ -1,2 +1,2 @@
1
- export default class UnexpectedCallError extends Error {
1
+ export class UnexpectedCallError extends Error {
2
2
  }
@@ -1,4 +1,4 @@
1
- import type { MLToken as MLASTToken } from '@markuplint/ml-ast';
1
+ import type { MLASTToken } from '@markuplint/ml-ast';
2
2
  export declare class MLToken<A extends MLASTToken = MLASTToken> {
3
3
  #private;
4
4
  readonly uuid: string;
@@ -19,7 +19,7 @@ export declare class MLToken<A extends MLASTToken = MLASTToken> {
19
19
  /**
20
20
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
21
21
  */
22
- get originRaw(): string;
22
+ get fixed(): string;
23
23
  /**
24
24
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
25
25
  */
@@ -43,5 +43,5 @@ export declare class MLToken<A extends MLASTToken = MLASTToken> {
43
43
  /**
44
44
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
45
45
  */
46
- toString(): string;
46
+ toString(fixed?: boolean): string;
47
47
  }
@@ -52,14 +52,14 @@ export class MLToken {
52
52
  /**
53
53
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
54
54
  */
55
- get originRaw() {
56
- return __classPrivateFieldGet(this, _MLToken_raw, "f");
55
+ get fixed() {
56
+ return __classPrivateFieldGet(this, _MLToken_fixed, "f");
57
57
  }
58
58
  /**
59
59
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
60
60
  */
61
61
  get raw() {
62
- return __classPrivateFieldGet(this, _MLToken_fixed, "f");
62
+ return __classPrivateFieldGet(this, _MLToken_raw, "f");
63
63
  }
64
64
  /**
65
65
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
@@ -88,8 +88,8 @@ export class MLToken {
88
88
  /**
89
89
  * @implements `@markuplint/ml-core` API: `MLDOMToken`
90
90
  */
91
- toString() {
92
- return this.raw;
91
+ toString(fixed = false) {
92
+ return fixed ? __classPrivateFieldGet(this, _MLToken_fixed, "f") : __classPrivateFieldGet(this, _MLToken_raw, "f");
93
93
  }
94
94
  }
95
95
  _MLToken_endCol = new WeakMap(), _MLToken_endLine = new WeakMap(), _MLToken_endOffset = new WeakMap(), _MLToken_fixed = new WeakMap(), _MLToken_raw = new WeakMap(), _MLToken_startCol = new WeakMap(), _MLToken_startLine = new WeakMap(), _MLToken_startOffset = new WeakMap();
@@ -1,6 +1,6 @@
1
1
  import type { RuleSeed } from './types.js';
2
2
  import type { MLDocument } from '../ml-dom/node/document.js';
3
- import type Ruleset from '../ruleset/index.js';
3
+ import type { Ruleset } from '../ruleset/index.js';
4
4
  import type { LocaleSet } from '@markuplint/i18n';
5
5
  import type { GlobalRuleInfo, PlainData, Rule, RuleConfigValue, RuleInfo, Severity, Violation } from '@markuplint/ml-config';
6
6
  export declare class MLRule<T extends RuleConfigValue, O extends PlainData = undefined> {
@@ -3,6 +3,9 @@ import type { Attr, Element } from '../ml-dom/index.js';
3
3
  import type { Translator } from '@markuplint/i18n';
4
4
  import type { PlainData, Report, RuleConfigValue, Severity } from '@markuplint/ml-config';
5
5
  export type RuleSeed<T extends RuleConfigValue = boolean, O extends PlainData = undefined> = {
6
+ readonly meta?: {
7
+ readonly category?: 'validation' | 'style' | 'naming-convention' | 'a11y' | 'maintainability';
8
+ };
6
9
  readonly defaultSeverity?: Severity;
7
10
  readonly defaultValue?: T;
8
11
  readonly defaultOptions?: O;
@@ -1,5 +1,5 @@
1
1
  import type { ChildNodeRule, Config, NodeRule, Rules } from '@markuplint/ml-config';
2
- export default class Ruleset {
2
+ export declare class Ruleset {
3
3
  readonly childNodeRules: readonly ChildNodeRule[];
4
4
  readonly nodeRules: readonly NodeRule[];
5
5
  readonly rules: Rules;
@@ -1,4 +1,4 @@
1
- export default class Ruleset {
1
+ export class Ruleset {
2
2
  constructor(config) {
3
3
  this.rules = config.rules ?? {};
4
4
  this.nodeRules = config.nodeRules ?? [];
@@ -1,15 +1,17 @@
1
- import type { MLMarkupLanguageParser } from '@markuplint/ml-ast';
1
+ import type { MLParser } from '@markuplint/ml-ast';
2
2
  import type { Config, PlainData, RuleConfigValue } from '@markuplint/ml-config';
3
3
  import type { ExtendedSpec, MLMLSpec } from '@markuplint/ml-spec';
4
4
  import { Document } from '../ml-dom/index.js';
5
5
  export type CreateTestOptions = {
6
6
  readonly config?: Config;
7
- readonly parser?: Readonly<MLMarkupLanguageParser>;
7
+ readonly parser?: {
8
+ readonly parser: Readonly<MLParser>;
9
+ } | Readonly<MLParser>;
8
10
  readonly specs?: MLMLSpec;
9
11
  };
10
12
  export declare function createTestDocument<T extends RuleConfigValue = any, O extends PlainData = any>(sourceCode: string, options?: CreateTestOptions): Document<T, O>;
11
- export declare function createTestNodeList(sourceCode: string, options?: CreateTestOptions): readonly import("../ml-dom/node/node.js").MLNode<any, any, import("@markuplint/ml-ast").MLASTAbstractNode>[];
12
- export declare function createTestTokenList(sourceCode: string, options?: CreateTestOptions): readonly import("../ml-dom/token/token.js").MLToken<import("@markuplint/ml-ast").MLToken>[];
13
+ export declare function createTestNodeList(sourceCode: string, options?: CreateTestOptions): readonly import("../ml-dom/node/node.js").MLNode<any, any, import("@markuplint/ml-ast").MLASTNode>[];
14
+ export declare function createTestTokenList(sourceCode: string, options?: CreateTestOptions): readonly import("../ml-dom/token/token.js").MLToken<import("@markuplint/ml-ast").MLASTToken>[];
13
15
  export declare function createTestElement(sourceCode: string, options?: CreateTestOptions): import("../ml-dom/index.js").Element<any, any>;
14
16
  /**
15
17
  * for test suite
package/lib/test/index.js CHANGED
@@ -1,9 +1,13 @@
1
- import { parse } from '@markuplint/html-parser';
1
+ import { parser } from '@markuplint/html-parser';
2
2
  import spec from '@markuplint/html-spec';
3
3
  import { convertRuleset } from '../convert-ruleset.js';
4
4
  import { Document } from '../ml-dom/index.js';
5
5
  export function createTestDocument(sourceCode, options) {
6
- const ast = options?.parser ? options.parser.parse(sourceCode) : parse(sourceCode);
6
+ const ast = options?.parser
7
+ ? 'parser' in options.parser
8
+ ? options.parser.parser.parse(sourceCode, options.config?.parserOptions)
9
+ : options.parser.parse(sourceCode, options.config?.parserOptions)
10
+ : parser.parse(sourceCode, options?.config?.parserOptions);
7
11
  const ruleset = convertRuleset(options?.config);
8
12
  const document = new Document(ast, ruleset, [options?.specs ?? {}, {}]);
9
13
  return document;
package/lib/types.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { AnyMLRule } from './ml-rule/index.js';
2
- import type Ruleset from './ruleset/index.js';
2
+ import type { Ruleset } from './ruleset/index.js';
3
3
  import type { LocaleSet } from '@markuplint/i18n';
4
- import type { MLMarkupLanguageParser, ParserOptions } from '@markuplint/ml-ast';
4
+ import type { MLParser, ParserOptions } from '@markuplint/ml-ast';
5
5
  import type { Pretender } from '@markuplint/ml-config';
6
6
  import type { ExtendedSpec, MLMLSpec } from '@markuplint/ml-spec';
7
7
  export type MLSchema = readonly [MLMLSpec, ...ExtendedSpec[]];
8
8
  export type MLFabric = {
9
- readonly parser: Readonly<MLMarkupLanguageParser>;
9
+ readonly parser: Readonly<MLParser>;
10
10
  readonly ruleset: Partial<Readonly<Ruleset>>;
11
11
  readonly rules: readonly Readonly<AnyMLRule>[];
12
12
  readonly locale: LocaleSet;
@@ -1,5 +1,5 @@
1
1
  export function getLocationFromChars(searches, text, currentLine, currentCol) {
2
- const lines = text.split(/\r?\n/g);
2
+ const lines = text.split(/\r?\n/);
3
3
  const foundLocations = [];
4
4
  for (const [i, lineText] of lines.entries()) {
5
5
  let offset = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/ml-core",
3
- "version": "4.0.0-dev.28+0131de5e",
3
+ "version": "4.0.0-rc.1",
4
4
  "description": "The core module of markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -28,19 +28,19 @@
28
28
  "./lib/configs.js": "./lib/configs.browser.js"
29
29
  },
30
30
  "dependencies": {
31
- "@markuplint/config-presets": "4.0.0-dev.28+0131de5e",
32
- "@markuplint/html-parser": "4.0.0-dev.28+0131de5e",
33
- "@markuplint/html-spec": "4.0.0-dev.28+0131de5e",
34
- "@markuplint/i18n": "4.0.0-dev.28+0131de5e",
35
- "@markuplint/ml-ast": "4.0.0-dev.28+0131de5e",
36
- "@markuplint/ml-config": "4.0.0-dev.28+0131de5e",
37
- "@markuplint/ml-spec": "4.0.0-dev.28+0131de5e",
38
- "@markuplint/parser-utils": "4.0.0-dev.28+0131de5e",
39
- "@markuplint/selector": "4.0.0-dev.28+0131de5e",
40
- "@types/debug": "^4.1.10",
31
+ "@markuplint/config-presets": "4.0.0-rc.1",
32
+ "@markuplint/html-parser": "4.0.0-rc.1",
33
+ "@markuplint/html-spec": "4.0.0-rc.1",
34
+ "@markuplint/i18n": "4.0.0-rc.1",
35
+ "@markuplint/ml-ast": "4.0.0-rc.1",
36
+ "@markuplint/ml-config": "4.0.0-rc.1",
37
+ "@markuplint/ml-spec": "4.0.0-rc.1",
38
+ "@markuplint/parser-utils": "4.0.0-rc.1",
39
+ "@markuplint/selector": "4.0.0-rc.1",
40
+ "@types/debug": "^4.1.12",
41
41
  "debug": "^4.3.4",
42
42
  "is-plain-object": "^5.0.0",
43
- "type-fest": "^4.5.0"
43
+ "type-fest": "^4.10.2"
44
44
  },
45
- "gitHead": "0131de5ea9dd6d3fd5472d7b414b66644c758881"
45
+ "gitHead": "3a9dbbf4c3c05de66d402802919ee94a46a5eb67"
46
46
  }
package/lib/configs.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { Config } from '@markuplint/ml-config';
2
- export declare function getPreset(name: string): Promise<Config>;