tempile-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/ast/base/Node.d.ts +9 -0
  2. package/dist/ast/base/Node.js +9 -0
  3. package/dist/ast/base/Pos.d.ts +10 -0
  4. package/dist/ast/base/Pos.js +1 -0
  5. package/dist/ast/base/Root.d.ts +13 -0
  6. package/dist/ast/base/Root.js +105 -0
  7. package/dist/ast/base/node-types.d.ts +18 -0
  8. package/dist/ast/base/node-types.js +19 -0
  9. package/dist/ast/base/parse5-type-guards.d.ts +4 -0
  10. package/dist/ast/base/parse5-type-guards.js +9 -0
  11. package/dist/ast/base/parse5-types.d.ts +5 -0
  12. package/dist/ast/base/parse5-types.js +1 -0
  13. package/dist/ast/base/parser-types.d.ts +3 -0
  14. package/dist/ast/base/parser-types.js +1 -0
  15. package/dist/ast/control/ElseIfNode.d.ts +13 -0
  16. package/dist/ast/control/ElseIfNode.js +41 -0
  17. package/dist/ast/control/ElseNode.d.ts +11 -0
  18. package/dist/ast/control/ElseNode.js +34 -0
  19. package/dist/ast/control/ForNode.d.ts +13 -0
  20. package/dist/ast/control/ForNode.js +37 -0
  21. package/dist/ast/control/IfNode.d.ts +17 -0
  22. package/dist/ast/control/IfNode.js +64 -0
  23. package/dist/ast/features/AttrExprNode.d.ts +1 -0
  24. package/dist/ast/features/AttrExprNode.js +13 -0
  25. package/dist/ast/features/ContentNode.d.ts +12 -0
  26. package/dist/ast/features/ContentNode.js +44 -0
  27. package/dist/ast/features/ImportNode.d.ts +12 -0
  28. package/dist/ast/features/ImportNode.js +51 -0
  29. package/dist/ast/features/IncludeNode.d.ts +14 -0
  30. package/dist/ast/features/IncludeNode.js +42 -0
  31. package/dist/ast/features/LogicNode.d.ts +11 -0
  32. package/dist/ast/features/LogicNode.js +48 -0
  33. package/dist/ast/features/OutNode.d.ts +11 -0
  34. package/dist/ast/features/OutNode.js +45 -0
  35. package/dist/ast/features/SlotNode.d.ts +12 -0
  36. package/dist/ast/features/SlotNode.js +39 -0
  37. package/dist/ast/features/TempileNode.d.ts +14 -0
  38. package/dist/ast/features/TempileNode.js +53 -0
  39. package/dist/ast/html/Attribute.d.ts +15 -0
  40. package/dist/ast/html/Attribute.js +1 -0
  41. package/dist/ast/html/CommentNode.d.ts +10 -0
  42. package/dist/ast/html/CommentNode.js +23 -0
  43. package/dist/ast/html/DoctypeNode.d.ts +8 -0
  44. package/dist/ast/html/DoctypeNode.js +13 -0
  45. package/dist/ast/html/ElementNode.d.ts +14 -0
  46. package/dist/ast/html/ElementNode.js +29 -0
  47. package/dist/ast/html/TextNode.d.ts +10 -0
  48. package/dist/ast/html/TextNode.js +23 -0
  49. package/dist/ast/nodes.d.ts +15 -0
  50. package/dist/ast/nodes.js +15 -0
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.js +1 -0
  53. package/dist/parser/parser.d.ts +6 -0
  54. package/dist/parser/parser.js +71 -0
  55. package/dist/utils/utils.d.ts +7 -0
  56. package/dist/utils/utils.js +74 -0
  57. package/package.json +37 -0
  58. package/tsconfig.json +15 -0
