illimi-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.
- package/LICENSE +21 -0
- package/README.md +135 -0
- package/dist/ast/nodes.d.ts +91 -0
- package/dist/ast/nodes.d.ts.map +1 -0
- package/dist/ast/nodes.js +8 -0
- package/dist/ast/nodes.js.map +1 -0
- package/dist/compiler/mergeSlots.d.ts +31 -0
- package/dist/compiler/mergeSlots.d.ts.map +1 -0
- package/dist/compiler/mergeSlots.js +85 -0
- package/dist/compiler/mergeSlots.js.map +1 -0
- package/dist/compiler/resolveLayout.d.ts +22 -0
- package/dist/compiler/resolveLayout.d.ts.map +1 -0
- package/dist/compiler/resolveLayout.js +212 -0
- package/dist/compiler/resolveLayout.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/transform.d.ts +50 -0
- package/dist/ir/transform.d.ts.map +1 -0
- package/dist/ir/transform.js +128 -0
- package/dist/ir/transform.js.map +1 -0
- package/dist/parser/directiveParser.d.ts +34 -0
- package/dist/parser/directiveParser.d.ts.map +1 -0
- package/dist/parser/directiveParser.js +131 -0
- package/dist/parser/directiveParser.js.map +1 -0
- package/dist/parser/htmlParser.d.ts +13 -0
- package/dist/parser/htmlParser.d.ts.map +1 -0
- package/dist/parser/htmlParser.js +350 -0
- package/dist/parser/htmlParser.js.map +1 -0
- package/dist/vdom/diff.d.ts +33 -0
- package/dist/vdom/diff.d.ts.map +1 -0
- package/dist/vdom/diff.js +259 -0
- package/dist/vdom/diff.js.map +1 -0
- package/dist/vdom/vnode.d.ts +52 -0
- package/dist/vdom/vnode.d.ts.map +1 -0
- package/dist/vdom/vnode.js +206 -0
- package/dist/vdom/vnode.js.map +1 -0
- package/package.json +38 -0
- package/tsconfig.base.json +28 -0
- package/tsconfig.json +8 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// FeedJS Core - Main Entry Point
|
|
2
|
+
// Re-export all public APIs
|
|
3
|
+
// Re-export parser
|
|
4
|
+
export { parseTemplate } from './parser/htmlParser.js';
|
|
5
|
+
// Re-export IR
|
|
6
|
+
export { transformAST, } from './ir/transform.js';
|
|
7
|
+
// Re-export VDOM
|
|
8
|
+
export { createVDOM, FragmentSymbol, TextSymbol, isTextVNode, isFragment, getVNodeType, } from './vdom/vnode.js';
|
|
9
|
+
// Re-export diff types and functions
|
|
10
|
+
export { diff, applyPatches } from './vdom/diff.js';
|
|
11
|
+
// Re-export compiler utilities
|
|
12
|
+
export { resolveLayout, CompileError } from './compiler/resolveLayout.js';
|
|
13
|
+
export { mergeSlots, extractSlots } from './compiler/mergeSlots.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,4BAA4B;AAE5B,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAkBvD,eAAe;AACf,OAAO,EACL,YAAY,GAKb,MAAM,mBAAmB,CAAC;AAE3B,iBAAiB;AACjB,OAAO,EACL,UAAU,EACV,cAAc,EACd,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,GAMb,MAAM,iBAAiB,CAAC;AAEzB,qCAAqC;AACrC,OAAO,EAAE,IAAI,EAAE,YAAY,EAA8C,MAAM,gBAAgB,CAAC;AAEhG,+BAA+B;AAC/B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FeedJS Core - IR Transformer
|
|
3
|
+
*
|
|
4
|
+
* Transforms the Feed AST into an Intermediate Representation (IR).
|
|
5
|
+
* IR is a normalized, explicit representation without raw strings or HTML parsing logic.
|
|
6
|
+
*/
|
|
7
|
+
import type { FeedAST } from '../ast/nodes.js';
|
|
8
|
+
export type IRNodeKind = 'element' | 'text' | 'fragment';
|
|
9
|
+
export interface IRProps {
|
|
10
|
+
[key: string]: IRPropValue;
|
|
11
|
+
}
|
|
12
|
+
export type IRPropValue = string | number | boolean | undefined;
|
|
13
|
+
export interface IRNode {
|
|
14
|
+
kind: IRNodeKind;
|
|
15
|
+
tag?: string;
|
|
16
|
+
props?: IRProps;
|
|
17
|
+
children?: IRNode[];
|
|
18
|
+
key?: string;
|
|
19
|
+
directives?: IRDirective[];
|
|
20
|
+
value?: string;
|
|
21
|
+
interpolation?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface IRDirective {
|
|
24
|
+
type: string;
|
|
25
|
+
name: string;
|
|
26
|
+
value: string;
|
|
27
|
+
expression: string;
|
|
28
|
+
modifiers: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface IRConditionalBranch {
|
|
31
|
+
condition: string | null;
|
|
32
|
+
nodes: IRNode[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Transform Feed AST to IR
|
|
36
|
+
*/
|
|
37
|
+
export declare function transformAST(ast: FeedAST): IRNode[];
|
|
38
|
+
/**
|
|
39
|
+
* Check if an IR node has conditional directives
|
|
40
|
+
*/
|
|
41
|
+
export declare function hasConditionals(node: IRNode): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Check if an IR node has a for loop
|
|
44
|
+
*/
|
|
45
|
+
export declare function hasForLoop(node: IRNode): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Get key from IR node
|
|
48
|
+
*/
|
|
49
|
+
export declare function getKey(node: IRNode): string | number | undefined;
|
|
50
|
+
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/ir/transform.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,OAAO,EAMR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAGzD,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAGhE,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAEnD;AA2GD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhE"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FeedJS Core - IR Transformer
|
|
3
|
+
*
|
|
4
|
+
* Transforms the Feed AST into an Intermediate Representation (IR).
|
|
5
|
+
* IR is a normalized, explicit representation without raw strings or HTML parsing logic.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Transform Feed AST to IR
|
|
9
|
+
*/
|
|
10
|
+
export function transformAST(ast) {
|
|
11
|
+
return ast.nodes.map(transformNode);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Transform a single AST node to IR
|
|
15
|
+
*/
|
|
16
|
+
function transformNode(node) {
|
|
17
|
+
switch (node.type) {
|
|
18
|
+
case 'Element':
|
|
19
|
+
return transformElement(node);
|
|
20
|
+
case 'Text':
|
|
21
|
+
return transformText(node);
|
|
22
|
+
case 'Comment':
|
|
23
|
+
// Comments are not rendered in IR - skip them
|
|
24
|
+
return {
|
|
25
|
+
kind: 'text',
|
|
26
|
+
value: '',
|
|
27
|
+
};
|
|
28
|
+
case 'Fragment':
|
|
29
|
+
return transformFragment(node);
|
|
30
|
+
default:
|
|
31
|
+
// Default to text node
|
|
32
|
+
return {
|
|
33
|
+
kind: 'text',
|
|
34
|
+
value: '',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Transform element node
|
|
40
|
+
*/
|
|
41
|
+
function transformElement(node) {
|
|
42
|
+
const props = {};
|
|
43
|
+
// Transform static attributes
|
|
44
|
+
for (const [key, value] of Object.entries(node.attributes)) {
|
|
45
|
+
props[key] = value;
|
|
46
|
+
}
|
|
47
|
+
// Extract and transform directives
|
|
48
|
+
const directives = [];
|
|
49
|
+
let key = '';
|
|
50
|
+
for (const directive of node.directives) {
|
|
51
|
+
const irDirective = transformDirective(directive);
|
|
52
|
+
directives.push(irDirective);
|
|
53
|
+
// Extract key
|
|
54
|
+
if (directive.type === 'key' && directive.expression) {
|
|
55
|
+
key = directive.expression;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const children = node.children.map(transformNode);
|
|
59
|
+
return {
|
|
60
|
+
kind: 'element',
|
|
61
|
+
tag: node.tag,
|
|
62
|
+
props,
|
|
63
|
+
children,
|
|
64
|
+
key,
|
|
65
|
+
directives,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Transform directive to IR format
|
|
70
|
+
*/
|
|
71
|
+
function transformDirective(directive) {
|
|
72
|
+
return {
|
|
73
|
+
type: directive.type,
|
|
74
|
+
name: directive.name,
|
|
75
|
+
value: directive.value,
|
|
76
|
+
expression: directive.expression ?? '',
|
|
77
|
+
modifiers: directive.modifiers ?? [],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Transform text node
|
|
82
|
+
*/
|
|
83
|
+
function transformText(node) {
|
|
84
|
+
// Check if this is an interpolation
|
|
85
|
+
if (node.interpolation) {
|
|
86
|
+
return {
|
|
87
|
+
kind: 'text',
|
|
88
|
+
value: '',
|
|
89
|
+
interpolation: node.interpolation,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
kind: 'text',
|
|
94
|
+
value: node.value,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Transform fragment node
|
|
99
|
+
*/
|
|
100
|
+
function transformFragment(node) {
|
|
101
|
+
return {
|
|
102
|
+
kind: 'fragment',
|
|
103
|
+
children: node.children.map(transformNode),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check if an IR node has conditional directives
|
|
108
|
+
*/
|
|
109
|
+
export function hasConditionals(node) {
|
|
110
|
+
if (!node.directives)
|
|
111
|
+
return false;
|
|
112
|
+
return node.directives.some(d => d.type === 'if' || d.type === 'else-if' || d.type === 'else');
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if an IR node has a for loop
|
|
116
|
+
*/
|
|
117
|
+
export function hasForLoop(node) {
|
|
118
|
+
if (!node.directives)
|
|
119
|
+
return false;
|
|
120
|
+
return node.directives.some(d => d.type === 'for' || d.type === 'items');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get key from IR node
|
|
124
|
+
*/
|
|
125
|
+
export function getKey(node) {
|
|
126
|
+
return node.key;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/ir/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Illimi Core - Directive Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses and normalizes directives from HTML attributes.
|
|
5
|
+
* Preferred prefix: x- (f- accepted for backward compatibility).
|
|
6
|
+
*/
|
|
7
|
+
import type { FeedDirective, ForLoopData } from '../ast/nodes.js';
|
|
8
|
+
/**
|
|
9
|
+
* Check if an attribute name is a framework directive.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isDirective(attrName: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Parse a directive attribute name and value into a normalized directive.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseDirective(attrName: string, attrValue: string): FeedDirective;
|
|
16
|
+
/**
|
|
17
|
+
* Parse for loop expression.
|
|
18
|
+
*
|
|
19
|
+
* Format: "item in items" or "(item, index) in items"
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseForLoop(expression: string): ForLoopData;
|
|
22
|
+
/**
|
|
23
|
+
* Parse if/else-if/else expression.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseIfExpression(expression: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Check if an element has conditional rendering directives.
|
|
28
|
+
*/
|
|
29
|
+
export declare function hasConditionalDirectives(directives: FeedDirective[]): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Check if an element has list rendering directives.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hasListDirectives(directives: FeedDirective[]): boolean;
|
|
34
|
+
//# sourceMappingURL=directiveParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directiveParser.d.ts","sourceRoot":"","sources":["../../src/parser/directiveParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,EAEb,WAAW,EAQZ,MAAM,iBAAiB,CAAC;AAKzB;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CAajF;AAmED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAkB5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO,CAE7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO,CAEtE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Illimi Core - Directive Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses and normalizes directives from HTML attributes.
|
|
5
|
+
* Preferred prefix: x- (f- accepted for backward compatibility).
|
|
6
|
+
*/
|
|
7
|
+
const DIRECTIVE_PREFIXES = ['x-', 'f-'];
|
|
8
|
+
const DEFAULT_PREFIX = 'x-';
|
|
9
|
+
/**
|
|
10
|
+
* Check if an attribute name is a framework directive.
|
|
11
|
+
*/
|
|
12
|
+
export function isDirective(attrName) {
|
|
13
|
+
return DIRECTIVE_PREFIXES.some((prefix) => attrName.startsWith(prefix));
|
|
14
|
+
}
|
|
15
|
+
function getPrefix(attrName) {
|
|
16
|
+
return DIRECTIVE_PREFIXES.find((prefix) => attrName.startsWith(prefix)) || DEFAULT_PREFIX;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a directive attribute name and value into a normalized directive.
|
|
20
|
+
*/
|
|
21
|
+
export function parseDirective(attrName, attrValue) {
|
|
22
|
+
const prefix = getPrefix(attrName);
|
|
23
|
+
const nameWithoutPrefix = attrName.slice(prefix.length);
|
|
24
|
+
if (nameWithoutPrefix.startsWith('bind:')) {
|
|
25
|
+
return parseBindDirective(nameWithoutPrefix, attrValue, prefix);
|
|
26
|
+
}
|
|
27
|
+
if (nameWithoutPrefix.startsWith('on:')) {
|
|
28
|
+
return parseEventDirective(nameWithoutPrefix, attrValue, prefix);
|
|
29
|
+
}
|
|
30
|
+
return parseSimpleDirective(nameWithoutPrefix, attrValue, prefix);
|
|
31
|
+
}
|
|
32
|
+
function parseSimpleDirective(name, value, prefix) {
|
|
33
|
+
const type = getDirectiveType(name);
|
|
34
|
+
return {
|
|
35
|
+
type,
|
|
36
|
+
name: `${prefix}${name}`,
|
|
37
|
+
value,
|
|
38
|
+
expression: value,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function parseBindDirective(name, value, prefix) {
|
|
42
|
+
return {
|
|
43
|
+
type: 'bind',
|
|
44
|
+
name: `${prefix}${name}`,
|
|
45
|
+
value,
|
|
46
|
+
expression: value,
|
|
47
|
+
modifiers: [],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function parseEventDirective(name, value, prefix) {
|
|
51
|
+
const event = name.slice(3); // remove on:
|
|
52
|
+
const parts = event.split('.');
|
|
53
|
+
const eventName = parts[0] || '';
|
|
54
|
+
const modifiers = parts.slice(1);
|
|
55
|
+
return {
|
|
56
|
+
type: 'on',
|
|
57
|
+
name: `${prefix}on:${eventName}`,
|
|
58
|
+
value,
|
|
59
|
+
expression: value,
|
|
60
|
+
modifiers,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function getDirectiveType(name) {
|
|
64
|
+
switch (name) {
|
|
65
|
+
case 'if':
|
|
66
|
+
return 'if';
|
|
67
|
+
case 'else-if':
|
|
68
|
+
return 'else-if';
|
|
69
|
+
case 'else':
|
|
70
|
+
return 'else';
|
|
71
|
+
case 'for':
|
|
72
|
+
return 'for';
|
|
73
|
+
case 'items':
|
|
74
|
+
return 'items';
|
|
75
|
+
case 'key':
|
|
76
|
+
return 'key';
|
|
77
|
+
case 'text':
|
|
78
|
+
return 'text';
|
|
79
|
+
case 'html':
|
|
80
|
+
return 'html';
|
|
81
|
+
case 'show':
|
|
82
|
+
return 'show';
|
|
83
|
+
case 'model':
|
|
84
|
+
return 'model';
|
|
85
|
+
default:
|
|
86
|
+
if (name.startsWith('bind:'))
|
|
87
|
+
return 'bind';
|
|
88
|
+
if (name.startsWith('on:'))
|
|
89
|
+
return 'on';
|
|
90
|
+
throw new Error(`Unknown directive: ${name}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Parse for loop expression.
|
|
95
|
+
*
|
|
96
|
+
* Format: "item in items" or "(item, index) in items"
|
|
97
|
+
*/
|
|
98
|
+
export function parseForLoop(expression) {
|
|
99
|
+
const match = expression.match(/^\s*(?:(\w+),\s*)?(\w+)\s+in\s+(\S+)\s*$/);
|
|
100
|
+
if (!match) {
|
|
101
|
+
throw new Error(`Invalid for loop expression: ${expression}`);
|
|
102
|
+
}
|
|
103
|
+
const [, indexName, item, collection] = match;
|
|
104
|
+
if (!item || !collection) {
|
|
105
|
+
throw new Error(`Invalid for loop expression: ${expression}`);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
item,
|
|
109
|
+
index: indexName ?? '',
|
|
110
|
+
collection,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Parse if/else-if/else expression.
|
|
115
|
+
*/
|
|
116
|
+
export function parseIfExpression(expression) {
|
|
117
|
+
return expression.trim();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if an element has conditional rendering directives.
|
|
121
|
+
*/
|
|
122
|
+
export function hasConditionalDirectives(directives) {
|
|
123
|
+
return directives.some((d) => d.type === 'if' || d.type === 'else-if' || d.type === 'else');
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if an element has list rendering directives.
|
|
127
|
+
*/
|
|
128
|
+
export function hasListDirectives(directives) {
|
|
129
|
+
return directives.some((d) => d.type === 'for' || d.type === 'items');
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=directiveParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directiveParser.js","sourceRoot":"","sources":["../../src/parser/directiveParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FeedJS Core - HTML Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses HTML templates into Feed AST nodes.
|
|
5
|
+
* Handles standard HTML elements, text, comments, slots, and template blocks.
|
|
6
|
+
* Supports {{ expression }} interpolation syntax.
|
|
7
|
+
*/
|
|
8
|
+
import type { FeedAST } from '../ast/nodes.js';
|
|
9
|
+
/**
|
|
10
|
+
* Parse HTML template string into Feed AST
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseTemplate(html: string): FeedAST;
|
|
13
|
+
//# sourceMappingURL=htmlParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"htmlParser.d.ts","sourceRoot":"","sources":["../../src/parser/htmlParser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,OAAO,EASR,MAAM,iBAAiB,CAAC;AAyBzB;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUnD"}
|