@reidelsaltres/pureper 0.1.113 → 0.1.115
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/out/foundation/HMLEParser.d.ts +87 -0
- package/out/foundation/HMLEParser.d.ts.map +1 -0
- package/out/foundation/HMLEParser.js +430 -0
- package/out/foundation/HMLEParser.js.map +1 -0
- package/out/foundation/PHTMLParser.d.ts +1 -0
- package/out/foundation/PHTMLParser.d.ts.map +1 -1
- package/out/foundation/PHTMLParser.js +22 -3
- package/out/foundation/PHTMLParser.js.map +1 -1
- package/out/index.d.ts +2 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +2 -0
- package/out/index.js.map +1 -1
- package/package.json +1 -1
- package/src/foundation/HMLEParser.ts +485 -0
- package/src/foundation/PHTMLParser.ts +23 -3
- package/src/index.ts +2 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMLEParser - HTML Markup Language Extensions Parser
|
|
3
|
+
*
|
|
4
|
+
* Two-stage parsing:
|
|
5
|
+
* Stage 1: String processing - @for loops, @(expression) interpolations
|
|
6
|
+
* Stage 2: DOM processing - @[event](handler) bindings, attribute directives
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const parser = new HMLEParser();
|
|
10
|
+
* parser.addVariable('items', [{name: 'Item 1'}, {name: 'Item 2'}]);
|
|
11
|
+
* const fragment = parser.parseToDOM(templateString, scopeObject);
|
|
12
|
+
*/
|
|
13
|
+
export default class HMLEParser {
|
|
14
|
+
private static extractBalancedBraces;
|
|
15
|
+
private static extractBalancedParens;
|
|
16
|
+
private static rules;
|
|
17
|
+
private static domRules;
|
|
18
|
+
variables: Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* Add a variable to the parser's global scope
|
|
21
|
+
*/
|
|
22
|
+
addVariable(name: string, value: unknown): this;
|
|
23
|
+
/**
|
|
24
|
+
* Build execution context that includes prototype methods from scope
|
|
25
|
+
*/
|
|
26
|
+
private buildContext;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a dotted expression against the parser variables and optional local scope.
|
|
29
|
+
*/
|
|
30
|
+
resolveExpression(expr: string, scope?: Record<string, any>): any;
|
|
31
|
+
/**
|
|
32
|
+
* Convert value to string for text content
|
|
33
|
+
*/
|
|
34
|
+
private stringifyValue;
|
|
35
|
+
/**
|
|
36
|
+
* Evaluate a JavaScript expression in a given context
|
|
37
|
+
*/
|
|
38
|
+
private evaluateInContext;
|
|
39
|
+
/**
|
|
40
|
+
* Parse HMLE template string and return processed HTML string
|
|
41
|
+
* @param content HMLE template string
|
|
42
|
+
* @param scope Optional scope object (can be a class instance)
|
|
43
|
+
* @returns Processed HTML string
|
|
44
|
+
*/
|
|
45
|
+
parse(content: string, scope?: Record<string, any>): string;
|
|
46
|
+
/**
|
|
47
|
+
* Stage 2: Process DOM rules on a fragment
|
|
48
|
+
* Walks all elements and applies DOM rules based on attributes
|
|
49
|
+
*/
|
|
50
|
+
private processDOMRules;
|
|
51
|
+
/**
|
|
52
|
+
* Parse HMLE template and create DOM elements (Stage 1 + Stage 2)
|
|
53
|
+
* @param content HMLE template string
|
|
54
|
+
* @param scope Optional scope object
|
|
55
|
+
* @returns DocumentFragment containing parsed HTML with bindings applied
|
|
56
|
+
*/
|
|
57
|
+
parseToDOM(content: string, scope?: Record<string, any>): DocumentFragment;
|
|
58
|
+
/**
|
|
59
|
+
* Parse HMLE template and return single element (first child)
|
|
60
|
+
* @param content HMLE template string
|
|
61
|
+
* @param scope Optional scope object
|
|
62
|
+
* @returns First element from parsed HTML, or null
|
|
63
|
+
*/
|
|
64
|
+
parseToElement<T extends Element = Element>(content: string, scope?: Record<string, any>): T | null;
|
|
65
|
+
/**
|
|
66
|
+
* Parse and append to a parent element
|
|
67
|
+
* @param content HMLE template string
|
|
68
|
+
* @param parent Parent element to append to
|
|
69
|
+
* @param scope Optional scope object
|
|
70
|
+
* @returns The parent element
|
|
71
|
+
*/
|
|
72
|
+
parseAndAppend(content: string, parent: Element, scope?: Record<string, any>): Element;
|
|
73
|
+
/**
|
|
74
|
+
* Parse and replace element's innerHTML
|
|
75
|
+
* @param content HMLE template string
|
|
76
|
+
* @param element Element to update
|
|
77
|
+
* @param scope Optional scope object
|
|
78
|
+
* @returns The updated element
|
|
79
|
+
*/
|
|
80
|
+
parseAndReplace(content: string, element: Element, scope?: Record<string, any>): Element;
|
|
81
|
+
/**
|
|
82
|
+
* Apply DOM rules to an existing element (Stage 2 only)
|
|
83
|
+
* Useful when you already have DOM and just want to process bindings
|
|
84
|
+
*/
|
|
85
|
+
applyBindings(element: Element, scope?: Record<string, any>): Element;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=HMLEParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HMLEParser.d.ts","sourceRoot":"","sources":["../../src/foundation/HMLEParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8BH,MAAM,CAAC,OAAO,OAAO,UAAU;IAE3B,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAcpC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAcpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAkFlB;IAGF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAuHrB;IAEK,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAE/C;;OAEG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAKtD;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;IACI,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;IAWxE;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;OAKG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAqClE;;;OAGG;IACH,OAAO,CAAC,eAAe;IAuBvB;;;;;OAKG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB;IAajF;;;;;OAKG;IACI,cAAc,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI;IAK1G;;;;;;OAMG;IACI,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAM7F;;;;;;OAMG;IACI,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAO/F;;;OAGG;IACI,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;CAI/E"}
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMLEParser - HTML Markup Language Extensions Parser
|
|
3
|
+
*
|
|
4
|
+
* Two-stage parsing:
|
|
5
|
+
* Stage 1: String processing - @for loops, @(expression) interpolations
|
|
6
|
+
* Stage 2: DOM processing - @[event](handler) bindings, attribute directives
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const parser = new HMLEParser();
|
|
10
|
+
* parser.addVariable('items', [{name: 'Item 1'}, {name: 'Item 2'}]);
|
|
11
|
+
* const fragment = parser.parseToDOM(templateString, scopeObject);
|
|
12
|
+
*/
|
|
13
|
+
// Stage 1: String-based rules
|
|
14
|
+
class HMLEParserRule {
|
|
15
|
+
pattern;
|
|
16
|
+
replacer;
|
|
17
|
+
constructor(pattern, replacer) {
|
|
18
|
+
this.pattern = pattern;
|
|
19
|
+
this.replacer = replacer;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Stage 2: DOM-based rules for attribute processing
|
|
23
|
+
class HMLEDOMRule {
|
|
24
|
+
attrPattern;
|
|
25
|
+
processor;
|
|
26
|
+
constructor(attrPattern, processor) {
|
|
27
|
+
this.attrPattern = attrPattern;
|
|
28
|
+
this.processor = processor;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export default class HMLEParser {
|
|
32
|
+
// Extract balanced braces { ... }
|
|
33
|
+
static extractBalancedBraces(content, start) {
|
|
34
|
+
if (content[start] !== '{')
|
|
35
|
+
return null;
|
|
36
|
+
let depth = 1;
|
|
37
|
+
let i = start + 1;
|
|
38
|
+
while (i < content.length && depth > 0) {
|
|
39
|
+
if (content[i] === '{')
|
|
40
|
+
depth++;
|
|
41
|
+
else if (content[i] === '}')
|
|
42
|
+
depth--;
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
if (depth !== 0)
|
|
46
|
+
return null;
|
|
47
|
+
return { block: content.slice(start + 1, i - 1), end: i };
|
|
48
|
+
}
|
|
49
|
+
// Extract balanced parentheses ( ... )
|
|
50
|
+
static extractBalancedParens(content, start) {
|
|
51
|
+
if (content[start] !== '(')
|
|
52
|
+
return null;
|
|
53
|
+
let depth = 1;
|
|
54
|
+
let i = start + 1;
|
|
55
|
+
while (i < content.length && depth > 0) {
|
|
56
|
+
if (content[i] === '(')
|
|
57
|
+
depth++;
|
|
58
|
+
else if (content[i] === ')')
|
|
59
|
+
depth--;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
if (depth !== 0)
|
|
63
|
+
return null;
|
|
64
|
+
return { block: content.slice(start + 1, i - 1), end: i };
|
|
65
|
+
}
|
|
66
|
+
// Predefined rules processed in order
|
|
67
|
+
static rules = [
|
|
68
|
+
// Rule: @for (item in items) { ... }
|
|
69
|
+
new HMLEParserRule(/@for\s*\(\s*([A-Za-z_$][A-Za-z0-9_$]*)\s+in\s+([A-Za-z_$][A-Za-z0-9_$.]*)\s*\)\s*\{/g, (parser, match, input, scope) => {
|
|
70
|
+
const iterVar = match[1];
|
|
71
|
+
const iterableExpr = match[2];
|
|
72
|
+
const blockStart = match.index + match[0].length - 1; // position of '{'
|
|
73
|
+
const extracted = HMLEParser.extractBalancedBraces(input, blockStart);
|
|
74
|
+
if (!extracted)
|
|
75
|
+
return match[0];
|
|
76
|
+
const inner = extracted.block;
|
|
77
|
+
const resolved = parser.resolveExpression(iterableExpr, scope);
|
|
78
|
+
const arr = Array.isArray(resolved) ? resolved : [];
|
|
79
|
+
const parts = [];
|
|
80
|
+
for (const item of arr) {
|
|
81
|
+
const fullScope = Object.assign({}, scope, { [iterVar]: item });
|
|
82
|
+
parts.push(parser.parse(inner, fullScope));
|
|
83
|
+
}
|
|
84
|
+
return { text: parts.join('\n'), end: extracted.end };
|
|
85
|
+
}),
|
|
86
|
+
// Rule: @(( code )) — double-paren for complex expressions
|
|
87
|
+
new HMLEParserRule(/@\(\(/g, (parser, match, input, scope) => {
|
|
88
|
+
const blockStart = match.index + match[0].length - 1; // points at inner '('
|
|
89
|
+
const extracted = HMLEParser.extractBalancedParens(input, blockStart);
|
|
90
|
+
if (!extracted)
|
|
91
|
+
return match[0];
|
|
92
|
+
const code = extracted.block;
|
|
93
|
+
const ctx = parser.buildContext(scope);
|
|
94
|
+
let result;
|
|
95
|
+
try {
|
|
96
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
97
|
+
result = fn.call(ctx);
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
try {
|
|
101
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
102
|
+
result = fn2.call(ctx);
|
|
103
|
+
}
|
|
104
|
+
catch (e2) {
|
|
105
|
+
return { text: '', end: extracted.end };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Skip outer ')' if present
|
|
109
|
+
let finalEnd = extracted.end;
|
|
110
|
+
if (input[extracted.end] === ')')
|
|
111
|
+
finalEnd = extracted.end + 1;
|
|
112
|
+
return { text: parser.stringifyValue(result), end: finalEnd };
|
|
113
|
+
}),
|
|
114
|
+
// Rule: @( code ) — single-paren expression
|
|
115
|
+
new HMLEParserRule(/@\(/g, (parser, match, input, scope) => {
|
|
116
|
+
const blockStart = match.index + match[0].length - 1; // points at '('
|
|
117
|
+
const extracted = HMLEParser.extractBalancedParens(input, blockStart);
|
|
118
|
+
if (!extracted)
|
|
119
|
+
return match[0];
|
|
120
|
+
const code = extracted.block;
|
|
121
|
+
const ctx = parser.buildContext(scope);
|
|
122
|
+
let result;
|
|
123
|
+
try {
|
|
124
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
125
|
+
result = fn.call(ctx);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
try {
|
|
129
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
130
|
+
result = fn2.call(ctx);
|
|
131
|
+
}
|
|
132
|
+
catch (e2) {
|
|
133
|
+
return { text: '', end: extracted.end };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { text: parser.stringifyValue(result), end: extracted.end };
|
|
137
|
+
}),
|
|
138
|
+
];
|
|
139
|
+
// Stage 2: DOM rules for attribute processing
|
|
140
|
+
static domRules = [
|
|
141
|
+
// Rule: @[eventName](expression) — event binding
|
|
142
|
+
// Example: @[onClick](handleClick) or @[onInput](value = $event.target.value)
|
|
143
|
+
new HMLEDOMRule(/^@\[on([A-Za-z]+)\]$/i, (parser, element, attrName, attrValue, match, scope) => {
|
|
144
|
+
const eventName = match[1].toLowerCase(); // onClick -> click
|
|
145
|
+
const ctx = parser.buildContext(scope);
|
|
146
|
+
const handler = (event) => {
|
|
147
|
+
// Add $event to context
|
|
148
|
+
const eventCtx = Object.assign({}, ctx, { $event: event, $el: element });
|
|
149
|
+
try {
|
|
150
|
+
const fn = new Function('with(this){ ' + attrValue + ' }');
|
|
151
|
+
fn.call(eventCtx);
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
console.error(`HMLEParser: Error in @[on${match[1]}] handler:`, e);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
element.addEventListener(eventName, handler);
|
|
158
|
+
element.removeAttribute(attrName);
|
|
159
|
+
}),
|
|
160
|
+
// Rule: @[bind:attribute](expression) — two-way binding
|
|
161
|
+
// Example: @[bind:value](inputValue)
|
|
162
|
+
new HMLEDOMRule(/^@\[bind:([A-Za-z-]+)\]$/, (parser, element, attrName, attrValue, match, scope) => {
|
|
163
|
+
const boundAttr = match[1];
|
|
164
|
+
const ctx = parser.buildContext(scope);
|
|
165
|
+
// Set initial value
|
|
166
|
+
const initialValue = parser.evaluateInContext(attrValue, ctx);
|
|
167
|
+
if (boundAttr === 'value' && 'value' in element) {
|
|
168
|
+
element.value = initialValue ?? '';
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
element.setAttribute(boundAttr, parser.stringifyValue(initialValue));
|
|
172
|
+
}
|
|
173
|
+
// For input elements, listen for changes
|
|
174
|
+
if (boundAttr === 'value' && (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT')) {
|
|
175
|
+
element.addEventListener('input', (event) => {
|
|
176
|
+
const newValue = event.target.value;
|
|
177
|
+
// Try to update the bound variable in scope
|
|
178
|
+
if (scope && attrValue in scope) {
|
|
179
|
+
scope[attrValue] = newValue;
|
|
180
|
+
}
|
|
181
|
+
else if (attrValue in parser.variables) {
|
|
182
|
+
parser.variables[attrValue] = newValue;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
element.removeAttribute(attrName);
|
|
187
|
+
}),
|
|
188
|
+
// Rule: @[ref](refName) — element reference
|
|
189
|
+
// Example: @[ref](myButton)
|
|
190
|
+
new HMLEDOMRule(/^@\[ref\]$/, (parser, element, attrName, attrValue, match, scope) => {
|
|
191
|
+
if (scope && attrValue) {
|
|
192
|
+
scope[attrValue] = element;
|
|
193
|
+
}
|
|
194
|
+
else if (attrValue) {
|
|
195
|
+
parser.variables[attrValue] = element;
|
|
196
|
+
}
|
|
197
|
+
element.removeAttribute(attrName);
|
|
198
|
+
}),
|
|
199
|
+
// Rule: @[class:className](condition) — conditional class
|
|
200
|
+
// Example: @[class:active](isActive)
|
|
201
|
+
new HMLEDOMRule(/^@\[class:([A-Za-z_-][A-Za-z0-9_-]*)\]$/, (parser, element, attrName, attrValue, match, scope) => {
|
|
202
|
+
const className = match[1];
|
|
203
|
+
const ctx = parser.buildContext(scope);
|
|
204
|
+
const condition = parser.evaluateInContext(attrValue, ctx);
|
|
205
|
+
if (condition) {
|
|
206
|
+
element.classList.add(className);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
element.classList.remove(className);
|
|
210
|
+
}
|
|
211
|
+
element.removeAttribute(attrName);
|
|
212
|
+
}),
|
|
213
|
+
// Rule: @[style:property](expression) — dynamic style
|
|
214
|
+
// Example: @[style:color](textColor)
|
|
215
|
+
new HMLEDOMRule(/^@\[style:([A-Za-z-]+)\]$/, (parser, element, attrName, attrValue, match, scope) => {
|
|
216
|
+
const styleProp = match[1];
|
|
217
|
+
const ctx = parser.buildContext(scope);
|
|
218
|
+
const value = parser.evaluateInContext(attrValue, ctx);
|
|
219
|
+
if (value != null) {
|
|
220
|
+
element.style.setProperty(styleProp, String(value));
|
|
221
|
+
}
|
|
222
|
+
element.removeAttribute(attrName);
|
|
223
|
+
}),
|
|
224
|
+
// Rule: @[if](condition) — conditional rendering
|
|
225
|
+
// Example: @[if](showElement)
|
|
226
|
+
new HMLEDOMRule(/^@\[if\]$/, (parser, element, attrName, attrValue, match, scope) => {
|
|
227
|
+
const ctx = parser.buildContext(scope);
|
|
228
|
+
const condition = parser.evaluateInContext(attrValue, ctx);
|
|
229
|
+
if (!condition) {
|
|
230
|
+
// Create a placeholder comment
|
|
231
|
+
const placeholder = document.createComment(`@[if](${attrValue})`);
|
|
232
|
+
element.parentNode?.replaceChild(placeholder, element);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
element.removeAttribute(attrName);
|
|
236
|
+
}
|
|
237
|
+
}),
|
|
238
|
+
];
|
|
239
|
+
variables = {};
|
|
240
|
+
/**
|
|
241
|
+
* Add a variable to the parser's global scope
|
|
242
|
+
*/
|
|
243
|
+
addVariable(name, value) {
|
|
244
|
+
this.variables[name] = value;
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Build execution context that includes prototype methods from scope
|
|
249
|
+
*/
|
|
250
|
+
buildContext(scope) {
|
|
251
|
+
const ctx = Object.assign({}, this.variables);
|
|
252
|
+
if (scope) {
|
|
253
|
+
// Copy own properties
|
|
254
|
+
Object.assign(ctx, scope);
|
|
255
|
+
// Copy prototype methods (for class instances)
|
|
256
|
+
let proto = Object.getPrototypeOf(scope);
|
|
257
|
+
while (proto && proto !== Object.prototype) {
|
|
258
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
259
|
+
if (key !== 'constructor' && typeof proto[key] === 'function' && !(key in ctx)) {
|
|
260
|
+
ctx[key] = proto[key].bind(scope);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
proto = Object.getPrototypeOf(proto);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return ctx;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Resolve a dotted expression against the parser variables and optional local scope.
|
|
270
|
+
*/
|
|
271
|
+
resolveExpression(expr, scope) {
|
|
272
|
+
const combined = this.buildContext(scope);
|
|
273
|
+
const parts = expr.split('.').map(p => p.trim()).filter(Boolean);
|
|
274
|
+
let cur = combined;
|
|
275
|
+
for (const part of parts) {
|
|
276
|
+
if (cur == null)
|
|
277
|
+
return undefined;
|
|
278
|
+
cur = cur[part];
|
|
279
|
+
}
|
|
280
|
+
return cur;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Convert value to string for text content
|
|
284
|
+
*/
|
|
285
|
+
stringifyValue(val) {
|
|
286
|
+
if (val == null)
|
|
287
|
+
return '';
|
|
288
|
+
if (typeof val === 'string')
|
|
289
|
+
return val;
|
|
290
|
+
return String(val);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Evaluate a JavaScript expression in a given context
|
|
294
|
+
*/
|
|
295
|
+
evaluateInContext(code, ctx) {
|
|
296
|
+
try {
|
|
297
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
298
|
+
return fn.call(ctx);
|
|
299
|
+
}
|
|
300
|
+
catch (e) {
|
|
301
|
+
try {
|
|
302
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
303
|
+
return fn2.call(ctx);
|
|
304
|
+
}
|
|
305
|
+
catch (e2) {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Parse HMLE template string and return processed HTML string
|
|
312
|
+
* @param content HMLE template string
|
|
313
|
+
* @param scope Optional scope object (can be a class instance)
|
|
314
|
+
* @returns Processed HTML string
|
|
315
|
+
*/
|
|
316
|
+
parse(content, scope) {
|
|
317
|
+
let working = content;
|
|
318
|
+
for (const rule of HMLEParser.rules) {
|
|
319
|
+
const pattern = rule.pattern;
|
|
320
|
+
let result = '';
|
|
321
|
+
let lastIndex = 0;
|
|
322
|
+
let match;
|
|
323
|
+
// Reset scanning position
|
|
324
|
+
pattern.lastIndex = 0;
|
|
325
|
+
while ((match = pattern.exec(working)) !== null) {
|
|
326
|
+
// Append text before this match
|
|
327
|
+
result += working.slice(lastIndex, match.index);
|
|
328
|
+
const out = rule.replacer(this, match, working, scope);
|
|
329
|
+
if (typeof out === 'string') {
|
|
330
|
+
result += out;
|
|
331
|
+
lastIndex = match.index + match[0].length;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
result += out.text;
|
|
335
|
+
lastIndex = out.end;
|
|
336
|
+
}
|
|
337
|
+
// Continue scanning from the correct position
|
|
338
|
+
pattern.lastIndex = lastIndex;
|
|
339
|
+
}
|
|
340
|
+
// Append tail and update working
|
|
341
|
+
result += working.slice(lastIndex);
|
|
342
|
+
working = result;
|
|
343
|
+
}
|
|
344
|
+
return working;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Stage 2: Process DOM rules on a fragment
|
|
348
|
+
* Walks all elements and applies DOM rules based on attributes
|
|
349
|
+
*/
|
|
350
|
+
processDOMRules(fragment, scope) {
|
|
351
|
+
const elements = fragment instanceof DocumentFragment
|
|
352
|
+
? Array.from(fragment.querySelectorAll('*'))
|
|
353
|
+
: [fragment, ...Array.from(fragment.querySelectorAll('*'))];
|
|
354
|
+
for (const element of elements) {
|
|
355
|
+
// Get all attributes to process (copy to avoid mutation issues)
|
|
356
|
+
const attrs = Array.from(element.attributes);
|
|
357
|
+
for (const attr of attrs) {
|
|
358
|
+
// Check each DOM rule
|
|
359
|
+
for (const rule of HMLEParser.domRules) {
|
|
360
|
+
rule.attrPattern.lastIndex = 0;
|
|
361
|
+
const match = rule.attrPattern.exec(attr.name);
|
|
362
|
+
if (match) {
|
|
363
|
+
rule.processor(this, element, attr.name, attr.value, match, scope);
|
|
364
|
+
break; // Only one rule per attribute
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Parse HMLE template and create DOM elements (Stage 1 + Stage 2)
|
|
372
|
+
* @param content HMLE template string
|
|
373
|
+
* @param scope Optional scope object
|
|
374
|
+
* @returns DocumentFragment containing parsed HTML with bindings applied
|
|
375
|
+
*/
|
|
376
|
+
parseToDOM(content, scope) {
|
|
377
|
+
// Stage 1: String processing
|
|
378
|
+
const html = this.parse(content, scope);
|
|
379
|
+
const template = document.createElement('template');
|
|
380
|
+
template.innerHTML = html.trim();
|
|
381
|
+
const fragment = template.content;
|
|
382
|
+
// Stage 2: DOM processing
|
|
383
|
+
this.processDOMRules(fragment, scope);
|
|
384
|
+
return fragment;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Parse HMLE template and return single element (first child)
|
|
388
|
+
* @param content HMLE template string
|
|
389
|
+
* @param scope Optional scope object
|
|
390
|
+
* @returns First element from parsed HTML, or null
|
|
391
|
+
*/
|
|
392
|
+
parseToElement(content, scope) {
|
|
393
|
+
const fragment = this.parseToDOM(content, scope);
|
|
394
|
+
return fragment.firstElementChild;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Parse and append to a parent element
|
|
398
|
+
* @param content HMLE template string
|
|
399
|
+
* @param parent Parent element to append to
|
|
400
|
+
* @param scope Optional scope object
|
|
401
|
+
* @returns The parent element
|
|
402
|
+
*/
|
|
403
|
+
parseAndAppend(content, parent, scope) {
|
|
404
|
+
const fragment = this.parseToDOM(content, scope);
|
|
405
|
+
parent.appendChild(fragment);
|
|
406
|
+
return parent;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Parse and replace element's innerHTML
|
|
410
|
+
* @param content HMLE template string
|
|
411
|
+
* @param element Element to update
|
|
412
|
+
* @param scope Optional scope object
|
|
413
|
+
* @returns The updated element
|
|
414
|
+
*/
|
|
415
|
+
parseAndReplace(content, element, scope) {
|
|
416
|
+
const fragment = this.parseToDOM(content, scope);
|
|
417
|
+
element.innerHTML = '';
|
|
418
|
+
element.appendChild(fragment);
|
|
419
|
+
return element;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Apply DOM rules to an existing element (Stage 2 only)
|
|
423
|
+
* Useful when you already have DOM and just want to process bindings
|
|
424
|
+
*/
|
|
425
|
+
applyBindings(element, scope) {
|
|
426
|
+
this.processDOMRules(element, scope);
|
|
427
|
+
return element;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
//# sourceMappingURL=HMLEParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HMLEParser.js","sourceRoot":"","sources":["../../src/foundation/HMLEParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ export default class PHTMLParser {
|
|
|
5
5
|
variables: Record<string, unknown>;
|
|
6
6
|
addVariable(name: string, value: unknown): this;
|
|
7
7
|
resolveExpression(expr: string, scope?: Record<string, any>): any;
|
|
8
|
+
private buildContext;
|
|
8
9
|
private stringifyValue;
|
|
9
10
|
parse(content: string, scope?: Record<string, any>): string;
|
|
10
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PHTMLParser.d.ts","sourceRoot":"","sources":["../../src/foundation/PHTMLParser.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,OAAO,OAAO,WAAW;IAG5B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAcnC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAiBpC,OAAO,CAAC,MAAM,CAAC,KAAK,CA6FlB;IACK,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAExC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;
|
|
1
|
+
{"version":3,"file":"PHTMLParser.d.ts","sourceRoot":"","sources":["../../src/foundation/PHTMLParser.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,OAAO,OAAO,WAAW;IAG5B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAcnC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAiBpC,OAAO,CAAC,MAAM,CAAC,KAAK,CA6FlB;IACK,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAExC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;IAYxE,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,cAAc;IAOf,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;CAyCrE"}
|
|
@@ -87,7 +87,7 @@ export default class PHTMLParser {
|
|
|
87
87
|
return match[0];
|
|
88
88
|
const code = extracted.block;
|
|
89
89
|
// Evaluate code using parser.variables + local scope
|
|
90
|
-
const ctx =
|
|
90
|
+
const ctx = parser.buildContext(scope);
|
|
91
91
|
let result;
|
|
92
92
|
try {
|
|
93
93
|
// try to evaluate as expression first
|
|
@@ -120,7 +120,7 @@ export default class PHTMLParser {
|
|
|
120
120
|
if (!extracted)
|
|
121
121
|
return match[0];
|
|
122
122
|
const code = extracted.block;
|
|
123
|
-
const ctx =
|
|
123
|
+
const ctx = parser.buildContext(scope);
|
|
124
124
|
let result;
|
|
125
125
|
try {
|
|
126
126
|
const fn = new Function('with(this){ return (' + code + '); }');
|
|
@@ -147,7 +147,7 @@ export default class PHTMLParser {
|
|
|
147
147
|
// Examples: "subjectChips" -> this.variables.subjectChips
|
|
148
148
|
// "chip.Color" -> scope.chip.Color (if chip exists in scope) or this.variables.chip.Color
|
|
149
149
|
resolveExpression(expr, scope) {
|
|
150
|
-
const combined =
|
|
150
|
+
const combined = this.buildContext(scope);
|
|
151
151
|
const parts = expr.split('.').map(p => p.trim()).filter(Boolean);
|
|
152
152
|
let cur = combined;
|
|
153
153
|
for (const part of parts) {
|
|
@@ -157,6 +157,25 @@ export default class PHTMLParser {
|
|
|
157
157
|
}
|
|
158
158
|
return cur;
|
|
159
159
|
}
|
|
160
|
+
// Build execution context that includes prototype methods from scope
|
|
161
|
+
buildContext(scope) {
|
|
162
|
+
const ctx = Object.assign({}, this.variables);
|
|
163
|
+
if (scope) {
|
|
164
|
+
// Copy own properties
|
|
165
|
+
Object.assign(ctx, scope);
|
|
166
|
+
// Copy prototype methods (for class instances)
|
|
167
|
+
let proto = Object.getPrototypeOf(scope);
|
|
168
|
+
while (proto && proto !== Object.prototype) {
|
|
169
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
170
|
+
if (key !== 'constructor' && typeof proto[key] === 'function' && !(key in ctx)) {
|
|
171
|
+
ctx[key] = proto[key].bind(scope);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
proto = Object.getPrototypeOf(proto);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return ctx;
|
|
178
|
+
}
|
|
160
179
|
stringifyValue(val) {
|
|
161
180
|
if (val == null)
|
|
162
181
|
return '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PHTMLParser.js","sourceRoot":"","sources":["../../src/foundation/PHTMLParser.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"PHTMLParser.js","sourceRoot":"","sources":["../../src/foundation/PHTMLParser.ts"],"names":[],"mappings":"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"}
|
package/out/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { default as Component } from './foundation/component_api/Component.js';
|
|
|
8
8
|
export { default as Triplet, TripletBuilder, AccessType } from './foundation/Triplet.js';
|
|
9
9
|
export { ReComponent, RePage } from './foundation/TripletDecorator.js';
|
|
10
10
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
11
|
+
export { default as PHTMLParser } from './foundation/PHTMLParser.js';
|
|
12
|
+
export { default as HMLEParser } from './foundation/HMLEParser.js';
|
|
11
13
|
export { Router } from './foundation/worker/Router.js';
|
|
12
14
|
export { default as ServiceWorker } from './foundation/worker/ServiceWorker.js';
|
|
13
15
|
export * from './foundation/Theme.js';
|
package/out/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAE1D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAE1D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAEhF,cAAc,uBAAuB,CAAC;AAEtC,eAAO,MAAM,kBAAkB,EAAG,MAA8D,CAAC;AAGjG,eAAO,MAAM,OAAO,EAAG,MAA8E,CAAC;AAEtG,eAAO,MAAM,cAAc,EAAG,MACwC,CAAC"}
|
package/out/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export { default as Component } from './foundation/component_api/Component.js';
|
|
|
6
6
|
export { default as Triplet, TripletBuilder, AccessType } from './foundation/Triplet.js';
|
|
7
7
|
export { ReComponent, RePage } from './foundation/TripletDecorator.js';
|
|
8
8
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
9
|
+
export { default as PHTMLParser } from './foundation/PHTMLParser.js';
|
|
10
|
+
export { default as HMLEParser } from './foundation/HMLEParser.js';
|
|
9
11
|
export { Router } from './foundation/worker/Router.js';
|
|
10
12
|
export { default as ServiceWorker } from './foundation/worker/ServiceWorker.js';
|
|
11
13
|
export * from './foundation/Theme.js';
|
package/out/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAE1D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE3D,cAAc,2CAA2C,CAAC;AAE1D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAEhF,cAAc,uBAAuB,CAAC;AAEtC,MAAM,CAAC,MAAM,kBAAkB,GAAY,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjG,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC1B,MAAM,CAAC,MAAM,OAAO,GAAY,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;AAEtG,MAAM,CAAC,MAAM,cAAc,GAAY,CAAC,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;AACnE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACjC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAEnD,qEAAqE;AACrE;;WAEQ;AAER,yEAAyE"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMLEParser - HTML Markup Language Extensions Parser
|
|
3
|
+
*
|
|
4
|
+
* Two-stage parsing:
|
|
5
|
+
* Stage 1: String processing - @for loops, @(expression) interpolations
|
|
6
|
+
* Stage 2: DOM processing - @[event](handler) bindings, attribute directives
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const parser = new HMLEParser();
|
|
10
|
+
* parser.addVariable('items', [{name: 'Item 1'}, {name: 'Item 2'}]);
|
|
11
|
+
* const fragment = parser.parseToDOM(templateString, scopeObject);
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Stage 1: String-based rules
|
|
15
|
+
class HMLEParserRule {
|
|
16
|
+
public pattern: RegExp;
|
|
17
|
+
public replacer: (parser: HMLEParser, match: RegExpExecArray, input: string, scope?: Record<string, any>) => string | { text: string; end: number };
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
pattern: RegExp,
|
|
21
|
+
replacer: (parser: HMLEParser, match: RegExpExecArray, input: string, scope?: Record<string, any>) => string | { text: string; end: number }
|
|
22
|
+
) {
|
|
23
|
+
this.pattern = pattern;
|
|
24
|
+
this.replacer = replacer;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Stage 2: DOM-based rules for attribute processing
|
|
29
|
+
class HMLEDOMRule {
|
|
30
|
+
public attrPattern: RegExp;
|
|
31
|
+
public processor: (parser: HMLEParser, element: Element, attrName: string, attrValue: string, match: RegExpExecArray, scope?: Record<string, any>) => void;
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
attrPattern: RegExp,
|
|
35
|
+
processor: (parser: HMLEParser, element: Element, attrName: string, attrValue: string, match: RegExpExecArray, scope?: Record<string, any>) => void
|
|
36
|
+
) {
|
|
37
|
+
this.attrPattern = attrPattern;
|
|
38
|
+
this.processor = processor;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default class HMLEParser {
|
|
43
|
+
// Extract balanced braces { ... }
|
|
44
|
+
private static extractBalancedBraces(content: string, start: number): { block: string; end: number } | null {
|
|
45
|
+
if (content[start] !== '{') return null;
|
|
46
|
+
let depth = 1;
|
|
47
|
+
let i = start + 1;
|
|
48
|
+
while (i < content.length && depth > 0) {
|
|
49
|
+
if (content[i] === '{') depth++;
|
|
50
|
+
else if (content[i] === '}') depth--;
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
if (depth !== 0) return null;
|
|
54
|
+
return { block: content.slice(start + 1, i - 1), end: i };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Extract balanced parentheses ( ... )
|
|
58
|
+
private static extractBalancedParens(content: string, start: number): { block: string; end: number } | null {
|
|
59
|
+
if (content[start] !== '(') return null;
|
|
60
|
+
let depth = 1;
|
|
61
|
+
let i = start + 1;
|
|
62
|
+
while (i < content.length && depth > 0) {
|
|
63
|
+
if (content[i] === '(') depth++;
|
|
64
|
+
else if (content[i] === ')') depth--;
|
|
65
|
+
i++;
|
|
66
|
+
}
|
|
67
|
+
if (depth !== 0) return null;
|
|
68
|
+
return { block: content.slice(start + 1, i - 1), end: i };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Predefined rules processed in order
|
|
72
|
+
private static rules: HMLEParserRule[] = [
|
|
73
|
+
// Rule: @for (item in items) { ... }
|
|
74
|
+
new HMLEParserRule(/@for\s*\(\s*([A-Za-z_$][A-Za-z0-9_$]*)\s+in\s+([A-Za-z_$][A-Za-z0-9_$.]*)\s*\)\s*\{/g,
|
|
75
|
+
(parser, match, input, scope) => {
|
|
76
|
+
const iterVar = match[1];
|
|
77
|
+
const iterableExpr = match[2];
|
|
78
|
+
const blockStart = match.index + match[0].length - 1; // position of '{'
|
|
79
|
+
|
|
80
|
+
const extracted = HMLEParser.extractBalancedBraces(input, blockStart);
|
|
81
|
+
if (!extracted) return match[0];
|
|
82
|
+
|
|
83
|
+
const inner = extracted.block;
|
|
84
|
+
const resolved = parser.resolveExpression(iterableExpr, scope);
|
|
85
|
+
const arr = Array.isArray(resolved) ? resolved : [];
|
|
86
|
+
|
|
87
|
+
const parts: string[] = [];
|
|
88
|
+
for (const item of arr) {
|
|
89
|
+
const fullScope = Object.assign({}, scope, { [iterVar]: item });
|
|
90
|
+
parts.push(parser.parse(inner, fullScope));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { text: parts.join('\n'), end: extracted.end };
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
|
|
97
|
+
// Rule: @(( code )) — double-paren for complex expressions
|
|
98
|
+
new HMLEParserRule(/@\(\(/g,
|
|
99
|
+
(parser, match, input, scope) => {
|
|
100
|
+
const blockStart = match.index + match[0].length - 1; // points at inner '('
|
|
101
|
+
|
|
102
|
+
const extracted = HMLEParser.extractBalancedParens(input, blockStart);
|
|
103
|
+
if (!extracted) return match[0];
|
|
104
|
+
|
|
105
|
+
const code = extracted.block;
|
|
106
|
+
const ctx = parser.buildContext(scope);
|
|
107
|
+
let result: any;
|
|
108
|
+
try {
|
|
109
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
110
|
+
result = fn.call(ctx);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
try {
|
|
113
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
114
|
+
result = fn2.call(ctx);
|
|
115
|
+
} catch (e2) {
|
|
116
|
+
return { text: '', end: extracted.end };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Skip outer ')' if present
|
|
121
|
+
let finalEnd = extracted.end;
|
|
122
|
+
if (input[extracted.end] === ')') finalEnd = extracted.end + 1;
|
|
123
|
+
|
|
124
|
+
return { text: parser.stringifyValue(result), end: finalEnd };
|
|
125
|
+
}
|
|
126
|
+
),
|
|
127
|
+
|
|
128
|
+
// Rule: @( code ) — single-paren expression
|
|
129
|
+
new HMLEParserRule(/@\(/g,
|
|
130
|
+
(parser, match, input, scope) => {
|
|
131
|
+
const blockStart = match.index + match[0].length - 1; // points at '('
|
|
132
|
+
|
|
133
|
+
const extracted = HMLEParser.extractBalancedParens(input, blockStart);
|
|
134
|
+
if (!extracted) return match[0];
|
|
135
|
+
|
|
136
|
+
const code = extracted.block;
|
|
137
|
+
const ctx = parser.buildContext(scope);
|
|
138
|
+
let result: any;
|
|
139
|
+
try {
|
|
140
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
141
|
+
result = fn.call(ctx);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
try {
|
|
144
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
145
|
+
result = fn2.call(ctx);
|
|
146
|
+
} catch (e2) {
|
|
147
|
+
return { text: '', end: extracted.end };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return { text: parser.stringifyValue(result), end: extracted.end };
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
// Stage 2: DOM rules for attribute processing
|
|
157
|
+
private static domRules: HMLEDOMRule[] = [
|
|
158
|
+
// Rule: @[eventName](expression) — event binding
|
|
159
|
+
// Example: @[onClick](handleClick) or @[onInput](value = $event.target.value)
|
|
160
|
+
new HMLEDOMRule(/^@\[on([A-Za-z]+)\]$/i,
|
|
161
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
162
|
+
const eventName = match[1].toLowerCase(); // onClick -> click
|
|
163
|
+
const ctx = parser.buildContext(scope);
|
|
164
|
+
|
|
165
|
+
const handler = (event: Event) => {
|
|
166
|
+
// Add $event to context
|
|
167
|
+
const eventCtx = Object.assign({}, ctx, { $event: event, $el: element });
|
|
168
|
+
try {
|
|
169
|
+
const fn = new Function('with(this){ ' + attrValue + ' }');
|
|
170
|
+
fn.call(eventCtx);
|
|
171
|
+
} catch (e) {
|
|
172
|
+
console.error(`HMLEParser: Error in @[on${match[1]}] handler:`, e);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
element.addEventListener(eventName, handler);
|
|
177
|
+
element.removeAttribute(attrName);
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
|
|
181
|
+
// Rule: @[bind:attribute](expression) — two-way binding
|
|
182
|
+
// Example: @[bind:value](inputValue)
|
|
183
|
+
new HMLEDOMRule(/^@\[bind:([A-Za-z-]+)\]$/,
|
|
184
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
185
|
+
const boundAttr = match[1];
|
|
186
|
+
const ctx = parser.buildContext(scope);
|
|
187
|
+
|
|
188
|
+
// Set initial value
|
|
189
|
+
const initialValue = parser.evaluateInContext(attrValue, ctx);
|
|
190
|
+
if (boundAttr === 'value' && 'value' in element) {
|
|
191
|
+
(element as HTMLInputElement).value = initialValue ?? '';
|
|
192
|
+
} else {
|
|
193
|
+
element.setAttribute(boundAttr, parser.stringifyValue(initialValue));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// For input elements, listen for changes
|
|
197
|
+
if (boundAttr === 'value' && (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT')) {
|
|
198
|
+
element.addEventListener('input', (event) => {
|
|
199
|
+
const newValue = (event.target as HTMLInputElement).value;
|
|
200
|
+
// Try to update the bound variable in scope
|
|
201
|
+
if (scope && attrValue in scope) {
|
|
202
|
+
scope[attrValue] = newValue;
|
|
203
|
+
} else if (attrValue in parser.variables) {
|
|
204
|
+
parser.variables[attrValue] = newValue;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
element.removeAttribute(attrName);
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
|
|
213
|
+
// Rule: @[ref](refName) — element reference
|
|
214
|
+
// Example: @[ref](myButton)
|
|
215
|
+
new HMLEDOMRule(/^@\[ref\]$/,
|
|
216
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
217
|
+
if (scope && attrValue) {
|
|
218
|
+
scope[attrValue] = element;
|
|
219
|
+
} else if (attrValue) {
|
|
220
|
+
parser.variables[attrValue] = element;
|
|
221
|
+
}
|
|
222
|
+
element.removeAttribute(attrName);
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
|
|
226
|
+
// Rule: @[class:className](condition) — conditional class
|
|
227
|
+
// Example: @[class:active](isActive)
|
|
228
|
+
new HMLEDOMRule(/^@\[class:([A-Za-z_-][A-Za-z0-9_-]*)\]$/,
|
|
229
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
230
|
+
const className = match[1];
|
|
231
|
+
const ctx = parser.buildContext(scope);
|
|
232
|
+
const condition = parser.evaluateInContext(attrValue, ctx);
|
|
233
|
+
|
|
234
|
+
if (condition) {
|
|
235
|
+
element.classList.add(className);
|
|
236
|
+
} else {
|
|
237
|
+
element.classList.remove(className);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
element.removeAttribute(attrName);
|
|
241
|
+
}
|
|
242
|
+
),
|
|
243
|
+
|
|
244
|
+
// Rule: @[style:property](expression) — dynamic style
|
|
245
|
+
// Example: @[style:color](textColor)
|
|
246
|
+
new HMLEDOMRule(/^@\[style:([A-Za-z-]+)\]$/,
|
|
247
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
248
|
+
const styleProp = match[1];
|
|
249
|
+
const ctx = parser.buildContext(scope);
|
|
250
|
+
const value = parser.evaluateInContext(attrValue, ctx);
|
|
251
|
+
|
|
252
|
+
if (value != null) {
|
|
253
|
+
(element as HTMLElement).style.setProperty(styleProp, String(value));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
element.removeAttribute(attrName);
|
|
257
|
+
}
|
|
258
|
+
),
|
|
259
|
+
|
|
260
|
+
// Rule: @[if](condition) — conditional rendering
|
|
261
|
+
// Example: @[if](showElement)
|
|
262
|
+
new HMLEDOMRule(/^@\[if\]$/,
|
|
263
|
+
(parser, element, attrName, attrValue, match, scope) => {
|
|
264
|
+
const ctx = parser.buildContext(scope);
|
|
265
|
+
const condition : boolean = parser.evaluateInContext(attrValue, ctx);
|
|
266
|
+
|
|
267
|
+
if (!condition) {
|
|
268
|
+
// Create a placeholder comment
|
|
269
|
+
const placeholder = document.createComment(`@[if](${attrValue})`);
|
|
270
|
+
element.parentNode?.replaceChild(placeholder, element);
|
|
271
|
+
} else {
|
|
272
|
+
element.removeAttribute(attrName);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
),
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
public variables: Record<string, unknown> = {};
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Add a variable to the parser's global scope
|
|
282
|
+
*/
|
|
283
|
+
public addVariable(name: string, value: unknown): this {
|
|
284
|
+
this.variables[name] = value;
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Build execution context that includes prototype methods from scope
|
|
290
|
+
*/
|
|
291
|
+
private buildContext(scope?: Record<string, any>): Record<string, any> {
|
|
292
|
+
const ctx: Record<string, any> = Object.assign({}, this.variables);
|
|
293
|
+
if (scope) {
|
|
294
|
+
// Copy own properties
|
|
295
|
+
Object.assign(ctx, scope);
|
|
296
|
+
// Copy prototype methods (for class instances)
|
|
297
|
+
let proto = Object.getPrototypeOf(scope);
|
|
298
|
+
while (proto && proto !== Object.prototype) {
|
|
299
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
300
|
+
if (key !== 'constructor' && typeof proto[key] === 'function' && !(key in ctx)) {
|
|
301
|
+
ctx[key] = proto[key].bind(scope);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
proto = Object.getPrototypeOf(proto);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return ctx;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Resolve a dotted expression against the parser variables and optional local scope.
|
|
312
|
+
*/
|
|
313
|
+
public resolveExpression(expr: string, scope?: Record<string, any>): any {
|
|
314
|
+
const combined = this.buildContext(scope);
|
|
315
|
+
const parts = expr.split('.').map(p => p.trim()).filter(Boolean);
|
|
316
|
+
let cur: any = combined;
|
|
317
|
+
for (const part of parts) {
|
|
318
|
+
if (cur == null) return undefined;
|
|
319
|
+
cur = cur[part];
|
|
320
|
+
}
|
|
321
|
+
return cur;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Convert value to string for text content
|
|
326
|
+
*/
|
|
327
|
+
private stringifyValue(val: any): string {
|
|
328
|
+
if (val == null) return '';
|
|
329
|
+
if (typeof val === 'string') return val;
|
|
330
|
+
return String(val);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Evaluate a JavaScript expression in a given context
|
|
335
|
+
*/
|
|
336
|
+
private evaluateInContext(code: string, ctx: Record<string, any>): any {
|
|
337
|
+
try {
|
|
338
|
+
const fn = new Function('with(this){ return (' + code + '); }');
|
|
339
|
+
return fn.call(ctx);
|
|
340
|
+
} catch (e) {
|
|
341
|
+
try {
|
|
342
|
+
const fn2 = new Function('with(this){ ' + code + ' }');
|
|
343
|
+
return fn2.call(ctx);
|
|
344
|
+
} catch (e2) {
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Parse HMLE template string and return processed HTML string
|
|
352
|
+
* @param content HMLE template string
|
|
353
|
+
* @param scope Optional scope object (can be a class instance)
|
|
354
|
+
* @returns Processed HTML string
|
|
355
|
+
*/
|
|
356
|
+
public parse(content: string, scope?: Record<string, any>): string {
|
|
357
|
+
let working = content;
|
|
358
|
+
|
|
359
|
+
for (const rule of HMLEParser.rules) {
|
|
360
|
+
const pattern = rule.pattern;
|
|
361
|
+
let result = '';
|
|
362
|
+
let lastIndex = 0;
|
|
363
|
+
let match: RegExpExecArray | null;
|
|
364
|
+
|
|
365
|
+
// Reset scanning position
|
|
366
|
+
pattern.lastIndex = 0;
|
|
367
|
+
while ((match = pattern.exec(working)) !== null) {
|
|
368
|
+
// Append text before this match
|
|
369
|
+
result += working.slice(lastIndex, match.index);
|
|
370
|
+
|
|
371
|
+
const out = rule.replacer(this, match, working, scope);
|
|
372
|
+
|
|
373
|
+
if (typeof out === 'string') {
|
|
374
|
+
result += out;
|
|
375
|
+
lastIndex = match.index + match[0].length;
|
|
376
|
+
} else {
|
|
377
|
+
result += out.text;
|
|
378
|
+
lastIndex = out.end;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Continue scanning from the correct position
|
|
382
|
+
pattern.lastIndex = lastIndex;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Append tail and update working
|
|
386
|
+
result += working.slice(lastIndex);
|
|
387
|
+
working = result;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return working;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Stage 2: Process DOM rules on a fragment
|
|
395
|
+
* Walks all elements and applies DOM rules based on attributes
|
|
396
|
+
*/
|
|
397
|
+
private processDOMRules(fragment: DocumentFragment | Element, scope?: Record<string, any>): void {
|
|
398
|
+
const elements = fragment instanceof DocumentFragment
|
|
399
|
+
? Array.from(fragment.querySelectorAll('*'))
|
|
400
|
+
: [fragment, ...Array.from(fragment.querySelectorAll('*'))];
|
|
401
|
+
|
|
402
|
+
for (const element of elements) {
|
|
403
|
+
// Get all attributes to process (copy to avoid mutation issues)
|
|
404
|
+
const attrs = Array.from(element.attributes);
|
|
405
|
+
|
|
406
|
+
for (const attr of attrs) {
|
|
407
|
+
// Check each DOM rule
|
|
408
|
+
for (const rule of HMLEParser.domRules) {
|
|
409
|
+
rule.attrPattern.lastIndex = 0;
|
|
410
|
+
const match = rule.attrPattern.exec(attr.name);
|
|
411
|
+
if (match) {
|
|
412
|
+
rule.processor(this, element, attr.name, attr.value, match, scope);
|
|
413
|
+
break; // Only one rule per attribute
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Parse HMLE template and create DOM elements (Stage 1 + Stage 2)
|
|
422
|
+
* @param content HMLE template string
|
|
423
|
+
* @param scope Optional scope object
|
|
424
|
+
* @returns DocumentFragment containing parsed HTML with bindings applied
|
|
425
|
+
*/
|
|
426
|
+
public parseToDOM(content: string, scope?: Record<string, any>): DocumentFragment {
|
|
427
|
+
// Stage 1: String processing
|
|
428
|
+
const html = this.parse(content, scope);
|
|
429
|
+
const template = document.createElement('template');
|
|
430
|
+
template.innerHTML = html.trim();
|
|
431
|
+
const fragment = template.content;
|
|
432
|
+
|
|
433
|
+
// Stage 2: DOM processing
|
|
434
|
+
this.processDOMRules(fragment, scope);
|
|
435
|
+
|
|
436
|
+
return fragment;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Parse HMLE template and return single element (first child)
|
|
441
|
+
* @param content HMLE template string
|
|
442
|
+
* @param scope Optional scope object
|
|
443
|
+
* @returns First element from parsed HTML, or null
|
|
444
|
+
*/
|
|
445
|
+
public parseToElement<T extends Element = Element>(content: string, scope?: Record<string, any>): T | null {
|
|
446
|
+
const fragment = this.parseToDOM(content, scope);
|
|
447
|
+
return fragment.firstElementChild as T | null;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Parse and append to a parent element
|
|
452
|
+
* @param content HMLE template string
|
|
453
|
+
* @param parent Parent element to append to
|
|
454
|
+
* @param scope Optional scope object
|
|
455
|
+
* @returns The parent element
|
|
456
|
+
*/
|
|
457
|
+
public parseAndAppend(content: string, parent: Element, scope?: Record<string, any>): Element {
|
|
458
|
+
const fragment = this.parseToDOM(content, scope);
|
|
459
|
+
parent.appendChild(fragment);
|
|
460
|
+
return parent;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Parse and replace element's innerHTML
|
|
465
|
+
* @param content HMLE template string
|
|
466
|
+
* @param element Element to update
|
|
467
|
+
* @param scope Optional scope object
|
|
468
|
+
* @returns The updated element
|
|
469
|
+
*/
|
|
470
|
+
public parseAndReplace(content: string, element: Element, scope?: Record<string, any>): Element {
|
|
471
|
+
const fragment = this.parseToDOM(content, scope);
|
|
472
|
+
element.innerHTML = '';
|
|
473
|
+
element.appendChild(fragment);
|
|
474
|
+
return element;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Apply DOM rules to an existing element (Stage 2 only)
|
|
479
|
+
* Useful when you already have DOM and just want to process bindings
|
|
480
|
+
*/
|
|
481
|
+
public applyBindings(element: Element, scope?: Record<string, any>): Element {
|
|
482
|
+
this.processDOMRules(element, scope);
|
|
483
|
+
return element;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
@@ -90,7 +90,7 @@ export default class PHTMLParser {
|
|
|
90
90
|
|
|
91
91
|
const code = extracted.block;
|
|
92
92
|
// Evaluate code using parser.variables + local scope
|
|
93
|
-
const ctx =
|
|
93
|
+
const ctx = parser.buildContext(scope);
|
|
94
94
|
let result: any;
|
|
95
95
|
try {
|
|
96
96
|
// try to evaluate as expression first
|
|
@@ -122,7 +122,7 @@ export default class PHTMLParser {
|
|
|
122
122
|
if (!extracted) return match[0];
|
|
123
123
|
|
|
124
124
|
const code = extracted.block;
|
|
125
|
-
const ctx =
|
|
125
|
+
const ctx = parser.buildContext(scope);
|
|
126
126
|
let result: any;
|
|
127
127
|
try {
|
|
128
128
|
const fn = new Function('with(this){ return (' + code + '); }');
|
|
@@ -150,7 +150,7 @@ export default class PHTMLParser {
|
|
|
150
150
|
// Examples: "subjectChips" -> this.variables.subjectChips
|
|
151
151
|
// "chip.Color" -> scope.chip.Color (if chip exists in scope) or this.variables.chip.Color
|
|
152
152
|
public resolveExpression(expr: string, scope?: Record<string, any>): any {
|
|
153
|
-
const combined =
|
|
153
|
+
const combined = this.buildContext(scope);
|
|
154
154
|
const parts = expr.split('.').map(p => p.trim()).filter(Boolean);
|
|
155
155
|
let cur: any = combined;
|
|
156
156
|
for (const part of parts) {
|
|
@@ -160,6 +160,26 @@ export default class PHTMLParser {
|
|
|
160
160
|
return cur;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
// Build execution context that includes prototype methods from scope
|
|
164
|
+
private buildContext(scope?: Record<string, any>): Record<string, any> {
|
|
165
|
+
const ctx: Record<string, any> = Object.assign({}, this.variables);
|
|
166
|
+
if (scope) {
|
|
167
|
+
// Copy own properties
|
|
168
|
+
Object.assign(ctx, scope);
|
|
169
|
+
// Copy prototype methods (for class instances)
|
|
170
|
+
let proto = Object.getPrototypeOf(scope);
|
|
171
|
+
while (proto && proto !== Object.prototype) {
|
|
172
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
173
|
+
if (key !== 'constructor' && typeof proto[key] === 'function' && !(key in ctx)) {
|
|
174
|
+
ctx[key] = proto[key].bind(scope);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
proto = Object.getPrototypeOf(proto);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return ctx;
|
|
181
|
+
}
|
|
182
|
+
|
|
163
183
|
private stringifyValue(val: any): string {
|
|
164
184
|
if (val == null) return '';
|
|
165
185
|
if (typeof val === 'string') return val;
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,8 @@ export { default as Triplet, TripletBuilder, AccessType } from './foundation/Tri
|
|
|
13
13
|
export { ReComponent, RePage } from './foundation/TripletDecorator.js';
|
|
14
14
|
|
|
15
15
|
export { default as Fetcher } from './foundation/Fetcher.js';
|
|
16
|
+
export { default as PHTMLParser } from './foundation/PHTMLParser.js';
|
|
17
|
+
export { default as HMLEParser } from './foundation/HMLEParser.js';
|
|
16
18
|
|
|
17
19
|
export { Router } from './foundation/worker/Router.js';
|
|
18
20
|
export { default as ServiceWorker } from './foundation/worker/ServiceWorker.js';
|