@@ -0,0 +1,9 @@
1
+ import NodeType from "./node-types.js";
2
+ import Pos from "./Pos.js";
3
+ declare abstract class Node {
4
+ type: NodeType;
5
+ pos: Pos | null | undefined;
6
+ constructor(type: NodeType, pos: Pos | null | undefined);
7
+ abstract getChildren(): Node[];
8
+ }
9
+ export default Node;
@@ -0,0 +1,9 @@
1
+ class Node {
2
+ type;
3
+ pos;
4
+ constructor(type, pos) {
5
+ this.type = type;
6
+ this.pos = pos;
7
+ }
8
+ }
9
+ export default Node;
@@ -0,0 +1,10 @@
1
+ type Pos = {
2
+ fileName: string;
3
+ startLine?: number;
4
+ startCol?: number;
5
+ startOffset?: number;
6
+ endLine?: number;
7
+ endCol?: number;
8
+ endOffset?: number;
9
+ };
10
+ export default Pos;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import Node from "./Node.js";
2
+ declare class Root {
3
+ children: Node[];
4
+ fileName: string;
5
+ constructor(children: Node[], fileName: string);
6
+ resolveIncludes(srcPath: string): void;
7
+ private resolveIncludesRecursive;
8
+ matchSlotsAndContents(): void;
9
+ private collectIncludes;
10
+ private collectSlotsAndContents;
11
+ private unwrapSlotsAndIncludes;
12
+ }
13
+ export default Root;
@@ -0,0 +1,105 @@
1
+ import path from "node:path";
2
+ import NodeType from "./node-types.js";
3
+ import fs from "fs";
4
+ import { parse } from "../../parser/parser.js";
5
+ class Root {
6
+ children;
7
+ fileName;
8
+ constructor(children, fileName) {
9
+ this.children = children;
10
+ this.fileName = fileName;
11
+ }
12
+ resolveIncludes(srcPath) {
13
+ this.resolveIncludesRecursive(this.children, srcPath);
14
+ }
15
+ resolveIncludesRecursive(nodes, srcPath) {
16
+ for (const child of nodes) {
17
+ if (child.type === NodeType.Include) {
18
+ const includeNode = child;
19
+ const pos = includeNode.path.pos;
20
+ if (path.basename(includeNode.path.value) === this.fileName) {
21
+ throw new Error(`Circular include detected: file "${this.fileName}" tries to include itself at ${includeNode.path.value}
22
+ File: ${pos?.fileName} Line: ${pos?.startLine} Col: ${pos?.startCol}
23
+ `);
24
+ }
25
+ const filePath = path.join(srcPath, includeNode.path.value);
26
+ let file = "";
27
+ try {
28
+ file = fs.readFileSync(filePath, "utf-8");
29
+ }
30
+ catch (err) {
31
+ throw new Error(`Failed to read file at path "${filePath}". Error: ${err.message}
32
+ File: ${pos?.fileName} Line: ${pos?.startLine} Col: ${pos?.startCol}
33
+ `);
34
+ }
35
+ const parsedRoot = parse(file, filePath);
36
+ parsedRoot.resolveIncludes(srcPath);
37
+ this.resolveIncludesRecursive(includeNode.children, srcPath);
38
+ includeNode.children = [...parsedRoot.children, ...includeNode.children];
39
+ }
40
+ else {
41
+ this.resolveIncludesRecursive(child.getChildren(), srcPath);
42
+ }
43
+ }
44
+ }
45
+ matchSlotsAndContents() {
46
+ const includeNodes = this.collectIncludes(this.children);
47
+ const slots = new Map();
48
+ const contents = new Map();
49
+ for (const iNode of includeNodes) {
50
+ slots.set(iNode.ctxId, new Map());
51
+ contents.set(iNode.ctxId, new Map());
52
+ this.collectSlotsAndContents(iNode.children, iNode.ctxId, slots, contents);
53
+ }
54
+ for (const [k, v] of contents) {
55
+ for (const [innerK, innerV] of v) {
56
+ const slot = slots.get(k)?.get(innerK);
57
+ slot?.children.push(...innerV.children);
58
+ }
59
+ }
60
+ this.unwrapSlotsAndIncludes(this.children);
61
+ }
62
+ collectIncludes(nodes) {
63
+ const includeNodes = [];
64
+ for (const node of nodes) {
65
+ if (node.type === NodeType.Include) {
66
+ includeNodes.push(node);
67
+ }
68
+ includeNodes.push(...this.collectIncludes(node.getChildren()));
69
+ }
70
+ return includeNodes;
71
+ }
72
+ collectSlotsAndContents(nodes, ctxId, slots, contents) {
73
+ for (let i = 0; i < nodes.length; i++) {
74
+ const node = nodes[i];
75
+ if (node.type === NodeType.Slot) {
76
+ slots.get(ctxId)?.set(node.name, node);
77
+ }
78
+ else if (node.type === NodeType.Content) {
79
+ contents.get(ctxId)?.set(node.name, node);
80
+ this.collectSlotsAndContents(node.getChildren(), ctxId, slots, contents);
81
+ nodes.splice(i, 1);
82
+ i--;
83
+ continue;
84
+ }
85
+ this.collectSlotsAndContents(node.getChildren(), ctxId, slots, contents);
86
+ }
87
+ }
88
+ unwrapSlotsAndIncludes(nodes) {
89
+ for (let i = 0; i < nodes.length; i++) {
90
+ const node = nodes[i];
91
+ const isUnwrap = node.type === NodeType.Include ||
92
+ node.type === NodeType.Slot;
93
+ const children = node.getChildren();
94
+ if (isUnwrap) {
95
+ this.unwrapSlotsAndIncludes(children);
96
+ nodes.splice(i, 1, ...children);
97
+ i += children.length - 1;
98
+ }
99
+ else {
100
+ this.unwrapSlotsAndIncludes(children);
101
+ }
102
+ }
103
+ }
104
+ }
105
+ export default Root;
@@ -0,0 +1,18 @@
1
+ declare enum NodeType {
2
+ Import = "import",
3
+ Doctype = "doctype",
4
+ Tempile = "tempile",
5
+ Comment = "comment",
6
+ Text = "text",
7
+ Element = "element",
8
+ If = "if",
9
+ ElseIf = "elseif",
10
+ Else = "else",
11
+ For = "for",
12
+ Include = "include",
13
+ Slot = "slot",
14
+ Content = "content",
15
+ Out = "out",
16
+ Logic = "logic"
17
+ }
18
+ export default NodeType;
@@ -0,0 +1,19 @@
1
+ var NodeType;
2
+ (function (NodeType) {
3
+ NodeType["Import"] = "import";
4
+ NodeType["Doctype"] = "doctype";
5
+ NodeType["Tempile"] = "tempile";
6
+ NodeType["Comment"] = "comment";
7
+ NodeType["Text"] = "text";
8
+ NodeType["Element"] = "element";
9
+ NodeType["If"] = "if";
10
+ NodeType["ElseIf"] = "elseif";
11
+ NodeType["Else"] = "else";
12
+ NodeType["For"] = "for";
13
+ NodeType["Include"] = "include";
14
+ NodeType["Slot"] = "slot";
15
+ NodeType["Content"] = "content";
16
+ NodeType["Out"] = "out";
17
+ NodeType["Logic"] = "logic";
18
+ })(NodeType || (NodeType = {}));
19
+ export default NodeType;
@@ -0,0 +1,4 @@
1
+ import { RawChildNode, RawCommentNode, RawElementNode, RawTextNode } from "./parse5-types.js";
2
+ export declare function isRawTextNode(node: RawChildNode): node is RawTextNode;
3
+ export declare function isRawCommentNode(node: RawChildNode): node is RawCommentNode;
4
+ export declare function isRawElementNode(node: RawChildNode): node is RawElementNode;
@@ -0,0 +1,9 @@
1
+ export function isRawTextNode(node) {
2
+ return node.nodeName === "#text";
3
+ }
4
+ export function isRawCommentNode(node) {
5
+ return node.nodeName === "#comment";
6
+ }
7
+ export function isRawElementNode(node) {
8
+ return "tagName" in node;
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { DefaultTreeAdapterTypes } from "parse5";
2
+ export type RawChildNode = DefaultTreeAdapterTypes.ChildNode;
3
+ export type RawTextNode = DefaultTreeAdapterTypes.TextNode;
4
+ export type RawCommentNode = DefaultTreeAdapterTypes.CommentNode;
5
+ export type RawElementNode = DefaultTreeAdapterTypes.Element;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import Node from "./Node.js";
2
+ import { RawChildNode } from "./parse5-types.js";
3
+ export type RawASTParserFunction = (raw: RawChildNode[], fileName: string) => Node[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Attribute } from "../html/Attribute.js";
2
+ import Node from "../base/Node.js";
3
+ import Pos from "../base/Pos.js";
4
+ import { RawChildNode } from "../base/parse5-types.js";
5
+ import { RawASTParserFunction } from "../base/parser-types.js";
6
+ declare class ElseIfNode extends Node {
7
+ conditions: Attribute[];
8
+ children: Node[];
9
+ constructor(conditions: Attribute[], children: Node[], pos: Pos);
10
+ getChildren(): Node[];
11
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node | null;
12
+ }
13
+ export default ElseIfNode;
@@ -0,0 +1,41 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ import { isRawElementNode } from "../base/parse5-type-guards.js";
4
+ import { getAtAttributes, getPos } from "../../utils/utils.js";
5
+ class ElseIfNode extends Node {
6
+ conditions;
7
+ children;
8
+ constructor(conditions, children, pos) {
9
+ super(NodeType.ElseIf, pos);
10
+ this.conditions = conditions;
11
+ this.children = children;
12
+ }
13
+ getChildren() {
14
+ return this.children;
15
+ }
16
+ static newFromRawNode(node, fileName, rawAstParserFn) {
17
+ if (!isRawElementNode(node)) {
18
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
19
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
20
+ }
21
+ if (node.tagName !== "elseif") {
22
+ throw new Error(`Expected element tag name 'elseif' but found '${node.tagName}'. ` +
23
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
24
+ }
25
+ if (!node.parentNode || node.parentNode.nodeName !== "if") {
26
+ throw new Error(`<elseif> must be a child of <if>. ` +
27
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
28
+ }
29
+ const attributes = getAtAttributes(node, fileName);
30
+ if (attributes.length < 1) {
31
+ throw new Error(`Missing @[lang] attribute on <elseif> tag. ` +
32
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
33
+ }
34
+ if (node.childNodes.length === 0)
35
+ return null;
36
+ const children = rawAstParserFn(node.childNodes, fileName);
37
+ const pos = getPos(node, fileName);
38
+ return new ElseIfNode(attributes, children, pos);
39
+ }
40
+ }
41
+ export default ElseIfNode;
@@ -0,0 +1,11 @@
1
+ import Node from "../base/Node.js";
2
+ import Pos from "../base/Pos.js";
3
+ import { RawChildNode } from "../base/parse5-types.js";
4
+ import { RawASTParserFunction } from "../base/parser-types.js";
5
+ declare class ElseNode extends Node {
6
+ children: Node[];
7
+ constructor(children: Node[], pos: Pos);
8
+ getChildren(): Node[];
9
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node | null;
10
+ }
11
+ export default ElseNode;
@@ -0,0 +1,34 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ import { isRawElementNode } from "../base/parse5-type-guards.js";
4
+ import { getPos } from "../../utils/utils.js";
5
+ class ElseNode extends Node {
6
+ children;
7
+ constructor(children, pos) {
8
+ super(NodeType.Else, pos);
9
+ this.children = children;
10
+ }
11
+ getChildren() {
12
+ return this.children;
13
+ }
14
+ static newFromRawNode(node, fileName, rawAstParserFn) {
15
+ if (!isRawElementNode(node)) {
16
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
17
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
18
+ }
19
+ if (node.tagName !== "else") {
20
+ throw new Error(`Expected element tag name 'else' but found '${node.tagName}'. ` +
21
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
22
+ }
23
+ if (!node.parentNode || node.parentNode.nodeName !== "if") {
24
+ throw new Error(`<else> must be a child of <if>. ` +
25
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
26
+ }
27
+ if (node.childNodes.length === 0)
28
+ return null;
29
+ const children = rawAstParserFn(node.childNodes, fileName);
30
+ const pos = getPos(node, fileName);
31
+ return new ElseNode(children, pos);
32
+ }
33
+ }
34
+ export default ElseNode;
@@ -0,0 +1,13 @@
1
+ import { Attribute } from "../html/Attribute.js";
2
+ import Node from "../base/Node.js";
3
+ import Pos from "../base/Pos.js";
4
+ import { RawChildNode } from "../base/parse5-types.js";
5
+ import { RawASTParserFunction } from "../base/parser-types.js";
6
+ declare class ForNode extends Node {
7
+ loops: Attribute[];
8
+ children: Node[];
9
+ constructor(loops: Attribute[], children: Node[], pos: Pos);
10
+ getChildren(): Node[];
11
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node | null;
12
+ }
13
+ export default ForNode;
@@ -0,0 +1,37 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ import { isRawElementNode } from "../base/parse5-type-guards.js";
4
+ import { getAtAttributes, getPos } from "../../utils/utils.js";
5
+ class ForNode extends Node {
6
+ loops;
7
+ children;
8
+ constructor(loops, children, pos) {
9
+ super(NodeType.For, pos);
10
+ this.loops = loops;
11
+ this.children = children;
12
+ }
13
+ getChildren() {
14
+ return this.children;
15
+ }
16
+ static newFromRawNode(node, fileName, rawAstParserFn) {
17
+ if (!isRawElementNode(node)) {
18
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
19
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
20
+ }
21
+ if (node.tagName !== "for") {
22
+ throw new Error(`Expected element tag name 'for' but found '${node.tagName}'. ` +
23
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
24
+ }
25
+ const atAttrs = getAtAttributes(node, fileName);
26
+ if (atAttrs.length < 1) {
27
+ throw new Error(`Missing @[lang] attribute on <for> tag. ` +
28
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
29
+ }
30
+ if (node.childNodes.length === 0)
31
+ return null;
32
+ const children = rawAstParserFn(node.childNodes, fileName);
33
+ const pos = getPos(node, fileName);
34
+ return new ForNode(atAttrs, children, pos);
35
+ }
36
+ }
37
+ export default ForNode;
@@ -0,0 +1,17 @@
1
+ import { Attribute } from "../html/Attribute.js";
2
+ import ElseIfNode from "./ElseIfNode.js";
3
+ import ElseNode from "./ElseNode.js";
4
+ import Node from "../base/Node.js";
5
+ import Pos from "../base/Pos.js";
6
+ import { RawChildNode } from "../base/parse5-types.js";
7
+ import { RawASTParserFunction } from "../base/parser-types.js";
8
+ declare class IfNode extends Node {
9
+ conditions: Attribute[];
10
+ ifContent: Node[];
11
+ elseIfNodes: ElseIfNode[];
12
+ elseNode?: ElseNode;
13
+ constructor(conditions: Attribute[], ifContent: Node[], pos: Pos, elseIfNodes?: ElseIfNode[], elseNode?: ElseNode);
14
+ getChildren(): Node[];
15
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node | null;
16
+ }
17
+ export default IfNode;
@@ -0,0 +1,64 @@
1
+ import ElseIfNode from "./ElseIfNode.js";
2
+ import ElseNode from "./ElseNode.js";
3
+ import Node from "../base/Node.js";
4
+ import NodeType from "../base/node-types.js";
5
+ import { isRawElementNode } from "../base/parse5-type-guards.js";
6
+ import { getAtAttributes, getPos } from "../../utils/utils.js";
7
+ class IfNode extends Node {
8
+ conditions;
9
+ ifContent;
10
+ elseIfNodes;
11
+ elseNode;
12
+ constructor(conditions, ifContent, pos, elseIfNodes = [], elseNode) {
13
+ super(NodeType.If, pos);
14
+ this.conditions = conditions;
15
+ this.ifContent = ifContent;
16
+ this.elseIfNodes = elseIfNodes;
17
+ this.elseNode = elseNode;
18
+ }
19
+ getChildren() {
20
+ return this.ifContent;
21
+ }
22
+ static newFromRawNode(node, fileName, rawAstParserFn) {
23
+ if (!isRawElementNode(node)) {
24
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
25
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
26
+ }
27
+ if (node.tagName !== "if") {
28
+ throw new Error(`Expected element tag name 'if' but found '${node.tagName}'. ` +
29
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
30
+ }
31
+ const attributes = getAtAttributes(node, fileName);
32
+ if (attributes.length < 1) {
33
+ throw new Error(`Missing @[lang] attribute on <if> tag. ` +
34
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
35
+ }
36
+ const thenChildren = [];
37
+ const elseIfChildren = [];
38
+ let elseNode;
39
+ const children = rawAstParserFn(node.childNodes, fileName);
40
+ for (const child of children) {
41
+ if (child instanceof ElseIfNode) {
42
+ elseIfChildren.push(child);
43
+ }
44
+ else if (child instanceof ElseNode) {
45
+ if (!elseNode) {
46
+ elseNode = child;
47
+ }
48
+ else {
49
+ throw new Error(`Multiple <else> blocks are not allowed. ` +
50
+ `File: ${fileName}, Line: ${child.pos?.startLine}, Col: ${child.pos?.startCol}`);
51
+ }
52
+ }
53
+ else {
54
+ thenChildren.push(child);
55
+ }
56
+ }
57
+ if (thenChildren.length === 0) {
58
+ return null;
59
+ }
60
+ const pos = getPos(node, fileName);
61
+ return new IfNode(attributes, thenChildren, pos, elseIfChildren, elseNode);
62
+ }
63
+ }
64
+ export default IfNode;
@@ -0,0 +1 @@
1
+ export default OutNode;
@@ -0,0 +1,13 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ class AttrExprNode extends Node {
4
+ data;
5
+ constructor(data, pos) {
6
+ super(NodeType.Out, pos);
7
+ this.data = data;
8
+ }
9
+ getChildren() {
10
+ return [];
11
+ }
12
+ }
13
+ export default OutNode;
@@ -0,0 +1,12 @@
1
+ import Node from "../base/Node.js";
2
+ import Pos from "../base/Pos.js";
3
+ import { RawChildNode } from "../base/parse5-types.js";
4
+ import { RawASTParserFunction } from "../base/parser-types.js";
5
+ declare class ContentNode extends Node {
6
+ name: string;
7
+ children: Node[];
8
+ constructor(name: string, children: Node[], pos: Pos);
9
+ getChildren(): Node[];
10
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node;
11
+ }
12
+ export default ContentNode;
@@ -0,0 +1,44 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ import { getAtAttributes, getPos } from "../../utils/utils.js";
4
+ import { isRawElementNode } from "../base/parse5-type-guards.js";
5
+ class ContentNode extends Node {
6
+ name;
7
+ children;
8
+ constructor(name, children, pos) {
9
+ super(NodeType.Content, pos);
10
+ this.name = name;
11
+ this.children = children;
12
+ }
13
+ getChildren() {
14
+ return this.children;
15
+ }
16
+ static newFromRawNode(node, fileName, rawAstParserFn) {
17
+ if (!isRawElementNode(node)) {
18
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
19
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
20
+ }
21
+ if (node.tagName !== "content") {
22
+ throw new Error(`Expected element tag name 'content' but found '${node.tagName}'. ` +
23
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
24
+ }
25
+ const parentNode = node.parentNode;
26
+ if (!node.parentNode || !parentNode.tagName || parentNode.tagName !== "include") {
27
+ throw new Error(`<content> element can only appear inside an <include> element. ` +
28
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
29
+ }
30
+ const atAttrs = getAtAttributes(node, fileName);
31
+ if (atAttrs.length < 1) {
32
+ throw new Error(`Missing @[name] attribute on <content> tag. ` +
33
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
34
+ }
35
+ else if (atAttrs.length > 1) {
36
+ throw new Error(`Multiple @ attributes on <content> tag are not allowed: found [${atAttrs.map(a => a.name).join(", ")}]. ` +
37
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
38
+ }
39
+ const children = rawAstParserFn(node.childNodes, fileName);
40
+ const pos = getPos(node, fileName);
41
+ return new ContentNode(atAttrs[0].value, children, pos);
42
+ }
43
+ }
44
+ export default ContentNode;
@@ -0,0 +1,12 @@
1
+ import Node from "../base/Node.js";
2
+ import Pos from "../base/Pos.js";
3
+ import { RawChildNode } from "../base/parse5-types.js";
4
+ import { RawASTParserFunction } from "../base/parser-types.js";
5
+ declare class ImportNode extends Node {
6
+ lang: string;
7
+ data: Node[];
8
+ constructor(lang: string, data: Node[], pos: Pos);
9
+ getChildren(): Node[];
10
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node;
11
+ }
12
+ export default ImportNode;
@@ -0,0 +1,51 @@
1
+ import Node from "../base/Node.js";
2
+ import NodeType from "../base/node-types.js";
3
+ import { isRawCommentNode, isRawElementNode, isRawTextNode } from "../base/parse5-type-guards.js";
4
+ import { getAtAttributes, getPos } from "../../utils/utils.js";
5
+ class ImportNode extends Node {
6
+ lang;
7
+ data;
8
+ constructor(lang, data, pos) {
9
+ super(NodeType.Import, pos);
10
+ this.lang = lang;
11
+ this.data = data;
12
+ }
13
+ getChildren() {
14
+ return this.data;
15
+ }
16
+ static newFromRawNode(node, fileName, rawAstParserFn) {
17
+ if (!isRawElementNode(node)) {
18
+ throw new Error(`Expected an element node but found '${node.nodeName}'. ` +
19
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
20
+ }
21
+ if (node.tagName !== "import") {
22
+ throw new Error(`Expected element tag name 'import' but found '${node.tagName}'. ` +
23
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine}, Col: ${node.sourceCodeLocation?.startCol}`);
24
+ }
25
+ if (node.parentNode && node.parentNode.nodeName !== "#document-fragment") {
26
+ throw new Error(`<import> node cannot be a child of another element. ` +
27
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
28
+ }
29
+ if (node.childNodes.length > 0) {
30
+ for (const n of node.childNodes) {
31
+ if (!isRawTextNode(n) && !isRawCommentNode(n)) {
32
+ throw new Error(`Invalid child node inside <import>: found '${n.nodeName}' but only text or comment nodes are allowed. ` +
33
+ `File: ${fileName}, Line: ${n.sourceCodeLocation?.startLine ?? "?"}, Col: ${n.sourceCodeLocation?.startCol ?? "?"}`);
34
+ }
35
+ }
36
+ }
37
+ const attributes = getAtAttributes(node, fileName);
38
+ if (attributes.length === 0) {
39
+ throw new Error(`Missing @[lang] attribute on <import> tag. ` +
40
+ `File: ${fileName}, Line: ${node.sourceCodeLocation?.startLine ?? "?"}, Col: ${node.sourceCodeLocation?.startCol ?? "?"}`);
41
+ }
42
+ if (attributes.length > 1) {
43
+ throw new Error(`Multiple @ attributes on <import> tag are not allowed: found [${attributes.map(a => a.name).join(", ")}]. ` +
44
+ `File: ${fileName}, line ${node.sourceCodeLocation?.startLine ?? "?"}, col ${node.sourceCodeLocation?.startCol ?? "?"}`);
45
+ }
46
+ const childNodes = rawAstParserFn(node.childNodes, fileName);
47
+ const pos = getPos(node, fileName);
48
+ return new ImportNode(attributes[0].name, childNodes, pos);
49
+ }
50
+ }
51
+ export default ImportNode;
@@ -0,0 +1,14 @@
1
+ import Node from "../base/Node.js";
2
+ import Pos from "../base/Pos.js";
3
+ import { RawChildNode } from "../base/parse5-types.js";
4
+ import { RawASTParserFunction } from "../base/parser-types.js";
5
+ import { Attribute } from "../html/Attribute.js";
6
+ declare class IncludeNode extends Node {
7
+ ctxId: string;
8
+ path: Attribute;
9
+ children: Node[];
10
+ constructor(ctxId: string, path: Attribute, children: Node[], pos: Pos);
11
+ getChildren(): Node[];
12
+ static newFromRawNode(node: RawChildNode, fileName: string, rawAstParserFn: RawASTParserFunction): Node;
13
+ }
14
+ export default IncludeNode;