bobe 0.0.10 → 0.0.12
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 +755 -172
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +751 -174
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +136 -100
- package/dist/index.umd.js +755 -172
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -22,35 +22,116 @@ var LogicType = /* @__PURE__ */ ((LogicType2) => {
|
|
|
22
22
|
LogicType2[LogicType2["Component"] = 16] = "Component";
|
|
23
23
|
LogicType2[LogicType2["Fragment"] = 32] = "Fragment";
|
|
24
24
|
LogicType2[LogicType2["Root"] = 64] = "Root";
|
|
25
|
+
LogicType2[LogicType2["Real"] = 128] = "Real";
|
|
25
26
|
return LogicType2;
|
|
26
27
|
})(LogicType || {});
|
|
28
|
+
const Logical = 1 /* If */ | 2 /* ElseIf */ | 4 /* Else */ | 8 /* For */;
|
|
29
|
+
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
30
|
+
NodeType2[NodeType2["Logic"] = Logical] = "Logic";
|
|
31
|
+
NodeType2[NodeType2["Real"] = 128 /* Real */] = "Real";
|
|
32
|
+
NodeType2[NodeType2["Component"] = 16 /* Component */] = "Component";
|
|
33
|
+
return NodeType2;
|
|
34
|
+
})(NodeType || {});
|
|
27
35
|
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
28
36
|
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
29
37
|
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
30
38
|
return TerpEvt2;
|
|
31
39
|
})(TerpEvt || {});
|
|
40
|
+
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
class TypedStack {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.top = null;
|
|
45
|
+
// 存储每种类型最近一次出现的包装单元引用
|
|
46
|
+
// 使用 Record 来动态支持不同的类型标签
|
|
47
|
+
this.lastNodes = {};
|
|
48
|
+
this.length = 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @param rawNode 原始节点数据
|
|
52
|
+
* @param type 节点类型
|
|
53
|
+
*/
|
|
54
|
+
push(rawNode, type) {
|
|
55
|
+
var _a;
|
|
56
|
+
const newNode = {
|
|
57
|
+
data: rawNode,
|
|
58
|
+
type,
|
|
59
|
+
prev: this.top,
|
|
60
|
+
prevSameType: (_a = this.lastNodes[type]) != null ? _a : null
|
|
61
|
+
};
|
|
62
|
+
this.top = newNode;
|
|
63
|
+
this.length++;
|
|
64
|
+
this.lastNodes[type] = newNode;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 出栈操作
|
|
68
|
+
* @returns 原始节点数据或 null
|
|
69
|
+
*/
|
|
70
|
+
pop() {
|
|
71
|
+
if (!this.top) return null;
|
|
72
|
+
const popped = this.top;
|
|
73
|
+
this.lastNodes[popped.type] = popped.prevSameType;
|
|
74
|
+
this.top = popped.prev;
|
|
75
|
+
this.length--;
|
|
76
|
+
return popped.data;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* O(1) 获取栈顶节点的前一个同类型节点
|
|
80
|
+
*/
|
|
81
|
+
getPrevSameType() {
|
|
82
|
+
if (!this.top || !this.top.prevSameType) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return this.top.prevSameType.data;
|
|
86
|
+
}
|
|
87
|
+
findPrevSameType(cb) {
|
|
88
|
+
if (!this.top) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
let point = this.top.prevSameType;
|
|
92
|
+
while (point) {
|
|
93
|
+
if (cb(point.data)) {
|
|
94
|
+
return point.data;
|
|
95
|
+
}
|
|
96
|
+
point = point.prevSameType;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 获取当前栈顶的类型
|
|
102
|
+
*/
|
|
103
|
+
get peekType() {
|
|
104
|
+
return this.top ? this.top.type : null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 获取栈顶元素
|
|
108
|
+
*/
|
|
109
|
+
peek() {
|
|
110
|
+
return this.top.data;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var __defProp$1 = Object.defineProperty;
|
|
115
|
+
var __defProps$1 = Object.defineProperties;
|
|
116
|
+
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
117
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
118
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
119
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
120
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
121
|
+
var __spreadValues$1 = (a, b) => {
|
|
41
122
|
for (var prop in b || (b = {}))
|
|
42
|
-
if (__hasOwnProp.call(b, prop))
|
|
43
|
-
__defNormalProp(a, prop, b[prop]);
|
|
44
|
-
if (__getOwnPropSymbols)
|
|
45
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
46
|
-
if (__propIsEnum.call(b, prop))
|
|
47
|
-
__defNormalProp(a, prop, b[prop]);
|
|
123
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
124
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
125
|
+
if (__getOwnPropSymbols$1)
|
|
126
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
127
|
+
if (__propIsEnum$1.call(b, prop))
|
|
128
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
48
129
|
}
|
|
49
130
|
return a;
|
|
50
131
|
};
|
|
51
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
132
|
+
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
52
133
|
const tap = new bobeShared.BaseEvent();
|
|
53
|
-
class
|
|
134
|
+
class Interpreter {
|
|
54
135
|
constructor(tokenizer) {
|
|
55
136
|
this.tokenizer = tokenizer;
|
|
56
137
|
/** 模板字符串动态节点的占位符 */
|
|
@@ -59,7 +140,6 @@ class Terp {
|
|
|
59
140
|
this.data = {};
|
|
60
141
|
/** 模板字符串动态节点索引 */
|
|
61
142
|
this.hookI = 0;
|
|
62
|
-
this.stack = [];
|
|
63
143
|
this._hook = (props) => {
|
|
64
144
|
const value = this.tokenizer.token.value;
|
|
65
145
|
const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
|
|
@@ -67,7 +147,7 @@ class Terp {
|
|
|
67
147
|
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
68
148
|
if (this.hook && isStaticHook) {
|
|
69
149
|
const hookI = Number(value.slice(this.HookId.length));
|
|
70
|
-
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
150
|
+
const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
|
|
71
151
|
HookId: this.HookId,
|
|
72
152
|
i: hookI
|
|
73
153
|
}));
|
|
@@ -79,123 +159,115 @@ class Terp {
|
|
|
79
159
|
return [hookType, value];
|
|
80
160
|
};
|
|
81
161
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
162
|
+
isLogicNode(node) {
|
|
163
|
+
return node && node.__logicType & Logical;
|
|
164
|
+
}
|
|
165
|
+
program(root, before) {
|
|
166
|
+
var _a;
|
|
167
|
+
const componentNode = {
|
|
88
168
|
__logicType: LogicType.Component,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
directList: []
|
|
169
|
+
realParent: root,
|
|
170
|
+
store: new aoye.Store()
|
|
92
171
|
};
|
|
93
172
|
this.tokenizer.consume();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
173
|
+
const stack = new TypedStack();
|
|
174
|
+
stack.push({ node: root, prev: null }, NodeType.Real);
|
|
175
|
+
const ctx = {
|
|
176
|
+
realParent: root,
|
|
177
|
+
prevSibling: before,
|
|
178
|
+
current: null,
|
|
179
|
+
stack,
|
|
180
|
+
before
|
|
181
|
+
};
|
|
182
|
+
const rootPulling = aoye.getPulling();
|
|
97
183
|
while (1) {
|
|
98
184
|
if (this.tokenizer.isEof()) {
|
|
99
|
-
|
|
185
|
+
if (!ctx.prevSibling) ctx.prevSibling = before;
|
|
186
|
+
this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
|
|
100
187
|
break;
|
|
101
188
|
}
|
|
102
189
|
const token = this.tokenizer.token;
|
|
103
190
|
if (token.type & TokenType.Indent) {
|
|
104
191
|
this.tokenizer.consume();
|
|
105
|
-
this.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
192
|
+
const isLogicNode = this.isLogicNode(ctx.current);
|
|
193
|
+
stack.push(
|
|
194
|
+
{
|
|
195
|
+
node: ctx.current,
|
|
196
|
+
prev: ctx.prevSibling
|
|
197
|
+
},
|
|
198
|
+
ctx.current.__logicType ? isLogicNode ? NodeType.Logic : NodeType.Component : NodeType.Real
|
|
199
|
+
);
|
|
200
|
+
if (ctx.current.__logicType) {
|
|
201
|
+
if (isLogicNode) {
|
|
202
|
+
aoye.setPulling(ctx.current.effect.ins);
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
ctx.realParent = ctx.current;
|
|
206
|
+
ctx.prevSibling = null;
|
|
207
|
+
}
|
|
208
|
+
ctx.current = this.declaration(ctx);
|
|
111
209
|
continue;
|
|
112
210
|
}
|
|
113
|
-
if (current) {
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
this.handleInsert(parent, current, prevSibling);
|
|
117
|
-
} else {
|
|
118
|
-
this.handleInsert(root, current, prevSibling);
|
|
211
|
+
if (ctx.current) {
|
|
212
|
+
if (stack.length === 1 && !ctx.prevSibling) {
|
|
213
|
+
ctx.prevSibling = before;
|
|
119
214
|
}
|
|
215
|
+
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
120
216
|
}
|
|
121
217
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
122
218
|
this.tokenizer.consume();
|
|
123
|
-
const { node: parent,
|
|
124
|
-
|
|
125
|
-
|
|
219
|
+
const { node: parent, prev } = stack.peek();
|
|
220
|
+
if (!parent.__logicType) {
|
|
221
|
+
const prevSameType = stack.getPrevSameType();
|
|
222
|
+
ctx.realParent = prevSameType == null ? void 0 : prevSameType.node;
|
|
223
|
+
} else {
|
|
224
|
+
if (this.isLogicNode(parent)) {
|
|
225
|
+
const parentLogic = (_a = stack.getPrevSameType()) == null ? void 0 : _a.node;
|
|
226
|
+
if (parentLogic) {
|
|
227
|
+
aoye.setPulling(parentLogic.effect.ins);
|
|
228
|
+
} else {
|
|
229
|
+
aoye.setPulling(rootPulling);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
stack.pop();
|
|
234
|
+
ctx.prevSibling = prev;
|
|
235
|
+
ctx.current = parent;
|
|
126
236
|
} else {
|
|
127
|
-
prevSibling = current;
|
|
128
|
-
current = this.declaration();
|
|
237
|
+
ctx.prevSibling = ctx.current || ctx.prevSibling;
|
|
238
|
+
ctx.current = this.declaration(ctx);
|
|
129
239
|
}
|
|
130
240
|
}
|
|
131
|
-
return
|
|
241
|
+
return componentNode;
|
|
242
|
+
}
|
|
243
|
+
insertAfterAnchor(ctx) {
|
|
244
|
+
const { realParent, prevSibling, stack, before } = ctx;
|
|
245
|
+
const afterAnchor = this.createAnchor();
|
|
246
|
+
ctx.prevSibling = stack.length === 1 && !prevSibling ? before : prevSibling;
|
|
247
|
+
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
248
|
+
return afterAnchor;
|
|
132
249
|
}
|
|
133
250
|
/** 处理
|
|
134
|
-
*
|
|
135
|
-
* 父节点
|
|
136
|
-
* 子节点
|
|
251
|
+
* 是逻辑 是普通
|
|
252
|
+
* 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
|
|
253
|
+
* 子节点 仅插入到父逻辑节点 将本节点插入父节点
|
|
254
|
+
* 理论上父节点不能是一个 逻辑节点,遇到if 时 Terp 会重新执行 program 这种情况下,会指定 root 为真实 dom
|
|
137
255
|
*/
|
|
138
|
-
handleInsert(parent, child,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (child.__logicType) {
|
|
146
|
-
const realList = child.realList;
|
|
147
|
-
for (let i = realList.length; i--; ) {
|
|
148
|
-
const item = realList[i];
|
|
149
|
-
insertFn(parent, item, prevSibling);
|
|
256
|
+
handleInsert(parent, child, prev, parentComponent) {
|
|
257
|
+
if (!child.__logicType) {
|
|
258
|
+
if (!prev || !prev.__logicType) {
|
|
259
|
+
this.insertAfter(parent, child, prev);
|
|
260
|
+
} else {
|
|
261
|
+
const before = prev.realAfter;
|
|
262
|
+
this.insertAfter(parent, child, before);
|
|
150
263
|
}
|
|
151
264
|
} else {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
* 可以是一个节点,也可以跟随更多节点
|
|
159
|
-
* <nodeList> ::= <node> <nodeList> <EOF|Dedent>
|
|
160
|
-
* |
|
|
161
|
-
*/
|
|
162
|
-
nodeList(parent) {
|
|
163
|
-
let _node;
|
|
164
|
-
let prevSibling;
|
|
165
|
-
let prevItem;
|
|
166
|
-
while (1) {
|
|
167
|
-
if (this.tokenizer.isEof()) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
171
|
-
this.tokenizer.consume();
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
_node = this.node();
|
|
175
|
-
const insert = parent.__logicType ? this.defaultInsert : this.insert.bind(this);
|
|
176
|
-
parent.__logicType ? this.defaultRemove : this.remove.bind(this);
|
|
177
|
-
if (!_node.__logicType) {
|
|
178
|
-
const realPrev = this.getPrevRealSibling(prevSibling);
|
|
179
|
-
const currItem = insert(parent, _node, realPrev, prevItem);
|
|
180
|
-
prevItem = currItem;
|
|
181
|
-
prevSibling = _node;
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
if (prevSibling) {
|
|
185
|
-
_node.anchor = prevSibling;
|
|
186
|
-
} else if (parent.__logicType) {
|
|
187
|
-
_node.anchor = parent;
|
|
188
|
-
} else ;
|
|
189
|
-
if (_node.child && _node.condition()) {
|
|
190
|
-
let item = _node.child;
|
|
191
|
-
while (item != null) {
|
|
192
|
-
const { value: child } = item;
|
|
193
|
-
const realPrev = this.getPrevRealSibling(prevSibling);
|
|
194
|
-
const currItem = insert(parent, child, realPrev, prevItem);
|
|
195
|
-
item = item.next;
|
|
196
|
-
prevItem = currItem;
|
|
197
|
-
prevSibling = child;
|
|
198
|
-
}
|
|
265
|
+
const childCmp = child;
|
|
266
|
+
childCmp.realParent = parent;
|
|
267
|
+
if (prev.__logicType) {
|
|
268
|
+
childCmp.realBefore = prev.realAfter;
|
|
269
|
+
} else {
|
|
270
|
+
childCmp.realBefore = prev;
|
|
199
271
|
}
|
|
200
272
|
}
|
|
201
273
|
}
|
|
@@ -212,33 +284,20 @@ class Terp {
|
|
|
212
284
|
point = point.anchor;
|
|
213
285
|
}
|
|
214
286
|
}
|
|
215
|
-
/**
|
|
216
|
-
* 单个节点:
|
|
217
|
-
* 由声明部分和(可选的)子节点块组成
|
|
218
|
-
* <node> ::= <declaration> <childrenBlockOpt>
|
|
219
|
-
* */
|
|
220
|
-
node() {
|
|
221
|
-
const _declaration = this.declaration();
|
|
222
|
-
if (_declaration.__logicType & LogicType.If && !_declaration.condition()) {
|
|
223
|
-
return _declaration;
|
|
224
|
-
}
|
|
225
|
-
this.childrenBlockOpt(_declaration);
|
|
226
|
-
return _declaration;
|
|
227
|
-
}
|
|
228
287
|
/**
|
|
229
288
|
* 声明部分:
|
|
230
289
|
* 包含首行定义和(可选的)多行属性扩展
|
|
231
290
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
232
291
|
* */
|
|
233
|
-
declaration() {
|
|
292
|
+
declaration(ctx) {
|
|
234
293
|
const [hookType, value] = this._hook({});
|
|
235
294
|
let _node;
|
|
236
295
|
if (value === "if") {
|
|
237
|
-
return this.ifDeclaration();
|
|
296
|
+
return this.ifDeclaration(ctx);
|
|
238
297
|
} else if (hookType) {
|
|
239
298
|
if (hookType === "static") {
|
|
240
299
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
241
|
-
_node = this.componentDeclaration(value);
|
|
300
|
+
_node = this.componentDeclaration(value, ctx);
|
|
242
301
|
} else if (typeof value === "function") {
|
|
243
302
|
_node = this.fragmentDeclaration(value);
|
|
244
303
|
} else {
|
|
@@ -265,8 +324,7 @@ class Terp {
|
|
|
265
324
|
fragmentDeclaration(renderFragment) {
|
|
266
325
|
const fragmentNode = {
|
|
267
326
|
__logicType: LogicType.Fragment,
|
|
268
|
-
|
|
269
|
-
realList: []
|
|
327
|
+
realParent: null
|
|
270
328
|
};
|
|
271
329
|
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
272
330
|
return fragmentNode;
|
|
@@ -294,7 +352,7 @@ class Terp {
|
|
|
294
352
|
this.setProp(node, key, value, hookI);
|
|
295
353
|
}
|
|
296
354
|
}
|
|
297
|
-
componentDeclaration(Component) {
|
|
355
|
+
componentDeclaration(Component, ctx) {
|
|
298
356
|
const child = Component.new();
|
|
299
357
|
const prevOnePropParsed = this.onePropParsed;
|
|
300
358
|
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
@@ -309,36 +367,66 @@ class Terp {
|
|
|
309
367
|
child[aoye.Keys.Raw][key] = value;
|
|
310
368
|
}
|
|
311
369
|
};
|
|
370
|
+
const afterAnchor = this.insertAfterAnchor(ctx);
|
|
312
371
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
372
|
+
const parent = ctx.realParent;
|
|
373
|
+
const prev = ctx.prevSibling;
|
|
313
374
|
this.onePropParsed = prevOnePropParsed;
|
|
314
|
-
const
|
|
315
|
-
|
|
375
|
+
const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
|
|
376
|
+
componentNode.realAfter = afterAnchor;
|
|
377
|
+
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
316
378
|
});
|
|
317
379
|
return { __logicType: LogicType.Component };
|
|
318
380
|
}
|
|
319
|
-
ifDeclaration() {
|
|
381
|
+
ifDeclaration(ctx) {
|
|
320
382
|
this.tokenizer.consume();
|
|
321
|
-
const [
|
|
383
|
+
const [hookType, value] = this._hook({});
|
|
322
384
|
const ifNode = {
|
|
323
385
|
__logicType: LogicType.If,
|
|
324
|
-
condition: value,
|
|
325
|
-
directList: [],
|
|
326
|
-
realList: [],
|
|
327
386
|
snapshot: this.tokenizer.snapshot(),
|
|
387
|
+
condition: null,
|
|
388
|
+
realParent: null,
|
|
328
389
|
isFirstRender: true,
|
|
329
|
-
|
|
330
|
-
anchor: null
|
|
390
|
+
effect: null
|
|
331
391
|
};
|
|
332
|
-
|
|
392
|
+
const valueIsMapKey = Reflect.has(this.data[aoye.Keys.Raw], value);
|
|
393
|
+
let signal;
|
|
394
|
+
if (valueIsMapKey) {
|
|
395
|
+
aoye.runWithPulling(() => this.data[value], null);
|
|
396
|
+
const { cells } = this.data[aoye.Keys.Meta];
|
|
397
|
+
signal = cells.get(value);
|
|
398
|
+
} else {
|
|
399
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, this.data);
|
|
400
|
+
signal = aoye.$(fn);
|
|
401
|
+
}
|
|
402
|
+
ifNode.condition = signal;
|
|
403
|
+
ifNode.realAfter = this.insertAfterAnchor(ctx);
|
|
404
|
+
ifNode.effect = aoye.effect(
|
|
333
405
|
({ val }) => {
|
|
334
406
|
if (val) {
|
|
335
|
-
|
|
336
|
-
|
|
407
|
+
if (ifNode.isFirstRender) {
|
|
408
|
+
this.tokenizer.consume();
|
|
409
|
+
this.tokenizer.consume();
|
|
410
|
+
} else {
|
|
411
|
+
this.tokenizer.resume(ifNode.snapshot);
|
|
412
|
+
this.program(ifNode.realParent, ifNode.realBefore);
|
|
413
|
+
}
|
|
337
414
|
} else {
|
|
338
|
-
|
|
415
|
+
if (ifNode.isFirstRender) {
|
|
416
|
+
this.tokenizer.skip();
|
|
417
|
+
} else {
|
|
418
|
+
const { realBefore, realAfter, realParent } = ifNode;
|
|
419
|
+
let point = this.nextSib(realBefore);
|
|
420
|
+
while (point !== realAfter) {
|
|
421
|
+
const next = this.nextSib(point);
|
|
422
|
+
this.remove(point, realParent, realBefore);
|
|
423
|
+
point = next;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
339
426
|
}
|
|
427
|
+
ifNode.isFirstRender = false;
|
|
340
428
|
},
|
|
341
|
-
[
|
|
429
|
+
[signal]
|
|
342
430
|
);
|
|
343
431
|
return ifNode;
|
|
344
432
|
}
|
|
@@ -402,19 +490,6 @@ class Terp {
|
|
|
402
490
|
this.tokenizer.consume();
|
|
403
491
|
}
|
|
404
492
|
}
|
|
405
|
-
/** 子节点块:
|
|
406
|
-
* 必须被缩进包裹
|
|
407
|
-
* <childrenBlockOpt> ::= INDENT <nodeList>
|
|
408
|
-
* | ε /* 空(表示叶子节点,没有孩子)
|
|
409
|
-
* */
|
|
410
|
-
childrenBlockOpt(parent) {
|
|
411
|
-
if (!(this.tokenizer.token.type & TokenType.Indent)) {
|
|
412
|
-
return [];
|
|
413
|
-
}
|
|
414
|
-
this.tokenizer.consume();
|
|
415
|
-
const list = this.nodeList(parent);
|
|
416
|
-
return list;
|
|
417
|
-
}
|
|
418
493
|
config(opt) {
|
|
419
494
|
Object.assign(this, opt);
|
|
420
495
|
this.opt = opt;
|
|
@@ -422,28 +497,47 @@ class Terp {
|
|
|
422
497
|
createNode(name) {
|
|
423
498
|
return {
|
|
424
499
|
name,
|
|
425
|
-
props: {}
|
|
500
|
+
props: {},
|
|
501
|
+
nextSibling: null
|
|
426
502
|
};
|
|
427
503
|
}
|
|
428
|
-
|
|
429
|
-
return
|
|
504
|
+
nextSib(node) {
|
|
505
|
+
return node.nextSibling;
|
|
430
506
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
507
|
+
_createAnchor() {
|
|
508
|
+
const anchor = this.createAnchor();
|
|
509
|
+
anchor[IsAnchor] = true;
|
|
510
|
+
return anchor;
|
|
511
|
+
}
|
|
512
|
+
createAnchor() {
|
|
513
|
+
return {
|
|
514
|
+
name: "anchor",
|
|
515
|
+
nextSibling: null
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
insertAfter(parent, node, prev) {
|
|
519
|
+
return this.defaultInsert(parent, node, prev);
|
|
520
|
+
}
|
|
521
|
+
defaultInsert(parent, node, prev) {
|
|
522
|
+
if (prev) {
|
|
523
|
+
const next = prev.nextSibling;
|
|
524
|
+
prev.nextSibling = node;
|
|
525
|
+
node.nextSibling = next;
|
|
436
526
|
} else {
|
|
437
|
-
parent.
|
|
527
|
+
parent.firstChild = node;
|
|
438
528
|
}
|
|
439
529
|
}
|
|
440
|
-
remove(
|
|
441
|
-
return this.defaultRemove(
|
|
530
|
+
remove(node, parent, prev) {
|
|
531
|
+
return this.defaultRemove(node, parent, prev);
|
|
442
532
|
}
|
|
443
533
|
// TODO: 默认改成 prevItem
|
|
444
|
-
defaultRemove(
|
|
445
|
-
|
|
446
|
-
|
|
534
|
+
defaultRemove(node, parent, prevSibling) {
|
|
535
|
+
const next = node.nextSibling;
|
|
536
|
+
if (prevSibling) {
|
|
537
|
+
prevSibling.nextSibling = next;
|
|
538
|
+
}
|
|
539
|
+
if (parent.firstChild === node) {
|
|
540
|
+
parent.firstChild = next;
|
|
447
541
|
}
|
|
448
542
|
}
|
|
449
543
|
setProp(node, key, value, hookI) {
|
|
@@ -463,5 +557,494 @@ class Terp {
|
|
|
463
557
|
}
|
|
464
558
|
}
|
|
465
559
|
|
|
466
|
-
|
|
560
|
+
const _Tokenizer = class _Tokenizer {
|
|
561
|
+
constructor() {
|
|
562
|
+
/** 缩进大小 默认 2 */
|
|
563
|
+
this.TabSize = 2;
|
|
564
|
+
/** 缩进字符 */
|
|
565
|
+
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
566
|
+
/** 匹配标识符 */
|
|
567
|
+
this.IdExp = /[\d\w\/]/;
|
|
568
|
+
/** 回车后需要判断缩进 */
|
|
569
|
+
this.needIndent = false;
|
|
570
|
+
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
571
|
+
this.isFirstToken = true;
|
|
572
|
+
/** 记录历史缩进的长度,相对于行首 */
|
|
573
|
+
this.dentStack = [0];
|
|
574
|
+
/** 当前字符 index */
|
|
575
|
+
this.i = 0;
|
|
576
|
+
this.handledTokens = [];
|
|
577
|
+
/**
|
|
578
|
+
* 有些标识符能产生多个 token
|
|
579
|
+
* 例如 dedent
|
|
580
|
+
* parent1
|
|
581
|
+
* child
|
|
582
|
+
* subChild
|
|
583
|
+
* parent2 <- 产生两个 dedent
|
|
584
|
+
*/
|
|
585
|
+
this.waitingTokens = new bobeShared.Queue();
|
|
586
|
+
}
|
|
587
|
+
consume() {
|
|
588
|
+
const token = this.token;
|
|
589
|
+
this.nextToken();
|
|
590
|
+
return token;
|
|
591
|
+
}
|
|
592
|
+
// /** 恢复至某一个现场,进行 token 重算 */
|
|
593
|
+
resume(_snapshot) {
|
|
594
|
+
this.token = void 0;
|
|
595
|
+
this.needIndent = false;
|
|
596
|
+
this.isFirstToken = true;
|
|
597
|
+
this.dentStack = [0];
|
|
598
|
+
Object.assign(this, _snapshot);
|
|
599
|
+
}
|
|
600
|
+
snapshot() {
|
|
601
|
+
return {
|
|
602
|
+
i: this.i,
|
|
603
|
+
waitingTokens: this.waitingTokens.clone()
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
skip() {
|
|
607
|
+
const logicDentLen = this.dentStack[this.dentStack.length - 1];
|
|
608
|
+
let needIndent = false;
|
|
609
|
+
let skipFragment = ``;
|
|
610
|
+
this.token = void 0;
|
|
611
|
+
while (1) {
|
|
612
|
+
const char = this.char;
|
|
613
|
+
if (char === "\n") {
|
|
614
|
+
needIndent = true;
|
|
615
|
+
skipFragment += char;
|
|
616
|
+
this.next();
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
if (!needIndent) {
|
|
620
|
+
skipFragment += char;
|
|
621
|
+
this.next();
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
needIndent = false;
|
|
625
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
626
|
+
const currLen = value.length;
|
|
627
|
+
if (isEmptyLine) continue;
|
|
628
|
+
if (currLen > logicDentLen) {
|
|
629
|
+
skipFragment += value;
|
|
630
|
+
} else {
|
|
631
|
+
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
632
|
+
const expLen = this.dentStack[i];
|
|
633
|
+
if (currLen === expLen) break;
|
|
634
|
+
if (currLen > expLen) {
|
|
635
|
+
throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
|
|
636
|
+
}
|
|
637
|
+
if (this.shorterThanBaseDentEof()) {
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
this.dentStack.pop();
|
|
641
|
+
if (!this.token) {
|
|
642
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
643
|
+
} else {
|
|
644
|
+
this.waitingTokens.push({
|
|
645
|
+
type: TokenType.Dedent,
|
|
646
|
+
typeName: TokenType[TokenType.Dedent],
|
|
647
|
+
value: String(expLen)
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
if (!this.token) {
|
|
655
|
+
this.nextToken();
|
|
656
|
+
}
|
|
657
|
+
return skipFragment;
|
|
658
|
+
}
|
|
659
|
+
setCode(code) {
|
|
660
|
+
this.code = "\n" + code.trimEnd() + `
|
|
661
|
+
${_Tokenizer.EofId}`;
|
|
662
|
+
}
|
|
663
|
+
tokenize() {
|
|
664
|
+
var _a, _b;
|
|
665
|
+
do {
|
|
666
|
+
this.nextToken();
|
|
667
|
+
console.log("token:", TokenType[(_a = this.token) == null ? void 0 : _a.type], JSON.stringify(((_b = this.token) == null ? void 0 : _b.value) || ""));
|
|
668
|
+
} while (!this.isEof());
|
|
669
|
+
}
|
|
670
|
+
isEof() {
|
|
671
|
+
if (!this.token) return false;
|
|
672
|
+
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
673
|
+
}
|
|
674
|
+
get char() {
|
|
675
|
+
return this.code[this.i];
|
|
676
|
+
}
|
|
677
|
+
get prev() {
|
|
678
|
+
return this.code[this.i - 1];
|
|
679
|
+
}
|
|
680
|
+
get after() {
|
|
681
|
+
return this.code[this.i + 1];
|
|
682
|
+
}
|
|
683
|
+
next() {
|
|
684
|
+
const prev = this.code[this.i];
|
|
685
|
+
this.i++;
|
|
686
|
+
const curr = this.code[this.i];
|
|
687
|
+
return [prev, curr];
|
|
688
|
+
}
|
|
689
|
+
setToken(type, value) {
|
|
690
|
+
this.token = {
|
|
691
|
+
type,
|
|
692
|
+
typeName: TokenType[type],
|
|
693
|
+
value
|
|
694
|
+
};
|
|
695
|
+
this.isFirstToken = false;
|
|
696
|
+
}
|
|
697
|
+
testId(value) {
|
|
698
|
+
if (typeof value !== "string") return false;
|
|
699
|
+
return this.IdExp.test(value);
|
|
700
|
+
}
|
|
701
|
+
nextToken() {
|
|
702
|
+
try {
|
|
703
|
+
if (this.isEof()) {
|
|
704
|
+
return this.token;
|
|
705
|
+
}
|
|
706
|
+
this.token = void 0;
|
|
707
|
+
if (this.waitingTokens.len) {
|
|
708
|
+
const item = this.waitingTokens.shift();
|
|
709
|
+
this.setToken(item.type, item.value);
|
|
710
|
+
return this.token;
|
|
711
|
+
}
|
|
712
|
+
outer: while (1) {
|
|
713
|
+
if (this.needIndent) {
|
|
714
|
+
this.dent();
|
|
715
|
+
} else {
|
|
716
|
+
let { char } = this;
|
|
717
|
+
switch (char) {
|
|
718
|
+
case " ":
|
|
719
|
+
case " ":
|
|
720
|
+
break;
|
|
721
|
+
// 找后续所有 newLine
|
|
722
|
+
case "\n":
|
|
723
|
+
this.newLine();
|
|
724
|
+
this.needIndent = true;
|
|
725
|
+
break;
|
|
726
|
+
case "=":
|
|
727
|
+
this.assignment();
|
|
728
|
+
break;
|
|
729
|
+
case "|":
|
|
730
|
+
this.pipe();
|
|
731
|
+
break;
|
|
732
|
+
case "'":
|
|
733
|
+
case '"':
|
|
734
|
+
this.str(char);
|
|
735
|
+
break;
|
|
736
|
+
case "{":
|
|
737
|
+
this.brace();
|
|
738
|
+
break;
|
|
739
|
+
case "$":
|
|
740
|
+
const handled = this.dynamic(char);
|
|
741
|
+
if (handled) break;
|
|
742
|
+
default:
|
|
743
|
+
if (bobeShared.isNum(char)) {
|
|
744
|
+
this.number(char);
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
if (this.testId(char)) {
|
|
748
|
+
this.identifier(char);
|
|
749
|
+
}
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
this.next();
|
|
753
|
+
}
|
|
754
|
+
if (this.token) {
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return this.token;
|
|
759
|
+
} catch (error) {
|
|
760
|
+
console.error(error);
|
|
761
|
+
} finally {
|
|
762
|
+
this.handledTokens.push(this.token);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
assignment() {
|
|
766
|
+
this.setToken(TokenType.Assign, "=");
|
|
767
|
+
}
|
|
768
|
+
pipe() {
|
|
769
|
+
this.setToken(TokenType.Pipe, "|");
|
|
770
|
+
}
|
|
771
|
+
dynamic(char) {
|
|
772
|
+
let nextC = this.after;
|
|
773
|
+
if (nextC !== "{") {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
this.next();
|
|
777
|
+
let value = "${";
|
|
778
|
+
let innerBrace = 0;
|
|
779
|
+
while (1) {
|
|
780
|
+
nextC = this.after;
|
|
781
|
+
value += nextC;
|
|
782
|
+
this.next();
|
|
783
|
+
if (nextC === "{") {
|
|
784
|
+
innerBrace++;
|
|
785
|
+
}
|
|
786
|
+
if (nextC === "}") {
|
|
787
|
+
if (!innerBrace) {
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
innerBrace--;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
this.setToken(TokenType.Identifier, value);
|
|
794
|
+
return true;
|
|
795
|
+
}
|
|
796
|
+
brace() {
|
|
797
|
+
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
798
|
+
while (1) {
|
|
799
|
+
const char = this.char;
|
|
800
|
+
const nextChar = this.after;
|
|
801
|
+
if (inComment === "single" && char === "\n") {
|
|
802
|
+
inComment = null;
|
|
803
|
+
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
804
|
+
inComment = null;
|
|
805
|
+
value += this.next()[0];
|
|
806
|
+
} else if (inString) {
|
|
807
|
+
if (char === inString && backslashCount % 2 === 0) {
|
|
808
|
+
inString = null;
|
|
809
|
+
}
|
|
810
|
+
backslashCount = char === "\\" ? backslashCount + 1 : 0;
|
|
811
|
+
} else {
|
|
812
|
+
if (char === "/" && nextChar === "/") {
|
|
813
|
+
inComment = "single";
|
|
814
|
+
value += this.next()[0];
|
|
815
|
+
} else if (char === "/" && nextChar === "*") {
|
|
816
|
+
inComment = "multi";
|
|
817
|
+
value += this.next()[0];
|
|
818
|
+
} else if (char === "'" || char === '"' || char === "`") {
|
|
819
|
+
inString = char;
|
|
820
|
+
} else if (char === "{") {
|
|
821
|
+
count++;
|
|
822
|
+
} else if (char === "}") {
|
|
823
|
+
count--;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
if (count === 0 && inString == null && inComment == null) {
|
|
827
|
+
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
value += this.next()[0];
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
newLine() {
|
|
834
|
+
let value = "\n";
|
|
835
|
+
let nextC;
|
|
836
|
+
while (1) {
|
|
837
|
+
nextC = this.after;
|
|
838
|
+
if (nextC !== "\n") {
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
value += nextC;
|
|
842
|
+
this.next();
|
|
843
|
+
}
|
|
844
|
+
if (this.isFirstToken) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
this.setToken(TokenType.NewLine, value);
|
|
848
|
+
}
|
|
849
|
+
getDentValue() {
|
|
850
|
+
let value = "";
|
|
851
|
+
let nextC;
|
|
852
|
+
let isEmptyLine = false;
|
|
853
|
+
while (1) {
|
|
854
|
+
const nextChar = this.char;
|
|
855
|
+
switch (nextChar) {
|
|
856
|
+
case " ":
|
|
857
|
+
nextC = this.Tab;
|
|
858
|
+
break;
|
|
859
|
+
case " ":
|
|
860
|
+
nextC = " ";
|
|
861
|
+
break;
|
|
862
|
+
case "\n":
|
|
863
|
+
nextC = "\n";
|
|
864
|
+
break;
|
|
865
|
+
default:
|
|
866
|
+
nextC = "";
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
if (nextC === "\n") {
|
|
870
|
+
isEmptyLine = true;
|
|
871
|
+
break;
|
|
872
|
+
}
|
|
873
|
+
if (!nextC) {
|
|
874
|
+
break;
|
|
875
|
+
}
|
|
876
|
+
value += nextC;
|
|
877
|
+
this.next();
|
|
878
|
+
}
|
|
879
|
+
return {
|
|
880
|
+
value,
|
|
881
|
+
isEmptyLine
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
dent() {
|
|
885
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
886
|
+
if (isEmptyLine) {
|
|
887
|
+
this.needIndent = true;
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
this.needIndent = false;
|
|
891
|
+
if (this.isFirstToken) {
|
|
892
|
+
this.dentStack[0] = value.length;
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
let currLen = value.length;
|
|
896
|
+
const indentHasLen = currLen > 0;
|
|
897
|
+
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
898
|
+
if (currLen > prevLen) {
|
|
899
|
+
this.dentStack.push(currLen);
|
|
900
|
+
this.setToken(TokenType.Indent, String(currLen));
|
|
901
|
+
return indentHasLen;
|
|
902
|
+
}
|
|
903
|
+
if (currLen < prevLen) {
|
|
904
|
+
for (let i = this.dentStack.length; i--; ) {
|
|
905
|
+
const expLen = this.dentStack[i];
|
|
906
|
+
if (currLen === expLen) break;
|
|
907
|
+
if (currLen > expLen) {
|
|
908
|
+
throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
|
|
909
|
+
}
|
|
910
|
+
if (this.shorterThanBaseDentEof()) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
this.dentStack.pop();
|
|
914
|
+
if (!this.token) {
|
|
915
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
916
|
+
} else {
|
|
917
|
+
this.waitingTokens.push({
|
|
918
|
+
type: TokenType.Dedent,
|
|
919
|
+
typeName: TokenType[TokenType.Dedent],
|
|
920
|
+
value: String(expLen)
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return indentHasLen;
|
|
925
|
+
}
|
|
926
|
+
return indentHasLen;
|
|
927
|
+
}
|
|
928
|
+
shorterThanBaseDentEof() {
|
|
929
|
+
const yes = this.dentStack.length === 1;
|
|
930
|
+
if (yes) {
|
|
931
|
+
if (!this.token) {
|
|
932
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
933
|
+
} else {
|
|
934
|
+
this.waitingTokens.push({
|
|
935
|
+
type: TokenType.Identifier,
|
|
936
|
+
typeName: TokenType[TokenType.Identifier],
|
|
937
|
+
value: _Tokenizer.EofId
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return yes;
|
|
942
|
+
}
|
|
943
|
+
identifier(char) {
|
|
944
|
+
let value = char;
|
|
945
|
+
let nextC;
|
|
946
|
+
while (1) {
|
|
947
|
+
nextC = this.after;
|
|
948
|
+
if (!this.testId(nextC)) {
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
value += nextC;
|
|
952
|
+
this.next();
|
|
953
|
+
}
|
|
954
|
+
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
955
|
+
this.setToken(TokenType.Identifier, realValue);
|
|
956
|
+
}
|
|
957
|
+
str(char) {
|
|
958
|
+
let value = '"';
|
|
959
|
+
let nextC;
|
|
960
|
+
let continuousBackslashCount = 0;
|
|
961
|
+
while (1) {
|
|
962
|
+
nextC = this.after;
|
|
963
|
+
value += nextC;
|
|
964
|
+
const memoCount = continuousBackslashCount;
|
|
965
|
+
if (nextC === "\\") {
|
|
966
|
+
continuousBackslashCount++;
|
|
967
|
+
} else {
|
|
968
|
+
continuousBackslashCount = 0;
|
|
969
|
+
}
|
|
970
|
+
this.next();
|
|
971
|
+
if (nextC === char && memoCount % 2 === 0) {
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
this.setToken(TokenType.Identifier, JSON.parse(value.slice(0, -1) + '"'));
|
|
976
|
+
}
|
|
977
|
+
number(char) {
|
|
978
|
+
let value = char;
|
|
979
|
+
let nextC;
|
|
980
|
+
while (1) {
|
|
981
|
+
nextC = this.after;
|
|
982
|
+
if (!bobeShared.isNum(nextC)) {
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
value += nextC;
|
|
986
|
+
this.next();
|
|
987
|
+
}
|
|
988
|
+
this.setToken(TokenType.Identifier, Number(value));
|
|
989
|
+
}
|
|
990
|
+
eof() {
|
|
991
|
+
this.setToken(TokenType.Eof, "End Of File");
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
/** Eof 标识符的值 */
|
|
995
|
+
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
996
|
+
let Tokenizer = _Tokenizer;
|
|
997
|
+
|
|
998
|
+
var __defProp = Object.defineProperty;
|
|
999
|
+
var __defProps = Object.defineProperties;
|
|
1000
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
1001
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
1002
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
1003
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1004
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1005
|
+
var __spreadValues = (a, b) => {
|
|
1006
|
+
for (var prop in b || (b = {}))
|
|
1007
|
+
if (__hasOwnProp.call(b, prop))
|
|
1008
|
+
__defNormalProp(a, prop, b[prop]);
|
|
1009
|
+
if (__getOwnPropSymbols)
|
|
1010
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
1011
|
+
if (__propIsEnum.call(b, prop))
|
|
1012
|
+
__defNormalProp(a, prop, b[prop]);
|
|
1013
|
+
}
|
|
1014
|
+
return a;
|
|
1015
|
+
};
|
|
1016
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
1017
|
+
function bobe(fragments, ...values) {
|
|
1018
|
+
const ui = function ui2(options, valueOpt, root, before) {
|
|
1019
|
+
const tokenizer = new Tokenizer();
|
|
1020
|
+
const cmp = new Interpreter(tokenizer);
|
|
1021
|
+
Object.assign(cmp, valueOpt);
|
|
1022
|
+
cmp.config(__spreadProps(__spreadValues({}, options), {
|
|
1023
|
+
hook({ i }) {
|
|
1024
|
+
return values[i];
|
|
1025
|
+
},
|
|
1026
|
+
setProp(node, key, value, hookI) {
|
|
1027
|
+
node.props[key] = value;
|
|
1028
|
+
}
|
|
1029
|
+
}));
|
|
1030
|
+
cmp.init(Array.from(fragments));
|
|
1031
|
+
return cmp.program(root, before);
|
|
1032
|
+
};
|
|
1033
|
+
return ui;
|
|
1034
|
+
}
|
|
1035
|
+
function customRender(option) {
|
|
1036
|
+
return function render(Ctor, root) {
|
|
1037
|
+
const store = Ctor.new();
|
|
1038
|
+
return [store["ui"](option, { data: store }, root), store];
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
exports.bobe = bobe;
|
|
1043
|
+
exports.customRender = customRender;
|
|
1044
|
+
Object.keys(aoye).forEach(function (k) {
|
|
1045
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1046
|
+
enumerable: true,
|
|
1047
|
+
get: function () { return aoye[k]; }
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
467
1050
|
//# sourceMappingURL=bobe.cjs.js.map
|