@junnyontop-pixel/neo-app 2.1.0 → 2.2.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/compiler/NeoParser.js +40 -2
- package/core/NeoCore.js +12 -1
- package/package.json +1 -5
- package/src/App.neo +27 -3
- package/src/state.js +3 -5
package/compiler/NeoParser.js
CHANGED
|
@@ -5,7 +5,8 @@ export class NeoParser {
|
|
|
5
5
|
tag: "",
|
|
6
6
|
styles: [],
|
|
7
7
|
innerHTML: "",
|
|
8
|
-
events: []
|
|
8
|
+
events: [],
|
|
9
|
+
children: []
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
// @ID:Tag
|
|
@@ -27,7 +28,19 @@ export class NeoParser {
|
|
|
27
28
|
// { content }
|
|
28
29
|
const contentMatch = rawCode.match(/\{([\s\S]*?)\}$/);
|
|
29
30
|
if (contentMatch) {
|
|
30
|
-
|
|
31
|
+
let content = contentMatch[1].trim(); // ⭐ 이게 content
|
|
32
|
+
let rest = content; // ⭐ 여기서 rest 생성
|
|
33
|
+
|
|
34
|
+
while (rest.includes('@')) {
|
|
35
|
+
const start = rest.indexOf('@');
|
|
36
|
+
const { block, nextIndex } = extractTag(rest, start);
|
|
37
|
+
|
|
38
|
+
result.children.push(this.parse(block));
|
|
39
|
+
|
|
40
|
+
rest = rest.slice(0, start) + rest.slice(nextIndex);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const lines = rest.split('\n');
|
|
31
44
|
|
|
32
45
|
lines.forEach(line => {
|
|
33
46
|
const text = line.trim();
|
|
@@ -55,4 +68,29 @@ export class NeoParser {
|
|
|
55
68
|
|
|
56
69
|
return result;
|
|
57
70
|
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function extractTag(code, startIndex) {
|
|
74
|
+
let i = startIndex;
|
|
75
|
+
let depth = 0;
|
|
76
|
+
let opened = false;
|
|
77
|
+
|
|
78
|
+
while (i < code.length) {
|
|
79
|
+
if (code[i] === '{') {
|
|
80
|
+
depth++;
|
|
81
|
+
opened = true;
|
|
82
|
+
} else if (code[i] === '}') {
|
|
83
|
+
depth--;
|
|
84
|
+
if (opened && depth === 0) {
|
|
85
|
+
i++; // 닫는 } 포함
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
i++;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
block: code.slice(startIndex, i).trim(),
|
|
94
|
+
nextIndex: i
|
|
95
|
+
};
|
|
58
96
|
}
|
package/core/NeoCore.js
CHANGED
|
@@ -7,8 +7,19 @@ export class NeoCore {
|
|
|
7
7
|
el.className = data.styles.join(' ');
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// 1️⃣ 텍스트 먼저
|
|
11
|
+
if (data.innerHTML) {
|
|
12
|
+
el.innerHTML = NeoCore.renderTemplate(data.innerHTML);
|
|
13
|
+
}
|
|
11
14
|
|
|
15
|
+
// 2️⃣ ⭐ 자식 태그 렌더링 (이게 핵심)
|
|
16
|
+
if (Array.isArray(data.children)) {
|
|
17
|
+
data.children.forEach(child => {
|
|
18
|
+
const childEl = NeoCore.create(child);
|
|
19
|
+
el.appendChild(childEl);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
(data.events || []).forEach(evt => {
|
|
13
24
|
el.addEventListener(evt.type, () => {
|
|
14
25
|
try {
|
package/package.json
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junnyontop-pixel/neo-app",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "나만의 커스텀 프레임워크 Neo",
|
|
5
5
|
"main": "core/NeoCore.js",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"neoc-init": "scripts/init.js"
|
|
9
|
-
},
|
|
10
7
|
"files": [
|
|
11
8
|
"compiler",
|
|
12
9
|
"core",
|
|
13
|
-
"scripts",
|
|
14
10
|
"index.html",
|
|
15
11
|
"src",
|
|
16
12
|
"README.md"
|
package/src/App.neo
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
@
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
@App:div [p-6, bg-gray-100] {
|
|
2
|
+
|
|
3
|
+
innerHTML: "Neo Nested Test"
|
|
4
|
+
|
|
5
|
+
@Header:div [mb-4, p-3, bg-white, rounded] {
|
|
6
|
+
|
|
7
|
+
@Title:h1 [text-2xl, font-bold] {
|
|
8
|
+
innerHTML: "Header Title"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@Sub:p [text-gray-500] {
|
|
12
|
+
innerHTML: "This is a nested paragraph"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Content:div [p-4, bg-blue-50, rounded] {
|
|
17
|
+
|
|
18
|
+
@Counter:p [mb-2] {
|
|
19
|
+
innerHTML: "Count: $Store.count"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Button:button [px-3, py-2, bg-blue-600, text-white, rounded] {
|
|
23
|
+
innerHTML: "Increase"
|
|
24
|
+
on:click: Store.add()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
4
28
|
}
|