bobe 0.0.15 → 0.0.17
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/bobe.cjs.js +335 -285
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +337 -287
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +54 -63
- package/dist/index.umd.js +335 -285
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.umd.js
CHANGED
|
@@ -15,25 +15,27 @@
|
|
|
15
15
|
TokenType2[TokenType2["InsertionExp"] = 128] = "InsertionExp";
|
|
16
16
|
return TokenType2;
|
|
17
17
|
})(TokenType || {});
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
18
|
+
var FakeType = /* @__PURE__ */ ((FakeType2) => {
|
|
19
|
+
FakeType2[FakeType2["If"] = 1] = "If";
|
|
20
|
+
FakeType2[FakeType2["Fail"] = 2] = "Fail";
|
|
21
|
+
FakeType2[FakeType2["Else"] = 4] = "Else";
|
|
22
|
+
FakeType2[FakeType2["For"] = 8] = "For";
|
|
23
|
+
FakeType2[FakeType2["Component"] = 16] = "Component";
|
|
24
|
+
FakeType2[FakeType2["Fragment"] = 32] = "Fragment";
|
|
25
|
+
FakeType2[FakeType2["ForItem"] = 64] = "ForItem";
|
|
26
|
+
return FakeType2;
|
|
27
|
+
})(FakeType || {});
|
|
28
|
+
const CondBit = 1 /* If */ | 2 /* Fail */ | 4 /* Else */;
|
|
29
|
+
const LogicalBit = 1 /* If */ | 2 /* Fail */ | 4 /* Else */ | 8 /* For */ | 64 /* ForItem */;
|
|
30
|
+
const TokenizerSwitcherBit = 16 /* Component */ | 32 /* Fragment */;
|
|
31
|
+
var NodeSort = /* @__PURE__ */ ((NodeSort2) => {
|
|
32
|
+
NodeSort2[NodeSort2["Logic"] = 1] = "Logic";
|
|
33
|
+
NodeSort2[NodeSort2["Real"] = 2] = "Real";
|
|
34
|
+
NodeSort2[NodeSort2["Component"] = 4] = "Component";
|
|
35
|
+
NodeSort2[NodeSort2["CtxProvider"] = 8] = "CtxProvider";
|
|
36
|
+
NodeSort2[NodeSort2["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
|
|
37
|
+
return NodeSort2;
|
|
38
|
+
})(NodeSort || {});
|
|
37
39
|
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
38
40
|
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
39
41
|
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
@@ -41,140 +43,123 @@
|
|
|
41
43
|
})(TerpEvt || {});
|
|
42
44
|
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
43
45
|
|
|
44
|
-
class
|
|
46
|
+
class MultiTypeStack {
|
|
45
47
|
constructor() {
|
|
48
|
+
// 记录全局栈顶
|
|
46
49
|
this.top = null;
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
this.lastNodes = {};
|
|
50
|
+
// 记录每个类别的当前最新节点(各分类的“栈顶”)
|
|
51
|
+
this.typeTops = {};
|
|
50
52
|
this.length = 0;
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @param
|
|
55
|
+
* 入栈操作
|
|
56
|
+
* @param value 数据
|
|
57
|
+
* @param bits 该节点所属的类别数组
|
|
55
58
|
*/
|
|
56
|
-
push(
|
|
57
|
-
var _a;
|
|
59
|
+
push(value, bits) {
|
|
58
60
|
const newNode = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
value,
|
|
62
|
+
types: bits,
|
|
63
|
+
prevGlobal: this.top,
|
|
64
|
+
prevByType: {}
|
|
63
65
|
};
|
|
66
|
+
let bit;
|
|
67
|
+
while (1) {
|
|
68
|
+
bit = bits & ~bits + 1;
|
|
69
|
+
if (!bit) break;
|
|
70
|
+
bits &= ~bit;
|
|
71
|
+
newNode.prevByType[bit] = this.typeTops[bit] || void 0;
|
|
72
|
+
this.typeTops[bit] = newNode;
|
|
73
|
+
}
|
|
64
74
|
this.top = newNode;
|
|
65
75
|
this.length++;
|
|
66
|
-
this.lastNodes[type] = newNode;
|
|
67
76
|
}
|
|
68
77
|
/**
|
|
69
78
|
* 出栈操作
|
|
70
|
-
* @returns 原始节点数据或 null
|
|
71
79
|
*/
|
|
72
80
|
pop() {
|
|
73
|
-
if (!this.top) return
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
if (!this.top) return void 0;
|
|
82
|
+
const poppedNode = this.top;
|
|
83
|
+
let { types: bits } = poppedNode;
|
|
84
|
+
let bit;
|
|
85
|
+
while (1) {
|
|
86
|
+
bit = bits & ~bits + 1;
|
|
87
|
+
if (!bit) break;
|
|
88
|
+
bits &= ~bit;
|
|
89
|
+
this.typeTops[bit] = poppedNode.prevByType[bit];
|
|
90
|
+
}
|
|
91
|
+
this.top = poppedNode.prevGlobal;
|
|
77
92
|
this.length--;
|
|
78
|
-
return
|
|
93
|
+
return [poppedNode.value, poppedNode.types];
|
|
79
94
|
}
|
|
80
95
|
/**
|
|
81
|
-
*
|
|
96
|
+
* 获取某个类别的当前“顶部”元素
|
|
82
97
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
return this.top.prevSameType.data;
|
|
88
|
-
}
|
|
89
|
-
findPrevSameType(cb) {
|
|
90
|
-
if (!this.top) {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
let point = this.top.prevSameType;
|
|
94
|
-
while (point) {
|
|
95
|
-
if (cb(point.data)) {
|
|
96
|
-
return point.data;
|
|
97
|
-
}
|
|
98
|
-
point = point.prevSameType;
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
98
|
+
peekByType(cat) {
|
|
99
|
+
var _a;
|
|
100
|
+
return (_a = this.typeTops[cat]) == null ? void 0 : _a.value;
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
get peekType() {
|
|
106
|
-
return this.top ? this.top.type : null;
|
|
102
|
+
peekType() {
|
|
103
|
+
var _a;
|
|
104
|
+
return (_a = this.top) == null ? void 0 : _a.types;
|
|
107
105
|
}
|
|
108
106
|
/**
|
|
109
|
-
*
|
|
107
|
+
* 获取全局栈顶
|
|
110
108
|
*/
|
|
111
109
|
peek() {
|
|
112
|
-
|
|
110
|
+
var _a;
|
|
111
|
+
return (_a = this.top) == null ? void 0 : _a.value;
|
|
113
112
|
}
|
|
113
|
+
// /**
|
|
114
|
+
// * 1. 全局向前遍历 (不分类)
|
|
115
|
+
// * 从栈顶开始,沿着全局链条向栈底遍历
|
|
116
|
+
// */
|
|
117
|
+
// forEach(callback: (value: T, types: number) => any): void {
|
|
118
|
+
// let current = this.top;
|
|
119
|
+
// while (current !== null) {
|
|
120
|
+
// // 执行回调,如果返回 false 则立即停止
|
|
121
|
+
// const shouldBreak = callback(current.value, current.types);
|
|
122
|
+
// if (shouldBreak) break;
|
|
123
|
+
// current = current.prevGlobal;
|
|
124
|
+
// }
|
|
125
|
+
// }
|
|
126
|
+
// /**
|
|
127
|
+
// * 2. 按类别向前遍历
|
|
128
|
+
// * 仅遍历属于指定类别 cat 的节点
|
|
129
|
+
// */
|
|
130
|
+
// forEachByType(cat: number, callback: (value: T) => any): void {
|
|
131
|
+
// // 从该类别的当前“顶端”节点开始
|
|
132
|
+
// let current = this.typeTops[cat];
|
|
133
|
+
// while (current) {
|
|
134
|
+
// const shouldBreak = callback(current.value);
|
|
135
|
+
// if (shouldBreak) break;
|
|
136
|
+
// // 关键点:直接跳向该节点记录的“上一个同类节点”
|
|
137
|
+
// // 这比遍历全局栈再筛选类别要快得多 (O(m) vs O(n))
|
|
138
|
+
// current = current.prevByType[cat];
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
var __defProp$1 = Object.defineProperty;
|
|
117
|
-
var __defProps$1 = Object.defineProperties;
|
|
118
|
-
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
119
|
-
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
120
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
121
|
-
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
122
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
123
|
-
var __spreadValues$1 = (a, b) => {
|
|
124
|
-
for (var prop in b || (b = {}))
|
|
125
|
-
if (__hasOwnProp$1.call(b, prop))
|
|
126
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
127
|
-
if (__getOwnPropSymbols$1)
|
|
128
|
-
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
129
|
-
if (__propIsEnum$1.call(b, prop))
|
|
130
|
-
__defNormalProp$1(a, prop, b[prop]);
|
|
131
|
-
}
|
|
132
|
-
return a;
|
|
133
|
-
};
|
|
134
|
-
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
135
143
|
const tap = new bobeShared.BaseEvent();
|
|
136
144
|
class Interpreter {
|
|
137
145
|
constructor(tokenizer) {
|
|
138
146
|
this.tokenizer = tokenizer;
|
|
139
|
-
|
|
140
|
-
this.HookId = "_h_o_o_k_";
|
|
141
|
-
/** 用于渲染的数据 */
|
|
142
|
-
this.data = {};
|
|
143
|
-
/** 模板字符串动态节点索引 */
|
|
144
|
-
this.hookI = 0;
|
|
145
|
-
this._hook = (props) => {
|
|
146
|
-
const value = this.tokenizer.token.value;
|
|
147
|
-
const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
|
|
148
|
-
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
149
|
-
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
150
|
-
if (this.hook && isStaticHook) {
|
|
151
|
-
const hookI = Number(value.slice(this.HookId.length));
|
|
152
|
-
const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
|
|
153
|
-
HookId: this.HookId,
|
|
154
|
-
i: hookI
|
|
155
|
-
}));
|
|
156
|
-
this.hookI++;
|
|
157
|
-
return [hookType, res];
|
|
158
|
-
} else if (isDynamicHook) {
|
|
159
|
-
return [hookType, value];
|
|
160
|
-
}
|
|
161
|
-
return [hookType, value];
|
|
162
|
-
};
|
|
147
|
+
this.rootComponent = null;
|
|
163
148
|
}
|
|
164
149
|
isLogicNode(node) {
|
|
165
|
-
return node && node.__logicType &
|
|
150
|
+
return node && node.__logicType & LogicalBit;
|
|
166
151
|
}
|
|
167
|
-
program(root, before) {
|
|
168
|
-
var _a;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const ctx = {
|
|
152
|
+
program(root, componentNode, before) {
|
|
153
|
+
var _a, _b;
|
|
154
|
+
this.rootComponent = componentNode;
|
|
155
|
+
this.tokenizer.nextToken();
|
|
156
|
+
const stack = new MultiTypeStack();
|
|
157
|
+
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
158
|
+
stack.push(
|
|
159
|
+
{ node: componentNode, prev: null },
|
|
160
|
+
NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher
|
|
161
|
+
);
|
|
162
|
+
const ctx = this.ctx = {
|
|
178
163
|
realParent: root,
|
|
179
164
|
prevSibling: before,
|
|
180
165
|
current: null,
|
|
@@ -190,14 +175,14 @@
|
|
|
190
175
|
}
|
|
191
176
|
const token = this.tokenizer.token;
|
|
192
177
|
if (token.type & TokenType.Indent) {
|
|
193
|
-
this.tokenizer.
|
|
178
|
+
this.tokenizer.nextToken();
|
|
194
179
|
const isLogicNode = this.isLogicNode(ctx.current);
|
|
195
180
|
stack.push(
|
|
196
181
|
{
|
|
197
182
|
node: ctx.current,
|
|
198
183
|
prev: ctx.prevSibling
|
|
199
184
|
},
|
|
200
|
-
ctx.current.__logicType ?
|
|
185
|
+
!ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider
|
|
201
186
|
);
|
|
202
187
|
if (ctx.current.__logicType) {
|
|
203
188
|
if (isLogicNode) {
|
|
@@ -213,28 +198,31 @@
|
|
|
213
198
|
continue;
|
|
214
199
|
}
|
|
215
200
|
if (ctx.current) {
|
|
216
|
-
if (stack.length ===
|
|
201
|
+
if (stack.length === 2 && !ctx.prevSibling) {
|
|
217
202
|
ctx.prevSibling = before;
|
|
218
203
|
}
|
|
219
204
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
220
205
|
}
|
|
221
206
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
222
|
-
this.tokenizer.
|
|
223
|
-
const { node: parent, prev } = stack.
|
|
207
|
+
this.tokenizer.nextToken();
|
|
208
|
+
const [{ node: parent, prev }, sort] = stack.pop();
|
|
224
209
|
if (!parent.__logicType) {
|
|
225
|
-
const prevSameType = stack.
|
|
210
|
+
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
226
211
|
ctx.realParent = (prevSameType == null ? void 0 : prevSameType.node) || root;
|
|
227
212
|
} else {
|
|
228
|
-
if (
|
|
229
|
-
const parentLogic = (_a = stack.
|
|
213
|
+
if (sort & NodeSort.Logic) {
|
|
214
|
+
const parentLogic = (_a = stack.peekByType(NodeSort.Logic)) == null ? void 0 : _a.node;
|
|
230
215
|
if (parentLogic) {
|
|
231
216
|
aoye.setPulling(parentLogic.effect.ins);
|
|
232
217
|
} else {
|
|
233
218
|
aoye.setPulling(rootPulling);
|
|
234
219
|
}
|
|
235
220
|
}
|
|
221
|
+
if (sort & NodeSort.TokenizerSwitcher) {
|
|
222
|
+
const switcher = (_b = stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _b.node;
|
|
223
|
+
this.tokenizer = switcher.tokenizer;
|
|
224
|
+
}
|
|
236
225
|
}
|
|
237
|
-
stack.pop();
|
|
238
226
|
ctx.prevSibling = prev;
|
|
239
227
|
ctx.current = parent;
|
|
240
228
|
} else {
|
|
@@ -244,10 +232,15 @@
|
|
|
244
232
|
}
|
|
245
233
|
return componentNode;
|
|
246
234
|
}
|
|
235
|
+
switcherIsRootComponent() {
|
|
236
|
+
var _a;
|
|
237
|
+
const currentSwitcher = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
238
|
+
return currentSwitcher === this.rootComponent;
|
|
239
|
+
}
|
|
247
240
|
insertAfterAnchor(ctx) {
|
|
248
241
|
const { realParent, prevSibling, stack, before } = ctx;
|
|
249
242
|
const afterAnchor = this.createAnchor();
|
|
250
|
-
ctx.prevSibling = stack.length ===
|
|
243
|
+
ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
251
244
|
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
252
245
|
return afterAnchor;
|
|
253
246
|
}
|
|
@@ -294,7 +287,7 @@
|
|
|
294
287
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
295
288
|
* */
|
|
296
289
|
declaration(ctx) {
|
|
297
|
-
const [hookType, value] = this._hook({});
|
|
290
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
298
291
|
let _node;
|
|
299
292
|
if (value === "if" || value === "else" || value === "fail") {
|
|
300
293
|
return this.condDeclaration(ctx);
|
|
@@ -303,34 +296,42 @@
|
|
|
303
296
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
304
297
|
_node = this.componentDeclaration(value, ctx);
|
|
305
298
|
} else if (typeof value === "function") {
|
|
306
|
-
_node = this.fragmentDeclaration(value);
|
|
299
|
+
_node = this.fragmentDeclaration(value, ctx);
|
|
307
300
|
} else {
|
|
308
301
|
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
309
302
|
}
|
|
310
303
|
} else {
|
|
311
|
-
|
|
304
|
+
const data = this.getData();
|
|
305
|
+
Boolean(data[aoye.Keys.Raw][value]);
|
|
312
306
|
new Function("data", `let v;with(data){v=(${value})};return v`);
|
|
313
307
|
_node = this.createNode(value);
|
|
314
308
|
}
|
|
315
309
|
} else {
|
|
316
310
|
_node = this.createNode(value);
|
|
317
311
|
}
|
|
318
|
-
this.tokenizer.
|
|
312
|
+
this.tokenizer.nextToken();
|
|
319
313
|
this.headerLine(_node);
|
|
320
314
|
this.extensionLines(_node);
|
|
321
|
-
if (_node.__logicType ===
|
|
315
|
+
if (_node.__logicType === FakeType.Component) {
|
|
322
316
|
tap.once(TerpEvt.HandledComponentNode, (node) => _node = node);
|
|
323
317
|
tap.emit(TerpEvt.AllAttrGot);
|
|
324
318
|
}
|
|
325
319
|
return _node;
|
|
326
320
|
}
|
|
321
|
+
getData() {
|
|
322
|
+
const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
|
|
323
|
+
return node.data || node.owner.data;
|
|
324
|
+
}
|
|
327
325
|
// TODO: 指定挂载位置
|
|
328
|
-
fragmentDeclaration(renderFragment) {
|
|
326
|
+
fragmentDeclaration(renderFragment, ctx) {
|
|
327
|
+
const data = this.getData();
|
|
328
|
+
const tokenizer = renderFragment.call(data, this.opt, { data, root: "", anchor: "" });
|
|
329
329
|
const fragmentNode = {
|
|
330
|
-
__logicType:
|
|
331
|
-
realParent: null
|
|
330
|
+
__logicType: FakeType.Fragment,
|
|
331
|
+
realParent: null,
|
|
332
|
+
tokenizer,
|
|
333
|
+
data: null
|
|
332
334
|
};
|
|
333
|
-
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
334
335
|
return fragmentNode;
|
|
335
336
|
}
|
|
336
337
|
/**
|
|
@@ -341,15 +342,17 @@
|
|
|
341
342
|
*
|
|
342
343
|
* mapKey 映射, 对应子组件的属性
|
|
343
344
|
* */
|
|
344
|
-
onePropParsed(node, key, value, valueIsMapKey, hookI) {
|
|
345
|
-
if (
|
|
345
|
+
onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
|
|
346
|
+
if (isFn) {
|
|
347
|
+
this.setProp(node, key, value, hookI);
|
|
348
|
+
} else if (typeof value === "function") {
|
|
346
349
|
aoye.effect(() => {
|
|
347
350
|
const res = value();
|
|
348
351
|
this.setProp(node, key, res, hookI);
|
|
349
352
|
});
|
|
350
353
|
} else if (valueIsMapKey) {
|
|
351
354
|
aoye.effect(() => {
|
|
352
|
-
const res =
|
|
355
|
+
const res = data[value];
|
|
353
356
|
this.setProp(node, key, res, hookI);
|
|
354
357
|
});
|
|
355
358
|
} else {
|
|
@@ -358,10 +361,18 @@
|
|
|
358
361
|
}
|
|
359
362
|
componentDeclaration(Component, ctx) {
|
|
360
363
|
const child = Component.new();
|
|
364
|
+
const componentNode = {
|
|
365
|
+
__logicType: FakeType.Component,
|
|
366
|
+
realParent: ctx.realParent,
|
|
367
|
+
data: child,
|
|
368
|
+
tokenizer: null
|
|
369
|
+
};
|
|
361
370
|
const prevOnePropParsed = this.onePropParsed;
|
|
362
|
-
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
363
|
-
if (
|
|
364
|
-
aoye.
|
|
371
|
+
this.onePropParsed = (data, node, key, value, valueIsMapKey, isFn, hookI) => {
|
|
372
|
+
if (isFn) {
|
|
373
|
+
child[aoye.Keys.Raw][key] = value;
|
|
374
|
+
} else if (valueIsMapKey) {
|
|
375
|
+
aoye.shareSignal(data, value, child, key);
|
|
365
376
|
} else if (typeof value === "function") {
|
|
366
377
|
const meta = child[aoye.Keys.Meta];
|
|
367
378
|
const cells = meta.cells;
|
|
@@ -371,37 +382,41 @@
|
|
|
371
382
|
child[aoye.Keys.Raw][key] = value;
|
|
372
383
|
}
|
|
373
384
|
};
|
|
374
|
-
|
|
385
|
+
componentNode.realAfter = this.insertAfterAnchor(ctx);
|
|
375
386
|
const { realParent, prevSibling } = ctx;
|
|
376
387
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
377
|
-
const parent = realParent;
|
|
378
|
-
const prev = prevSibling;
|
|
379
388
|
this.onePropParsed = prevOnePropParsed;
|
|
380
|
-
const
|
|
381
|
-
componentNode.
|
|
389
|
+
const subTkr = child["ui"](true);
|
|
390
|
+
componentNode.tokenizer = subTkr;
|
|
391
|
+
this.tokenizer = subTkr;
|
|
382
392
|
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
383
393
|
});
|
|
384
|
-
return
|
|
394
|
+
return componentNode;
|
|
385
395
|
}
|
|
386
396
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
387
397
|
condDeclaration(ctx) {
|
|
398
|
+
var _a;
|
|
388
399
|
const { prevSibling } = ctx;
|
|
389
400
|
const snapbackUp = this.tokenizer.snapshot();
|
|
390
|
-
const keyWord = this.tokenizer.
|
|
401
|
+
const keyWord = this.tokenizer.token;
|
|
402
|
+
this.tokenizer.nextToken();
|
|
391
403
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
392
|
-
const [hookType, value] = this._hook({});
|
|
404
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
393
405
|
const isElse = keyWord.value === "else";
|
|
394
406
|
const isIf = keyWord.value === "if";
|
|
395
|
-
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) &
|
|
407
|
+
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
|
|
396
408
|
const needCalcWithPrevIf = isElse && preIsCond;
|
|
409
|
+
const data = this.getData();
|
|
410
|
+
const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
397
411
|
const ifNode = {
|
|
398
|
-
__logicType: isElse ?
|
|
412
|
+
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
399
413
|
snapshot: noSelfCond ? snapbackUp : this.tokenizer.snapshot(),
|
|
400
414
|
condition: null,
|
|
401
415
|
realParent: null,
|
|
402
416
|
preCond: preIsCond ? prevSibling : null,
|
|
403
417
|
isFirstRender: true,
|
|
404
|
-
effect: null
|
|
418
|
+
effect: null,
|
|
419
|
+
owner
|
|
405
420
|
};
|
|
406
421
|
let signal;
|
|
407
422
|
if (noSelfCond) {
|
|
@@ -412,7 +427,7 @@
|
|
|
412
427
|
if (point.condition.v) {
|
|
413
428
|
return false;
|
|
414
429
|
}
|
|
415
|
-
if (point.__logicType ===
|
|
430
|
+
if (point.__logicType === FakeType.If) {
|
|
416
431
|
break;
|
|
417
432
|
}
|
|
418
433
|
point = point.preCond;
|
|
@@ -432,13 +447,13 @@
|
|
|
432
447
|
});
|
|
433
448
|
}
|
|
434
449
|
} else {
|
|
435
|
-
const valueIsMapKey = Reflect.has(
|
|
450
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
436
451
|
if (valueIsMapKey && !needCalcWithPrevIf) {
|
|
437
|
-
aoye.runWithPulling(() =>
|
|
438
|
-
const { cells } =
|
|
452
|
+
aoye.runWithPulling(() => data[value], null);
|
|
453
|
+
const { cells } = data[aoye.Keys.Meta];
|
|
439
454
|
signal = cells.get(value);
|
|
440
455
|
} else {
|
|
441
|
-
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0,
|
|
456
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
442
457
|
if (needCalcWithPrevIf) {
|
|
443
458
|
signal = aoye.$(() => {
|
|
444
459
|
let point = ifNode.preCond;
|
|
@@ -446,7 +461,7 @@
|
|
|
446
461
|
if (point.condition.v) {
|
|
447
462
|
return false;
|
|
448
463
|
}
|
|
449
|
-
if (point.__logicType ===
|
|
464
|
+
if (point.__logicType === FakeType.If) {
|
|
450
465
|
break;
|
|
451
466
|
}
|
|
452
467
|
point = point.preCond;
|
|
@@ -465,12 +480,13 @@
|
|
|
465
480
|
if (val) {
|
|
466
481
|
if (ifNode.isFirstRender) {
|
|
467
482
|
if (!noSelfCond) {
|
|
468
|
-
this.tokenizer.
|
|
483
|
+
this.tokenizer.nextToken();
|
|
469
484
|
}
|
|
470
|
-
this.tokenizer.
|
|
485
|
+
this.tokenizer.nextToken();
|
|
471
486
|
} else {
|
|
487
|
+
this.tokenizer = ifNode.owner.tokenizer;
|
|
472
488
|
this.tokenizer.resume(ifNode.snapshot);
|
|
473
|
-
this.program(ifNode.realParent, ifNode.realBefore);
|
|
489
|
+
this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore);
|
|
474
490
|
}
|
|
475
491
|
} else {
|
|
476
492
|
if (ifNode.isFirstRender) {
|
|
@@ -481,7 +497,7 @@
|
|
|
481
497
|
this.tokenizer.skip();
|
|
482
498
|
} else {
|
|
483
499
|
const { realBefore, realAfter, realParent } = ifNode;
|
|
484
|
-
let point = realBefore ? this.nextSib(realBefore) : this.
|
|
500
|
+
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
485
501
|
while (point !== realAfter) {
|
|
486
502
|
const next = this.nextSib(point);
|
|
487
503
|
this.remove(point, realParent, realBefore);
|
|
@@ -501,15 +517,15 @@
|
|
|
501
517
|
*/
|
|
502
518
|
extensionLines(_node) {
|
|
503
519
|
while (1) {
|
|
504
|
-
if (
|
|
520
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
505
521
|
return;
|
|
506
522
|
}
|
|
507
|
-
this.tokenizer.
|
|
523
|
+
this.tokenizer.nextToken();
|
|
508
524
|
this.attributeList(_node);
|
|
509
|
-
if (
|
|
525
|
+
if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
510
526
|
return;
|
|
511
527
|
}
|
|
512
|
-
this.tokenizer.
|
|
528
|
+
this.tokenizer.nextToken();
|
|
513
529
|
}
|
|
514
530
|
}
|
|
515
531
|
/**
|
|
@@ -519,7 +535,7 @@
|
|
|
519
535
|
*/
|
|
520
536
|
headerLine(_node) {
|
|
521
537
|
this.attributeList(_node);
|
|
522
|
-
this.tokenizer.
|
|
538
|
+
this.tokenizer.nextToken();
|
|
523
539
|
}
|
|
524
540
|
/**
|
|
525
541
|
* 属性列表:
|
|
@@ -529,30 +545,33 @@
|
|
|
529
545
|
*
|
|
530
546
|
* <attribute> ::= <key> = <value>
|
|
531
547
|
* 1. 普通节点 执行 setProps 🪝
|
|
532
|
-
* 2. 组件节点
|
|
548
|
+
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
533
549
|
*/
|
|
534
550
|
attributeList(_node) {
|
|
535
551
|
let key, eq;
|
|
536
|
-
|
|
552
|
+
const data = this.getData();
|
|
553
|
+
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
537
554
|
if (key == null) {
|
|
538
555
|
key = this.tokenizer.token.value;
|
|
539
556
|
} else if (eq == null) {
|
|
540
557
|
eq = "=";
|
|
541
558
|
} else {
|
|
542
|
-
const [hookType, value] = this._hook({});
|
|
559
|
+
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
560
|
+
const rawVal = data[aoye.Keys.Raw][value];
|
|
561
|
+
const isFn = typeof rawVal === "function";
|
|
543
562
|
if (hookType === "dynamic") {
|
|
544
|
-
const valueIsMapKey = Reflect.has(
|
|
545
|
-
const fn = valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0,
|
|
546
|
-
this.onePropParsed(_node, key, fn, valueIsMapKey,
|
|
563
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
564
|
+
const fn = isFn ? rawVal : valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
565
|
+
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
547
566
|
} else if (hookType === "static") {
|
|
548
|
-
this.onePropParsed(_node, key, value, false,
|
|
567
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
549
568
|
} else {
|
|
550
|
-
this.onePropParsed(_node, key, value, false,
|
|
569
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
551
570
|
}
|
|
552
571
|
key = null;
|
|
553
572
|
eq = null;
|
|
554
573
|
}
|
|
555
|
-
this.tokenizer.
|
|
574
|
+
this.tokenizer.nextToken();
|
|
556
575
|
}
|
|
557
576
|
}
|
|
558
577
|
config(opt) {
|
|
@@ -569,7 +588,7 @@
|
|
|
569
588
|
nextSib(node) {
|
|
570
589
|
return node.nextSibling;
|
|
571
590
|
}
|
|
572
|
-
|
|
591
|
+
firstChild(node) {
|
|
573
592
|
return node.firstChild;
|
|
574
593
|
}
|
|
575
594
|
_createAnchor() {
|
|
@@ -613,28 +632,35 @@
|
|
|
613
632
|
setProp(node, key, value, hookI) {
|
|
614
633
|
node.props[key] = value;
|
|
615
634
|
}
|
|
616
|
-
init(fragments) {
|
|
617
|
-
if (typeof fragments === "string") {
|
|
618
|
-
this.tokenizer.setCode(fragments);
|
|
619
|
-
} else {
|
|
620
|
-
let code = "";
|
|
621
|
-
for (let i = 0; i < fragments.length - 1; i++) {
|
|
622
|
-
const fragment = fragments[i];
|
|
623
|
-
code += fragment + `${this.HookId}${i}`;
|
|
624
|
-
}
|
|
625
|
-
this.tokenizer.setCode(code + fragments[fragments.length - 1]);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
635
|
}
|
|
629
636
|
|
|
637
|
+
var __defProp = Object.defineProperty;
|
|
638
|
+
var __defProps = Object.defineProperties;
|
|
639
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
640
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
641
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
642
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
643
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
644
|
+
var __spreadValues = (a, b) => {
|
|
645
|
+
for (var prop in b || (b = {}))
|
|
646
|
+
if (__hasOwnProp.call(b, prop))
|
|
647
|
+
__defNormalProp(a, prop, b[prop]);
|
|
648
|
+
if (__getOwnPropSymbols)
|
|
649
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
650
|
+
if (__propIsEnum.call(b, prop))
|
|
651
|
+
__defNormalProp(a, prop, b[prop]);
|
|
652
|
+
}
|
|
653
|
+
return a;
|
|
654
|
+
};
|
|
655
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
630
656
|
const _Tokenizer = class _Tokenizer {
|
|
631
|
-
constructor() {
|
|
657
|
+
constructor(hook, isSubToken) {
|
|
658
|
+
this.hook = hook;
|
|
659
|
+
this.isSubToken = isSubToken;
|
|
632
660
|
/** 缩进大小 默认 2 */
|
|
633
661
|
this.TabSize = 2;
|
|
634
662
|
/** 缩进字符 */
|
|
635
663
|
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
636
|
-
/** 匹配标识符 */
|
|
637
|
-
this.IdExp = /[\d\w\/]/;
|
|
638
664
|
/** 回车后需要判断缩进 */
|
|
639
665
|
this.needIndent = false;
|
|
640
666
|
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
@@ -643,6 +669,7 @@
|
|
|
643
669
|
this.dentStack = [0];
|
|
644
670
|
/** 当前字符 index */
|
|
645
671
|
this.i = 0;
|
|
672
|
+
// TODO: 生产环境不需要这个,导致不必要的内存占用
|
|
646
673
|
this.handledTokens = [];
|
|
647
674
|
/**
|
|
648
675
|
* 有些标识符能产生多个 token
|
|
@@ -653,6 +680,31 @@
|
|
|
653
680
|
* parent2 <- 产生两个 dedent
|
|
654
681
|
*/
|
|
655
682
|
this.waitingTokens = new bobeShared.Queue();
|
|
683
|
+
/** 模板字符串动态节点的占位符 */
|
|
684
|
+
this.HookId = "_h_o_o_k_";
|
|
685
|
+
/** 模板字符串动态节点索引 */
|
|
686
|
+
this.hookI = 0;
|
|
687
|
+
this._hook = (props) => {
|
|
688
|
+
const value = this.token.value;
|
|
689
|
+
const isDynamicHook = this.token.type & TokenType.InsertionExp;
|
|
690
|
+
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
691
|
+
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
692
|
+
if (this.hook && isStaticHook) {
|
|
693
|
+
const hookI = Number(value.slice(this.HookId.length));
|
|
694
|
+
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
695
|
+
HookId: this.HookId,
|
|
696
|
+
i: hookI
|
|
697
|
+
}));
|
|
698
|
+
return [hookType, res, hookI];
|
|
699
|
+
} else if (isDynamicHook) {
|
|
700
|
+
return [hookType, value];
|
|
701
|
+
}
|
|
702
|
+
return [hookType, value];
|
|
703
|
+
};
|
|
704
|
+
if (isSubToken) {
|
|
705
|
+
this.setToken(TokenType.Indent, "");
|
|
706
|
+
this.isFirstToken = true;
|
|
707
|
+
}
|
|
656
708
|
}
|
|
657
709
|
consume() {
|
|
658
710
|
const token = this.token;
|
|
@@ -679,16 +731,16 @@
|
|
|
679
731
|
let skipFragment = ``;
|
|
680
732
|
this.token = void 0;
|
|
681
733
|
while (1) {
|
|
682
|
-
const char = this.
|
|
734
|
+
const char = this.code[this.i];
|
|
683
735
|
if (char === "\n") {
|
|
684
736
|
needIndent = true;
|
|
685
737
|
skipFragment += char;
|
|
686
|
-
this.
|
|
738
|
+
this.i++;
|
|
687
739
|
continue;
|
|
688
740
|
}
|
|
689
741
|
if (!needIndent) {
|
|
690
742
|
skipFragment += char;
|
|
691
|
-
this.
|
|
743
|
+
this.i++;
|
|
692
744
|
continue;
|
|
693
745
|
}
|
|
694
746
|
needIndent = false;
|
|
@@ -741,21 +793,6 @@ ${_Tokenizer.EofId}`;
|
|
|
741
793
|
if (!this.token) return false;
|
|
742
794
|
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
743
795
|
}
|
|
744
|
-
get char() {
|
|
745
|
-
return this.code[this.i];
|
|
746
|
-
}
|
|
747
|
-
get prev() {
|
|
748
|
-
return this.code[this.i - 1];
|
|
749
|
-
}
|
|
750
|
-
get after() {
|
|
751
|
-
return this.code[this.i + 1];
|
|
752
|
-
}
|
|
753
|
-
next() {
|
|
754
|
-
const prev = this.code[this.i];
|
|
755
|
-
this.i++;
|
|
756
|
-
const curr = this.code[this.i];
|
|
757
|
-
return [prev, curr];
|
|
758
|
-
}
|
|
759
796
|
setToken(type, value) {
|
|
760
797
|
this.token = {
|
|
761
798
|
type,
|
|
@@ -764,10 +801,6 @@ ${_Tokenizer.EofId}`;
|
|
|
764
801
|
};
|
|
765
802
|
this.isFirstToken = false;
|
|
766
803
|
}
|
|
767
|
-
testId(value) {
|
|
768
|
-
if (typeof value !== "string") return false;
|
|
769
|
-
return this.IdExp.test(value);
|
|
770
|
-
}
|
|
771
804
|
nextToken() {
|
|
772
805
|
try {
|
|
773
806
|
if (this.isEof()) {
|
|
@@ -783,7 +816,7 @@ ${_Tokenizer.EofId}`;
|
|
|
783
816
|
if (this.needIndent) {
|
|
784
817
|
this.dent();
|
|
785
818
|
} else {
|
|
786
|
-
|
|
819
|
+
const char = this.code[this.i];
|
|
787
820
|
switch (char) {
|
|
788
821
|
case " ":
|
|
789
822
|
case " ":
|
|
@@ -814,12 +847,12 @@ ${_Tokenizer.EofId}`;
|
|
|
814
847
|
this.number(char);
|
|
815
848
|
break;
|
|
816
849
|
}
|
|
817
|
-
if (
|
|
850
|
+
if (typeof char === "string" && bobeShared.matchIdStart(char)) {
|
|
818
851
|
this.identifier(char);
|
|
819
852
|
}
|
|
820
853
|
break;
|
|
821
854
|
}
|
|
822
|
-
this.
|
|
855
|
+
this.i++;
|
|
823
856
|
}
|
|
824
857
|
if (this.token) {
|
|
825
858
|
break;
|
|
@@ -828,6 +861,7 @@ ${_Tokenizer.EofId}`;
|
|
|
828
861
|
return this.token;
|
|
829
862
|
} catch (error) {
|
|
830
863
|
console.error(error);
|
|
864
|
+
return this.token;
|
|
831
865
|
} finally {
|
|
832
866
|
this.handledTokens.push(this.token);
|
|
833
867
|
}
|
|
@@ -839,17 +873,17 @@ ${_Tokenizer.EofId}`;
|
|
|
839
873
|
this.setToken(TokenType.Pipe, "|");
|
|
840
874
|
}
|
|
841
875
|
dynamic(char) {
|
|
842
|
-
let nextC = this.
|
|
876
|
+
let nextC = this.code[this.i + 1];
|
|
843
877
|
if (nextC !== "{") {
|
|
844
878
|
return false;
|
|
845
879
|
}
|
|
846
|
-
this.
|
|
880
|
+
this.i++;
|
|
847
881
|
let value = "${";
|
|
848
882
|
let innerBrace = 0;
|
|
849
883
|
while (1) {
|
|
850
|
-
nextC = this.
|
|
884
|
+
nextC = this.code[this.i + 1];
|
|
851
885
|
value += nextC;
|
|
852
|
-
this.
|
|
886
|
+
this.i++;
|
|
853
887
|
if (nextC === "{") {
|
|
854
888
|
innerBrace++;
|
|
855
889
|
}
|
|
@@ -866,13 +900,14 @@ ${_Tokenizer.EofId}`;
|
|
|
866
900
|
brace() {
|
|
867
901
|
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
868
902
|
while (1) {
|
|
869
|
-
const char = this.
|
|
870
|
-
const nextChar = this.
|
|
903
|
+
const char = this.code[this.i];
|
|
904
|
+
const nextChar = this.code[this.i + 1];
|
|
871
905
|
if (inComment === "single" && char === "\n") {
|
|
872
906
|
inComment = null;
|
|
873
907
|
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
874
908
|
inComment = null;
|
|
875
|
-
value += this.
|
|
909
|
+
value += this.code[this.i];
|
|
910
|
+
this.i++;
|
|
876
911
|
} else if (inString) {
|
|
877
912
|
if (char === inString && backslashCount % 2 === 0) {
|
|
878
913
|
inString = null;
|
|
@@ -881,10 +916,12 @@ ${_Tokenizer.EofId}`;
|
|
|
881
916
|
} else {
|
|
882
917
|
if (char === "/" && nextChar === "/") {
|
|
883
918
|
inComment = "single";
|
|
884
|
-
value += this.
|
|
919
|
+
value += this.code[this.i];
|
|
920
|
+
this.i++;
|
|
885
921
|
} else if (char === "/" && nextChar === "*") {
|
|
886
922
|
inComment = "multi";
|
|
887
|
-
value += this.
|
|
923
|
+
value += this.code[this.i];
|
|
924
|
+
this.i++;
|
|
888
925
|
} else if (char === "'" || char === '"' || char === "`") {
|
|
889
926
|
inString = char;
|
|
890
927
|
} else if (char === "{") {
|
|
@@ -897,19 +934,20 @@ ${_Tokenizer.EofId}`;
|
|
|
897
934
|
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
898
935
|
return;
|
|
899
936
|
}
|
|
900
|
-
value += this.
|
|
937
|
+
value += this.code[this.i];
|
|
938
|
+
this.i++;
|
|
901
939
|
}
|
|
902
940
|
}
|
|
903
941
|
newLine() {
|
|
904
942
|
let value = "\n";
|
|
905
943
|
let nextC;
|
|
906
944
|
while (1) {
|
|
907
|
-
nextC = this.
|
|
945
|
+
nextC = this.code[this.i + 1];
|
|
908
946
|
if (nextC !== "\n") {
|
|
909
947
|
break;
|
|
910
948
|
}
|
|
911
949
|
value += nextC;
|
|
912
|
-
this.
|
|
950
|
+
this.i++;
|
|
913
951
|
}
|
|
914
952
|
if (this.isFirstToken) {
|
|
915
953
|
return;
|
|
@@ -921,7 +959,7 @@ ${_Tokenizer.EofId}`;
|
|
|
921
959
|
let nextC;
|
|
922
960
|
let isEmptyLine = false;
|
|
923
961
|
while (1) {
|
|
924
|
-
const nextChar = this.
|
|
962
|
+
const nextChar = this.code[this.i];
|
|
925
963
|
switch (nextChar) {
|
|
926
964
|
case " ":
|
|
927
965
|
nextC = this.Tab;
|
|
@@ -944,7 +982,7 @@ ${_Tokenizer.EofId}`;
|
|
|
944
982
|
break;
|
|
945
983
|
}
|
|
946
984
|
value += nextC;
|
|
947
|
-
this.
|
|
985
|
+
this.i++;
|
|
948
986
|
}
|
|
949
987
|
return {
|
|
950
988
|
value,
|
|
@@ -967,7 +1005,7 @@ ${_Tokenizer.EofId}`;
|
|
|
967
1005
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
968
1006
|
if (currLen > prevLen) {
|
|
969
1007
|
this.dentStack.push(currLen);
|
|
970
|
-
this.setToken(TokenType.Indent,
|
|
1008
|
+
this.setToken(TokenType.Indent, currLen);
|
|
971
1009
|
return indentHasLen;
|
|
972
1010
|
}
|
|
973
1011
|
if (currLen < prevLen) {
|
|
@@ -999,13 +1037,25 @@ ${_Tokenizer.EofId}`;
|
|
|
999
1037
|
const yes = this.dentStack.length === 1;
|
|
1000
1038
|
if (yes) {
|
|
1001
1039
|
if (!this.token) {
|
|
1002
|
-
this.
|
|
1040
|
+
if (this.isSubToken) {
|
|
1041
|
+
this.setToken(TokenType.Dedent, "");
|
|
1042
|
+
} else {
|
|
1043
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
1044
|
+
}
|
|
1003
1045
|
} else {
|
|
1004
|
-
this.
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1046
|
+
if (this.isSubToken) {
|
|
1047
|
+
this.waitingTokens.push({
|
|
1048
|
+
type: TokenType.Dedent,
|
|
1049
|
+
typeName: TokenType[TokenType.Dedent],
|
|
1050
|
+
value: ""
|
|
1051
|
+
});
|
|
1052
|
+
} else {
|
|
1053
|
+
this.waitingTokens.push({
|
|
1054
|
+
type: TokenType.Identifier,
|
|
1055
|
+
typeName: TokenType[TokenType.Identifier],
|
|
1056
|
+
value: _Tokenizer.EofId
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1009
1059
|
}
|
|
1010
1060
|
}
|
|
1011
1061
|
return yes;
|
|
@@ -1014,98 +1064,98 @@ ${_Tokenizer.EofId}`;
|
|
|
1014
1064
|
let value = char;
|
|
1015
1065
|
let nextC;
|
|
1016
1066
|
while (1) {
|
|
1017
|
-
nextC = this.
|
|
1018
|
-
if (!
|
|
1067
|
+
nextC = this.code[this.i + 1];
|
|
1068
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart(nextC)) {
|
|
1019
1069
|
break;
|
|
1020
1070
|
}
|
|
1021
1071
|
value += nextC;
|
|
1022
|
-
this.
|
|
1072
|
+
this.i++;
|
|
1073
|
+
}
|
|
1074
|
+
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1075
|
+
this.setToken(TokenType.Dedent, "");
|
|
1076
|
+
return;
|
|
1023
1077
|
}
|
|
1024
1078
|
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
1025
1079
|
this.setToken(TokenType.Identifier, realValue);
|
|
1026
1080
|
}
|
|
1027
1081
|
str(char) {
|
|
1028
|
-
let value =
|
|
1082
|
+
let value = "";
|
|
1029
1083
|
let nextC;
|
|
1030
1084
|
let continuousBackslashCount = 0;
|
|
1031
1085
|
while (1) {
|
|
1032
|
-
nextC = this.
|
|
1033
|
-
value += nextC;
|
|
1086
|
+
nextC = this.code[this.i + 1];
|
|
1034
1087
|
const memoCount = continuousBackslashCount;
|
|
1035
1088
|
if (nextC === "\\") {
|
|
1036
1089
|
continuousBackslashCount++;
|
|
1037
1090
|
} else {
|
|
1038
1091
|
continuousBackslashCount = 0;
|
|
1039
1092
|
}
|
|
1040
|
-
this.
|
|
1093
|
+
this.i++;
|
|
1041
1094
|
if (nextC === char && memoCount % 2 === 0) {
|
|
1042
1095
|
break;
|
|
1043
1096
|
}
|
|
1097
|
+
value += nextC;
|
|
1044
1098
|
}
|
|
1045
|
-
this.setToken(TokenType.Identifier,
|
|
1099
|
+
this.setToken(TokenType.Identifier, value);
|
|
1046
1100
|
}
|
|
1047
1101
|
number(char) {
|
|
1048
1102
|
let value = char;
|
|
1049
1103
|
let nextC;
|
|
1050
1104
|
while (1) {
|
|
1051
|
-
nextC = this.
|
|
1105
|
+
nextC = this.code[this.i + 1];
|
|
1052
1106
|
if (!bobeShared.isNum(nextC)) {
|
|
1053
1107
|
break;
|
|
1054
1108
|
}
|
|
1055
1109
|
value += nextC;
|
|
1056
|
-
this.
|
|
1110
|
+
this.i++;
|
|
1057
1111
|
}
|
|
1058
1112
|
this.setToken(TokenType.Identifier, Number(value));
|
|
1059
1113
|
}
|
|
1060
1114
|
eof() {
|
|
1061
1115
|
this.setToken(TokenType.Eof, "End Of File");
|
|
1062
1116
|
}
|
|
1117
|
+
init(fragments) {
|
|
1118
|
+
if (typeof fragments === "string") {
|
|
1119
|
+
this.setCode(fragments);
|
|
1120
|
+
} else {
|
|
1121
|
+
let code = "";
|
|
1122
|
+
for (let i = 0; i < fragments.length - 1; i++) {
|
|
1123
|
+
const fragment = fragments[i];
|
|
1124
|
+
code += fragment + `${this.HookId}${i}`;
|
|
1125
|
+
}
|
|
1126
|
+
this.setCode(code + fragments[fragments.length - 1]);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1063
1129
|
};
|
|
1064
1130
|
/** Eof 标识符的值 */
|
|
1065
1131
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1132
|
+
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|
|
1066
1133
|
let Tokenizer = _Tokenizer;
|
|
1067
1134
|
|
|
1068
|
-
var __defProp = Object.defineProperty;
|
|
1069
|
-
var __defProps = Object.defineProperties;
|
|
1070
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
1071
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
1072
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
1073
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1074
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1075
|
-
var __spreadValues = (a, b) => {
|
|
1076
|
-
for (var prop in b || (b = {}))
|
|
1077
|
-
if (__hasOwnProp.call(b, prop))
|
|
1078
|
-
__defNormalProp(a, prop, b[prop]);
|
|
1079
|
-
if (__getOwnPropSymbols)
|
|
1080
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
1081
|
-
if (__propIsEnum.call(b, prop))
|
|
1082
|
-
__defNormalProp(a, prop, b[prop]);
|
|
1083
|
-
}
|
|
1084
|
-
return a;
|
|
1085
|
-
};
|
|
1086
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
1087
1135
|
function bobe(fragments, ...values) {
|
|
1088
|
-
const ui = function ui2(
|
|
1089
|
-
const tokenizer = new Tokenizer()
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
return values[i];
|
|
1095
|
-
},
|
|
1096
|
-
setProp(node, key, value, hookI) {
|
|
1097
|
-
node.props[key] = value;
|
|
1098
|
-
}
|
|
1099
|
-
}));
|
|
1100
|
-
cmp.init(Array.from(fragments));
|
|
1101
|
-
return cmp.program(root, before);
|
|
1136
|
+
const ui = function ui2(isSub) {
|
|
1137
|
+
const tokenizer = new Tokenizer(({ i }) => {
|
|
1138
|
+
return values[i];
|
|
1139
|
+
}, isSub);
|
|
1140
|
+
tokenizer.init(Array.from(fragments));
|
|
1141
|
+
return tokenizer;
|
|
1102
1142
|
};
|
|
1103
1143
|
return ui;
|
|
1104
1144
|
}
|
|
1105
1145
|
function customRender(option) {
|
|
1106
1146
|
return function render(Ctor, root) {
|
|
1107
1147
|
const store = Ctor.new();
|
|
1108
|
-
|
|
1148
|
+
const tokenizer = store["ui"](false);
|
|
1149
|
+
const terp = new Interpreter(tokenizer);
|
|
1150
|
+
terp.config(option);
|
|
1151
|
+
const componentNode = {
|
|
1152
|
+
__logicType: FakeType.Component,
|
|
1153
|
+
realParent: root,
|
|
1154
|
+
data: store,
|
|
1155
|
+
tokenizer
|
|
1156
|
+
};
|
|
1157
|
+
terp.program(root, componentNode);
|
|
1158
|
+
return [componentNode, store];
|
|
1109
1159
|
};
|
|
1110
1160
|
}
|
|
1111
1161
|
|