@junnyontop-pixel/neo-app 2.5.0 → 2.5.2
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 +46 -33
- package/core/NeoCore.js +27 -0
- package/package.json +1 -1
- package/src/App.neo +1 -1
- package/src/state.js +3 -1
package/compiler/NeoParser.js
CHANGED
|
@@ -34,27 +34,38 @@ export class NeoParser {
|
|
|
34
34
|
if (contentMatch) {
|
|
35
35
|
let rest = contentMatch[1].trim();
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
while (rest.includes('::if')) {
|
|
38
|
+
const start = rest.indexOf('::if');
|
|
39
|
+
|
|
40
|
+
const conditionMatch = rest.slice(start).match(/::if\s*\((.*?)\)/);
|
|
41
|
+
const condition = conditionMatch ? conditionMatch[1].trim() : "true";
|
|
42
|
+
|
|
43
|
+
const { block, nextIndex } = extractBlock(rest, start);
|
|
44
|
+
const dummyParsed = this.parse(`@if-container:div { ${block} }`);
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
result.children.push({
|
|
47
|
+
type: "ifBlock",
|
|
48
|
+
condition: condition,
|
|
49
|
+
children: dummyParsed.children,
|
|
50
|
+
_pos: start
|
|
51
|
+
});
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
// rest = rest.slice(0, start) + rest.slice(nextIndex);
|
|
54
|
+
rest = rest.slice(0, start) + " ".repeat(nextIndex - start) + rest.slice(nextIndex);
|
|
55
|
+
}
|
|
49
56
|
|
|
50
57
|
// ✅ 1) children 태그들 파싱
|
|
51
58
|
while (rest.includes('@')) {
|
|
52
59
|
const start = rest.indexOf('@');
|
|
53
60
|
const { block, nextIndex } = extractTag(rest, start);
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
const childNode = this.parse(block);
|
|
63
|
+
childNode._pos = start;
|
|
56
64
|
|
|
57
|
-
|
|
65
|
+
result.children.push(childNode);
|
|
66
|
+
|
|
67
|
+
// rest = rest.slice(0, start) + rest.slice(nextIndex);
|
|
68
|
+
rest = rest.slice(0, start) + " ".repeat(nextIndex - start) + rest.slice(nextIndex);
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
// ✅ 2) ::attrs 메타 블록 파싱
|
|
@@ -64,34 +75,36 @@ export class NeoParser {
|
|
|
64
75
|
|
|
65
76
|
result.attrs = parseAttrs(block);
|
|
66
77
|
|
|
67
|
-
rest = rest.slice(0, start) + rest.slice(nextIndex);
|
|
78
|
+
rest = rest.slice(0, start) + " ".repeat(nextIndex - start) + rest.slice(nextIndex);
|
|
68
79
|
}
|
|
69
80
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
result.children.sort((a, b) => a._pos - b._pos);
|
|
82
|
+
|
|
83
|
+
// // ✅ 3) ::if 조건 렌더링 파싱 // 순서 옮기기
|
|
84
|
+
// while (rest.includes('::if')) {
|
|
85
|
+
// const start = rest.indexOf('::if');
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
// // 1. 조건식 파싱
|
|
88
|
+
// const conditionMatch = rest.slice(start).match(/::if\s*\((.*?)\)/);
|
|
89
|
+
// const condition = conditionMatch ? conditionMatch[1].trim() : "true";
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
// // 2. 블록 파싱
|
|
92
|
+
// // startIndex를 주면 알아서 가장 가까운 { } 블록을 찾아줌
|
|
93
|
+
// const { block, nextIndex } = extractBlock(rest, start);
|
|
81
94
|
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
// // 3. 재귀 파싱
|
|
96
|
+
// const dummyParsed = this.parse(`@if-container:div { ${block} }`);
|
|
84
97
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
// // 4. 결과 저장
|
|
99
|
+
// result.children.push({
|
|
100
|
+
// type: "ifBlock",
|
|
101
|
+
// condition: condition,
|
|
102
|
+
// children: dummyParsed.children
|
|
103
|
+
// });
|
|
91
104
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
105
|
+
// // 5. 처리한 문자열 잘라내기 (무한 루프 방지)
|
|
106
|
+
// rest = rest.slice(0, start) + rest.slice(nextIndex);
|
|
107
|
+
// }
|
|
95
108
|
|
|
96
109
|
// ✅ 4) 남은 것에서 innerHTML / on: 만 파싱
|
|
97
110
|
const lines = rest.split('\n');
|
package/core/NeoCore.js
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
export class NeoCore {
|
|
2
2
|
static create(data) {
|
|
3
|
+
|
|
4
|
+
if (data.type === "ifBlock") {
|
|
5
|
+
let isTrue = false;
|
|
6
|
+
try {
|
|
7
|
+
// "$Store.state" -> "false" 로 변환
|
|
8
|
+
const conditionStr = NeoCore.renderTemplate(data.condition);
|
|
9
|
+
// "return false" 를 자바스크립트로 실행해서 진짜 false로 만듦
|
|
10
|
+
isTrue = new Function(`return ${conditionStr}`)();
|
|
11
|
+
} catch (e) {
|
|
12
|
+
console.warn("Neo if condition error:", e);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (isTrue) {
|
|
16
|
+
// 참일 때: 껍데기(div) 없이 알맹이만 DocumentFragment로 묶어서 반환
|
|
17
|
+
const frag = document.createDocumentFragment();
|
|
18
|
+
if (Array.isArray(data.children)) {
|
|
19
|
+
data.children.forEach(child => {
|
|
20
|
+
frag.appendChild(NeoCore.create(child));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return frag;
|
|
24
|
+
} else {
|
|
25
|
+
// 거짓일 때: 화면에 아무것도 안 그리는 '빈 텍스트 노드' 반환 ⭐ (이게 핵심!)
|
|
26
|
+
return document.createTextNode('');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
3
30
|
const el = document.createElement(data.tag || 'div');
|
|
4
31
|
|
|
5
32
|
if (data.id) el.id = data.id;
|
package/package.json
CHANGED
package/src/App.neo
CHANGED