@mulanjs/mulanjs 1.0.1-dev.20261016101332 → 1.0.1-dev.20261017044620
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler/ast-parser.js +50 -6
- package/package.json +16 -9
- package/src/cli/index.js +10 -4
- package/src/compiler/ast-parser.ts +54 -6
|
@@ -42,6 +42,45 @@ function parse(template, errors) {
|
|
|
42
42
|
};
|
|
43
43
|
while (cursor < template.length) {
|
|
44
44
|
const char = template[cursor];
|
|
45
|
+
const currentParent = stack[stack.length - 1];
|
|
46
|
+
const isCurrentRawText = currentParent && (currentParent.tag.toLowerCase() === 'style' || currentParent.tag.toLowerCase() === 'script');
|
|
47
|
+
if (isCurrentRawText) {
|
|
48
|
+
const closeTag = `</${currentParent.tag.toLowerCase()}>`;
|
|
49
|
+
const lowerTemplate = template.toLowerCase();
|
|
50
|
+
const closeIdx = lowerTemplate.indexOf(closeTag, cursor);
|
|
51
|
+
if (closeIdx !== -1) {
|
|
52
|
+
const rawContent = template.slice(cursor, closeIdx);
|
|
53
|
+
if (rawContent) {
|
|
54
|
+
const startPos = getPos(cursor);
|
|
55
|
+
const endPos = getPos(closeIdx);
|
|
56
|
+
currentParent.children.push({
|
|
57
|
+
type: 'Text',
|
|
58
|
+
content: rawContent,
|
|
59
|
+
...startPos,
|
|
60
|
+
endLine: endPos.startLine,
|
|
61
|
+
endColumn: endPos.startColumn
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
stack.pop();
|
|
65
|
+
cursor = closeIdx + closeTag.length;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const rawContent = template.slice(cursor);
|
|
69
|
+
if (rawContent) {
|
|
70
|
+
const startPos = getPos(cursor);
|
|
71
|
+
const endPos = getPos(template.length);
|
|
72
|
+
currentParent.children.push({
|
|
73
|
+
type: 'Text',
|
|
74
|
+
content: rawContent,
|
|
75
|
+
...startPos,
|
|
76
|
+
endLine: endPos.startLine,
|
|
77
|
+
endColumn: endPos.startColumn
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
cursor = template.length;
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
45
84
|
// 1. Comments
|
|
46
85
|
if (template.startsWith('<!--', cursor)) {
|
|
47
86
|
const end = template.indexOf('-->', cursor);
|
|
@@ -153,7 +192,10 @@ function parse(template, errors) {
|
|
|
153
192
|
cursor = innerCursor;
|
|
154
193
|
}
|
|
155
194
|
// 5. Single-Brace Interpolation { } (Svelte / Minicode)
|
|
156
|
-
else if (template.startsWith('{', cursor) &&
|
|
195
|
+
else if (template.startsWith('{', cursor) &&
|
|
196
|
+
!template.startsWith('{{', cursor) &&
|
|
197
|
+
!template.startsWith('${', cursor) &&
|
|
198
|
+
!stack.some(el => ['style', 'script', 'pre', 'code'].includes(el.tag.toLowerCase()))) {
|
|
157
199
|
let innerCursor = cursor + 1;
|
|
158
200
|
let depth = 1;
|
|
159
201
|
while (innerCursor < template.length && depth > 0) {
|
|
@@ -163,13 +205,14 @@ function parse(template, errors) {
|
|
|
163
205
|
depth--;
|
|
164
206
|
innerCursor++;
|
|
165
207
|
}
|
|
166
|
-
|
|
167
|
-
|
|
208
|
+
const candidateContent = depth === 0 ? template.slice(cursor + 1, innerCursor - 1).trim() : '';
|
|
209
|
+
const containsHtmlTags = /<[a-zA-Z\/]/.test(candidateContent);
|
|
210
|
+
if (depth === 0 && !containsHtmlTags) {
|
|
168
211
|
const startPos = getPos(cursor);
|
|
169
212
|
const endPos = getPos(innerCursor);
|
|
170
213
|
stack[stack.length - 1].children.push({
|
|
171
214
|
type: 'Interpolation',
|
|
172
|
-
content,
|
|
215
|
+
content: candidateContent,
|
|
173
216
|
...startPos,
|
|
174
217
|
endLine: endPos.startLine,
|
|
175
218
|
endColumn: endPos.startColumn
|
|
@@ -195,12 +238,13 @@ function parse(template, errors) {
|
|
|
195
238
|
cursor++;
|
|
196
239
|
}
|
|
197
240
|
}
|
|
198
|
-
//
|
|
241
|
+
// 6. Text Nodes
|
|
199
242
|
else {
|
|
243
|
+
const isInsideCodeOrRaw = stack.some(el => ['style', 'script', 'pre', 'code'].includes(el.tag.toLowerCase()));
|
|
200
244
|
let nextTag = template.indexOf('<', cursor);
|
|
201
245
|
let nextInterp = template.indexOf('{{', cursor);
|
|
202
246
|
let nextNative = template.indexOf('${', cursor);
|
|
203
|
-
let nextBrace = template.indexOf('{', cursor);
|
|
247
|
+
let nextBrace = isInsideCodeOrRaw ? -1 : template.indexOf('{', cursor);
|
|
204
248
|
// Skip {{ and ${ for nextBrace
|
|
205
249
|
while (nextBrace !== -1) {
|
|
206
250
|
if (template[nextBrace + 1] !== '{' && (nextBrace === 0 || template[nextBrace - 1] !== '$')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mulanjs/mulanjs",
|
|
3
|
-
"version": "1.0.1-dev.
|
|
3
|
+
"version": "1.0.1-dev.20261017044620",
|
|
4
4
|
"description": "A powerful, secure, and enterprise-grade JavaScript framework.",
|
|
5
5
|
"main": "dist/mulan.js",
|
|
6
6
|
"module": "dist/mulan.esm.js",
|
|
@@ -59,16 +59,15 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"commander": "12.0.0",
|
|
61
61
|
"fs-extra": "11.3.3",
|
|
62
|
-
"webpack": "5.105.3",
|
|
63
|
-
"webpack-cli": "6.0.1",
|
|
64
|
-
"webpack-dev-server": "^5.2.6",
|
|
65
|
-
"ts-loader": "9.5.4",
|
|
66
|
-
"typescript": "5.3.3",
|
|
67
62
|
"source-map": "0.6.1"
|
|
68
63
|
},
|
|
69
64
|
"overrides": {
|
|
65
|
+
"braces": "^3.0.3",
|
|
66
|
+
"micromatch": "^4.0.8",
|
|
67
|
+
"chokidar": "^4.0.3",
|
|
68
|
+
"sprintf-js": "^1.1.3",
|
|
70
69
|
"minimatch": "^3.1.4",
|
|
71
|
-
"serialize-javascript": "^7.
|
|
70
|
+
"serialize-javascript": "^7.1.2",
|
|
72
71
|
"ws": "^8.21.0",
|
|
73
72
|
"websocket-driver": "^0.7.5",
|
|
74
73
|
"uuid": "^11.1.1",
|
|
@@ -81,12 +80,20 @@
|
|
|
81
80
|
"qs": "^6.15.2",
|
|
82
81
|
"@tootallnate/once": "^2.0.1",
|
|
83
82
|
"body-parser": "^1.20.6",
|
|
84
|
-
"brace-expansion": "^1.1.
|
|
85
|
-
"fast-uri": "^3.1.
|
|
83
|
+
"brace-expansion": "^1.1.21",
|
|
84
|
+
"fast-uri": "^3.1.8",
|
|
85
|
+
"proxy-addr": "^2.0.8",
|
|
86
|
+
"compression": "^1.8.2",
|
|
87
|
+
"browserslist": "^4.28.7",
|
|
86
88
|
"follow-redirects": "^1.15.12",
|
|
87
89
|
"@babel/core": "^7.29.1"
|
|
88
90
|
},
|
|
89
91
|
"devDependencies": {
|
|
92
|
+
"webpack": "5.105.3",
|
|
93
|
+
"webpack-cli": "6.0.1",
|
|
94
|
+
"webpack-dev-server": "^5.2.6",
|
|
95
|
+
"ts-loader": "^9.6.2",
|
|
96
|
+
"typescript": "5.3.3",
|
|
90
97
|
"@types/fs-extra": "11.0.4",
|
|
91
98
|
"@types/jest": "29.5.12",
|
|
92
99
|
"jest": "29.7.0",
|
package/src/cli/index.js
CHANGED
|
@@ -164,8 +164,11 @@ program
|
|
|
164
164
|
"sass-loader": "^16.0.0"
|
|
165
165
|
},
|
|
166
166
|
"overrides": {
|
|
167
|
+
"braces": "^3.0.3",
|
|
168
|
+
"micromatch": "^4.0.8",
|
|
169
|
+
"chokidar": "^4.0.3",
|
|
167
170
|
"minimatch": "^3.1.4",
|
|
168
|
-
"serialize-javascript": "^7.
|
|
171
|
+
"serialize-javascript": "^7.1.2",
|
|
169
172
|
"ws": "^8.21.0",
|
|
170
173
|
"websocket-driver": "^0.7.5",
|
|
171
174
|
"uuid": "^11.1.1",
|
|
@@ -178,8 +181,11 @@ program
|
|
|
178
181
|
"qs": "^6.15.2",
|
|
179
182
|
"@tootallnate/once": "^2.0.1",
|
|
180
183
|
"body-parser": "^1.20.6",
|
|
181
|
-
"brace-expansion": "^1.1.
|
|
182
|
-
"fast-uri": "^3.1.
|
|
184
|
+
"brace-expansion": "^1.1.21",
|
|
185
|
+
"fast-uri": "^3.1.8",
|
|
186
|
+
"proxy-addr": "^2.0.8",
|
|
187
|
+
"compression": "^1.8.2",
|
|
188
|
+
"browserslist": "^4.28.7",
|
|
183
189
|
"follow-redirects": "^1.15.12",
|
|
184
190
|
"@babel/core": "^7.29.1"
|
|
185
191
|
},
|
|
@@ -193,7 +199,7 @@ program
|
|
|
193
199
|
|
|
194
200
|
if (isTS) {
|
|
195
201
|
packageJson.devDependencies["typescript"] = "^5.3.3";
|
|
196
|
-
packageJson.devDependencies["ts-loader"] = "^9.
|
|
202
|
+
packageJson.devDependencies["ts-loader"] = "^9.6.2";
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
await fs.outputJson(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
|
|
@@ -82,6 +82,46 @@ export function parse(template: string, errors: string[]): ElementNode {
|
|
|
82
82
|
while (cursor < template.length) {
|
|
83
83
|
const char = template[cursor];
|
|
84
84
|
|
|
85
|
+
const currentParent = stack[stack.length - 1];
|
|
86
|
+
const isCurrentRawText = currentParent && (currentParent.tag.toLowerCase() === 'style' || currentParent.tag.toLowerCase() === 'script');
|
|
87
|
+
|
|
88
|
+
if (isCurrentRawText) {
|
|
89
|
+
const closeTag = `</${currentParent.tag.toLowerCase()}>`;
|
|
90
|
+
const lowerTemplate = template.toLowerCase();
|
|
91
|
+
const closeIdx = lowerTemplate.indexOf(closeTag, cursor);
|
|
92
|
+
if (closeIdx !== -1) {
|
|
93
|
+
const rawContent = template.slice(cursor, closeIdx);
|
|
94
|
+
if (rawContent) {
|
|
95
|
+
const startPos = getPos(cursor);
|
|
96
|
+
const endPos = getPos(closeIdx);
|
|
97
|
+
currentParent.children.push({
|
|
98
|
+
type: 'Text',
|
|
99
|
+
content: rawContent,
|
|
100
|
+
...startPos,
|
|
101
|
+
endLine: endPos.startLine,
|
|
102
|
+
endColumn: endPos.startColumn
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
stack.pop();
|
|
106
|
+
cursor = closeIdx + closeTag.length;
|
|
107
|
+
} else {
|
|
108
|
+
const rawContent = template.slice(cursor);
|
|
109
|
+
if (rawContent) {
|
|
110
|
+
const startPos = getPos(cursor);
|
|
111
|
+
const endPos = getPos(template.length);
|
|
112
|
+
currentParent.children.push({
|
|
113
|
+
type: 'Text',
|
|
114
|
+
content: rawContent,
|
|
115
|
+
...startPos,
|
|
116
|
+
endLine: endPos.startLine,
|
|
117
|
+
endColumn: endPos.startColumn
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
cursor = template.length;
|
|
121
|
+
}
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
85
125
|
// 1. Comments
|
|
86
126
|
if (template.startsWith('<!--', cursor)) {
|
|
87
127
|
const end = template.indexOf('-->', cursor);
|
|
@@ -195,7 +235,12 @@ export function parse(template: string, errors: string[]): ElementNode {
|
|
|
195
235
|
cursor = innerCursor;
|
|
196
236
|
}
|
|
197
237
|
// 5. Single-Brace Interpolation { } (Svelte / Minicode)
|
|
198
|
-
else if (
|
|
238
|
+
else if (
|
|
239
|
+
template.startsWith('{', cursor) &&
|
|
240
|
+
!template.startsWith('{{', cursor) &&
|
|
241
|
+
!template.startsWith('${', cursor) &&
|
|
242
|
+
!stack.some(el => ['style', 'script', 'pre', 'code'].includes(el.tag.toLowerCase()))
|
|
243
|
+
) {
|
|
199
244
|
let innerCursor = cursor + 1;
|
|
200
245
|
let depth = 1;
|
|
201
246
|
while (innerCursor < template.length && depth > 0) {
|
|
@@ -204,13 +249,15 @@ export function parse(template: string, errors: string[]): ElementNode {
|
|
|
204
249
|
innerCursor++;
|
|
205
250
|
}
|
|
206
251
|
|
|
207
|
-
|
|
208
|
-
|
|
252
|
+
const candidateContent = depth === 0 ? template.slice(cursor + 1, innerCursor - 1).trim() : '';
|
|
253
|
+
const containsHtmlTags = /<[a-zA-Z\/]/.test(candidateContent);
|
|
254
|
+
|
|
255
|
+
if (depth === 0 && !containsHtmlTags) {
|
|
209
256
|
const startPos = getPos(cursor);
|
|
210
257
|
const endPos = getPos(innerCursor);
|
|
211
258
|
stack[stack.length - 1].children.push({
|
|
212
259
|
type: 'Interpolation',
|
|
213
|
-
content,
|
|
260
|
+
content: candidateContent,
|
|
214
261
|
...startPos,
|
|
215
262
|
endLine: endPos.startLine,
|
|
216
263
|
endColumn: endPos.startColumn
|
|
@@ -234,12 +281,13 @@ export function parse(template: string, errors: string[]): ElementNode {
|
|
|
234
281
|
cursor++;
|
|
235
282
|
}
|
|
236
283
|
}
|
|
237
|
-
//
|
|
284
|
+
// 6. Text Nodes
|
|
238
285
|
else {
|
|
286
|
+
const isInsideCodeOrRaw = stack.some(el => ['style', 'script', 'pre', 'code'].includes(el.tag.toLowerCase()));
|
|
239
287
|
let nextTag = template.indexOf('<', cursor);
|
|
240
288
|
let nextInterp = template.indexOf('{{', cursor);
|
|
241
289
|
let nextNative = template.indexOf('${', cursor);
|
|
242
|
-
let nextBrace = template.indexOf('{', cursor);
|
|
290
|
+
let nextBrace = isInsideCodeOrRaw ? -1 : template.indexOf('{', cursor);
|
|
243
291
|
|
|
244
292
|
// Skip {{ and ${ for nextBrace
|
|
245
293
|
while (nextBrace !== -1) {
|