bobe 0.0.10 → 0.0.11
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 +578 -149
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +573 -150
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +96 -99
- package/dist/index.umd.js +578 -149
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.umd.js
CHANGED
|
@@ -31,27 +31,27 @@
|
|
|
31
31
|
return TerpEvt2;
|
|
32
32
|
})(TerpEvt || {});
|
|
33
33
|
|
|
34
|
-
var __defProp = Object.defineProperty;
|
|
35
|
-
var __defProps = Object.defineProperties;
|
|
36
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
37
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
38
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
39
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
40
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
41
|
-
var __spreadValues = (a, b) => {
|
|
34
|
+
var __defProp$1 = Object.defineProperty;
|
|
35
|
+
var __defProps$1 = Object.defineProperties;
|
|
36
|
+
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
37
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
38
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
39
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
40
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
41
|
+
var __spreadValues$1 = (a, b) => {
|
|
42
42
|
for (var prop in b || (b = {}))
|
|
43
|
-
if (__hasOwnProp.call(b, prop))
|
|
44
|
-
__defNormalProp(a, prop, b[prop]);
|
|
45
|
-
if (__getOwnPropSymbols)
|
|
46
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
47
|
-
if (__propIsEnum.call(b, prop))
|
|
48
|
-
__defNormalProp(a, prop, b[prop]);
|
|
43
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
44
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
45
|
+
if (__getOwnPropSymbols$1)
|
|
46
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
47
|
+
if (__propIsEnum$1.call(b, prop))
|
|
48
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
49
49
|
}
|
|
50
50
|
return a;
|
|
51
51
|
};
|
|
52
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
52
|
+
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
53
53
|
const tap = new bobeShared.BaseEvent();
|
|
54
|
-
class
|
|
54
|
+
class Interpreter {
|
|
55
55
|
constructor(tokenizer) {
|
|
56
56
|
this.tokenizer = tokenizer;
|
|
57
57
|
/** 模板字符串动态节点的占位符 */
|
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
this.data = {};
|
|
61
61
|
/** 模板字符串动态节点索引 */
|
|
62
62
|
this.hookI = 0;
|
|
63
|
-
this.stack = [];
|
|
64
63
|
this._hook = (props) => {
|
|
65
64
|
const value = this.tokenizer.token.value;
|
|
66
65
|
const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
|
|
@@ -68,7 +67,7 @@
|
|
|
68
67
|
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
69
68
|
if (this.hook && isStaticHook) {
|
|
70
69
|
const hookI = Number(value.slice(this.HookId.length));
|
|
71
|
-
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
70
|
+
const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
|
|
72
71
|
HookId: this.HookId,
|
|
73
72
|
i: hookI
|
|
74
73
|
}));
|
|
@@ -84,119 +83,89 @@
|
|
|
84
83
|
// root: any;
|
|
85
84
|
// /** program 挂载的前置节点 */
|
|
86
85
|
// anchor: any;
|
|
87
|
-
program() {
|
|
88
|
-
const
|
|
86
|
+
program(root, before) {
|
|
87
|
+
const componentNode = {
|
|
89
88
|
__logicType: LogicType.Component,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
directList: []
|
|
89
|
+
realParent: root,
|
|
90
|
+
store: new aoye.Store()
|
|
93
91
|
};
|
|
94
92
|
this.tokenizer.consume();
|
|
93
|
+
let prevSibling = null;
|
|
95
94
|
let current;
|
|
96
|
-
|
|
97
|
-
this.stack = [{ node: root, prevSibling }];
|
|
95
|
+
const stack = [{ node: root, prev: prevSibling }];
|
|
98
96
|
while (1) {
|
|
99
97
|
if (this.tokenizer.isEof()) {
|
|
100
|
-
this.handleInsert(root, current,
|
|
98
|
+
this.handleInsert(root, current, prevSibling, componentNode);
|
|
101
99
|
break;
|
|
102
100
|
}
|
|
103
101
|
const token = this.tokenizer.token;
|
|
104
102
|
if (token.type & TokenType.Indent) {
|
|
105
103
|
this.tokenizer.consume();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
stack.push({
|
|
105
|
+
node: current,
|
|
106
|
+
prev: prevSibling
|
|
109
107
|
});
|
|
108
|
+
current = this.declaration({ stack, prevSibling });
|
|
110
109
|
prevSibling = null;
|
|
111
|
-
current = this.declaration();
|
|
112
110
|
continue;
|
|
113
111
|
}
|
|
114
112
|
if (current) {
|
|
115
|
-
if (
|
|
116
|
-
const parent =
|
|
113
|
+
if (stack.length > 1) {
|
|
114
|
+
const { node: parent } = stack[stack.length - 1];
|
|
117
115
|
this.handleInsert(parent, current, prevSibling);
|
|
118
116
|
} else {
|
|
119
|
-
|
|
117
|
+
if (!prevSibling) {
|
|
118
|
+
prevSibling = before;
|
|
119
|
+
}
|
|
120
|
+
this.handleInsert(root, current, prevSibling, componentNode);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
123
124
|
this.tokenizer.consume();
|
|
124
|
-
const { node: parent,
|
|
125
|
-
prevSibling =
|
|
125
|
+
const { node: parent, prev } = stack.pop();
|
|
126
|
+
prevSibling = prev;
|
|
126
127
|
current = parent;
|
|
127
128
|
} else {
|
|
128
129
|
prevSibling = current;
|
|
129
|
-
current = this.declaration();
|
|
130
|
+
current = this.declaration({ stack, prevSibling });
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
+
componentNode.lastInserted = this.lastInserted;
|
|
134
|
+
this.lastInserted = null;
|
|
135
|
+
return componentNode;
|
|
133
136
|
}
|
|
134
137
|
/** 处理
|
|
135
|
-
*
|
|
136
|
-
* 父节点
|
|
137
|
-
* 子节点
|
|
138
|
+
* 是逻辑 是普通
|
|
139
|
+
* 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
|
|
140
|
+
* 子节点 仅插入到父逻辑节点 将本节点插入父节点
|
|
141
|
+
* 理论上父节点不能是一个 逻辑节点,遇到if 时 Terp 会重新执行 program 这种情况下,会指定 root 为真实 dom
|
|
138
142
|
*/
|
|
139
|
-
handleInsert(parent, child,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const realList = child.realList;
|
|
148
|
-
for (let i = realList.length; i--; ) {
|
|
149
|
-
const item = realList[i];
|
|
150
|
-
insertFn(parent, item, prevSibling);
|
|
143
|
+
handleInsert(parent, child, prev, parentComponent) {
|
|
144
|
+
if (!child.__logicType) {
|
|
145
|
+
if (!prev || !prev.__logicType) {
|
|
146
|
+
this.insertAfter(parent, child, prev);
|
|
147
|
+
} else {
|
|
148
|
+
const before = prev.lastInserted;
|
|
149
|
+
this.insertAfter(parent, child, before);
|
|
150
|
+
prev.realAfter = child;
|
|
151
151
|
}
|
|
152
152
|
} else {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
172
|
-
this.tokenizer.consume();
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
_node = this.node();
|
|
176
|
-
const insert = parent.__logicType ? this.defaultInsert : this.insert.bind(this);
|
|
177
|
-
parent.__logicType ? this.defaultRemove : this.remove.bind(this);
|
|
178
|
-
if (!_node.__logicType) {
|
|
179
|
-
const realPrev = this.getPrevRealSibling(prevSibling);
|
|
180
|
-
const currItem = insert(parent, _node, realPrev, prevItem);
|
|
181
|
-
prevItem = currItem;
|
|
182
|
-
prevSibling = _node;
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
if (prevSibling) {
|
|
186
|
-
_node.anchor = prevSibling;
|
|
187
|
-
} else if (parent.__logicType) {
|
|
188
|
-
_node.anchor = parent;
|
|
189
|
-
} else ;
|
|
190
|
-
if (_node.child && _node.condition()) {
|
|
191
|
-
let item = _node.child;
|
|
192
|
-
while (item != null) {
|
|
193
|
-
const { value: child } = item;
|
|
194
|
-
const realPrev = this.getPrevRealSibling(prevSibling);
|
|
195
|
-
const currItem = insert(parent, child, realPrev, prevItem);
|
|
196
|
-
item = item.next;
|
|
197
|
-
prevItem = currItem;
|
|
198
|
-
prevSibling = child;
|
|
199
|
-
}
|
|
153
|
+
const childCmp = child;
|
|
154
|
+
childCmp.realParent = parent;
|
|
155
|
+
if (!prev) {
|
|
156
|
+
const anchor = this.createAnchor();
|
|
157
|
+
this.insertAfter(parent, anchor, prev);
|
|
158
|
+
this.insertAfter(parent, child, anchor);
|
|
159
|
+
childCmp.realBefore = anchor;
|
|
160
|
+
} else if (prev.__logicType) {
|
|
161
|
+
const before = prev.lastInserted;
|
|
162
|
+
const anchor = this.createAnchor();
|
|
163
|
+
this.insertAfter(parent, anchor, before);
|
|
164
|
+
this.insertAfter(parent, child, anchor);
|
|
165
|
+
childCmp.realBefore = anchor;
|
|
166
|
+
prev.realAfter = anchor;
|
|
167
|
+
} else {
|
|
168
|
+
childCmp.realBefore = prev;
|
|
200
169
|
}
|
|
201
170
|
}
|
|
202
171
|
}
|
|
@@ -213,25 +182,12 @@
|
|
|
213
182
|
point = point.anchor;
|
|
214
183
|
}
|
|
215
184
|
}
|
|
216
|
-
/**
|
|
217
|
-
* 单个节点:
|
|
218
|
-
* 由声明部分和(可选的)子节点块组成
|
|
219
|
-
* <node> ::= <declaration> <childrenBlockOpt>
|
|
220
|
-
* */
|
|
221
|
-
node() {
|
|
222
|
-
const _declaration = this.declaration();
|
|
223
|
-
if (_declaration.__logicType & LogicType.If && !_declaration.condition()) {
|
|
224
|
-
return _declaration;
|
|
225
|
-
}
|
|
226
|
-
this.childrenBlockOpt(_declaration);
|
|
227
|
-
return _declaration;
|
|
228
|
-
}
|
|
229
185
|
/**
|
|
230
186
|
* 声明部分:
|
|
231
187
|
* 包含首行定义和(可选的)多行属性扩展
|
|
232
188
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
233
189
|
* */
|
|
234
|
-
declaration() {
|
|
190
|
+
declaration(ctx) {
|
|
235
191
|
const [hookType, value] = this._hook({});
|
|
236
192
|
let _node;
|
|
237
193
|
if (value === "if") {
|
|
@@ -239,7 +195,7 @@
|
|
|
239
195
|
} else if (hookType) {
|
|
240
196
|
if (hookType === "static") {
|
|
241
197
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
242
|
-
_node = this.componentDeclaration(value);
|
|
198
|
+
_node = this.componentDeclaration(value, ctx);
|
|
243
199
|
} else if (typeof value === "function") {
|
|
244
200
|
_node = this.fragmentDeclaration(value);
|
|
245
201
|
} else {
|
|
@@ -266,8 +222,7 @@
|
|
|
266
222
|
fragmentDeclaration(renderFragment) {
|
|
267
223
|
const fragmentNode = {
|
|
268
224
|
__logicType: LogicType.Fragment,
|
|
269
|
-
|
|
270
|
-
realList: []
|
|
225
|
+
realParent: null
|
|
271
226
|
};
|
|
272
227
|
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
273
228
|
return fragmentNode;
|
|
@@ -295,7 +250,7 @@
|
|
|
295
250
|
this.setProp(node, key, value, hookI);
|
|
296
251
|
}
|
|
297
252
|
}
|
|
298
|
-
componentDeclaration(Component) {
|
|
253
|
+
componentDeclaration(Component, ctx) {
|
|
299
254
|
const child = Component.new();
|
|
300
255
|
const prevOnePropParsed = this.onePropParsed;
|
|
301
256
|
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
@@ -311,9 +266,11 @@
|
|
|
311
266
|
}
|
|
312
267
|
};
|
|
313
268
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
269
|
+
const parent = ctx.stack[ctx.stack.length - 1].node;
|
|
270
|
+
const prev = ctx.prevSibling;
|
|
314
271
|
this.onePropParsed = prevOnePropParsed;
|
|
315
|
-
const
|
|
316
|
-
tap.emit(TerpEvt.HandledComponentNode,
|
|
272
|
+
const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
|
|
273
|
+
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
317
274
|
});
|
|
318
275
|
return { __logicType: LogicType.Component };
|
|
319
276
|
}
|
|
@@ -323,8 +280,7 @@
|
|
|
323
280
|
const ifNode = {
|
|
324
281
|
__logicType: LogicType.If,
|
|
325
282
|
condition: value,
|
|
326
|
-
|
|
327
|
-
realList: [],
|
|
283
|
+
realParent: null,
|
|
328
284
|
snapshot: this.tokenizer.snapshot(),
|
|
329
285
|
isFirstRender: true,
|
|
330
286
|
watcher: null,
|
|
@@ -403,19 +359,6 @@
|
|
|
403
359
|
this.tokenizer.consume();
|
|
404
360
|
}
|
|
405
361
|
}
|
|
406
|
-
/** 子节点块:
|
|
407
|
-
* 必须被缩进包裹
|
|
408
|
-
* <childrenBlockOpt> ::= INDENT <nodeList>
|
|
409
|
-
* | ε /* 空(表示叶子节点,没有孩子)
|
|
410
|
-
* */
|
|
411
|
-
childrenBlockOpt(parent) {
|
|
412
|
-
if (!(this.tokenizer.token.type & TokenType.Indent)) {
|
|
413
|
-
return [];
|
|
414
|
-
}
|
|
415
|
-
this.tokenizer.consume();
|
|
416
|
-
const list = this.nodeList(parent);
|
|
417
|
-
return list;
|
|
418
|
-
}
|
|
419
362
|
config(opt) {
|
|
420
363
|
Object.assign(this, opt);
|
|
421
364
|
this.opt = opt;
|
|
@@ -423,28 +366,43 @@
|
|
|
423
366
|
createNode(name) {
|
|
424
367
|
return {
|
|
425
368
|
name,
|
|
426
|
-
props: {}
|
|
369
|
+
props: {},
|
|
370
|
+
nextSibling: null
|
|
427
371
|
};
|
|
428
372
|
}
|
|
429
|
-
|
|
430
|
-
return
|
|
373
|
+
nextSib(node) {
|
|
374
|
+
return node.nextSibling;
|
|
431
375
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
376
|
+
createAnchor() {
|
|
377
|
+
return {
|
|
378
|
+
name: "anchor",
|
|
379
|
+
nextSibling: null
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
insertAfter(parent, node, prev) {
|
|
383
|
+
this.lastInserted = node;
|
|
384
|
+
return this.defaultInsert(parent, node, prev);
|
|
385
|
+
}
|
|
386
|
+
defaultInsert(parent, node, prev) {
|
|
387
|
+
if (prev) {
|
|
388
|
+
const next = prev.nextSibling;
|
|
389
|
+
prev.nextSibling = node;
|
|
390
|
+
node.nextSibling = next;
|
|
437
391
|
} else {
|
|
438
|
-
parent.
|
|
392
|
+
parent.firstChild = node;
|
|
439
393
|
}
|
|
440
394
|
}
|
|
441
|
-
remove(parent, node, prevSibling
|
|
442
|
-
return this.defaultRemove(parent, node, prevSibling
|
|
395
|
+
remove(parent, node, prevSibling) {
|
|
396
|
+
return this.defaultRemove(parent, node, prevSibling);
|
|
443
397
|
}
|
|
444
398
|
// TODO: 默认改成 prevItem
|
|
445
|
-
defaultRemove(parent, node, prevSibling
|
|
446
|
-
|
|
447
|
-
|
|
399
|
+
defaultRemove(parent, node, prevSibling) {
|
|
400
|
+
const next = node.nextSibling;
|
|
401
|
+
if (prevSibling) {
|
|
402
|
+
prevSibling.nextSibling = next;
|
|
403
|
+
}
|
|
404
|
+
if (parent.firstChild === node) {
|
|
405
|
+
parent.firstChild = next;
|
|
448
406
|
}
|
|
449
407
|
}
|
|
450
408
|
setProp(node, key, value, hookI) {
|
|
@@ -464,7 +422,478 @@
|
|
|
464
422
|
}
|
|
465
423
|
}
|
|
466
424
|
|
|
467
|
-
|
|
425
|
+
const _Tokenizer = class _Tokenizer {
|
|
426
|
+
constructor() {
|
|
427
|
+
/** 缩进大小 默认 2 */
|
|
428
|
+
this.TabSize = 2;
|
|
429
|
+
/** 缩进字符 */
|
|
430
|
+
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
431
|
+
/** 匹配标识符 */
|
|
432
|
+
this.IdExp = /[\d\w\/]/;
|
|
433
|
+
/** 回车后需要判断缩进 */
|
|
434
|
+
this.needIndent = false;
|
|
435
|
+
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
436
|
+
this.isFirstToken = true;
|
|
437
|
+
/** 记录历史缩进的长度,相对于行首 */
|
|
438
|
+
this.dentStack = [0];
|
|
439
|
+
/** 当前字符 index */
|
|
440
|
+
this.i = 0;
|
|
441
|
+
this.handledTokens = [];
|
|
442
|
+
/**
|
|
443
|
+
* 有些标识符能产生多个 token
|
|
444
|
+
* 例如 dedent
|
|
445
|
+
* parent1
|
|
446
|
+
* child
|
|
447
|
+
* subChild
|
|
448
|
+
* parent2 <- 产生两个 dedent
|
|
449
|
+
*/
|
|
450
|
+
this.waitingTokens = new bobeShared.Queue();
|
|
451
|
+
}
|
|
452
|
+
consume() {
|
|
453
|
+
const token = this.token;
|
|
454
|
+
this.nextToken();
|
|
455
|
+
return token;
|
|
456
|
+
}
|
|
457
|
+
// /** 恢复至某一个现场,进行 token 重算 */
|
|
458
|
+
resume(_snapshot) {
|
|
459
|
+
this.token = void 0;
|
|
460
|
+
this.needIndent = false;
|
|
461
|
+
this.isFirstToken = true;
|
|
462
|
+
this.dentStack = [0];
|
|
463
|
+
Object.assign(this, _snapshot);
|
|
464
|
+
}
|
|
465
|
+
snapshot() {
|
|
466
|
+
return {
|
|
467
|
+
i: this.i,
|
|
468
|
+
waitingTokens: this.waitingTokens.clone()
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
skip() {
|
|
472
|
+
const dentLen = this.dentStack[this.dentStack.length - 1];
|
|
473
|
+
let needIndent = false;
|
|
474
|
+
let skipFragment = ``;
|
|
475
|
+
this.token = void 0;
|
|
476
|
+
while (1) {
|
|
477
|
+
const char = this.char;
|
|
478
|
+
if (char === "\n") {
|
|
479
|
+
needIndent = true;
|
|
480
|
+
skipFragment += char;
|
|
481
|
+
this.next();
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (!needIndent) {
|
|
485
|
+
skipFragment += char;
|
|
486
|
+
this.next();
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
needIndent = false;
|
|
490
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
491
|
+
const currLen = value.length;
|
|
492
|
+
if (isEmptyLine) continue;
|
|
493
|
+
if (value.length > dentLen) {
|
|
494
|
+
skipFragment += value;
|
|
495
|
+
} else {
|
|
496
|
+
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
497
|
+
const expLen = this.dentStack[i];
|
|
498
|
+
if (currLen === expLen) break;
|
|
499
|
+
if (currLen > expLen) {
|
|
500
|
+
throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
|
|
501
|
+
}
|
|
502
|
+
this.dentStack.pop();
|
|
503
|
+
if (!this.token) {
|
|
504
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
505
|
+
} else {
|
|
506
|
+
this.waitingTokens.push({
|
|
507
|
+
type: TokenType.Dedent,
|
|
508
|
+
typeName: TokenType[TokenType.Dedent],
|
|
509
|
+
value: String(expLen)
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (!this.token) {
|
|
517
|
+
this.nextToken();
|
|
518
|
+
}
|
|
519
|
+
return skipFragment;
|
|
520
|
+
}
|
|
521
|
+
setCode(code) {
|
|
522
|
+
this.code = "\n" + code.trimEnd() + `
|
|
523
|
+
${_Tokenizer.EofId}`;
|
|
524
|
+
}
|
|
525
|
+
tokenize() {
|
|
526
|
+
var _a, _b;
|
|
527
|
+
do {
|
|
528
|
+
this.nextToken();
|
|
529
|
+
console.log("token:", TokenType[(_a = this.token) == null ? void 0 : _a.type], JSON.stringify(((_b = this.token) == null ? void 0 : _b.value) || ""));
|
|
530
|
+
} while (!this.isEof());
|
|
531
|
+
}
|
|
532
|
+
isEof() {
|
|
533
|
+
if (!this.token) return false;
|
|
534
|
+
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
535
|
+
}
|
|
536
|
+
get char() {
|
|
537
|
+
return this.code[this.i];
|
|
538
|
+
}
|
|
539
|
+
get prev() {
|
|
540
|
+
return this.code[this.i - 1];
|
|
541
|
+
}
|
|
542
|
+
get after() {
|
|
543
|
+
return this.code[this.i + 1];
|
|
544
|
+
}
|
|
545
|
+
next() {
|
|
546
|
+
const prev = this.code[this.i];
|
|
547
|
+
this.i++;
|
|
548
|
+
const curr = this.code[this.i];
|
|
549
|
+
return [prev, curr];
|
|
550
|
+
}
|
|
551
|
+
setToken(type, value) {
|
|
552
|
+
this.token = {
|
|
553
|
+
type,
|
|
554
|
+
typeName: TokenType[type],
|
|
555
|
+
value
|
|
556
|
+
};
|
|
557
|
+
this.isFirstToken = false;
|
|
558
|
+
}
|
|
559
|
+
testId(value) {
|
|
560
|
+
if (typeof value !== "string") return false;
|
|
561
|
+
return this.IdExp.test(value);
|
|
562
|
+
}
|
|
563
|
+
nextToken() {
|
|
564
|
+
try {
|
|
565
|
+
if (this.isEof()) {
|
|
566
|
+
return this.token;
|
|
567
|
+
}
|
|
568
|
+
this.token = void 0;
|
|
569
|
+
if (this.waitingTokens.len) {
|
|
570
|
+
const item = this.waitingTokens.shift();
|
|
571
|
+
this.setToken(item.type, item.value);
|
|
572
|
+
return this.token;
|
|
573
|
+
}
|
|
574
|
+
outer: while (1) {
|
|
575
|
+
if (this.needIndent) {
|
|
576
|
+
this.dent();
|
|
577
|
+
} else {
|
|
578
|
+
let { char } = this;
|
|
579
|
+
switch (char) {
|
|
580
|
+
case " ":
|
|
581
|
+
case " ":
|
|
582
|
+
break;
|
|
583
|
+
// 找后续所有 newLine
|
|
584
|
+
case "\n":
|
|
585
|
+
this.newLine();
|
|
586
|
+
this.needIndent = true;
|
|
587
|
+
break;
|
|
588
|
+
case "=":
|
|
589
|
+
this.assignment();
|
|
590
|
+
break;
|
|
591
|
+
case "|":
|
|
592
|
+
this.pipe();
|
|
593
|
+
break;
|
|
594
|
+
case "'":
|
|
595
|
+
case '"':
|
|
596
|
+
this.str(char);
|
|
597
|
+
break;
|
|
598
|
+
case "{":
|
|
599
|
+
this.brace();
|
|
600
|
+
break;
|
|
601
|
+
case "$":
|
|
602
|
+
const handled = this.dynamic(char);
|
|
603
|
+
if (handled) break;
|
|
604
|
+
default:
|
|
605
|
+
if (bobeShared.isNum(char)) {
|
|
606
|
+
this.number(char);
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
if (this.testId(char)) {
|
|
610
|
+
this.identifier(char);
|
|
611
|
+
}
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
this.next();
|
|
615
|
+
}
|
|
616
|
+
if (this.token) {
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return this.token;
|
|
621
|
+
} catch (error) {
|
|
622
|
+
console.error(error);
|
|
623
|
+
} finally {
|
|
624
|
+
this.handledTokens.push(this.token);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
assignment() {
|
|
628
|
+
this.setToken(TokenType.Assign, "=");
|
|
629
|
+
}
|
|
630
|
+
pipe() {
|
|
631
|
+
this.setToken(TokenType.Pipe, "|");
|
|
632
|
+
}
|
|
633
|
+
dynamic(char) {
|
|
634
|
+
let nextC = this.after;
|
|
635
|
+
if (nextC !== "{") {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
this.next();
|
|
639
|
+
let value = "${";
|
|
640
|
+
let innerBrace = 0;
|
|
641
|
+
while (1) {
|
|
642
|
+
nextC = this.after;
|
|
643
|
+
value += nextC;
|
|
644
|
+
this.next();
|
|
645
|
+
if (nextC === "{") {
|
|
646
|
+
innerBrace++;
|
|
647
|
+
}
|
|
648
|
+
if (nextC === "}") {
|
|
649
|
+
if (!innerBrace) {
|
|
650
|
+
break;
|
|
651
|
+
}
|
|
652
|
+
innerBrace--;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
this.setToken(TokenType.Identifier, value);
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
brace() {
|
|
659
|
+
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
660
|
+
while (1) {
|
|
661
|
+
const char = this.char;
|
|
662
|
+
const nextChar = this.after;
|
|
663
|
+
if (inComment === "single" && char === "\n") {
|
|
664
|
+
inComment = null;
|
|
665
|
+
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
666
|
+
inComment = null;
|
|
667
|
+
value += this.next()[0];
|
|
668
|
+
} else if (inString) {
|
|
669
|
+
if (char === inString && backslashCount % 2 === 0) {
|
|
670
|
+
inString = null;
|
|
671
|
+
}
|
|
672
|
+
backslashCount = char === "\\" ? backslashCount + 1 : 0;
|
|
673
|
+
} else {
|
|
674
|
+
if (char === "/" && nextChar === "/") {
|
|
675
|
+
inComment = "single";
|
|
676
|
+
value += this.next()[0];
|
|
677
|
+
} else if (char === "/" && nextChar === "*") {
|
|
678
|
+
inComment = "multi";
|
|
679
|
+
value += this.next()[0];
|
|
680
|
+
} else if (char === "'" || char === '"' || char === "`") {
|
|
681
|
+
inString = char;
|
|
682
|
+
} else if (char === "{") {
|
|
683
|
+
count++;
|
|
684
|
+
} else if (char === "}") {
|
|
685
|
+
count--;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
if (count === 0 && inString == null && inComment == null) {
|
|
689
|
+
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
value += this.next()[0];
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
newLine() {
|
|
696
|
+
let value = "\n";
|
|
697
|
+
let nextC;
|
|
698
|
+
while (1) {
|
|
699
|
+
nextC = this.after;
|
|
700
|
+
if (nextC !== "\n") {
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
value += nextC;
|
|
704
|
+
this.next();
|
|
705
|
+
}
|
|
706
|
+
if (this.isFirstToken) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
this.setToken(TokenType.NewLine, value);
|
|
710
|
+
}
|
|
711
|
+
getDentValue() {
|
|
712
|
+
let value = "";
|
|
713
|
+
let nextC;
|
|
714
|
+
let isEmptyLine = false;
|
|
715
|
+
while (1) {
|
|
716
|
+
const nextChar = this.char;
|
|
717
|
+
switch (nextChar) {
|
|
718
|
+
case " ":
|
|
719
|
+
nextC = this.Tab;
|
|
720
|
+
break;
|
|
721
|
+
case " ":
|
|
722
|
+
nextC = " ";
|
|
723
|
+
break;
|
|
724
|
+
case "\n":
|
|
725
|
+
nextC = "\n";
|
|
726
|
+
break;
|
|
727
|
+
default:
|
|
728
|
+
nextC = "";
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
if (nextC === "\n") {
|
|
732
|
+
isEmptyLine = true;
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
if (!nextC) {
|
|
736
|
+
break;
|
|
737
|
+
}
|
|
738
|
+
value += nextC;
|
|
739
|
+
this.next();
|
|
740
|
+
}
|
|
741
|
+
return {
|
|
742
|
+
value,
|
|
743
|
+
isEmptyLine
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
dent() {
|
|
747
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
748
|
+
if (isEmptyLine) {
|
|
749
|
+
this.needIndent = true;
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
this.needIndent = false;
|
|
753
|
+
if (this.isFirstToken) {
|
|
754
|
+
this.dentStack[0] = value.length;
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
let currLen = value.length;
|
|
758
|
+
const indentHasLen = currLen > 0;
|
|
759
|
+
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
760
|
+
if (currLen > prevLen) {
|
|
761
|
+
this.dentStack.push(currLen);
|
|
762
|
+
this.setToken(TokenType.Indent, String(currLen));
|
|
763
|
+
return indentHasLen;
|
|
764
|
+
}
|
|
765
|
+
if (currLen < prevLen) {
|
|
766
|
+
for (let i = this.dentStack.length - 2; i >= 0; i--) {
|
|
767
|
+
const expLen = this.dentStack[i];
|
|
768
|
+
const prevExpLen = this.dentStack[i + 1];
|
|
769
|
+
if (currLen > expLen && currLen < prevExpLen) {
|
|
770
|
+
throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
|
|
771
|
+
}
|
|
772
|
+
this.dentStack.pop();
|
|
773
|
+
if (!this.token) {
|
|
774
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
775
|
+
} else {
|
|
776
|
+
this.waitingTokens.push({
|
|
777
|
+
type: TokenType.Dedent,
|
|
778
|
+
typeName: TokenType[TokenType.Dedent],
|
|
779
|
+
value: String(expLen)
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
if (currLen === expLen) {
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return indentHasLen;
|
|
787
|
+
}
|
|
788
|
+
return indentHasLen;
|
|
789
|
+
}
|
|
790
|
+
identifier(char) {
|
|
791
|
+
let value = char;
|
|
792
|
+
let nextC;
|
|
793
|
+
while (1) {
|
|
794
|
+
nextC = this.after;
|
|
795
|
+
if (!this.testId(nextC)) {
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
798
|
+
value += nextC;
|
|
799
|
+
this.next();
|
|
800
|
+
}
|
|
801
|
+
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
802
|
+
this.setToken(TokenType.Identifier, realValue);
|
|
803
|
+
}
|
|
804
|
+
str(char) {
|
|
805
|
+
let value = '"';
|
|
806
|
+
let nextC;
|
|
807
|
+
let continuousBackslashCount = 0;
|
|
808
|
+
while (1) {
|
|
809
|
+
nextC = this.after;
|
|
810
|
+
value += nextC;
|
|
811
|
+
const memoCount = continuousBackslashCount;
|
|
812
|
+
if (nextC === "\\") {
|
|
813
|
+
continuousBackslashCount++;
|
|
814
|
+
} else {
|
|
815
|
+
continuousBackslashCount = 0;
|
|
816
|
+
}
|
|
817
|
+
this.next();
|
|
818
|
+
if (nextC === char && memoCount % 2 === 0) {
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
this.setToken(TokenType.Identifier, JSON.parse(value.slice(0, -1) + '"'));
|
|
823
|
+
}
|
|
824
|
+
number(char) {
|
|
825
|
+
let value = char;
|
|
826
|
+
let nextC;
|
|
827
|
+
while (1) {
|
|
828
|
+
nextC = this.after;
|
|
829
|
+
if (!bobeShared.isNum(nextC)) {
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
value += nextC;
|
|
833
|
+
this.next();
|
|
834
|
+
}
|
|
835
|
+
this.setToken(TokenType.Identifier, Number(value));
|
|
836
|
+
}
|
|
837
|
+
eof() {
|
|
838
|
+
this.setToken(TokenType.Eof, "End Of File");
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
/** Eof 标识符的值 */
|
|
842
|
+
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
843
|
+
let Tokenizer = _Tokenizer;
|
|
844
|
+
|
|
845
|
+
var __defProp = Object.defineProperty;
|
|
846
|
+
var __defProps = Object.defineProperties;
|
|
847
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
848
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
849
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
850
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
851
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
852
|
+
var __spreadValues = (a, b) => {
|
|
853
|
+
for (var prop in b || (b = {}))
|
|
854
|
+
if (__hasOwnProp.call(b, prop))
|
|
855
|
+
__defNormalProp(a, prop, b[prop]);
|
|
856
|
+
if (__getOwnPropSymbols)
|
|
857
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
858
|
+
if (__propIsEnum.call(b, prop))
|
|
859
|
+
__defNormalProp(a, prop, b[prop]);
|
|
860
|
+
}
|
|
861
|
+
return a;
|
|
862
|
+
};
|
|
863
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
864
|
+
function bobe(fragments, ...values) {
|
|
865
|
+
const ui = function ui2(options, valueOpt, root, before) {
|
|
866
|
+
const tokenizer = new Tokenizer();
|
|
867
|
+
const cmp = new Interpreter(tokenizer);
|
|
868
|
+
Object.assign(cmp, valueOpt);
|
|
869
|
+
cmp.config(__spreadProps(__spreadValues({}, options), {
|
|
870
|
+
hook({ i }) {
|
|
871
|
+
return values[i];
|
|
872
|
+
},
|
|
873
|
+
setProp(node, key, value, hookI) {
|
|
874
|
+
node.props[key] = value;
|
|
875
|
+
}
|
|
876
|
+
}));
|
|
877
|
+
cmp.init(Array.from(fragments));
|
|
878
|
+
return cmp.program(root, before);
|
|
879
|
+
};
|
|
880
|
+
return ui;
|
|
881
|
+
}
|
|
882
|
+
function customRender(option) {
|
|
883
|
+
return function render(Ctor, root) {
|
|
884
|
+
const store = Ctor.new();
|
|
885
|
+
return [store["ui"](option, { data: store }, root), store];
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
exports.bobe = bobe;
|
|
890
|
+
exports.customRender = customRender;
|
|
891
|
+
Object.keys(aoye).forEach(function (k) {
|
|
892
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
893
|
+
enumerable: true,
|
|
894
|
+
get: function () { return aoye[k]; }
|
|
895
|
+
});
|
|
896
|
+
});
|
|
468
897
|
|
|
469
898
|
}));
|
|
470
899
|
//# sourceMappingURL=index.umd.js.map
|