bobe 0.0.11 → 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 +223 -69
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +224 -70
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +56 -17
- package/dist/index.umd.js +223 -69
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.umd.js
CHANGED
|
@@ -23,13 +23,94 @@
|
|
|
23
23
|
LogicType2[LogicType2["Component"] = 16] = "Component";
|
|
24
24
|
LogicType2[LogicType2["Fragment"] = 32] = "Fragment";
|
|
25
25
|
LogicType2[LogicType2["Root"] = 64] = "Root";
|
|
26
|
+
LogicType2[LogicType2["Real"] = 128] = "Real";
|
|
26
27
|
return LogicType2;
|
|
27
28
|
})(LogicType || {});
|
|
29
|
+
const Logical = 1 /* If */ | 2 /* ElseIf */ | 4 /* Else */ | 8 /* For */;
|
|
30
|
+
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
31
|
+
NodeType2[NodeType2["Logic"] = Logical] = "Logic";
|
|
32
|
+
NodeType2[NodeType2["Real"] = 128 /* Real */] = "Real";
|
|
33
|
+
NodeType2[NodeType2["Component"] = 16 /* Component */] = "Component";
|
|
34
|
+
return NodeType2;
|
|
35
|
+
})(NodeType || {});
|
|
28
36
|
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
29
37
|
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
30
38
|
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
31
39
|
return TerpEvt2;
|
|
32
40
|
})(TerpEvt || {});
|
|
41
|
+
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
42
|
+
|
|
43
|
+
class TypedStack {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.top = null;
|
|
46
|
+
// 存储每种类型最近一次出现的包装单元引用
|
|
47
|
+
// 使用 Record 来动态支持不同的类型标签
|
|
48
|
+
this.lastNodes = {};
|
|
49
|
+
this.length = 0;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @param rawNode 原始节点数据
|
|
53
|
+
* @param type 节点类型
|
|
54
|
+
*/
|
|
55
|
+
push(rawNode, type) {
|
|
56
|
+
var _a;
|
|
57
|
+
const newNode = {
|
|
58
|
+
data: rawNode,
|
|
59
|
+
type,
|
|
60
|
+
prev: this.top,
|
|
61
|
+
prevSameType: (_a = this.lastNodes[type]) != null ? _a : null
|
|
62
|
+
};
|
|
63
|
+
this.top = newNode;
|
|
64
|
+
this.length++;
|
|
65
|
+
this.lastNodes[type] = newNode;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 出栈操作
|
|
69
|
+
* @returns 原始节点数据或 null
|
|
70
|
+
*/
|
|
71
|
+
pop() {
|
|
72
|
+
if (!this.top) return null;
|
|
73
|
+
const popped = this.top;
|
|
74
|
+
this.lastNodes[popped.type] = popped.prevSameType;
|
|
75
|
+
this.top = popped.prev;
|
|
76
|
+
this.length--;
|
|
77
|
+
return popped.data;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* O(1) 获取栈顶节点的前一个同类型节点
|
|
81
|
+
*/
|
|
82
|
+
getPrevSameType() {
|
|
83
|
+
if (!this.top || !this.top.prevSameType) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
return this.top.prevSameType.data;
|
|
87
|
+
}
|
|
88
|
+
findPrevSameType(cb) {
|
|
89
|
+
if (!this.top) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
let point = this.top.prevSameType;
|
|
93
|
+
while (point) {
|
|
94
|
+
if (cb(point.data)) {
|
|
95
|
+
return point.data;
|
|
96
|
+
}
|
|
97
|
+
point = point.prevSameType;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 获取当前栈顶的类型
|
|
103
|
+
*/
|
|
104
|
+
get peekType() {
|
|
105
|
+
return this.top ? this.top.type : null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 获取栈顶元素
|
|
109
|
+
*/
|
|
110
|
+
peek() {
|
|
111
|
+
return this.top.data;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
33
114
|
|
|
34
115
|
var __defProp$1 = Object.defineProperty;
|
|
35
116
|
var __defProps$1 = Object.defineProperties;
|
|
@@ -79,61 +160,94 @@
|
|
|
79
160
|
return [hookType, value];
|
|
80
161
|
};
|
|
81
162
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// anchor: any;
|
|
163
|
+
isLogicNode(node) {
|
|
164
|
+
return node && node.__logicType & Logical;
|
|
165
|
+
}
|
|
86
166
|
program(root, before) {
|
|
167
|
+
var _a;
|
|
87
168
|
const componentNode = {
|
|
88
169
|
__logicType: LogicType.Component,
|
|
89
170
|
realParent: root,
|
|
90
171
|
store: new aoye.Store()
|
|
91
172
|
};
|
|
92
173
|
this.tokenizer.consume();
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
174
|
+
const stack = new TypedStack();
|
|
175
|
+
stack.push({ node: root, prev: null }, NodeType.Real);
|
|
176
|
+
const ctx = {
|
|
177
|
+
realParent: root,
|
|
178
|
+
prevSibling: before,
|
|
179
|
+
current: null,
|
|
180
|
+
stack,
|
|
181
|
+
before
|
|
182
|
+
};
|
|
183
|
+
const rootPulling = aoye.getPulling();
|
|
96
184
|
while (1) {
|
|
97
185
|
if (this.tokenizer.isEof()) {
|
|
98
|
-
|
|
186
|
+
if (!ctx.prevSibling) ctx.prevSibling = before;
|
|
187
|
+
this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
|
|
99
188
|
break;
|
|
100
189
|
}
|
|
101
190
|
const token = this.tokenizer.token;
|
|
102
191
|
if (token.type & TokenType.Indent) {
|
|
103
192
|
this.tokenizer.consume();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
193
|
+
const isLogicNode = this.isLogicNode(ctx.current);
|
|
194
|
+
stack.push(
|
|
195
|
+
{
|
|
196
|
+
node: ctx.current,
|
|
197
|
+
prev: ctx.prevSibling
|
|
198
|
+
},
|
|
199
|
+
ctx.current.__logicType ? isLogicNode ? NodeType.Logic : NodeType.Component : NodeType.Real
|
|
200
|
+
);
|
|
201
|
+
if (ctx.current.__logicType) {
|
|
202
|
+
if (isLogicNode) {
|
|
203
|
+
aoye.setPulling(ctx.current.effect.ins);
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
ctx.realParent = ctx.current;
|
|
207
|
+
ctx.prevSibling = null;
|
|
208
|
+
}
|
|
209
|
+
ctx.current = this.declaration(ctx);
|
|
110
210
|
continue;
|
|
111
211
|
}
|
|
112
|
-
if (current) {
|
|
113
|
-
if (stack.length
|
|
114
|
-
|
|
115
|
-
this.handleInsert(parent, current, prevSibling);
|
|
116
|
-
} else {
|
|
117
|
-
if (!prevSibling) {
|
|
118
|
-
prevSibling = before;
|
|
119
|
-
}
|
|
120
|
-
this.handleInsert(root, current, prevSibling, componentNode);
|
|
212
|
+
if (ctx.current) {
|
|
213
|
+
if (stack.length === 1 && !ctx.prevSibling) {
|
|
214
|
+
ctx.prevSibling = before;
|
|
121
215
|
}
|
|
216
|
+
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
122
217
|
}
|
|
123
218
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
124
219
|
this.tokenizer.consume();
|
|
125
|
-
const { node: parent, prev } = stack.
|
|
126
|
-
|
|
127
|
-
|
|
220
|
+
const { node: parent, prev } = stack.peek();
|
|
221
|
+
if (!parent.__logicType) {
|
|
222
|
+
const prevSameType = stack.getPrevSameType();
|
|
223
|
+
ctx.realParent = prevSameType == null ? void 0 : prevSameType.node;
|
|
224
|
+
} else {
|
|
225
|
+
if (this.isLogicNode(parent)) {
|
|
226
|
+
const parentLogic = (_a = stack.getPrevSameType()) == null ? void 0 : _a.node;
|
|
227
|
+
if (parentLogic) {
|
|
228
|
+
aoye.setPulling(parentLogic.effect.ins);
|
|
229
|
+
} else {
|
|
230
|
+
aoye.setPulling(rootPulling);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
stack.pop();
|
|
235
|
+
ctx.prevSibling = prev;
|
|
236
|
+
ctx.current = parent;
|
|
128
237
|
} else {
|
|
129
|
-
prevSibling = current;
|
|
130
|
-
current = this.declaration(
|
|
238
|
+
ctx.prevSibling = ctx.current || ctx.prevSibling;
|
|
239
|
+
ctx.current = this.declaration(ctx);
|
|
131
240
|
}
|
|
132
241
|
}
|
|
133
|
-
componentNode.lastInserted = this.lastInserted;
|
|
134
|
-
this.lastInserted = null;
|
|
135
242
|
return componentNode;
|
|
136
243
|
}
|
|
244
|
+
insertAfterAnchor(ctx) {
|
|
245
|
+
const { realParent, prevSibling, stack, before } = ctx;
|
|
246
|
+
const afterAnchor = this.createAnchor();
|
|
247
|
+
ctx.prevSibling = stack.length === 1 && !prevSibling ? before : prevSibling;
|
|
248
|
+
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
249
|
+
return afterAnchor;
|
|
250
|
+
}
|
|
137
251
|
/** 处理
|
|
138
252
|
* 是逻辑 是普通
|
|
139
253
|
* 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
|
|
@@ -145,25 +259,14 @@
|
|
|
145
259
|
if (!prev || !prev.__logicType) {
|
|
146
260
|
this.insertAfter(parent, child, prev);
|
|
147
261
|
} else {
|
|
148
|
-
const before = prev.
|
|
262
|
+
const before = prev.realAfter;
|
|
149
263
|
this.insertAfter(parent, child, before);
|
|
150
|
-
prev.realAfter = child;
|
|
151
264
|
}
|
|
152
265
|
} else {
|
|
153
266
|
const childCmp = child;
|
|
154
267
|
childCmp.realParent = parent;
|
|
155
|
-
if (
|
|
156
|
-
|
|
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;
|
|
268
|
+
if (prev.__logicType) {
|
|
269
|
+
childCmp.realBefore = prev.realAfter;
|
|
167
270
|
} else {
|
|
168
271
|
childCmp.realBefore = prev;
|
|
169
272
|
}
|
|
@@ -191,7 +294,7 @@
|
|
|
191
294
|
const [hookType, value] = this._hook({});
|
|
192
295
|
let _node;
|
|
193
296
|
if (value === "if") {
|
|
194
|
-
return this.ifDeclaration();
|
|
297
|
+
return this.ifDeclaration(ctx);
|
|
195
298
|
} else if (hookType) {
|
|
196
299
|
if (hookType === "static") {
|
|
197
300
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
@@ -265,37 +368,66 @@
|
|
|
265
368
|
child[aoye.Keys.Raw][key] = value;
|
|
266
369
|
}
|
|
267
370
|
};
|
|
371
|
+
const afterAnchor = this.insertAfterAnchor(ctx);
|
|
268
372
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
269
|
-
const parent = ctx.
|
|
373
|
+
const parent = ctx.realParent;
|
|
270
374
|
const prev = ctx.prevSibling;
|
|
271
375
|
this.onePropParsed = prevOnePropParsed;
|
|
272
376
|
const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
|
|
377
|
+
componentNode.realAfter = afterAnchor;
|
|
273
378
|
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
274
379
|
});
|
|
275
380
|
return { __logicType: LogicType.Component };
|
|
276
381
|
}
|
|
277
|
-
ifDeclaration() {
|
|
382
|
+
ifDeclaration(ctx) {
|
|
278
383
|
this.tokenizer.consume();
|
|
279
|
-
const [
|
|
384
|
+
const [hookType, value] = this._hook({});
|
|
280
385
|
const ifNode = {
|
|
281
386
|
__logicType: LogicType.If,
|
|
282
|
-
condition: value,
|
|
283
|
-
realParent: null,
|
|
284
387
|
snapshot: this.tokenizer.snapshot(),
|
|
388
|
+
condition: null,
|
|
389
|
+
realParent: null,
|
|
285
390
|
isFirstRender: true,
|
|
286
|
-
|
|
287
|
-
anchor: null
|
|
391
|
+
effect: null
|
|
288
392
|
};
|
|
289
|
-
|
|
393
|
+
const valueIsMapKey = Reflect.has(this.data[aoye.Keys.Raw], value);
|
|
394
|
+
let signal;
|
|
395
|
+
if (valueIsMapKey) {
|
|
396
|
+
aoye.runWithPulling(() => this.data[value], null);
|
|
397
|
+
const { cells } = this.data[aoye.Keys.Meta];
|
|
398
|
+
signal = cells.get(value);
|
|
399
|
+
} else {
|
|
400
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, this.data);
|
|
401
|
+
signal = aoye.$(fn);
|
|
402
|
+
}
|
|
403
|
+
ifNode.condition = signal;
|
|
404
|
+
ifNode.realAfter = this.insertAfterAnchor(ctx);
|
|
405
|
+
ifNode.effect = aoye.effect(
|
|
290
406
|
({ val }) => {
|
|
291
407
|
if (val) {
|
|
292
|
-
|
|
293
|
-
|
|
408
|
+
if (ifNode.isFirstRender) {
|
|
409
|
+
this.tokenizer.consume();
|
|
410
|
+
this.tokenizer.consume();
|
|
411
|
+
} else {
|
|
412
|
+
this.tokenizer.resume(ifNode.snapshot);
|
|
413
|
+
this.program(ifNode.realParent, ifNode.realBefore);
|
|
414
|
+
}
|
|
294
415
|
} else {
|
|
295
|
-
|
|
416
|
+
if (ifNode.isFirstRender) {
|
|
417
|
+
this.tokenizer.skip();
|
|
418
|
+
} else {
|
|
419
|
+
const { realBefore, realAfter, realParent } = ifNode;
|
|
420
|
+
let point = this.nextSib(realBefore);
|
|
421
|
+
while (point !== realAfter) {
|
|
422
|
+
const next = this.nextSib(point);
|
|
423
|
+
this.remove(point, realParent, realBefore);
|
|
424
|
+
point = next;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
296
427
|
}
|
|
428
|
+
ifNode.isFirstRender = false;
|
|
297
429
|
},
|
|
298
|
-
[
|
|
430
|
+
[signal]
|
|
299
431
|
);
|
|
300
432
|
return ifNode;
|
|
301
433
|
}
|
|
@@ -373,6 +505,11 @@
|
|
|
373
505
|
nextSib(node) {
|
|
374
506
|
return node.nextSibling;
|
|
375
507
|
}
|
|
508
|
+
_createAnchor() {
|
|
509
|
+
const anchor = this.createAnchor();
|
|
510
|
+
anchor[IsAnchor] = true;
|
|
511
|
+
return anchor;
|
|
512
|
+
}
|
|
376
513
|
createAnchor() {
|
|
377
514
|
return {
|
|
378
515
|
name: "anchor",
|
|
@@ -380,7 +517,6 @@
|
|
|
380
517
|
};
|
|
381
518
|
}
|
|
382
519
|
insertAfter(parent, node, prev) {
|
|
383
|
-
this.lastInserted = node;
|
|
384
520
|
return this.defaultInsert(parent, node, prev);
|
|
385
521
|
}
|
|
386
522
|
defaultInsert(parent, node, prev) {
|
|
@@ -392,11 +528,11 @@
|
|
|
392
528
|
parent.firstChild = node;
|
|
393
529
|
}
|
|
394
530
|
}
|
|
395
|
-
remove(
|
|
396
|
-
return this.defaultRemove(
|
|
531
|
+
remove(node, parent, prev) {
|
|
532
|
+
return this.defaultRemove(node, parent, prev);
|
|
397
533
|
}
|
|
398
534
|
// TODO: 默认改成 prevItem
|
|
399
|
-
defaultRemove(
|
|
535
|
+
defaultRemove(node, parent, prevSibling) {
|
|
400
536
|
const next = node.nextSibling;
|
|
401
537
|
if (prevSibling) {
|
|
402
538
|
prevSibling.nextSibling = next;
|
|
@@ -469,7 +605,7 @@
|
|
|
469
605
|
};
|
|
470
606
|
}
|
|
471
607
|
skip() {
|
|
472
|
-
const
|
|
608
|
+
const logicDentLen = this.dentStack[this.dentStack.length - 1];
|
|
473
609
|
let needIndent = false;
|
|
474
610
|
let skipFragment = ``;
|
|
475
611
|
this.token = void 0;
|
|
@@ -490,7 +626,7 @@
|
|
|
490
626
|
const { value, isEmptyLine } = this.getDentValue();
|
|
491
627
|
const currLen = value.length;
|
|
492
628
|
if (isEmptyLine) continue;
|
|
493
|
-
if (
|
|
629
|
+
if (currLen > logicDentLen) {
|
|
494
630
|
skipFragment += value;
|
|
495
631
|
} else {
|
|
496
632
|
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
@@ -499,6 +635,9 @@
|
|
|
499
635
|
if (currLen > expLen) {
|
|
500
636
|
throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
|
|
501
637
|
}
|
|
638
|
+
if (this.shorterThanBaseDentEof()) {
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
502
641
|
this.dentStack.pop();
|
|
503
642
|
if (!this.token) {
|
|
504
643
|
this.setToken(TokenType.Dedent, String(expLen));
|
|
@@ -763,12 +902,15 @@ ${_Tokenizer.EofId}`;
|
|
|
763
902
|
return indentHasLen;
|
|
764
903
|
}
|
|
765
904
|
if (currLen < prevLen) {
|
|
766
|
-
for (let i = this.dentStack.length
|
|
905
|
+
for (let i = this.dentStack.length; i--; ) {
|
|
767
906
|
const expLen = this.dentStack[i];
|
|
768
|
-
|
|
769
|
-
if (currLen > expLen
|
|
907
|
+
if (currLen === expLen) break;
|
|
908
|
+
if (currLen > expLen) {
|
|
770
909
|
throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
|
|
771
910
|
}
|
|
911
|
+
if (this.shorterThanBaseDentEof()) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
772
914
|
this.dentStack.pop();
|
|
773
915
|
if (!this.token) {
|
|
774
916
|
this.setToken(TokenType.Dedent, String(expLen));
|
|
@@ -779,14 +921,26 @@ ${_Tokenizer.EofId}`;
|
|
|
779
921
|
value: String(expLen)
|
|
780
922
|
});
|
|
781
923
|
}
|
|
782
|
-
if (currLen === expLen) {
|
|
783
|
-
break;
|
|
784
|
-
}
|
|
785
924
|
}
|
|
786
925
|
return indentHasLen;
|
|
787
926
|
}
|
|
788
927
|
return indentHasLen;
|
|
789
928
|
}
|
|
929
|
+
shorterThanBaseDentEof() {
|
|
930
|
+
const yes = this.dentStack.length === 1;
|
|
931
|
+
if (yes) {
|
|
932
|
+
if (!this.token) {
|
|
933
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
934
|
+
} else {
|
|
935
|
+
this.waitingTokens.push({
|
|
936
|
+
type: TokenType.Identifier,
|
|
937
|
+
typeName: TokenType[TokenType.Identifier],
|
|
938
|
+
value: _Tokenizer.EofId
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return yes;
|
|
943
|
+
}
|
|
790
944
|
identifier(char) {
|
|
791
945
|
let value = char;
|
|
792
946
|
let nextC;
|