bobe 0.0.15 → 0.0.16
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 +280 -219
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +281 -220
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +61 -53
- package/dist/index.umd.js +280 -219
- 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,119 @@
|
|
|
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;
|
|
98
|
+
peekByType(cat) {
|
|
99
|
+
var _a;
|
|
100
|
+
return (_a = this.typeTops[cat]) == null ? void 0 : _a.value;
|
|
88
101
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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;
|
|
102
|
+
peekType() {
|
|
103
|
+
var _a;
|
|
104
|
+
return (_a = this.top) == null ? void 0 : _a.types;
|
|
101
105
|
}
|
|
102
106
|
/**
|
|
103
|
-
*
|
|
107
|
+
* 获取全局栈顶
|
|
104
108
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
peek() {
|
|
110
|
+
var _a;
|
|
111
|
+
return (_a = this.top) == null ? void 0 : _a.value;
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
|
-
*
|
|
114
|
+
* 1. 全局向前遍历 (不分类)
|
|
115
|
+
* 从栈顶开始,沿着全局链条向栈底遍历
|
|
110
116
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
forEach(callback) {
|
|
118
|
+
let current = this.top;
|
|
119
|
+
while (current !== null) {
|
|
120
|
+
const shouldBreak = callback(current.value, current.types);
|
|
121
|
+
if (shouldBreak) break;
|
|
122
|
+
current = current.prevGlobal;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 2. 按类别向前遍历
|
|
127
|
+
* 仅遍历属于指定类别 cat 的节点
|
|
128
|
+
*/
|
|
129
|
+
forEachByType(cat, callback) {
|
|
130
|
+
let current = this.typeTops[cat];
|
|
131
|
+
while (current) {
|
|
132
|
+
const shouldBreak = callback(current.value);
|
|
133
|
+
if (shouldBreak) break;
|
|
134
|
+
current = current.prevByType[cat];
|
|
135
|
+
}
|
|
113
136
|
}
|
|
114
137
|
}
|
|
115
138
|
|
|
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
139
|
const tap = new bobeShared.BaseEvent();
|
|
136
140
|
class Interpreter {
|
|
137
141
|
constructor(tokenizer) {
|
|
138
142
|
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
|
-
};
|
|
143
|
+
this.rootComponent = null;
|
|
163
144
|
}
|
|
164
145
|
isLogicNode(node) {
|
|
165
|
-
return node && node.__logicType &
|
|
146
|
+
return node && node.__logicType & LogicalBit;
|
|
166
147
|
}
|
|
167
|
-
program(root, before) {
|
|
168
|
-
var _a;
|
|
169
|
-
|
|
170
|
-
__logicType: LogicType.Component,
|
|
171
|
-
realParent: root,
|
|
172
|
-
store: new aoye.Store()
|
|
173
|
-
};
|
|
148
|
+
program(root, componentNode, before) {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
this.rootComponent = componentNode;
|
|
174
151
|
this.tokenizer.consume();
|
|
175
|
-
const stack = new
|
|
176
|
-
stack.push({ node: root, prev: null },
|
|
177
|
-
|
|
152
|
+
const stack = new MultiTypeStack();
|
|
153
|
+
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
154
|
+
stack.push(
|
|
155
|
+
{ node: componentNode, prev: null },
|
|
156
|
+
NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher
|
|
157
|
+
);
|
|
158
|
+
const ctx = this.ctx = {
|
|
178
159
|
realParent: root,
|
|
179
160
|
prevSibling: before,
|
|
180
161
|
current: null,
|
|
@@ -197,7 +178,7 @@
|
|
|
197
178
|
node: ctx.current,
|
|
198
179
|
prev: ctx.prevSibling
|
|
199
180
|
},
|
|
200
|
-
ctx.current.__logicType ?
|
|
181
|
+
!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
182
|
);
|
|
202
183
|
if (ctx.current.__logicType) {
|
|
203
184
|
if (isLogicNode) {
|
|
@@ -213,28 +194,31 @@
|
|
|
213
194
|
continue;
|
|
214
195
|
}
|
|
215
196
|
if (ctx.current) {
|
|
216
|
-
if (stack.length ===
|
|
197
|
+
if (stack.length === 2 && !ctx.prevSibling) {
|
|
217
198
|
ctx.prevSibling = before;
|
|
218
199
|
}
|
|
219
200
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
220
201
|
}
|
|
221
202
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
222
203
|
this.tokenizer.consume();
|
|
223
|
-
const { node: parent, prev } = stack.
|
|
204
|
+
const [{ node: parent, prev }, sort] = stack.pop();
|
|
224
205
|
if (!parent.__logicType) {
|
|
225
|
-
const prevSameType = stack.
|
|
206
|
+
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
226
207
|
ctx.realParent = (prevSameType == null ? void 0 : prevSameType.node) || root;
|
|
227
208
|
} else {
|
|
228
|
-
if (
|
|
229
|
-
const parentLogic = (_a = stack.
|
|
209
|
+
if (sort & NodeSort.Logic) {
|
|
210
|
+
const parentLogic = (_a = stack.peekByType(NodeSort.Logic)) == null ? void 0 : _a.node;
|
|
230
211
|
if (parentLogic) {
|
|
231
212
|
aoye.setPulling(parentLogic.effect.ins);
|
|
232
213
|
} else {
|
|
233
214
|
aoye.setPulling(rootPulling);
|
|
234
215
|
}
|
|
235
216
|
}
|
|
217
|
+
if (sort & NodeSort.TokenizerSwitcher) {
|
|
218
|
+
const switcher = (_b = stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _b.node;
|
|
219
|
+
this.tokenizer = switcher.tokenizer;
|
|
220
|
+
}
|
|
236
221
|
}
|
|
237
|
-
stack.pop();
|
|
238
222
|
ctx.prevSibling = prev;
|
|
239
223
|
ctx.current = parent;
|
|
240
224
|
} else {
|
|
@@ -244,10 +228,15 @@
|
|
|
244
228
|
}
|
|
245
229
|
return componentNode;
|
|
246
230
|
}
|
|
231
|
+
switcherIsRootComponent() {
|
|
232
|
+
var _a;
|
|
233
|
+
const currentSwitcher = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
234
|
+
return currentSwitcher === this.rootComponent;
|
|
235
|
+
}
|
|
247
236
|
insertAfterAnchor(ctx) {
|
|
248
237
|
const { realParent, prevSibling, stack, before } = ctx;
|
|
249
238
|
const afterAnchor = this.createAnchor();
|
|
250
|
-
ctx.prevSibling = stack.length ===
|
|
239
|
+
ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
251
240
|
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
252
241
|
return afterAnchor;
|
|
253
242
|
}
|
|
@@ -294,7 +283,7 @@
|
|
|
294
283
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
295
284
|
* */
|
|
296
285
|
declaration(ctx) {
|
|
297
|
-
const [hookType, value] = this._hook({});
|
|
286
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
298
287
|
let _node;
|
|
299
288
|
if (value === "if" || value === "else" || value === "fail") {
|
|
300
289
|
return this.condDeclaration(ctx);
|
|
@@ -303,12 +292,13 @@
|
|
|
303
292
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
304
293
|
_node = this.componentDeclaration(value, ctx);
|
|
305
294
|
} else if (typeof value === "function") {
|
|
306
|
-
_node = this.fragmentDeclaration(value);
|
|
295
|
+
_node = this.fragmentDeclaration(value, ctx);
|
|
307
296
|
} else {
|
|
308
297
|
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
309
298
|
}
|
|
310
299
|
} else {
|
|
311
|
-
|
|
300
|
+
const data = this.getData();
|
|
301
|
+
Boolean(data[aoye.Keys.Raw][value]);
|
|
312
302
|
new Function("data", `let v;with(data){v=(${value})};return v`);
|
|
313
303
|
_node = this.createNode(value);
|
|
314
304
|
}
|
|
@@ -318,19 +308,26 @@
|
|
|
318
308
|
this.tokenizer.consume();
|
|
319
309
|
this.headerLine(_node);
|
|
320
310
|
this.extensionLines(_node);
|
|
321
|
-
if (_node.__logicType ===
|
|
311
|
+
if (_node.__logicType === FakeType.Component) {
|
|
322
312
|
tap.once(TerpEvt.HandledComponentNode, (node) => _node = node);
|
|
323
313
|
tap.emit(TerpEvt.AllAttrGot);
|
|
324
314
|
}
|
|
325
315
|
return _node;
|
|
326
316
|
}
|
|
317
|
+
getData() {
|
|
318
|
+
const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
|
|
319
|
+
return node.data || node.owner.data;
|
|
320
|
+
}
|
|
327
321
|
// TODO: 指定挂载位置
|
|
328
|
-
fragmentDeclaration(renderFragment) {
|
|
322
|
+
fragmentDeclaration(renderFragment, ctx) {
|
|
323
|
+
const data = this.getData();
|
|
324
|
+
const tokenizer = renderFragment.call(data, this.opt, { data, root: "", anchor: "" });
|
|
329
325
|
const fragmentNode = {
|
|
330
|
-
__logicType:
|
|
331
|
-
realParent: null
|
|
326
|
+
__logicType: FakeType.Fragment,
|
|
327
|
+
realParent: null,
|
|
328
|
+
tokenizer,
|
|
329
|
+
data: null
|
|
332
330
|
};
|
|
333
|
-
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
334
331
|
return fragmentNode;
|
|
335
332
|
}
|
|
336
333
|
/**
|
|
@@ -341,15 +338,17 @@
|
|
|
341
338
|
*
|
|
342
339
|
* mapKey 映射, 对应子组件的属性
|
|
343
340
|
* */
|
|
344
|
-
onePropParsed(node, key, value, valueIsMapKey, hookI) {
|
|
345
|
-
if (
|
|
341
|
+
onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
|
|
342
|
+
if (isFn) {
|
|
343
|
+
this.setProp(node, key, value, hookI);
|
|
344
|
+
} else if (typeof value === "function") {
|
|
346
345
|
aoye.effect(() => {
|
|
347
346
|
const res = value();
|
|
348
347
|
this.setProp(node, key, res, hookI);
|
|
349
348
|
});
|
|
350
349
|
} else if (valueIsMapKey) {
|
|
351
350
|
aoye.effect(() => {
|
|
352
|
-
const res =
|
|
351
|
+
const res = data[value];
|
|
353
352
|
this.setProp(node, key, res, hookI);
|
|
354
353
|
});
|
|
355
354
|
} else {
|
|
@@ -358,10 +357,18 @@
|
|
|
358
357
|
}
|
|
359
358
|
componentDeclaration(Component, ctx) {
|
|
360
359
|
const child = Component.new();
|
|
360
|
+
const componentNode = {
|
|
361
|
+
__logicType: FakeType.Component,
|
|
362
|
+
realParent: ctx.realParent,
|
|
363
|
+
data: child,
|
|
364
|
+
tokenizer: null
|
|
365
|
+
};
|
|
361
366
|
const prevOnePropParsed = this.onePropParsed;
|
|
362
|
-
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
363
|
-
if (
|
|
364
|
-
aoye.
|
|
367
|
+
this.onePropParsed = (data, node, key, value, valueIsMapKey, isFn, hookI) => {
|
|
368
|
+
if (isFn) {
|
|
369
|
+
child[aoye.Keys.Raw][key] = value;
|
|
370
|
+
} else if (valueIsMapKey) {
|
|
371
|
+
aoye.shareSignal(data, value, child, key);
|
|
365
372
|
} else if (typeof value === "function") {
|
|
366
373
|
const meta = child[aoye.Keys.Meta];
|
|
367
374
|
const cells = meta.cells;
|
|
@@ -371,37 +378,40 @@
|
|
|
371
378
|
child[aoye.Keys.Raw][key] = value;
|
|
372
379
|
}
|
|
373
380
|
};
|
|
374
|
-
|
|
381
|
+
componentNode.realAfter = this.insertAfterAnchor(ctx);
|
|
375
382
|
const { realParent, prevSibling } = ctx;
|
|
376
383
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
377
|
-
const parent = realParent;
|
|
378
|
-
const prev = prevSibling;
|
|
379
384
|
this.onePropParsed = prevOnePropParsed;
|
|
380
|
-
const
|
|
381
|
-
componentNode.
|
|
385
|
+
const subTkr = child["ui"](true);
|
|
386
|
+
componentNode.tokenizer = subTkr;
|
|
387
|
+
this.tokenizer = subTkr;
|
|
382
388
|
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
383
389
|
});
|
|
384
|
-
return
|
|
390
|
+
return componentNode;
|
|
385
391
|
}
|
|
386
392
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
387
393
|
condDeclaration(ctx) {
|
|
394
|
+
var _a;
|
|
388
395
|
const { prevSibling } = ctx;
|
|
389
396
|
const snapbackUp = this.tokenizer.snapshot();
|
|
390
397
|
const keyWord = this.tokenizer.consume();
|
|
391
398
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
392
|
-
const [hookType, value] = this._hook({});
|
|
399
|
+
const [hookType, value] = this.tokenizer._hook({});
|
|
393
400
|
const isElse = keyWord.value === "else";
|
|
394
401
|
const isIf = keyWord.value === "if";
|
|
395
|
-
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) &
|
|
402
|
+
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
|
|
396
403
|
const needCalcWithPrevIf = isElse && preIsCond;
|
|
404
|
+
const data = this.getData();
|
|
405
|
+
const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
397
406
|
const ifNode = {
|
|
398
|
-
__logicType: isElse ?
|
|
407
|
+
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
399
408
|
snapshot: noSelfCond ? snapbackUp : this.tokenizer.snapshot(),
|
|
400
409
|
condition: null,
|
|
401
410
|
realParent: null,
|
|
402
411
|
preCond: preIsCond ? prevSibling : null,
|
|
403
412
|
isFirstRender: true,
|
|
404
|
-
effect: null
|
|
413
|
+
effect: null,
|
|
414
|
+
owner
|
|
405
415
|
};
|
|
406
416
|
let signal;
|
|
407
417
|
if (noSelfCond) {
|
|
@@ -412,7 +422,7 @@
|
|
|
412
422
|
if (point.condition.v) {
|
|
413
423
|
return false;
|
|
414
424
|
}
|
|
415
|
-
if (point.__logicType ===
|
|
425
|
+
if (point.__logicType === FakeType.If) {
|
|
416
426
|
break;
|
|
417
427
|
}
|
|
418
428
|
point = point.preCond;
|
|
@@ -432,13 +442,13 @@
|
|
|
432
442
|
});
|
|
433
443
|
}
|
|
434
444
|
} else {
|
|
435
|
-
const valueIsMapKey = Reflect.has(
|
|
445
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
436
446
|
if (valueIsMapKey && !needCalcWithPrevIf) {
|
|
437
|
-
aoye.runWithPulling(() =>
|
|
438
|
-
const { cells } =
|
|
447
|
+
aoye.runWithPulling(() => data[value], null);
|
|
448
|
+
const { cells } = data[aoye.Keys.Meta];
|
|
439
449
|
signal = cells.get(value);
|
|
440
450
|
} else {
|
|
441
|
-
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0,
|
|
451
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
442
452
|
if (needCalcWithPrevIf) {
|
|
443
453
|
signal = aoye.$(() => {
|
|
444
454
|
let point = ifNode.preCond;
|
|
@@ -446,7 +456,7 @@
|
|
|
446
456
|
if (point.condition.v) {
|
|
447
457
|
return false;
|
|
448
458
|
}
|
|
449
|
-
if (point.__logicType ===
|
|
459
|
+
if (point.__logicType === FakeType.If) {
|
|
450
460
|
break;
|
|
451
461
|
}
|
|
452
462
|
point = point.preCond;
|
|
@@ -469,8 +479,9 @@
|
|
|
469
479
|
}
|
|
470
480
|
this.tokenizer.consume();
|
|
471
481
|
} else {
|
|
482
|
+
this.tokenizer = ifNode.owner.tokenizer;
|
|
472
483
|
this.tokenizer.resume(ifNode.snapshot);
|
|
473
|
-
this.program(ifNode.realParent, ifNode.realBefore);
|
|
484
|
+
this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore);
|
|
474
485
|
}
|
|
475
486
|
} else {
|
|
476
487
|
if (ifNode.isFirstRender) {
|
|
@@ -481,7 +492,7 @@
|
|
|
481
492
|
this.tokenizer.skip();
|
|
482
493
|
} else {
|
|
483
494
|
const { realBefore, realAfter, realParent } = ifNode;
|
|
484
|
-
let point = realBefore ? this.nextSib(realBefore) : this.
|
|
495
|
+
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
485
496
|
while (point !== realAfter) {
|
|
486
497
|
const next = this.nextSib(point);
|
|
487
498
|
this.remove(point, realParent, realBefore);
|
|
@@ -533,21 +544,24 @@
|
|
|
533
544
|
*/
|
|
534
545
|
attributeList(_node) {
|
|
535
546
|
let key, eq;
|
|
547
|
+
const data = this.getData();
|
|
536
548
|
while (!(this.tokenizer.token.type & TokenType.NewLine)) {
|
|
537
549
|
if (key == null) {
|
|
538
550
|
key = this.tokenizer.token.value;
|
|
539
551
|
} else if (eq == null) {
|
|
540
552
|
eq = "=";
|
|
541
553
|
} else {
|
|
542
|
-
const [hookType, value] = this._hook({});
|
|
554
|
+
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
555
|
+
const rawVal = Reflect.get(data[aoye.Keys.Raw], value);
|
|
556
|
+
const isFn = typeof rawVal === "function";
|
|
543
557
|
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,
|
|
558
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
559
|
+
const fn = isFn ? rawVal : valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
560
|
+
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
547
561
|
} else if (hookType === "static") {
|
|
548
|
-
this.onePropParsed(_node, key, value, false,
|
|
562
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
549
563
|
} else {
|
|
550
|
-
this.onePropParsed(_node, key, value, false,
|
|
564
|
+
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
551
565
|
}
|
|
552
566
|
key = null;
|
|
553
567
|
eq = null;
|
|
@@ -569,7 +583,7 @@
|
|
|
569
583
|
nextSib(node) {
|
|
570
584
|
return node.nextSibling;
|
|
571
585
|
}
|
|
572
|
-
|
|
586
|
+
firstChild(node) {
|
|
573
587
|
return node.firstChild;
|
|
574
588
|
}
|
|
575
589
|
_createAnchor() {
|
|
@@ -613,28 +627,35 @@
|
|
|
613
627
|
setProp(node, key, value, hookI) {
|
|
614
628
|
node.props[key] = value;
|
|
615
629
|
}
|
|
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
630
|
}
|
|
629
631
|
|
|
632
|
+
var __defProp = Object.defineProperty;
|
|
633
|
+
var __defProps = Object.defineProperties;
|
|
634
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
635
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
636
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
637
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
638
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
639
|
+
var __spreadValues = (a, b) => {
|
|
640
|
+
for (var prop in b || (b = {}))
|
|
641
|
+
if (__hasOwnProp.call(b, prop))
|
|
642
|
+
__defNormalProp(a, prop, b[prop]);
|
|
643
|
+
if (__getOwnPropSymbols)
|
|
644
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
645
|
+
if (__propIsEnum.call(b, prop))
|
|
646
|
+
__defNormalProp(a, prop, b[prop]);
|
|
647
|
+
}
|
|
648
|
+
return a;
|
|
649
|
+
};
|
|
650
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
630
651
|
const _Tokenizer = class _Tokenizer {
|
|
631
|
-
constructor() {
|
|
652
|
+
constructor(hook, isSubToken) {
|
|
653
|
+
this.hook = hook;
|
|
654
|
+
this.isSubToken = isSubToken;
|
|
632
655
|
/** 缩进大小 默认 2 */
|
|
633
656
|
this.TabSize = 2;
|
|
634
657
|
/** 缩进字符 */
|
|
635
658
|
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
636
|
-
/** 匹配标识符 */
|
|
637
|
-
this.IdExp = /[\d\w\/]/;
|
|
638
659
|
/** 回车后需要判断缩进 */
|
|
639
660
|
this.needIndent = false;
|
|
640
661
|
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
@@ -643,6 +664,7 @@
|
|
|
643
664
|
this.dentStack = [0];
|
|
644
665
|
/** 当前字符 index */
|
|
645
666
|
this.i = 0;
|
|
667
|
+
// TODO: 生产环境不需要这个,导致不必要的内存占用
|
|
646
668
|
this.handledTokens = [];
|
|
647
669
|
/**
|
|
648
670
|
* 有些标识符能产生多个 token
|
|
@@ -653,6 +675,31 @@
|
|
|
653
675
|
* parent2 <- 产生两个 dedent
|
|
654
676
|
*/
|
|
655
677
|
this.waitingTokens = new bobeShared.Queue();
|
|
678
|
+
/** 模板字符串动态节点的占位符 */
|
|
679
|
+
this.HookId = "_h_o_o_k_";
|
|
680
|
+
/** 模板字符串动态节点索引 */
|
|
681
|
+
this.hookI = 0;
|
|
682
|
+
this._hook = (props) => {
|
|
683
|
+
const value = this.token.value;
|
|
684
|
+
const isDynamicHook = this.token.type & TokenType.InsertionExp;
|
|
685
|
+
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
686
|
+
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
687
|
+
if (this.hook && isStaticHook) {
|
|
688
|
+
const hookI = Number(value.slice(this.HookId.length));
|
|
689
|
+
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
690
|
+
HookId: this.HookId,
|
|
691
|
+
i: hookI
|
|
692
|
+
}));
|
|
693
|
+
return [hookType, res, hookI];
|
|
694
|
+
} else if (isDynamicHook) {
|
|
695
|
+
return [hookType, value];
|
|
696
|
+
}
|
|
697
|
+
return [hookType, value];
|
|
698
|
+
};
|
|
699
|
+
if (isSubToken) {
|
|
700
|
+
this.setToken(TokenType.Indent, "");
|
|
701
|
+
this.isFirstToken = true;
|
|
702
|
+
}
|
|
656
703
|
}
|
|
657
704
|
consume() {
|
|
658
705
|
const token = this.token;
|
|
@@ -766,7 +813,7 @@ ${_Tokenizer.EofId}`;
|
|
|
766
813
|
}
|
|
767
814
|
testId(value) {
|
|
768
815
|
if (typeof value !== "string") return false;
|
|
769
|
-
return
|
|
816
|
+
return _Tokenizer.IdExp.test(value);
|
|
770
817
|
}
|
|
771
818
|
nextToken() {
|
|
772
819
|
try {
|
|
@@ -999,13 +1046,25 @@ ${_Tokenizer.EofId}`;
|
|
|
999
1046
|
const yes = this.dentStack.length === 1;
|
|
1000
1047
|
if (yes) {
|
|
1001
1048
|
if (!this.token) {
|
|
1002
|
-
this.
|
|
1049
|
+
if (this.isSubToken) {
|
|
1050
|
+
this.setToken(TokenType.Dedent, "");
|
|
1051
|
+
} else {
|
|
1052
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
1053
|
+
}
|
|
1003
1054
|
} else {
|
|
1004
|
-
this.
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1055
|
+
if (this.isSubToken) {
|
|
1056
|
+
this.waitingTokens.push({
|
|
1057
|
+
type: TokenType.Dedent,
|
|
1058
|
+
typeName: TokenType[TokenType.Dedent],
|
|
1059
|
+
value: ""
|
|
1060
|
+
});
|
|
1061
|
+
} else {
|
|
1062
|
+
this.waitingTokens.push({
|
|
1063
|
+
type: TokenType.Identifier,
|
|
1064
|
+
typeName: TokenType[TokenType.Identifier],
|
|
1065
|
+
value: _Tokenizer.EofId
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1009
1068
|
}
|
|
1010
1069
|
}
|
|
1011
1070
|
return yes;
|
|
@@ -1021,6 +1080,10 @@ ${_Tokenizer.EofId}`;
|
|
|
1021
1080
|
value += nextC;
|
|
1022
1081
|
this.next();
|
|
1023
1082
|
}
|
|
1083
|
+
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1084
|
+
this.setToken(TokenType.Dedent, "");
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1024
1087
|
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
1025
1088
|
this.setToken(TokenType.Identifier, realValue);
|
|
1026
1089
|
}
|
|
@@ -1060,52 +1123,50 @@ ${_Tokenizer.EofId}`;
|
|
|
1060
1123
|
eof() {
|
|
1061
1124
|
this.setToken(TokenType.Eof, "End Of File");
|
|
1062
1125
|
}
|
|
1126
|
+
init(fragments) {
|
|
1127
|
+
if (typeof fragments === "string") {
|
|
1128
|
+
this.setCode(fragments);
|
|
1129
|
+
} else {
|
|
1130
|
+
let code = "";
|
|
1131
|
+
for (let i = 0; i < fragments.length - 1; i++) {
|
|
1132
|
+
const fragment = fragments[i];
|
|
1133
|
+
code += fragment + `${this.HookId}${i}`;
|
|
1134
|
+
}
|
|
1135
|
+
this.setCode(code + fragments[fragments.length - 1]);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1063
1138
|
};
|
|
1139
|
+
/** 匹配标识符 */
|
|
1140
|
+
_Tokenizer.IdExp = /[\d\w\/]/;
|
|
1064
1141
|
/** Eof 标识符的值 */
|
|
1065
1142
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1143
|
+
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|
|
1066
1144
|
let Tokenizer = _Tokenizer;
|
|
1067
1145
|
|
|
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
1146
|
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);
|
|
1147
|
+
const ui = function ui2(isSub) {
|
|
1148
|
+
const tokenizer = new Tokenizer(({ i }) => {
|
|
1149
|
+
return values[i];
|
|
1150
|
+
}, isSub);
|
|
1151
|
+
tokenizer.init(Array.from(fragments));
|
|
1152
|
+
return tokenizer;
|
|
1102
1153
|
};
|
|
1103
1154
|
return ui;
|
|
1104
1155
|
}
|
|
1105
1156
|
function customRender(option) {
|
|
1106
1157
|
return function render(Ctor, root) {
|
|
1107
1158
|
const store = Ctor.new();
|
|
1108
|
-
|
|
1159
|
+
const tokenizer = store["ui"](false);
|
|
1160
|
+
const terp = new Interpreter(tokenizer);
|
|
1161
|
+
terp.config(option);
|
|
1162
|
+
const componentNode = {
|
|
1163
|
+
__logicType: FakeType.Component,
|
|
1164
|
+
realParent: root,
|
|
1165
|
+
data: store,
|
|
1166
|
+
tokenizer
|
|
1167
|
+
};
|
|
1168
|
+
terp.program(root, componentNode);
|
|
1169
|
+
return [componentNode, store];
|
|
1109
1170
|
};
|
|
1110
1171
|
}
|
|
1111
1172
|
|