svg-eslint-parser 0.0.5 → 0.0.6

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/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { unionWith } from "eslint-visitor-keys";
3
3
 
4
4
  //#region package.json
5
5
  var name$1 = "svg-eslint-parser";
6
- var version = "0.0.5";
6
+ var version = "0.0.6";
7
7
 
8
8
  //#endregion
9
9
  //#region src/meta.ts
@@ -71,76 +71,72 @@ const RE_INCOMPLETE_CLOSING_TAG = /<\/[^>]+$/;
71
71
 
72
72
  //#endregion
73
73
  //#region src/constants/nodeTypes.ts
74
- let NodeTypes = /* @__PURE__ */ function(NodeTypes$1) {
75
- NodeTypes$1["Attribute"] = "Attribute";
76
- NodeTypes$1["AttributeKey"] = "AttributeKey";
77
- NodeTypes$1["AttributeValue"] = "AttributeValue";
78
- NodeTypes$1["AttributeValueWrapperEnd"] = "AttributeValueWrapperEnd";
79
- NodeTypes$1["AttributeValueWrapperStart"] = "AttributeValueWrapperStart";
80
- NodeTypes$1["CloseTag"] = "CloseTag";
81
- NodeTypes$1["Comment"] = "Comment";
82
- NodeTypes$1["CommentClose"] = "CommentClose";
83
- NodeTypes$1["CommentContent"] = "CommentContent";
84
- NodeTypes$1["CommentOpen"] = "CommentOpen";
85
- NodeTypes$1["Doctype"] = "Doctype";
86
- NodeTypes$1["DoctypeAttribute"] = "DoctypeAttribute";
87
- NodeTypes$1["DoctypeAttributeValue"] = "DoctypeAttributeValue";
88
- NodeTypes$1["DoctypeAttributeWrapperEnd"] = "DoctypeAttributeWrapperEnd";
89
- NodeTypes$1["DoctypeAttributeWrapperStart"] = "DoctypeAttributeWrapperStart";
90
- NodeTypes$1["DoctypeClose"] = "DoctypeClose";
91
- NodeTypes$1["DoctypeOpen"] = "DoctypeOpen";
92
- NodeTypes$1["Document"] = "Document";
93
- NodeTypes$1["OpenTagEnd"] = "OpenTagEnd";
94
- NodeTypes$1["OpenTagStart"] = "OpenTagStart";
95
- NodeTypes$1["Program"] = "Program";
96
- NodeTypes$1["Tag"] = "Tag";
97
- NodeTypes$1["Text"] = "Text";
98
- NodeTypes$1["XMLDeclaration"] = "XMLDeclaration";
99
- NodeTypes$1["XMLDeclarationAttribute"] = "XMLDeclarationAttribute";
100
- NodeTypes$1["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
101
- NodeTypes$1["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
102
- NodeTypes$1["XMLDeclarationAttributeValueWrapperEnd"] = "XMLDeclarationAttributeValueWrapperEnd";
103
- NodeTypes$1["XMLDeclarationAttributeValueWrapperStart"] = "XMLDeclarationAttributeValueWrapperStart";
104
- NodeTypes$1["XMLDeclarationClose"] = "XMLDeclarationClose";
105
- NodeTypes$1["XMLDeclarationOpen"] = "XMLDeclarationOpen";
106
- return NodeTypes$1;
74
+ let NodeTypes = /* @__PURE__ */ function(NodeTypes) {
75
+ NodeTypes["Attribute"] = "Attribute";
76
+ NodeTypes["AttributeKey"] = "AttributeKey";
77
+ NodeTypes["AttributeValue"] = "AttributeValue";
78
+ NodeTypes["Comment"] = "Comment";
79
+ NodeTypes["Doctype"] = "Doctype";
80
+ NodeTypes["DoctypeAttribute"] = "DoctypeAttribute";
81
+ NodeTypes["DoctypeAttributeValue"] = "DoctypeAttributeValue";
82
+ NodeTypes["Document"] = "Document";
83
+ NodeTypes["Error"] = "Error";
84
+ NodeTypes["Program"] = "Program";
85
+ NodeTypes["Tag"] = "Tag";
86
+ NodeTypes["Text"] = "Text";
87
+ NodeTypes["XMLDeclaration"] = "XMLDeclaration";
88
+ NodeTypes["XMLDeclarationAttribute"] = "XMLDeclarationAttribute";
89
+ NodeTypes["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
90
+ NodeTypes["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
91
+ return NodeTypes;
107
92
  }({});
108
93
 
109
94
  //#endregion
110
95
  //#region src/constants/tokenTypes.ts
111
- let TokenTypes = /* @__PURE__ */ function(TokenTypes$1) {
112
- TokenTypes$1["Attribute"] = "Attribute";
113
- TokenTypes$1["AttributeAssignment"] = "AttributeAssignment";
114
- TokenTypes$1["AttributeKey"] = "AttributeKey";
115
- TokenTypes$1["AttributeValue"] = "AttributeValue";
116
- TokenTypes$1["AttributeValueWrapperEnd"] = "AttributeValueWrapperEnd";
117
- TokenTypes$1["AttributeValueWrapperStart"] = "AttributeValueWrapperStart";
118
- TokenTypes$1["CloseTag"] = "CloseTag";
119
- TokenTypes$1["Comment"] = "Comment";
120
- TokenTypes$1["CommentClose"] = "CommentClose";
121
- TokenTypes$1["CommentContent"] = "CommentContent";
122
- TokenTypes$1["CommentOpen"] = "CommentOpen";
123
- TokenTypes$1["Doctype"] = "Doctype";
124
- TokenTypes$1["DoctypeAttributeValue"] = "DoctypeAttributeValue";
125
- TokenTypes$1["DoctypeAttributeWrapperEnd"] = "DoctypeAttributeWrapperEnd";
126
- TokenTypes$1["DoctypeAttributeWrapperStart"] = "DoctypeAttributeWrapperStart";
127
- TokenTypes$1["DoctypeClose"] = "DoctypeClose";
128
- TokenTypes$1["DoctypeOpen"] = "DoctypeOpen";
129
- TokenTypes$1["Document"] = "Document";
130
- TokenTypes$1["OpenTagEnd"] = "OpenTagEnd";
131
- TokenTypes$1["OpenTagStart"] = "OpenTagStart";
132
- TokenTypes$1["Program"] = "Program";
133
- TokenTypes$1["Tag"] = "Tag";
134
- TokenTypes$1["Text"] = "Text";
135
- TokenTypes$1["XMLDeclarationAttribute"] = "XMLDeclarationAttribute";
136
- TokenTypes$1["XMLDeclarationAttributeAssignment"] = "XMLDeclarationAttributeAssignment";
137
- TokenTypes$1["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
138
- TokenTypes$1["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
139
- TokenTypes$1["XMLDeclarationAttributeValueWrapperEnd"] = "XMLDeclarationAttributeValueWrapperEnd";
140
- TokenTypes$1["XMLDeclarationAttributeValueWrapperStart"] = "XMLDeclarationAttributeValueWrapperStart";
141
- TokenTypes$1["XMLDeclarationClose"] = "XMLDeclarationClose";
142
- TokenTypes$1["XMLDeclarationOpen"] = "XMLDeclarationOpen";
143
- return TokenTypes$1;
96
+ let TokenTypes = /* @__PURE__ */ function(TokenTypes) {
97
+ /**
98
+ * @pg Content tokens
99
+ */
100
+ TokenTypes["Text"] = "Text";
101
+ /**
102
+ * @pg Attribute tokens
103
+ */
104
+ TokenTypes["AttributeAssignment"] = "AttributeAssignment";
105
+ TokenTypes["AttributeKey"] = "AttributeKey";
106
+ TokenTypes["AttributeValue"] = "AttributeValue";
107
+ TokenTypes["AttributeValueWrapperEnd"] = "AttributeValueWrapperEnd";
108
+ TokenTypes["AttributeValueWrapperStart"] = "AttributeValueWrapperStart";
109
+ /**
110
+ * @pg Doctype tokens
111
+ */
112
+ TokenTypes["DoctypeAttributeValue"] = "DoctypeAttributeValue";
113
+ TokenTypes["DoctypeAttributeWrapperEnd"] = "DoctypeAttributeWrapperEnd";
114
+ TokenTypes["DoctypeAttributeWrapperStart"] = "DoctypeAttributeWrapperStart";
115
+ TokenTypes["DoctypeClose"] = "DoctypeClose";
116
+ TokenTypes["DoctypeOpen"] = "DoctypeOpen";
117
+ /**
118
+ * @pg Tag tokens
119
+ */
120
+ TokenTypes["CloseTag"] = "CloseTag";
121
+ TokenTypes["OpenTagEnd"] = "OpenTagEnd";
122
+ TokenTypes["OpenTagStart"] = "OpenTagStart";
123
+ /**
124
+ * @pg Comment tokens
125
+ */
126
+ TokenTypes["CommentClose"] = "CommentClose";
127
+ TokenTypes["CommentContent"] = "CommentContent";
128
+ TokenTypes["CommentOpen"] = "CommentOpen";
129
+ /**
130
+ * @pg XML Declaration tokens
131
+ */
132
+ TokenTypes["XMLDeclarationAttributeAssignment"] = "XMLDeclarationAttributeAssignment";
133
+ TokenTypes["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
134
+ TokenTypes["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
135
+ TokenTypes["XMLDeclarationAttributeValueWrapperEnd"] = "XMLDeclarationAttributeValueWrapperEnd";
136
+ TokenTypes["XMLDeclarationAttributeValueWrapperStart"] = "XMLDeclarationAttributeValueWrapperStart";
137
+ TokenTypes["XMLDeclarationClose"] = "XMLDeclarationClose";
138
+ TokenTypes["XMLDeclarationOpen"] = "XMLDeclarationOpen";
139
+ return TokenTypes;
144
140
  }({});
145
141
 
146
142
  //#endregion
@@ -299,79 +295,152 @@ const SELF_CLOSING_ELEMENTS = new Set([
299
295
 
300
296
  //#endregion
301
297
  //#region src/constants/tokenizerContextTypes.ts
302
- let TokenizerContextTypes = /* @__PURE__ */ function(TokenizerContextTypes$1) {
303
- TokenizerContextTypes$1["AttributeKey"] = "AttributeKey";
304
- TokenizerContextTypes$1["Attributes"] = "Attributes";
305
- TokenizerContextTypes$1["AttributeValue"] = "AttributeValue";
306
- TokenizerContextTypes$1["AttributeValueBare"] = "AttributeValueBare";
307
- TokenizerContextTypes$1["AttributeValueWrapped"] = "AttributeValueWrapped";
308
- TokenizerContextTypes$1["CloseTag"] = "CloseTag";
309
- TokenizerContextTypes$1["CommentClose"] = "CommentClose";
310
- TokenizerContextTypes$1["CommentContent"] = "CommentContent";
311
- TokenizerContextTypes$1["CommentOpen"] = "CommentOpen";
312
- TokenizerContextTypes$1["Data"] = "Data";
313
- TokenizerContextTypes$1["DoctypeAttributeBare"] = "DoctypeAttributeBare";
314
- TokenizerContextTypes$1["DoctypeAttributes"] = "DoctypeAttributes";
315
- TokenizerContextTypes$1["DoctypeAttributeWrapped"] = "DoctypeAttributeWrapped";
316
- TokenizerContextTypes$1["DoctypeClose"] = "DoctypeClose";
317
- TokenizerContextTypes$1["DoctypeOpen"] = "DoctypeOpen";
318
- TokenizerContextTypes$1["OpenTagEnd"] = "OpenTagEnd";
319
- TokenizerContextTypes$1["OpenTagStart"] = "OpenTagStart";
320
- TokenizerContextTypes$1["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
321
- TokenizerContextTypes$1["XMLDeclarationAttributes"] = "XMLDeclarationAttributes";
322
- TokenizerContextTypes$1["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
323
- TokenizerContextTypes$1["XMLDeclarationAttributeValueWrapped"] = "XMLDeclarationAttributeValueWrapped";
324
- TokenizerContextTypes$1["XMLDeclarationClose"] = "XMLDeclarationClose";
325
- TokenizerContextTypes$1["XMLDeclarationOpen"] = "XMLDeclarationOpen";
326
- return TokenizerContextTypes$1;
298
+ let TokenizerContextTypes = /* @__PURE__ */ function(TokenizerContextTypes) {
299
+ TokenizerContextTypes["AttributeKey"] = "AttributeKey";
300
+ TokenizerContextTypes["Attributes"] = "Attributes";
301
+ TokenizerContextTypes["AttributeValue"] = "AttributeValue";
302
+ TokenizerContextTypes["AttributeValueBare"] = "AttributeValueBare";
303
+ TokenizerContextTypes["AttributeValueWrapped"] = "AttributeValueWrapped";
304
+ TokenizerContextTypes["CloseTag"] = "CloseTag";
305
+ TokenizerContextTypes["CommentClose"] = "CommentClose";
306
+ TokenizerContextTypes["CommentContent"] = "CommentContent";
307
+ TokenizerContextTypes["CommentOpen"] = "CommentOpen";
308
+ TokenizerContextTypes["Data"] = "Data";
309
+ TokenizerContextTypes["DoctypeAttributeBare"] = "DoctypeAttributeBare";
310
+ TokenizerContextTypes["DoctypeAttributes"] = "DoctypeAttributes";
311
+ TokenizerContextTypes["DoctypeAttributeWrapped"] = "DoctypeAttributeWrapped";
312
+ TokenizerContextTypes["DoctypeClose"] = "DoctypeClose";
313
+ TokenizerContextTypes["DoctypeOpen"] = "DoctypeOpen";
314
+ TokenizerContextTypes["OpenTagEnd"] = "OpenTagEnd";
315
+ TokenizerContextTypes["OpenTagStart"] = "OpenTagStart";
316
+ TokenizerContextTypes["XMLDeclarationAttributeKey"] = "XMLDeclarationAttributeKey";
317
+ TokenizerContextTypes["XMLDeclarationAttributes"] = "XMLDeclarationAttributes";
318
+ TokenizerContextTypes["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
319
+ TokenizerContextTypes["XMLDeclarationAttributeValueWrapped"] = "XMLDeclarationAttributeValueWrapped";
320
+ TokenizerContextTypes["XMLDeclarationClose"] = "XMLDeclarationClose";
321
+ TokenizerContextTypes["XMLDeclarationOpen"] = "XMLDeclarationOpen";
322
+ return TokenizerContextTypes;
327
323
  }({});
328
324
 
329
325
  //#endregion
330
326
  //#region src/constants/constructTreeContextTypes.ts
331
- let ConstructTreeContextTypes = /* @__PURE__ */ function(ConstructTreeContextTypes$1) {
332
- ConstructTreeContextTypes$1["Attribute"] = "Attribute";
333
- ConstructTreeContextTypes$1["Attributes"] = "Attributes";
334
- ConstructTreeContextTypes$1["AttributeValue"] = "AttributeValue";
335
- ConstructTreeContextTypes$1["Comment"] = "Comment";
336
- ConstructTreeContextTypes$1["Doctype"] = "Doctype";
337
- ConstructTreeContextTypes$1["DoctypeAttribute"] = "DoctypeAttribute";
338
- ConstructTreeContextTypes$1["DoctypeAttributes"] = "DoctypeAttributes";
339
- ConstructTreeContextTypes$1["Tag"] = "Tag";
340
- ConstructTreeContextTypes$1["TagContent"] = "TagContent";
341
- ConstructTreeContextTypes$1["TagName"] = "TagName";
342
- ConstructTreeContextTypes$1["XMLDeclaration"] = "XMLDeclaration";
343
- ConstructTreeContextTypes$1["XMLDeclarationAttribute"] = "XMLDeclarationAttribute";
344
- ConstructTreeContextTypes$1["XMLDeclarationAttributes"] = "XMLDeclarationAttributes";
345
- ConstructTreeContextTypes$1["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
346
- return ConstructTreeContextTypes$1;
327
+ let ConstructTreeContextTypes = /* @__PURE__ */ function(ConstructTreeContextTypes) {
328
+ ConstructTreeContextTypes["Attribute"] = "Attribute";
329
+ ConstructTreeContextTypes["Attributes"] = "Attributes";
330
+ ConstructTreeContextTypes["AttributeValue"] = "AttributeValue";
331
+ ConstructTreeContextTypes["Comment"] = "Comment";
332
+ ConstructTreeContextTypes["Doctype"] = "Doctype";
333
+ ConstructTreeContextTypes["DoctypeAttribute"] = "DoctypeAttribute";
334
+ ConstructTreeContextTypes["DoctypeAttributes"] = "DoctypeAttributes";
335
+ ConstructTreeContextTypes["Tag"] = "Tag";
336
+ ConstructTreeContextTypes["TagContent"] = "TagContent";
337
+ ConstructTreeContextTypes["TagName"] = "TagName";
338
+ ConstructTreeContextTypes["XMLDeclaration"] = "XMLDeclaration";
339
+ ConstructTreeContextTypes["XMLDeclarationAttribute"] = "XMLDeclarationAttribute";
340
+ ConstructTreeContextTypes["XMLDeclarationAttributes"] = "XMLDeclarationAttributes";
341
+ ConstructTreeContextTypes["XMLDeclarationAttributeValue"] = "XMLDeclarationAttributeValue";
342
+ return ConstructTreeContextTypes;
347
343
  }({});
348
344
 
345
+ //#endregion
346
+ //#region src/utils/cloneNode.ts
347
+ /**
348
+ * Deep clone a node, removing parent references
349
+ * @param node - Node to clone
350
+ * @returns Cloned node
351
+ */
352
+ function cloneNode(node) {
353
+ if (!node || typeof node !== "object") return node;
354
+ if (Array.isArray(node)) return node.map((item) => cloneNode(item));
355
+ const cloned = {};
356
+ for (const key in node) {
357
+ if (!Object.prototype.hasOwnProperty.call(node, key)) continue;
358
+ if (key === "parentRef" || key === "parent") continue;
359
+ const value = node[key];
360
+ if (value && typeof value === "object") if (Array.isArray(value)) cloned[key] = value.map((item) => cloneNode(item));
361
+ else cloned[key] = cloneNode(value);
362
+ else cloned[key] = value;
363
+ }
364
+ return cloned;
365
+ }
366
+ /**
367
+ * Deep clone a node, preserving parent references
368
+ * @param node - Node to clone
369
+ * @param parent - Parent node for the cloned node
370
+ * @returns Cloned node with parent references
371
+ */
372
+ function cloneNodeWithParent(node, parent) {
373
+ if (!node || typeof node !== "object") return node;
374
+ if (Array.isArray(node)) return node.map((item) => cloneNodeWithParent(item));
375
+ const cloned = {};
376
+ for (const key in node) {
377
+ if (!Object.prototype.hasOwnProperty.call(node, key)) continue;
378
+ if (key === "parentRef" || key === "parent") continue;
379
+ const value = node[key];
380
+ if (value && typeof value === "object") if (Array.isArray(value)) cloned[key] = value.map((item) => cloneNodeWithParent(item, cloned));
381
+ else cloned[key] = cloneNodeWithParent(value, cloned);
382
+ else cloned[key] = value;
383
+ }
384
+ if (parent) cloned.parentRef = parent;
385
+ return cloned;
386
+ }
387
+
349
388
  //#endregion
350
389
  //#region src/utils/firstLast.ts
390
+ /**
391
+ * Get the first element of an array
392
+ * @param items - Array to get first element from
393
+ * @returns First element of the array
394
+ */
351
395
  function first(items) {
352
396
  return items[0];
353
397
  }
398
+ /**
399
+ * Get the last element of an array
400
+ * @param items - Array to get last element from
401
+ * @returns Last element of the array
402
+ */
354
403
  function last(items) {
355
404
  return items[items.length - 1];
356
405
  }
357
406
 
358
407
  //#endregion
359
408
  //#region src/utils/cloneRange.ts
409
+ /**
410
+ * Create a shallow copy of a range tuple
411
+ * @param range - Range tuple [start, end] to clone
412
+ * @returns New range tuple with copied values
413
+ */
360
414
  function cloneRange(range) {
361
415
  return [range[0], range[1]];
362
416
  }
363
417
 
364
418
  //#endregion
365
419
  //#region src/utils/initIfNone.ts
420
+ /**
421
+ * Initialize children array if it doesn't exist
422
+ * @param node - Node to initialize
423
+ * @param node.children - Children to set if none exist
424
+ */
366
425
  function initChildrenIfNone(node) {
367
426
  if (!node.children) node.children = [];
368
427
  }
428
+ /**
429
+ * Initialize attributes array if it doesn't exist
430
+ * @param node - Node to initialize
431
+ * @param node.attributes - Attributes to set if none exist
432
+ */
369
433
  function initAttributesIfNone(node) {
370
434
  if (!node.attributes) node.attributes = [];
371
435
  }
372
436
 
373
437
  //#endregion
374
438
  //#region src/utils/clearParent.ts
439
+ /**
440
+ * Recursively remove parent references from an AST
441
+ * @param ast - The AST node to clean
442
+ * @returns The cleaned AST with parentRef properties removed
443
+ */
375
444
  function clearParent(ast) {
376
445
  const cleanAst = ast;
377
446
  delete cleanAst.parentRef;
@@ -383,9 +452,21 @@ function clearParent(ast) {
383
452
 
384
453
  //#endregion
385
454
  //#region src/utils/getLineInfo.ts
455
+ /**
456
+ * Check if a character code represents a line break
457
+ * @param code - Character code to check
458
+ * @returns True if code is a newline character (LF, CR, LS, PS)
459
+ */
386
460
  function isNewLine(code) {
387
461
  return code === 10 || code === 13 || code === 8232 || code === 8233;
388
462
  }
463
+ /**
464
+ * Find the next line break position in a string
465
+ * @param code - String to search
466
+ * @param from - Starting position
467
+ * @param end - Ending position (default: string length)
468
+ * @returns Index of next line break, or -1 if not found
469
+ */
389
470
  function nextLineBreak(code, from, end = code.length) {
390
471
  for (let i = from; i < end; i++) {
391
472
  const next = code.codePointAt(i);
@@ -394,6 +475,12 @@ function nextLineBreak(code, from, end = code.length) {
394
475
  }
395
476
  return -1;
396
477
  }
478
+ /**
479
+ * Get the line and column number for a position in source code
480
+ * @param input - Source code string
481
+ * @param offset - Character offset position
482
+ * @returns Object with line (1-indexed) and column (0-indexed) information
483
+ */
397
484
  function getLineInfo(input, offset) {
398
485
  for (let line = 1, cur = 0;;) {
399
486
  const nextBreak = nextLineBreak(input, cur, offset);
@@ -406,14 +493,178 @@ function getLineInfo(input, offset) {
406
493
  }
407
494
  }
408
495
 
496
+ //#endregion
497
+ //#region src/utils/nodeHelpers.ts
498
+ /**
499
+ * Filter nodes by a predicate function
500
+ * @param node - Root node to filter from
501
+ * @param predicate - Filter function
502
+ * @returns Array of matching nodes
503
+ */
504
+ function filterNodes(node, predicate) {
505
+ const results = [];
506
+ function traverse$1(currentNode) {
507
+ if (predicate(currentNode)) results.push(currentNode);
508
+ if ("children" in currentNode && Array.isArray(currentNode.children)) for (const child of currentNode.children) traverse$1(child);
509
+ if ("attributes" in currentNode && Array.isArray(currentNode.attributes)) for (const attr of currentNode.attributes) traverse$1(attr);
510
+ }
511
+ traverse$1(node);
512
+ return results;
513
+ }
514
+ /**
515
+ * Map over all nodes in the AST
516
+ * @param node - Root node to map from
517
+ * @param mapper - Mapping function
518
+ * @returns Transformed node
519
+ */
520
+ function mapNodes(node, mapper) {
521
+ const mapped = mapper(node);
522
+ if ("children" in mapped && Array.isArray(mapped.children)) mapped.children = mapped.children.map((child) => mapNodes(child, mapper));
523
+ if ("attributes" in mapped && Array.isArray(mapped.attributes)) mapped.attributes = mapped.attributes.map((attr) => mapNodes(attr, mapper));
524
+ return mapped;
525
+ }
526
+ /**
527
+ * Get all parent nodes from a node up to the root
528
+ * @param node - Starting node
529
+ * @returns Array of parent nodes (from immediate parent to root)
530
+ */
531
+ function getParentChain(node) {
532
+ const chain = [];
533
+ let current = node.parentRef || node.parent;
534
+ while (current) {
535
+ chain.push(current);
536
+ current = current.parentRef || current.parent;
537
+ }
538
+ return chain;
539
+ }
540
+ /**
541
+ * Get the depth of a node in the AST (distance from root)
542
+ * @param node - Node to measure
543
+ * @returns Depth level (root = 0)
544
+ */
545
+ function getNodeDepth(node) {
546
+ let depth = 0;
547
+ let current = node.parentRef || node.parent;
548
+ while (current) {
549
+ depth++;
550
+ current = current.parentRef || current.parent;
551
+ }
552
+ return depth;
553
+ }
554
+ /**
555
+ * Count total number of nodes in the AST
556
+ * @param node - Root node
557
+ * @returns Total node count
558
+ */
559
+ function countNodes(node) {
560
+ let count = 1;
561
+ if ("children" in node && Array.isArray(node.children)) for (const child of node.children) count += countNodes(child);
562
+ if ("attributes" in node && Array.isArray(node.attributes)) for (const attr of node.attributes) count += countNodes(attr);
563
+ return count;
564
+ }
565
+
566
+ //#endregion
567
+ //#region src/utils/traverseAST.ts
568
+ /**
569
+ * Traverse the AST with a visitor pattern
570
+ * @param node - Root node to traverse from
571
+ * @param visitor - Visitor object with enter/leave hooks
572
+ * @param parent - Parent node (used internally)
573
+ */
574
+ function traverseAST(node, visitor, parent = null) {
575
+ let shouldTraverseChildren = true;
576
+ if (visitor.enter) {
577
+ if (visitor.enter(node, parent) === false) shouldTraverseChildren = false;
578
+ }
579
+ if (shouldTraverseChildren) {
580
+ if ("children" in node && Array.isArray(node.children)) for (const child of node.children) traverseAST(child, visitor, node);
581
+ if ("attributes" in node && Array.isArray(node.attributes)) for (const attr of node.attributes) traverseAST(attr, visitor, node);
582
+ }
583
+ if (visitor.leave) visitor.leave(node, parent);
584
+ }
585
+ /**
586
+ * Simple traversal function that calls a callback for each node
587
+ * @param node - Root node to traverse from
588
+ * @param callback - Function to call for each node
589
+ */
590
+ function walkAST(node, callback) {
591
+ traverseAST(node, { enter: callback });
592
+ }
593
+
409
594
  //#endregion
410
595
  //#region src/utils/isWhitespace.ts
596
+ /**
597
+ * Check if a character is whitespace (space, newline, return, or tab)
598
+ * @param char - Character to check
599
+ * @returns True if character is whitespace
600
+ */
411
601
  function isWhitespace(char) {
412
602
  return char === SPECIAL_CHAR.space || char === SPECIAL_CHAR.newline || char === SPECIAL_CHAR.return || char === SPECIAL_CHAR.tab;
413
603
  }
414
604
 
605
+ //#endregion
606
+ //#region src/utils/validateNode.ts
607
+ /**
608
+ * Validate if a node matches its expected structure
609
+ * @param node - Node to validate
610
+ * @returns True if node is valid
611
+ */
612
+ function validateNode(node) {
613
+ if (!node || typeof node !== "object") return false;
614
+ if (!("type" in node) || !("range" in node) || !("loc" in node)) return false;
615
+ if (!Array.isArray(node.range) || node.range.length !== 2 || typeof node.range[0] !== "number" || typeof node.range[1] !== "number") return false;
616
+ if (!node.loc || !node.loc.start || !node.loc.end || typeof node.loc.start.line !== "number" || typeof node.loc.start.column !== "number" || typeof node.loc.end.line !== "number" || typeof node.loc.end.column !== "number") return false;
617
+ switch (node.type) {
618
+ case NodeTypes.Tag: return validateTagNode(node);
619
+ case NodeTypes.Attribute: return validateAttributeNode(node);
620
+ case NodeTypes.Text: return validateTextNode(node);
621
+ case NodeTypes.Comment: return validateCommentNode(node);
622
+ case NodeTypes.Document: return validateDocumentNode(node);
623
+ case NodeTypes.Doctype: return validateDoctypeNode(node);
624
+ default: return true;
625
+ }
626
+ }
627
+ function validateTagNode(node) {
628
+ if (!("name" in node) || typeof node.name !== "string") return false;
629
+ if ("children" in node && !Array.isArray(node.children)) return false;
630
+ if ("attributes" in node && !Array.isArray(node.attributes)) return false;
631
+ return true;
632
+ }
633
+ function validateAttributeNode(node) {
634
+ if ("key" in node && node.key !== void 0 && typeof node.key !== "object") return false;
635
+ if ("value" in node && node.value !== void 0 && typeof node.value !== "object") return false;
636
+ return true;
637
+ }
638
+ function validateTextNode(node) {
639
+ return "value" in node && typeof node.value === "string";
640
+ }
641
+ function validateCommentNode(node) {
642
+ return "content" in node && typeof node.content === "string";
643
+ }
644
+ function validateDocumentNode(node) {
645
+ return "children" in node && Array.isArray(node.children);
646
+ }
647
+ function validateDoctypeNode(node) {
648
+ if ("attributes" in node && !Array.isArray(node.attributes)) return false;
649
+ return true;
650
+ }
651
+ /**
652
+ * Check if a node is of a specific type with type guard
653
+ * @param node - Node to check
654
+ * @param type - Expected node type
655
+ * @returns True if node is of the specified type
656
+ */
657
+ function isNodeType(node, type) {
658
+ return node.type === type;
659
+ }
660
+
415
661
  //#endregion
416
662
  //#region src/utils/cloneLocation.ts
663
+ /**
664
+ * Create a shallow copy of a source location object
665
+ * @param loc - Source location to clone
666
+ * @returns Cloned location with new start and end objects
667
+ */
417
668
  function cloneLocation(loc) {
418
669
  return {
419
670
  start: {
@@ -429,6 +680,11 @@ function cloneLocation(loc) {
429
680
 
430
681
  //#endregion
431
682
  //#region src/utils/updateNodeEnd.ts
683
+ /**
684
+ * Update a node's end position and location based on a token
685
+ * @param node - Node to update
686
+ * @param token - Token containing the new end position
687
+ */
432
688
  function updateNodeEnd(node, token) {
433
689
  node.range[1] = token.range[1];
434
690
  node.loc.end = { ...token.loc.end };
@@ -436,6 +692,11 @@ function updateNodeEnd(node, token) {
436
692
 
437
693
  //#endregion
438
694
  //#region src/utils/createNodeFrom.ts
695
+ /**
696
+ * Create a node object from a token, copying essential properties
697
+ * @param token - Token to convert to a node
698
+ * @returns Object with type, value, location, and range from the token
699
+ */
439
700
  function createNodeFrom(token) {
440
701
  const loc = cloneLocation(token.loc);
441
702
  const range = cloneRange(token.range);
@@ -447,6 +708,45 @@ function createNodeFrom(token) {
447
708
  };
448
709
  }
449
710
 
711
+ //#endregion
712
+ //#region src/utils/findNodeByType.ts
713
+ /**
714
+ * Find all nodes of a specific type in the AST
715
+ * @param node - Root node to search from
716
+ * @param type - Node type to search for
717
+ * @returns Array of matching nodes
718
+ */
719
+ function findNodeByType(node, type) {
720
+ const results = [];
721
+ function traverse$1(currentNode) {
722
+ if (currentNode.type === type) results.push(currentNode);
723
+ if ("children" in currentNode && Array.isArray(currentNode.children)) for (const child of currentNode.children) traverse$1(child);
724
+ if ("attributes" in currentNode && Array.isArray(currentNode.attributes)) for (const attr of currentNode.attributes) traverse$1(attr);
725
+ }
726
+ traverse$1(node);
727
+ return results;
728
+ }
729
+ /**
730
+ * Find the first node of a specific type in the AST
731
+ * @param node - Root node to search from
732
+ * @param type - Node type to search for
733
+ * @returns First matching node or undefined
734
+ */
735
+ function findFirstNodeByType(node, type) {
736
+ function traverse$1(currentNode) {
737
+ if (currentNode.type === type) return currentNode;
738
+ if ("children" in currentNode && Array.isArray(currentNode.children)) for (const child of currentNode.children) {
739
+ const result = traverse$1(child);
740
+ if (result) return result;
741
+ }
742
+ if ("attributes" in currentNode && Array.isArray(currentNode.attributes)) for (const attr of currentNode.attributes) {
743
+ const result = traverse$1(attr);
744
+ if (result) return result;
745
+ }
746
+ }
747
+ return traverse$1(node);
748
+ }
749
+
450
750
  //#endregion
451
751
  //#region src/utils/getLastAttribute.ts
452
752
  function getLastAttribute(state) {
@@ -456,6 +756,12 @@ function getLastAttribute(state) {
456
756
 
457
757
  //#endregion
458
758
  //#region src/utils/parseOpenTagName.ts
759
+ /**
760
+ * Parse the tag name from an opening tag token content
761
+ * @param openTagStartTokenContent - Raw opening tag content (e.g., "<svg ")
762
+ * @returns Extracted and normalized tag name in lowercase
763
+ * @throws {Error} if content doesn't match opening tag pattern
764
+ */
459
765
  function parseOpenTagName(openTagStartTokenContent) {
460
766
  const match = openTagStartTokenContent.match(RE_OPEN_TAG_NAME);
461
767
  if (match === null) throw new Error(`Unable to parse open tag name.\n${openTagStartTokenContent} does not match pattern of opening tag.`);
@@ -464,6 +770,12 @@ function parseOpenTagName(openTagStartTokenContent) {
464
770
 
465
771
  //#endregion
466
772
  //#region src/utils/parseCloseTagName.ts
773
+ /**
774
+ * Parse the tag name from a closing tag token content
775
+ * @param closeTagTokenContent - Raw closing tag content (e.g., "</svg>")
776
+ * @returns Extracted and normalized tag name in lowercase
777
+ * @throws {Error} if content doesn't match closing tag pattern
778
+ */
467
779
  function parseCloseTagName(closeTagTokenContent) {
468
780
  const match = closeTagTokenContent.match(RE_CLOSE_TAG_NAME);
469
781
  if (match === null) throw new Error(`Unable to parse close tag name.\n${closeTagTokenContent} does not match pattern of closing tag.`);
@@ -472,6 +784,12 @@ function parseCloseTagName(closeTagTokenContent) {
472
784
 
473
785
  //#endregion
474
786
  //#region src/utils/calculateTokenLocation.ts
787
+ /**
788
+ * Calculate the source location of a token based on its character range
789
+ * @param source - Source code string
790
+ * @param range - Character range [start, end]
791
+ * @returns Object with start and end line/column information
792
+ */
475
793
  function calculateTokenLocation(source, range) {
476
794
  return {
477
795
  start: getLineInfo(source, range[0]),
@@ -481,6 +799,13 @@ function calculateTokenLocation(source, range) {
481
799
 
482
800
  //#endregion
483
801
  //#region src/utils/calculateTokenCharactersRange.ts
802
+ /**
803
+ * Calculate the character range of a token based on tokenizer state
804
+ * @param state - Current tokenizer state
805
+ * @param options - Configuration options
806
+ * @param options.keepBuffer - Whether to include decision buffer in the range
807
+ * @returns Array containing [startPosition, endPosition + 1]
808
+ */
484
809
  function calculateTokenCharactersRange(state, options) {
485
810
  const startPosition = state.sourceCode.index() - (state.accumulatedContent.length() - 1) - state.decisionBuffer.length();
486
811
  let endPosition;
@@ -491,6 +816,13 @@ function calculateTokenCharactersRange(state, options) {
491
816
 
492
817
  //#endregion
493
818
  //#region src/utils/calculateTokenPosition.ts
819
+ /**
820
+ * Calculate both character range and source location of a token
821
+ * @param state - Current tokenizer state
822
+ * @param options - Configuration options
823
+ * @param options.keepBuffer - Whether to include decision buffer in the range
824
+ * @returns Object with range and location (loc) properties
825
+ */
494
826
  function calculateTokenPosition(state, options) {
495
827
  const range = calculateTokenCharactersRange(state, options);
496
828
  return {
@@ -500,453 +832,657 @@ function calculateTokenPosition(state, options) {
500
832
  }
501
833
 
502
834
  //#endregion
503
- //#region src/constructor/handlers/tag.ts
504
- var tag_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$13 });
505
- const ATTRIBUTE_START_TOKENS$2 = new Set([TokenTypes.AttributeKey, TokenTypes.AttributeAssignment]);
506
- function construct$13(token, state) {
507
- if (token.type === TokenTypes.OpenTagStart) return handleOpenTagStart$1(state, token);
508
- if (ATTRIBUTE_START_TOKENS$2.has(token.type)) return handleAttributeStart$1(state);
509
- if (token.type === TokenTypes.OpenTagEnd) return handleOpenTagEnd$2(state, token);
510
- if (token.type === TokenTypes.CloseTag) return handleCloseTag$1(state, token);
511
- state.caretPosition++;
512
- return state;
513
- }
514
- function handleOpenTagStart$1(state, token) {
515
- state.currentNode.openStart = createNodeFrom(token);
516
- state.currentContext = {
517
- parentRef: state.currentContext,
518
- type: ConstructTreeContextTypes.TagName
519
- };
520
- return state;
521
- }
522
- function handleAttributeStart$1(state) {
523
- state.currentContext = {
524
- parentRef: state.currentContext,
525
- type: ConstructTreeContextTypes.Attributes
526
- };
527
- return state;
528
- }
529
- function handleOpenTagEnd$2(state, token) {
530
- const tagName = state.currentNode.name;
531
- state.currentNode.openEnd = createNodeFrom(token);
532
- updateNodeEnd(state.currentNode, token);
533
- if (tagName && SELF_CLOSING_ELEMENTS.has(tagName) && state.currentNode.openEnd.value === "/>") {
534
- state.currentNode.selfClosing = true;
535
- state.currentNode = state.currentNode.parentRef;
536
- state.currentContext = state.currentContext.parentRef;
537
- state.caretPosition++;
835
+ //#region src/constructor/handlerFactory.ts
836
+ /**
837
+ * Creates a dispatch function from handler configurations
838
+ * @param handlers - Array of handler configurations
839
+ * @param defaultHandler - Optional default handler for unmatched tokens
840
+ * @returns A function that dispatches tokens to appropriate handlers
841
+ */
842
+ function createTokenDispatcher(handlers, defaultHandler) {
843
+ return (token, state) => {
844
+ for (const config of handlers) if (config.tokenType instanceof Set ? config.tokenType.has(token.type) : config.tokenType === token.type) return config.handler(token, state);
845
+ if (defaultHandler) return defaultHandler(token, state);
538
846
  return state;
539
- }
540
- state.currentNode.selfClosing = false;
541
- state.currentContext = {
542
- parentRef: state.currentContext,
543
- type: ConstructTreeContextTypes.TagContent
544
847
  };
545
- state.caretPosition++;
546
- return state;
547
848
  }
548
- function handleCloseTag$1(state, token) {
549
- state.currentNode.close = createNodeFrom(token);
550
- updateNodeEnd(state.currentNode, token);
551
- state.currentNode = state.currentNode.parentRef;
552
- state.currentContext = state.currentContext.parentRef;
849
+
850
+ //#endregion
851
+ //#region src/constructor/handlers/tag.ts
852
+ var tag_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$13 });
853
+ const ATTRIBUTE_START_TOKENS$3 = new Set([TokenTypes.AttributeKey, TokenTypes.AttributeAssignment]);
854
+ const dispatch$13 = createTokenDispatcher([
855
+ {
856
+ tokenType: TokenTypes.OpenTagStart,
857
+ handler(token, state) {
858
+ state.currentNode.openStart = createNodeFrom(token);
859
+ state.currentContext = {
860
+ parentRef: state.currentContext,
861
+ type: ConstructTreeContextTypes.TagName
862
+ };
863
+ return state;
864
+ }
865
+ },
866
+ {
867
+ tokenType: ATTRIBUTE_START_TOKENS$3,
868
+ handler(_, state) {
869
+ state.currentContext = {
870
+ parentRef: state.currentContext,
871
+ type: ConstructTreeContextTypes.Attributes
872
+ };
873
+ return state;
874
+ }
875
+ },
876
+ {
877
+ tokenType: TokenTypes.OpenTagEnd,
878
+ handler(token, state) {
879
+ const tagName = state.currentNode.name;
880
+ state.currentNode.openEnd = createNodeFrom(token);
881
+ updateNodeEnd(state.currentNode, token);
882
+ if (tagName && SELF_CLOSING_ELEMENTS.has(tagName) && state.currentNode.openEnd.value === "/>") {
883
+ state.currentNode.selfClosing = true;
884
+ state.currentNode = state.currentNode.parentRef;
885
+ state.currentContext = state.currentContext.parentRef;
886
+ state.caretPosition++;
887
+ return state;
888
+ }
889
+ state.currentNode.selfClosing = false;
890
+ state.currentContext = {
891
+ parentRef: state.currentContext,
892
+ type: ConstructTreeContextTypes.TagContent
893
+ };
894
+ state.caretPosition++;
895
+ return state;
896
+ }
897
+ },
898
+ {
899
+ tokenType: TokenTypes.CloseTag,
900
+ handler(token, state) {
901
+ state.currentNode.close = createNodeFrom(token);
902
+ updateNodeEnd(state.currentNode, token);
903
+ state.currentNode = state.currentNode.parentRef;
904
+ state.currentContext = state.currentContext.parentRef;
905
+ state.caretPosition++;
906
+ return state;
907
+ }
908
+ }
909
+ ], (_, state) => {
553
910
  state.caretPosition++;
554
911
  return state;
912
+ });
913
+ function construct$13(token, state) {
914
+ return dispatch$13(token, state);
555
915
  }
556
916
 
557
917
  //#endregion
558
918
  //#region src/constructor/handlers/comment.ts
559
919
  var comment_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$12 });
920
+ const dispatch$12 = createTokenDispatcher([
921
+ {
922
+ tokenType: TokenTypes.CommentOpen,
923
+ handler(_, state) {
924
+ state.caretPosition++;
925
+ return state;
926
+ }
927
+ },
928
+ {
929
+ tokenType: TokenTypes.CommentContent,
930
+ handler(token, state) {
931
+ state.currentNode.content = token.value;
932
+ state.caretPosition++;
933
+ return state;
934
+ }
935
+ },
936
+ {
937
+ tokenType: TokenTypes.CommentClose,
938
+ handler(token, state) {
939
+ updateNodeEnd(state.currentNode, token);
940
+ state.currentNode = state.currentNode.parentRef;
941
+ state.currentContext = state.currentContext.parentRef;
942
+ state.caretPosition++;
943
+ return state;
944
+ }
945
+ }
946
+ ]);
560
947
  function construct$12(token, state) {
561
- if (token.type === TokenTypes.CommentOpen) return handleCommentOpen$1(state, token);
562
- if (token.type === TokenTypes.CommentContent) return handleCommentContent(state, token);
563
- if (token.type === TokenTypes.CommentClose) return handleCommentClose(state, token);
564
- return state;
565
- }
566
- function handleCommentOpen$1(state, token) {
567
- state.currentNode.open = createNodeFrom(token);
568
- state.caretPosition++;
569
- return state;
570
- }
571
- function handleCommentContent(state, token) {
572
- state.currentNode.value = createNodeFrom(token);
573
- state.caretPosition++;
574
- return state;
575
- }
576
- function handleCommentClose(state, token) {
577
- state.currentNode.close = createNodeFrom(token);
578
- updateNodeEnd(state.currentNode, token);
579
- state.currentNode = state.currentNode.parentRef;
580
- state.currentContext = state.currentContext.parentRef;
581
- state.caretPosition++;
582
- return state;
948
+ return dispatch$12(token, state);
583
949
  }
584
950
 
585
951
  //#endregion
586
952
  //#region src/constructor/handlers/doctype.ts
587
953
  var doctype_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$11 });
588
954
  const ATTRIBUTES_START_TOKENS = new Set([TokenTypes.DoctypeAttributeWrapperStart, TokenTypes.DoctypeAttributeValue]);
589
- function construct$11(token, state) {
590
- if (token.type === TokenTypes.DoctypeOpen) return handleDoctypeOpen$1(state, token);
591
- if (token.type === TokenTypes.DoctypeClose) return handleDoctypeClose$2(state, token);
592
- if (ATTRIBUTES_START_TOKENS.has(token.type)) return handleDoctypeAttributes(state);
593
- state.caretPosition++;
594
- return state;
595
- }
596
- function handleDoctypeOpen$1(state, token) {
597
- state.currentNode.open = createNodeFrom(token);
598
- state.caretPosition++;
599
- return state;
600
- }
601
- function handleDoctypeClose$2(state, token) {
602
- state.currentNode.close = createNodeFrom(token);
603
- updateNodeEnd(state.currentNode, token);
604
- state.currentNode = state.currentNode.parentRef;
605
- state.currentContext = state.currentContext.parentRef;
955
+ const dispatch$11 = createTokenDispatcher([
956
+ {
957
+ tokenType: TokenTypes.DoctypeOpen,
958
+ handler(token, state) {
959
+ state.currentNode.open = createNodeFrom(token);
960
+ state.caretPosition++;
961
+ return state;
962
+ }
963
+ },
964
+ {
965
+ tokenType: TokenTypes.DoctypeClose,
966
+ handler(token, state) {
967
+ state.currentNode.close = createNodeFrom(token);
968
+ updateNodeEnd(state.currentNode, token);
969
+ state.currentNode = state.currentNode.parentRef;
970
+ state.currentContext = state.currentContext.parentRef;
971
+ state.caretPosition++;
972
+ return state;
973
+ }
974
+ },
975
+ {
976
+ tokenType: ATTRIBUTES_START_TOKENS,
977
+ handler(_, state) {
978
+ state.currentContext = {
979
+ parentRef: state.currentContext,
980
+ type: ConstructTreeContextTypes.DoctypeAttributes
981
+ };
982
+ return state;
983
+ }
984
+ }
985
+ ], (_, state) => {
606
986
  state.caretPosition++;
607
987
  return state;
608
- }
609
- function handleDoctypeAttributes(state) {
610
- state.currentContext = {
611
- parentRef: state.currentContext,
612
- type: ConstructTreeContextTypes.DoctypeAttributes
613
- };
614
- return state;
988
+ });
989
+ function construct$11(token, state) {
990
+ return dispatch$11(token, state);
615
991
  }
616
992
 
617
993
  //#endregion
618
994
  //#region src/constructor/handlers/tagName.ts
619
995
  var tagName_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$10 });
620
- function construct$10(token, state) {
621
- if (token.type === TokenTypes.OpenTagStart) handleTagOpenStart$4(state, token);
996
+ const dispatch$10 = createTokenDispatcher([{
997
+ tokenType: TokenTypes.OpenTagStart,
998
+ handler(token, state) {
999
+ state.currentNode.name = parseOpenTagName(token.value);
1000
+ state.currentContext = state.currentContext.parentRef;
1001
+ state.caretPosition++;
1002
+ return state;
1003
+ }
1004
+ }], (_, state) => {
622
1005
  state.caretPosition++;
623
1006
  return state;
624
- }
625
- function handleTagOpenStart$4(state, token) {
626
- state.currentNode.name = parseOpenTagName(token.value);
627
- state.currentContext = state.currentContext.parentRef;
628
- return state;
1007
+ });
1008
+ function construct$10(token, state) {
1009
+ return dispatch$10(token, state);
629
1010
  }
630
1011
 
631
1012
  //#endregion
632
1013
  //#region src/constructor/handlers/attribute.ts
633
1014
  var attribute_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$9 });
634
- const OPEN_TAG_END_TOKENS = new Set([TokenTypes.OpenTagEnd]);
635
- function construct$9(token, state) {
636
- if (OPEN_TAG_END_TOKENS.has(token.type)) return handleOpenTagEnd$1(state);
637
- if (token.type === TokenTypes.AttributeKey) return handleAttributeKey(state, token);
638
- if (token.type === TokenTypes.AttributeAssignment) return handleAttributeAssignment(state);
639
- state.caretPosition++;
640
- return state;
641
- }
642
- function handleOpenTagEnd$1(state) {
643
- state.currentContext = state.currentContext.parentRef;
644
- return state;
645
- }
646
- function handleAttributeKey(state, token) {
647
- const attribute = getLastAttribute(state);
648
- if (attribute.key !== void 0 || attribute.value !== void 0) {
649
- state.currentContext = state.currentContext.parentRef;
650
- return state;
651
- }
652
- attribute.key = createNodeFrom(token);
653
- state.caretPosition++;
654
- return state;
655
- }
656
- function handleAttributeAssignment(state) {
657
- if (getLastAttribute(state).value !== void 0) {
658
- state.currentContext = state.currentContext.parentRef;
659
- return state;
1015
+ const dispatch$9 = createTokenDispatcher([
1016
+ {
1017
+ tokenType: new Set([TokenTypes.OpenTagEnd]),
1018
+ handler(_, state) {
1019
+ state.currentContext = state.currentContext.parentRef;
1020
+ return state;
1021
+ }
1022
+ },
1023
+ {
1024
+ tokenType: TokenTypes.AttributeKey,
1025
+ handler(token, state) {
1026
+ const attribute = getLastAttribute(state);
1027
+ if (attribute.key !== void 0 || attribute.value !== void 0) {
1028
+ state.currentContext = state.currentContext.parentRef;
1029
+ return state;
1030
+ }
1031
+ attribute.key = createNodeFrom(token);
1032
+ state.caretPosition++;
1033
+ return state;
1034
+ }
1035
+ },
1036
+ {
1037
+ tokenType: TokenTypes.AttributeAssignment,
1038
+ handler(_, state) {
1039
+ if (getLastAttribute(state).value !== void 0) {
1040
+ state.currentContext = state.currentContext.parentRef;
1041
+ return state;
1042
+ }
1043
+ state.currentContext = {
1044
+ parentRef: state.currentContext,
1045
+ type: ConstructTreeContextTypes.AttributeValue
1046
+ };
1047
+ state.caretPosition++;
1048
+ return state;
1049
+ }
660
1050
  }
661
- state.currentContext = {
662
- parentRef: state.currentContext,
663
- type: ConstructTreeContextTypes.AttributeValue
664
- };
1051
+ ], (_, state) => {
665
1052
  state.caretPosition++;
666
1053
  return state;
1054
+ });
1055
+ function construct$9(token, state) {
1056
+ return dispatch$9(token, state);
667
1057
  }
668
1058
 
669
1059
  //#endregion
670
1060
  //#region src/constructor/handlers/attributes.ts
671
1061
  var attributes_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct$8 });
672
- const ATTRIBUTE_START_TOKENS$1 = new Set([TokenTypes.AttributeKey, TokenTypes.AttributeAssignment]);
1062
+ const ATTRIBUTE_START_TOKENS$2 = new Set([TokenTypes.AttributeKey, TokenTypes.AttributeAssignment]);
673
1063
  const ATTRIBUTE_END_TOKENS = new Set([TokenTypes.OpenTagEnd]);
674
- function construct$8(token, state) {
675
- if (ATTRIBUTE_START_TOKENS$1.has(token.type)) return handleAttributeStart(state, token);
676
- if (ATTRIBUTE_END_TOKENS.has(token.type)) return handleOpenTagEnd(state);
1064
+ const dispatch$8 = createTokenDispatcher([{
1065
+ tokenType: ATTRIBUTE_START_TOKENS$2,
1066
+ handler(token, state) {
1067
+ initAttributesIfNone(state.currentNode);
1068
+ state.currentNode.attributes.push({
1069
+ type: NodeTypes.Attribute,
1070
+ range: cloneRange(token.range),
1071
+ loc: cloneLocation(token.loc)
1072
+ });
1073
+ state.currentContext = {
1074
+ parentRef: state.currentContext,
1075
+ type: ConstructTreeContextTypes.Attribute
1076
+ };
1077
+ return state;
1078
+ }
1079
+ }, {
1080
+ tokenType: ATTRIBUTE_END_TOKENS,
1081
+ handler(_, state) {
1082
+ state.currentContext = state.currentContext.parentRef;
1083
+ return state;
1084
+ }
1085
+ }], (_, state) => {
677
1086
  state.caretPosition++;
678
1087
  return state;
679
- }
680
- function handleAttributeStart(state, token) {
681
- initAttributesIfNone(state.currentNode);
682
- state.currentNode.attributes.push({
683
- type: NodeTypes.Attribute,
684
- range: cloneRange(token.range),
685
- loc: cloneLocation(token.loc)
686
- });
687
- state.currentContext = {
688
- parentRef: state.currentContext,
689
- type: ConstructTreeContextTypes.Attribute
690
- };
691
- return state;
692
- }
693
- function handleOpenTagEnd(state) {
694
- state.currentContext = state.currentContext.parentRef;
695
- return state;
1088
+ });
1089
+ function construct$8(token, state) {
1090
+ return dispatch$8(token, state);
696
1091
  }
697
1092
 
698
1093
  //#endregion
699
1094
  //#region src/constructor/handlers/tagContent.ts
700
1095
  var tagContent_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$7 });
701
- function construct$7(token, state) {
702
- if (token.type === TokenTypes.OpenTagStart) return handleOpenTagStart(state, token);
703
- if (token.type === TokenTypes.Text) return handleText(state, token);
704
- if (token.type === TokenTypes.CloseTag) return handleCloseTag(state, token);
705
- if (token.type === TokenTypes.CommentOpen) return handleCommentOpen(state, token);
706
- if (token.type === TokenTypes.DoctypeOpen) return handleDoctypeOpen(state, token);
707
- state.caretPosition++;
708
- return state;
709
- }
710
- function handleOpenTagStart(state, token) {
711
- initChildrenIfNone(state.currentNode);
712
- const tagNode = {
713
- type: NodeTypes.Tag,
714
- parentRef: state.currentNode,
715
- range: cloneRange(token.range),
716
- loc: cloneLocation(token.loc),
717
- attributes: [],
718
- children: []
719
- };
720
- state.currentNode.children.push(tagNode);
721
- state.currentNode = tagNode;
722
- state.currentContext = {
723
- parentRef: state.currentContext,
724
- type: ConstructTreeContextTypes.Tag
725
- };
726
- return state;
727
- }
728
- function handleText(state, token) {
729
- initChildrenIfNone(state.currentNode);
730
- const textNode = createNodeFrom(token);
731
- state.currentNode.children.push(textNode);
732
- state.caretPosition++;
733
- return state;
734
- }
735
- function handleCloseTag(state, token) {
736
- if (parseCloseTagName(token.value) !== state.currentNode.name) {
737
- state.caretPosition++;
738
- return state;
1096
+ const dispatch$7 = createTokenDispatcher([
1097
+ {
1098
+ tokenType: TokenTypes.OpenTagStart,
1099
+ handler(token, state) {
1100
+ initChildrenIfNone(state.currentNode);
1101
+ const tagNode = {
1102
+ type: NodeTypes.Tag,
1103
+ parentRef: state.currentNode,
1104
+ range: cloneRange(token.range),
1105
+ loc: cloneLocation(token.loc),
1106
+ attributes: [],
1107
+ children: []
1108
+ };
1109
+ state.currentNode.children.push(tagNode);
1110
+ state.currentNode = tagNode;
1111
+ state.currentContext = {
1112
+ parentRef: state.currentContext,
1113
+ type: ConstructTreeContextTypes.Tag
1114
+ };
1115
+ return state;
1116
+ }
1117
+ },
1118
+ {
1119
+ tokenType: TokenTypes.Text,
1120
+ handler(token, state) {
1121
+ initChildrenIfNone(state.currentNode);
1122
+ const textNode = createNodeFrom(token);
1123
+ state.currentNode.children.push(textNode);
1124
+ state.caretPosition++;
1125
+ return state;
1126
+ }
1127
+ },
1128
+ {
1129
+ tokenType: TokenTypes.CloseTag,
1130
+ handler(token, state) {
1131
+ if (parseCloseTagName(token.value) !== state.currentNode.name) {
1132
+ state.caretPosition++;
1133
+ return state;
1134
+ }
1135
+ state.currentContext = state.currentContext.parentRef;
1136
+ return state;
1137
+ }
1138
+ },
1139
+ {
1140
+ tokenType: TokenTypes.CommentOpen,
1141
+ handler(token, state) {
1142
+ initChildrenIfNone(state.currentNode);
1143
+ const commentNode = {
1144
+ type: NodeTypes.Comment,
1145
+ parentRef: state.currentNode,
1146
+ range: cloneRange(token.range),
1147
+ loc: cloneLocation(token.loc)
1148
+ };
1149
+ state.currentNode.children.push(commentNode);
1150
+ state.currentNode = commentNode;
1151
+ state.currentContext = {
1152
+ parentRef: state.currentContext,
1153
+ type: ConstructTreeContextTypes.Comment
1154
+ };
1155
+ return state;
1156
+ }
1157
+ },
1158
+ {
1159
+ tokenType: TokenTypes.DoctypeOpen,
1160
+ handler(token, state) {
1161
+ initChildrenIfNone(state.currentNode);
1162
+ const doctypeNode = {
1163
+ type: NodeTypes.Doctype,
1164
+ parentRef: state.currentNode,
1165
+ range: cloneRange(token.range),
1166
+ loc: cloneLocation(token.loc),
1167
+ attributes: []
1168
+ };
1169
+ state.currentNode.children.push(doctypeNode);
1170
+ state.currentNode = doctypeNode;
1171
+ state.currentContext = {
1172
+ parentRef: state.currentContext,
1173
+ type: ConstructTreeContextTypes.Doctype
1174
+ };
1175
+ return state;
1176
+ }
739
1177
  }
740
- state.currentContext = state.currentContext.parentRef;
741
- return state;
742
- }
743
- function handleCommentOpen(state, token) {
744
- initChildrenIfNone(state.currentNode);
745
- const commentNode = {
746
- type: NodeTypes.Comment,
747
- parentRef: state.currentNode,
748
- range: cloneRange(token.range),
749
- loc: cloneLocation(token.loc)
750
- };
751
- state.currentNode.children.push(commentNode);
752
- state.currentNode = commentNode;
753
- state.currentContext = {
754
- parentRef: state.currentContext,
755
- type: ConstructTreeContextTypes.Comment
756
- };
757
- return state;
758
- }
759
- function handleDoctypeOpen(state, token) {
760
- initChildrenIfNone(state.currentNode);
761
- const doctypeNode = {
762
- type: NodeTypes.Doctype,
763
- parentRef: state.currentNode,
764
- range: cloneRange(token.range),
765
- loc: cloneLocation(token.loc),
766
- attributes: []
767
- };
768
- state.currentNode.children.push(doctypeNode);
769
- state.currentNode = doctypeNode;
770
- state.currentContext = {
771
- parentRef: state.currentContext,
772
- type: ConstructTreeContextTypes.Doctype
773
- };
1178
+ ], (_, state) => {
1179
+ state.caretPosition++;
774
1180
  return state;
1181
+ });
1182
+ function construct$7(token, state) {
1183
+ return dispatch$7(token, state);
775
1184
  }
776
1185
 
777
1186
  //#endregion
778
1187
  //#region src/constructor/handlers/attributeValue.ts
779
1188
  var attributeValue_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct$6 });
780
- const VALUE_END_TOKENS = new Set([
781
- TokenTypes.OpenTagEnd,
782
- TokenTypes.AttributeKey,
783
- TokenTypes.AttributeAssignment
784
- ]);
785
- function construct$6(token, state) {
786
- if (VALUE_END_TOKENS.has(token.type)) return handleValueEnd(state);
787
- if (token.type === TokenTypes.AttributeValue) return handleAttributeValue(state, token);
788
- if (token.type === TokenTypes.AttributeValueWrapperStart) return handleAttributeValueWrapperStart(state, token);
789
- if (token.type === TokenTypes.AttributeValueWrapperEnd) return handleAttributeValueWrapperEnd(state, token);
790
- state.caretPosition++;
791
- return state;
792
- }
793
- function handleValueEnd(state) {
794
- state.currentContext = state.currentContext.parentRef;
795
- return state;
796
- }
797
- function handleAttributeValue(state, token) {
798
- const attribute = getLastAttribute(state);
799
- attribute.value = createNodeFrom(token);
800
- updateNodeEnd(attribute, token);
801
- state.caretPosition++;
802
- return state;
803
- }
804
- function handleAttributeValueWrapperStart(state, token) {
805
- const attribute = getLastAttribute(state);
806
- attribute.startWrapper = createNodeFrom(token);
807
- if (!attribute.key) {
808
- attribute.range = cloneRange(token.range);
809
- attribute.loc = cloneLocation(token.loc);
1189
+ const dispatch$6 = createTokenDispatcher([
1190
+ {
1191
+ tokenType: new Set([
1192
+ TokenTypes.OpenTagEnd,
1193
+ TokenTypes.AttributeKey,
1194
+ TokenTypes.AttributeAssignment
1195
+ ]),
1196
+ handler(_, state) {
1197
+ state.currentContext = state.currentContext.parentRef;
1198
+ return state;
1199
+ }
1200
+ },
1201
+ {
1202
+ tokenType: TokenTypes.AttributeValue,
1203
+ handler(token, state) {
1204
+ const attribute = getLastAttribute(state);
1205
+ attribute.value = createNodeFrom(token);
1206
+ updateNodeEnd(attribute, token);
1207
+ state.caretPosition++;
1208
+ return state;
1209
+ }
1210
+ },
1211
+ {
1212
+ tokenType: TokenTypes.AttributeValueWrapperStart,
1213
+ handler(token, state) {
1214
+ const attribute = getLastAttribute(state);
1215
+ attribute.quoteChar = token.value;
1216
+ if (!attribute.key) {
1217
+ attribute.range = cloneRange(token.range);
1218
+ attribute.loc = cloneLocation(token.loc);
1219
+ }
1220
+ state.caretPosition++;
1221
+ return state;
1222
+ }
1223
+ },
1224
+ {
1225
+ tokenType: TokenTypes.AttributeValueWrapperEnd,
1226
+ handler(token, state) {
1227
+ updateNodeEnd(getLastAttribute(state), token);
1228
+ state.caretPosition++;
1229
+ return state;
1230
+ }
810
1231
  }
1232
+ ], (_, state) => {
811
1233
  state.caretPosition++;
812
1234
  return state;
813
- }
814
- function handleAttributeValueWrapperEnd(state, token) {
815
- const attribute = getLastAttribute(state);
816
- attribute.endWrapper = createNodeFrom(token);
817
- updateNodeEnd(attribute, token);
818
- state.caretPosition++;
819
- return state;
1235
+ });
1236
+ function construct$6(token, state) {
1237
+ return dispatch$6(token, state);
820
1238
  }
821
1239
 
822
1240
  //#endregion
823
1241
  //#region src/constructor/handlers/xmlDeclaration.ts
824
1242
  var xmlDeclaration_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$5 });
825
- function construct$5(token, state) {
826
- if (token.type === TokenTypes.OpenTagStart) handleTagOpenStart$3(state, token);
1243
+ const dispatch$5 = createTokenDispatcher([{
1244
+ tokenType: TokenTypes.OpenTagStart,
1245
+ handler(token, state) {
1246
+ state.currentNode.name = parseOpenTagName(token.value);
1247
+ state.currentContext = state.currentContext.parentRef;
1248
+ state.caretPosition++;
1249
+ return state;
1250
+ }
1251
+ }], (_, state) => {
827
1252
  state.caretPosition++;
828
1253
  return state;
829
- }
830
- function handleTagOpenStart$3(state, token) {
831
- state.currentNode.name = parseOpenTagName(token.value);
832
- state.currentContext = state.currentContext.parentRef;
833
- return state;
1254
+ });
1255
+ function construct$5(token, state) {
1256
+ return dispatch$5(token, state);
834
1257
  }
835
1258
 
836
1259
  //#endregion
837
1260
  //#region src/constructor/handlers/doctypeAttribute.ts
838
1261
  var doctypeAttribute_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$4 });
839
- function construct$4(token, state) {
840
- if (token.type === TokenTypes.DoctypeClose) return handleDoctypeClose$1(state);
841
- if (token.type === TokenTypes.DoctypeAttributeWrapperStart) return handleDoctypeAttributeWrapperStart(state, token);
842
- if (token.type === TokenTypes.DoctypeAttributeWrapperEnd) return handleDoctypeAttributeWrapperEnd(state, token);
843
- if (token.type === TokenTypes.DoctypeAttributeValue) return handleDoctypeAttributeValue(state, token);
1262
+ const dispatch$4 = createTokenDispatcher([
1263
+ {
1264
+ tokenType: TokenTypes.DoctypeClose,
1265
+ handler(_, state) {
1266
+ state.currentContext = state.currentContext.parentRef;
1267
+ return state;
1268
+ }
1269
+ },
1270
+ {
1271
+ tokenType: TokenTypes.DoctypeAttributeWrapperStart,
1272
+ handler(token, state) {
1273
+ const attribute = getLastAttribute(state);
1274
+ if (attribute.value !== void 0) {
1275
+ state.currentContext = state.currentContext.parentRef;
1276
+ return state;
1277
+ }
1278
+ attribute.quoteChar = token.value;
1279
+ attribute.range = cloneRange(token.range);
1280
+ state.caretPosition++;
1281
+ return state;
1282
+ }
1283
+ },
1284
+ {
1285
+ tokenType: TokenTypes.DoctypeAttributeWrapperEnd,
1286
+ handler(token, state) {
1287
+ updateNodeEnd(getLastAttribute(state), token);
1288
+ state.currentContext = state.currentContext.parentRef;
1289
+ state.caretPosition++;
1290
+ return state;
1291
+ }
1292
+ },
1293
+ {
1294
+ tokenType: TokenTypes.DoctypeAttributeValue,
1295
+ handler(token, state) {
1296
+ const attribute = getLastAttribute(state);
1297
+ if (attribute.value !== void 0) {
1298
+ state.currentContext = state.currentContext.parentRef;
1299
+ return state;
1300
+ }
1301
+ attribute.value = createNodeFrom(token);
1302
+ if (!attribute.quoteChar) attribute.range = cloneRange(token.range);
1303
+ state.caretPosition++;
1304
+ return state;
1305
+ }
1306
+ }
1307
+ ], (_, state) => {
844
1308
  state.caretPosition++;
845
1309
  return state;
1310
+ });
1311
+ function construct$4(token, state) {
1312
+ return dispatch$4(token, state);
846
1313
  }
847
- function handleDoctypeClose$1(state) {
848
- state.currentContext = state.currentContext.parentRef;
849
- return state;
850
- }
851
- function handleDoctypeAttributeWrapperStart(state, token) {
852
- const attribute = getLastAttribute(state);
853
- if (attribute.value !== void 0) {
1314
+
1315
+ //#endregion
1316
+ //#region src/constructor/handlers/doctypeAttributes.ts
1317
+ var doctypeAttributes_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct$3 });
1318
+ const ATTRIBUTE_START_TOKENS$1 = new Set([TokenTypes.DoctypeAttributeWrapperStart, TokenTypes.DoctypeAttributeValue]);
1319
+ const dispatch$3 = createTokenDispatcher([{
1320
+ tokenType: TokenTypes.DoctypeClose,
1321
+ handler(_, state) {
854
1322
  state.currentContext = state.currentContext.parentRef;
855
1323
  return state;
856
1324
  }
857
- attribute.startWrapper = createNodeFrom(token);
858
- attribute.range = cloneRange(token.range);
859
- state.caretPosition++;
860
- return state;
861
- }
862
- function handleDoctypeAttributeWrapperEnd(state, token) {
863
- const attribute = getLastAttribute(state);
864
- attribute.endWrapper = createNodeFrom(token);
865
- updateNodeEnd(attribute, token);
866
- state.currentContext = state.currentContext.parentRef;
867
- state.caretPosition++;
868
- return state;
869
- }
870
- function handleDoctypeAttributeValue(state, token) {
871
- const attribute = getLastAttribute(state);
872
- if (attribute.value !== void 0) {
873
- state.currentContext = state.currentContext.parentRef;
1325
+ }, {
1326
+ tokenType: ATTRIBUTE_START_TOKENS$1,
1327
+ handler(token, state) {
1328
+ initAttributesIfNone(state.currentNode);
1329
+ state.currentNode.attributes.push({
1330
+ type: NodeTypes.DoctypeAttribute,
1331
+ range: cloneRange(token.range),
1332
+ loc: cloneLocation(token.loc)
1333
+ });
1334
+ state.currentContext = {
1335
+ type: ConstructTreeContextTypes.DoctypeAttribute,
1336
+ parentRef: state.currentContext
1337
+ };
874
1338
  return state;
875
1339
  }
876
- attribute.value = createNodeFrom(token);
877
- if (!attribute.startWrapper) attribute.range = cloneRange(token.range);
1340
+ }], (_, state) => {
878
1341
  state.caretPosition++;
879
1342
  return state;
880
- }
881
-
882
- //#endregion
883
- //#region src/constructor/handlers/doctypeAttributes.ts
884
- var doctypeAttributes_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct$3 });
885
- const ATTRIBUTE_START_TOKENS = new Set([TokenTypes.DoctypeAttributeWrapperStart, TokenTypes.DoctypeAttributeValue]);
1343
+ });
886
1344
  function construct$3(token, state) {
887
- if (token.type === TokenTypes.DoctypeClose) return handleDoctypeClose(state);
888
- if (ATTRIBUTE_START_TOKENS.has(token.type)) return handleAttribute(state, token);
889
- state.caretPosition++;
890
- return state;
891
- }
892
- function handleDoctypeClose(state) {
893
- state.currentContext = state.currentContext.parentRef;
894
- return state;
895
- }
896
- function handleAttribute(state, token) {
897
- initAttributesIfNone(state.currentNode);
898
- state.currentNode.attributes.push({
899
- type: NodeTypes.DoctypeAttribute,
900
- range: cloneRange(token.range),
901
- loc: cloneLocation(token.loc)
902
- });
903
- state.currentContext = {
904
- type: ConstructTreeContextTypes.DoctypeAttribute,
905
- parentRef: state.currentContext
906
- };
907
- return state;
1345
+ return dispatch$3(token, state);
908
1346
  }
909
1347
 
910
1348
  //#endregion
911
1349
  //#region src/constructor/handlers/xmlDeclarationAttribute.ts
912
1350
  var xmlDeclarationAttribute_exports = /* @__PURE__ */ __exportAll({ construct: () => construct$2 });
913
- function construct$2(token, state) {
914
- if (token.type === TokenTypes.OpenTagStart) handleTagOpenStart$2(state, token);
1351
+ const dispatch$2 = createTokenDispatcher([
1352
+ {
1353
+ tokenType: new Set([
1354
+ TokenTypes.OpenTagEnd,
1355
+ TokenTypes.AttributeKey,
1356
+ TokenTypes.AttributeAssignment
1357
+ ]),
1358
+ handler(_, state) {
1359
+ state.currentContext = state.currentContext.parentRef;
1360
+ return state;
1361
+ }
1362
+ },
1363
+ {
1364
+ tokenType: TokenTypes.AttributeValue,
1365
+ handler(token, state) {
1366
+ const attribute = getLastAttribute(state);
1367
+ attribute.value = createNodeFrom(token);
1368
+ updateNodeEnd(attribute, token);
1369
+ state.caretPosition++;
1370
+ return state;
1371
+ }
1372
+ },
1373
+ {
1374
+ tokenType: TokenTypes.AttributeValueWrapperStart,
1375
+ handler(token, state) {
1376
+ const attribute = getLastAttribute(state);
1377
+ attribute.quoteChar = token.value;
1378
+ if (!attribute.key) attribute.range = cloneRange(token.range);
1379
+ state.caretPosition++;
1380
+ return state;
1381
+ }
1382
+ },
1383
+ {
1384
+ tokenType: TokenTypes.AttributeValueWrapperEnd,
1385
+ handler(token, state) {
1386
+ updateNodeEnd(getLastAttribute(state), token);
1387
+ state.caretPosition++;
1388
+ return state;
1389
+ }
1390
+ }
1391
+ ], (_, state) => {
915
1392
  state.caretPosition++;
916
1393
  return state;
917
- }
918
- function handleTagOpenStart$2(state, token) {
919
- state.currentNode.name = parseOpenTagName(token.value);
920
- state.currentContext = state.currentContext.parentRef;
921
- return state;
1394
+ });
1395
+ function construct$2(token, state) {
1396
+ return dispatch$2(token, state);
922
1397
  }
923
1398
 
924
1399
  //#endregion
925
1400
  //#region src/constructor/handlers/xmlDeclarationAttributes.ts
926
1401
  var xmlDeclarationAttributes_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct$1 });
927
- function construct$1(token, state) {
928
- if (token.type === TokenTypes.OpenTagStart) handleTagOpenStart$1(state, token);
1402
+ const ATTRIBUTE_START_TOKENS = new Set([TokenTypes.AttributeKey, TokenTypes.AttributeAssignment]);
1403
+ const dispatch$1 = createTokenDispatcher([{
1404
+ tokenType: TokenTypes.OpenTagEnd,
1405
+ handler(_, state) {
1406
+ state.currentContext = state.currentContext.parentRef;
1407
+ return state;
1408
+ }
1409
+ }, {
1410
+ tokenType: ATTRIBUTE_START_TOKENS,
1411
+ handler(token, state) {
1412
+ initAttributesIfNone(state.currentNode);
1413
+ state.currentNode.attributes.push({
1414
+ type: NodeTypes.Attribute,
1415
+ range: cloneRange(token.range),
1416
+ loc: cloneLocation(token.loc)
1417
+ });
1418
+ state.currentContext = {
1419
+ type: ConstructTreeContextTypes.XMLDeclarationAttribute,
1420
+ parentRef: state.currentContext
1421
+ };
1422
+ return state;
1423
+ }
1424
+ }], (_, state) => {
929
1425
  state.caretPosition++;
930
1426
  return state;
931
- }
932
- function handleTagOpenStart$1(state, token) {
933
- state.currentNode.name = parseOpenTagName(token.value);
934
- state.currentContext = state.currentContext.parentRef;
935
- return state;
1427
+ });
1428
+ function construct$1(token, state) {
1429
+ return dispatch$1(token, state);
936
1430
  }
937
1431
 
938
1432
  //#endregion
939
1433
  //#region src/constructor/handlers/xmlDeclarationAttributeValue.ts
940
1434
  var xmlDeclarationAttributeValue_exports$1 = /* @__PURE__ */ __exportAll({ construct: () => construct });
941
- function construct(token, state) {
942
- if (token.type === TokenTypes.OpenTagStart) handleTagOpenStart(state, token);
1435
+ const dispatch = createTokenDispatcher([
1436
+ {
1437
+ tokenType: TokenTypes.OpenTagEnd,
1438
+ handler(_, state) {
1439
+ state.currentContext = state.currentContext.parentRef;
1440
+ return state;
1441
+ }
1442
+ },
1443
+ {
1444
+ tokenType: TokenTypes.AttributeValue,
1445
+ handler(token, state) {
1446
+ const attribute = getLastAttribute(state);
1447
+ if (attribute.value !== void 0) {
1448
+ state.currentContext = state.currentContext.parentRef;
1449
+ return state;
1450
+ }
1451
+ attribute.value = createNodeFrom(token);
1452
+ if (!attribute.quoteChar) attribute.range = cloneRange(token.range);
1453
+ state.caretPosition++;
1454
+ return state;
1455
+ }
1456
+ },
1457
+ {
1458
+ tokenType: TokenTypes.AttributeValueWrapperStart,
1459
+ handler(token, state) {
1460
+ const attribute = getLastAttribute(state);
1461
+ if (attribute.value !== void 0) {
1462
+ state.currentContext = state.currentContext.parentRef;
1463
+ return state;
1464
+ }
1465
+ attribute.quoteChar = token.value;
1466
+ attribute.range = cloneRange(token.range);
1467
+ state.caretPosition++;
1468
+ return state;
1469
+ }
1470
+ },
1471
+ {
1472
+ tokenType: TokenTypes.AttributeValueWrapperEnd,
1473
+ handler(token, state) {
1474
+ updateNodeEnd(getLastAttribute(state), token);
1475
+ state.currentContext = state.currentContext.parentRef;
1476
+ state.caretPosition++;
1477
+ return state;
1478
+ }
1479
+ }
1480
+ ], (_, state) => {
943
1481
  state.caretPosition++;
944
1482
  return state;
945
- }
946
- function handleTagOpenStart(state, token) {
947
- state.currentNode.name = parseOpenTagName(token.value);
948
- state.currentContext = state.currentContext.parentRef;
949
- return state;
1483
+ });
1484
+ function construct(token, state) {
1485
+ return dispatch(token, state);
950
1486
  }
951
1487
 
952
1488
  //#endregion
@@ -1883,43 +2419,20 @@ function parse$1(source, _options = {}) {
1883
2419
  const keys = {
1884
2420
  Program: ["body"],
1885
2421
  Document: ["children"],
1886
- XMLDeclaration: [],
1887
- XMLDeclarationOpen: [],
1888
- XMLDeclarationClose: [],
2422
+ XMLDeclaration: ["attributes"],
1889
2423
  XMLDeclarationAttribute: ["key", "value"],
1890
2424
  XMLDeclarationAttributeKey: [],
1891
2425
  XMLDeclarationAttributeValue: [],
1892
- XMLDeclarationAttributeValueWrapperStart: [],
1893
- XMLDeclarationAttributeValueWrapperEnd: [],
1894
- Doctype: [
1895
- "open",
1896
- "close",
1897
- "attributes"
1898
- ],
1899
- DoctypeOpen: [],
1900
- DoctypeClose: [],
1901
- DoctypeAttribute: ["key", "value"],
1902
- DoctypeAttributeValue: ["value"],
1903
- DoctypeAttributeWrapperEnd: [],
1904
- DoctypeAttributeWrapperStart: [],
2426
+ Doctype: ["attributes"],
2427
+ DoctypeAttribute: ["value"],
2428
+ DoctypeAttributeValue: [],
1905
2429
  Attribute: ["key", "value"],
1906
- AttributeKey: ["value"],
1907
- AttributeValue: ["value"],
1908
- AttributeValueWrapperEnd: [],
1909
- AttributeValueWrapperStart: [],
1910
- Tag: ["children", "attributes"],
1911
- OpenTagEnd: [],
1912
- OpenTagStart: [],
1913
- CloseTag: [],
1914
- Comment: [
1915
- "open",
1916
- "close",
1917
- "value"
1918
- ],
1919
- CommentOpen: [],
1920
- CommentClose: [],
1921
- CommentContent: [],
1922
- Text: []
2430
+ AttributeKey: [],
2431
+ AttributeValue: [],
2432
+ Tag: ["attributes", "children"],
2433
+ Comment: [],
2434
+ Text: [],
2435
+ Error: []
1923
2436
  };
1924
2437
  let vistorKeysCache = null;
1925
2438
  function getVisitorKeys() {
@@ -1946,21 +2459,17 @@ function traverse(node, visitor) {
1946
2459
  //#region src/parser/parseForESLint.ts
1947
2460
  function parseForESLint(source, options = {}) {
1948
2461
  const { ast, tokens } = parse$1(source, options);
2462
+ const comments = [];
1949
2463
  const programNode = {
1950
2464
  type: NodeTypes.Program,
1951
2465
  body: [ast],
1952
- comments: [],
2466
+ comments,
1953
2467
  tokens: tokens.filter((token) => token.type !== TokenTypes.CommentOpen && token.type !== TokenTypes.CommentClose && token.type !== TokenTypes.CommentContent),
1954
2468
  range: ast.range,
1955
2469
  loc: ast.loc
1956
2470
  };
1957
2471
  traverse(programNode, (node) => {
1958
- if (node.type === NodeTypes.CommentContent) programNode.comments.push({
1959
- type: node.type,
1960
- range: node.range,
1961
- loc: node.loc,
1962
- value: node.value
1963
- });
2472
+ if (node.type === NodeTypes.Comment && "content" in node) comments.push(node.content);
1964
2473
  });
1965
2474
  return {
1966
2475
  ast: programNode,
@@ -1979,4 +2488,4 @@ function parse(code, options = {}) {
1979
2488
  }
1980
2489
 
1981
2490
  //#endregion
1982
- export { COMMENT_END, COMMENT_START, ConstructTreeContextTypes, DEPRECATED_SVG_ELEMENTS, NodeTypes, ParseError, RE_CLOSE_TAG_NAME, RE_INCOMPLETE_CLOSING_TAG, RE_OPEN_TAG_NAME, RE_OPEN_TAG_START, SELF_CLOSING_ELEMENTS, SPECIAL_CHAR, SVG_ELEMENTS, TokenTypes, TokenizerContextTypes, VisitorKeys, XML_DECLARATION_END, XML_DECLARATION_START, meta, name, parse, parseForESLint };
2491
+ export { COMMENT_END, COMMENT_START, ConstructTreeContextTypes, DEPRECATED_SVG_ELEMENTS, NodeTypes, ParseError, RE_CLOSE_TAG_NAME, RE_INCOMPLETE_CLOSING_TAG, RE_OPEN_TAG_NAME, RE_OPEN_TAG_START, SELF_CLOSING_ELEMENTS, SPECIAL_CHAR, SVG_ELEMENTS, TokenTypes, TokenizerContextTypes, VisitorKeys, XML_DECLARATION_END, XML_DECLARATION_START, cloneNode, cloneNodeWithParent, countNodes, filterNodes, findFirstNodeByType, findNodeByType, getNodeDepth, getParentChain, isNodeType, mapNodes, meta, name, parse, parseForESLint, traverseAST, validateNode, walkAST };