bobe 0.0.19 → 0.0.21
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 +394 -109
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +396 -111
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +43 -18
- package/dist/index.umd.js +394 -109
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -12,6 +12,7 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
|
12
12
|
TokenType2[TokenType2["Pipe"] = 32] = "Pipe";
|
|
13
13
|
TokenType2[TokenType2["Eof"] = 64] = "Eof";
|
|
14
14
|
TokenType2[TokenType2["InsertionExp"] = 128] = "InsertionExp";
|
|
15
|
+
TokenType2[TokenType2["Semicolon"] = 256] = "Semicolon";
|
|
15
16
|
return TokenType2;
|
|
16
17
|
})(TokenType || {});
|
|
17
18
|
var FakeType = /* @__PURE__ */ ((FakeType2) => {
|
|
@@ -35,7 +36,6 @@ var NodeSort = /* @__PURE__ */ ((NodeSort2) => {
|
|
|
35
36
|
NodeSort2[NodeSort2["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
|
|
36
37
|
return NodeSort2;
|
|
37
38
|
})(NodeSort || {});
|
|
38
|
-
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
39
39
|
|
|
40
40
|
class MultiTypeStack {
|
|
41
41
|
constructor() {
|
|
@@ -130,17 +130,33 @@ class MultiTypeStack {
|
|
|
130
130
|
// }
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
134
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
135
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
136
|
+
var __objRest = (source, exclude) => {
|
|
137
|
+
var target = {};
|
|
138
|
+
for (var prop in source)
|
|
139
|
+
if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
140
|
+
target[prop] = source[prop];
|
|
141
|
+
if (source != null && __getOwnPropSymbols$1)
|
|
142
|
+
for (var prop of __getOwnPropSymbols$1(source)) {
|
|
143
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
|
|
144
|
+
target[prop] = source[prop];
|
|
145
|
+
}
|
|
146
|
+
return target;
|
|
147
|
+
};
|
|
133
148
|
new bobeShared.BaseEvent();
|
|
134
149
|
class Interpreter {
|
|
135
150
|
constructor(tokenizer) {
|
|
136
151
|
this.tokenizer = tokenizer;
|
|
137
152
|
this.rootComponent = null;
|
|
153
|
+
this.forItemId = 0;
|
|
138
154
|
this.oneRealPropParsed = this.onePropParsed.bind(this);
|
|
139
155
|
}
|
|
140
156
|
isLogicNode(node) {
|
|
141
157
|
return node && node.__logicType & LogicalBit;
|
|
142
158
|
}
|
|
143
|
-
program(root, componentNode, before) {
|
|
159
|
+
program(root, componentNode, before, ctxProvider) {
|
|
144
160
|
var _a, _b;
|
|
145
161
|
this.rootComponent = componentNode;
|
|
146
162
|
this.tokenizer.nextToken();
|
|
@@ -150,6 +166,12 @@ class Interpreter {
|
|
|
150
166
|
{ node: componentNode, prev: null },
|
|
151
167
|
NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher
|
|
152
168
|
);
|
|
169
|
+
if (ctxProvider) {
|
|
170
|
+
stack.push(
|
|
171
|
+
{ node: ctxProvider, prev: null },
|
|
172
|
+
(ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider
|
|
173
|
+
);
|
|
174
|
+
}
|
|
153
175
|
const ctx = this.ctx = {
|
|
154
176
|
realParent: root,
|
|
155
177
|
prevSibling: before,
|
|
@@ -213,6 +235,21 @@ class Interpreter {
|
|
|
213
235
|
const switcher = (_b = stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _b.node;
|
|
214
236
|
this.tokenizer = switcher.tokenizer;
|
|
215
237
|
}
|
|
238
|
+
if (parent.__logicType === FakeType.ForItem) {
|
|
239
|
+
const { forNode } = parent;
|
|
240
|
+
const { i, arr, snapshot } = forNode;
|
|
241
|
+
if (i + 1 < arr.length) {
|
|
242
|
+
this.tokenizer.resume(snapshot);
|
|
243
|
+
this.tokenizer.nextToken();
|
|
244
|
+
this.tokenizer.nextToken();
|
|
245
|
+
ctx.prevSibling = parent;
|
|
246
|
+
ctx.current = forNode.children[++forNode.i];
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
ctx.prevSibling = forNode.prevSibling;
|
|
250
|
+
ctx.current = forNode;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
216
253
|
}
|
|
217
254
|
ctx.prevSibling = prev;
|
|
218
255
|
ctx.current = parent;
|
|
@@ -223,15 +260,10 @@ class Interpreter {
|
|
|
223
260
|
}
|
|
224
261
|
return componentNode;
|
|
225
262
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
insertAfterAnchor(ctx) {
|
|
232
|
-
const { realParent, prevSibling, stack, before } = ctx;
|
|
233
|
-
const afterAnchor = this.createAnchor();
|
|
234
|
-
ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
263
|
+
insertAfterAnchor(name = "anchor") {
|
|
264
|
+
const { realParent, prevSibling, stack, before } = this.ctx;
|
|
265
|
+
const afterAnchor = this.createAnchor(name);
|
|
266
|
+
this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
|
|
235
267
|
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
236
268
|
return afterAnchor;
|
|
237
269
|
}
|
|
@@ -253,7 +285,7 @@ class Interpreter {
|
|
|
253
285
|
const childCmp = child;
|
|
254
286
|
childCmp.realParent = parent;
|
|
255
287
|
if (prev == null ? void 0 : prev.__logicType) {
|
|
256
|
-
childCmp.realBefore = prev.realAfter;
|
|
288
|
+
childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
|
|
257
289
|
} else {
|
|
258
290
|
childCmp.realBefore = prev;
|
|
259
291
|
}
|
|
@@ -282,7 +314,10 @@ class Interpreter {
|
|
|
282
314
|
let _node;
|
|
283
315
|
if (value === "if" || value === "else" || value === "fail") {
|
|
284
316
|
return this.condDeclaration(ctx);
|
|
317
|
+
} else if (value === "for") {
|
|
318
|
+
return this.forDeclaration();
|
|
285
319
|
} else if (hookType) {
|
|
320
|
+
const data = this.getData();
|
|
286
321
|
if (hookType === "static") {
|
|
287
322
|
if (typeof value === "function") {
|
|
288
323
|
_node = this.componentOrFragmentDeclaration(value, ctx);
|
|
@@ -290,7 +325,15 @@ class Interpreter {
|
|
|
290
325
|
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
291
326
|
}
|
|
292
327
|
} else {
|
|
293
|
-
|
|
328
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
329
|
+
const val = data[aoye.Keys.Raw][value];
|
|
330
|
+
if (typeof val === "function") {
|
|
331
|
+
_node = this.componentOrFragmentDeclaration(val, ctx);
|
|
332
|
+
} else {
|
|
333
|
+
const str = valueIsMapKey ? value : this.getFn(data, value);
|
|
334
|
+
_node = this.createNode("text");
|
|
335
|
+
this.onePropParsed(data, _node, "text", str, valueIsMapKey, false);
|
|
336
|
+
}
|
|
294
337
|
}
|
|
295
338
|
} else {
|
|
296
339
|
_node = this.createNode(value);
|
|
@@ -304,6 +347,183 @@ class Interpreter {
|
|
|
304
347
|
}
|
|
305
348
|
return _node;
|
|
306
349
|
}
|
|
350
|
+
forDeclaration() {
|
|
351
|
+
var _a;
|
|
352
|
+
const arrExp = this.tokenizer.nextToken().value;
|
|
353
|
+
this.tokenizer.nextToken();
|
|
354
|
+
const itemToken = this.tokenizer.nextToken();
|
|
355
|
+
const isDestruct = itemToken.type === TokenType.InsertionExp;
|
|
356
|
+
let itemExp = itemToken.value;
|
|
357
|
+
if (isDestruct) {
|
|
358
|
+
itemExp = "{" + itemExp + "}";
|
|
359
|
+
const vars = itemExp.match(bobeShared.jsVarRegexp).join(",");
|
|
360
|
+
itemExp = new Function("item", `let ${vars}; (${itemExp}=item); return {${vars}};`);
|
|
361
|
+
}
|
|
362
|
+
let indexName, keyExp;
|
|
363
|
+
while (this.tokenizer.code[this.tokenizer.i] !== "\n") {
|
|
364
|
+
const next = this.tokenizer.nextToken();
|
|
365
|
+
if (next.type !== TokenType.Semicolon) {
|
|
366
|
+
if (!indexName) {
|
|
367
|
+
indexName = next.value;
|
|
368
|
+
} else {
|
|
369
|
+
keyExp = next.value;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const owner = (_a = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
374
|
+
const prevSibling = this.ctx.prevSibling;
|
|
375
|
+
const forNode = {
|
|
376
|
+
__logicType: FakeType.For,
|
|
377
|
+
snapshot: this.tokenizer.snapshot(["dentStack", "isFirstToken"]),
|
|
378
|
+
realParent: this.ctx.realParent,
|
|
379
|
+
prevSibling,
|
|
380
|
+
realBefore: (prevSibling == null ? void 0 : prevSibling.realAfter) || prevSibling,
|
|
381
|
+
realAfter: null,
|
|
382
|
+
arr: null,
|
|
383
|
+
itemExp,
|
|
384
|
+
indexName,
|
|
385
|
+
getKey: null,
|
|
386
|
+
children: [],
|
|
387
|
+
effect: null,
|
|
388
|
+
owner,
|
|
389
|
+
i: 0
|
|
390
|
+
};
|
|
391
|
+
if (keyExp) {
|
|
392
|
+
forNode.getKey = new Function("data", `let v;with(data){v=${keyExp}};return v;`);
|
|
393
|
+
}
|
|
394
|
+
window["for1"] = forNode;
|
|
395
|
+
const data = this.getData();
|
|
396
|
+
const cells = data[aoye.Keys.Meta].cells;
|
|
397
|
+
const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
|
|
398
|
+
const arrSignal = hasArrExpKey ? (
|
|
399
|
+
// 有 key 直接拿
|
|
400
|
+
(data[arrExp], cells.get(arrExp))
|
|
401
|
+
) : (
|
|
402
|
+
// 无key
|
|
403
|
+
aoye.$(this.getFn(data, arrExp))
|
|
404
|
+
);
|
|
405
|
+
forNode.realAfter = this.insertAfterAnchor("for-after");
|
|
406
|
+
const _b = forNode.snapshot, { dentStack, isFirstToken } = _b, snapshotForUpdate = __objRest(_b, ["dentStack", "isFirstToken"]);
|
|
407
|
+
let isFirstRender = true;
|
|
408
|
+
forNode.effect = aoye.effect(() => {
|
|
409
|
+
var _a2;
|
|
410
|
+
let arr = forNode.arr = arrSignal.v;
|
|
411
|
+
arr[aoye.Keys.Iterator];
|
|
412
|
+
arr = aoye.toRaw(arr);
|
|
413
|
+
const children = forNode.children;
|
|
414
|
+
if (isFirstRender) {
|
|
415
|
+
const len = arr.length;
|
|
416
|
+
for (let i = len; i--; ) {
|
|
417
|
+
const nextItem = children[i + 1];
|
|
418
|
+
const item = this.createForItem(forNode, i, data);
|
|
419
|
+
const anchor = this.insertAfterAnchor("for-item-after");
|
|
420
|
+
item.realAfter = anchor;
|
|
421
|
+
if (nextItem) {
|
|
422
|
+
nextItem.realBefore = anchor;
|
|
423
|
+
}
|
|
424
|
+
item.realParent = forNode.realParent;
|
|
425
|
+
children[i] = item;
|
|
426
|
+
}
|
|
427
|
+
const firstInsert = children[0];
|
|
428
|
+
if (firstInsert) {
|
|
429
|
+
firstInsert.realBefore = forNode.realBefore;
|
|
430
|
+
this.tokenizer.nextToken();
|
|
431
|
+
this.tokenizer.nextToken();
|
|
432
|
+
} else {
|
|
433
|
+
this.tokenizer.skip();
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
const oldLen = children.length;
|
|
437
|
+
const newLen = arr.length;
|
|
438
|
+
const minLen = Math.min(oldLen, newLen);
|
|
439
|
+
const newChildren = [];
|
|
440
|
+
if (!forNode.getKey) {
|
|
441
|
+
if (newLen < oldLen) {
|
|
442
|
+
for (let i = oldLen - 1; i >= newLen; i--) {
|
|
443
|
+
const child = children[i];
|
|
444
|
+
this.removeLogicNode(child);
|
|
445
|
+
this.remove(child.realAfter);
|
|
446
|
+
child.effect();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (oldLen < newLen) {
|
|
450
|
+
const lastAfter = ((_a2 = children.at(-1)) == null ? void 0 : _a2.realAfter) || forNode.realBefore;
|
|
451
|
+
for (let i = newLen - 1; i >= oldLen; i--) {
|
|
452
|
+
const item = this.createForItem(forNode, i, data);
|
|
453
|
+
newChildren[i] = item;
|
|
454
|
+
const nextItem = newChildren[i + 1];
|
|
455
|
+
const anchor = this.createAnchor("for-item-after");
|
|
456
|
+
this.insertAfter(forNode.realParent, anchor, lastAfter);
|
|
457
|
+
item.realAfter = anchor;
|
|
458
|
+
if (nextItem) {
|
|
459
|
+
nextItem.realBefore = anchor;
|
|
460
|
+
}
|
|
461
|
+
item.realParent = forNode.realParent;
|
|
462
|
+
this.tokenizer = owner.tokenizer;
|
|
463
|
+
this.tokenizer.resume(snapshotForUpdate);
|
|
464
|
+
this.tokenizer.useDedentAsEof = false;
|
|
465
|
+
aoye.runWithPulling(() => {
|
|
466
|
+
this.program(forNode.realParent, forNode.owner, lastAfter, item);
|
|
467
|
+
}, item.effect.ins);
|
|
468
|
+
}
|
|
469
|
+
const firstInsert = newChildren[oldLen];
|
|
470
|
+
if (firstInsert) {
|
|
471
|
+
firstInsert.realBefore = lastAfter;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
for (let i = minLen; i--; ) {
|
|
475
|
+
const child = children[i];
|
|
476
|
+
newChildren[i] = child;
|
|
477
|
+
if (typeof itemExp === "string") {
|
|
478
|
+
child.data[itemExp] = arr[i];
|
|
479
|
+
} else {
|
|
480
|
+
Object.assign(child.data, itemExp(arr[i]));
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
forNode.children = newChildren;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
isFirstRender = false;
|
|
487
|
+
});
|
|
488
|
+
return forNode.children[0] || forNode;
|
|
489
|
+
}
|
|
490
|
+
createForItem(forNode, i, parentData) {
|
|
491
|
+
let forItemNode;
|
|
492
|
+
const effect2 = aoye.scope(() => {
|
|
493
|
+
}, null);
|
|
494
|
+
const { arr, itemExp, indexName, getKey } = forNode;
|
|
495
|
+
let data;
|
|
496
|
+
if (typeof itemExp === "string") {
|
|
497
|
+
data = aoye.$(
|
|
498
|
+
indexName ? {
|
|
499
|
+
[itemExp]: arr[i],
|
|
500
|
+
[indexName]: i
|
|
501
|
+
} : {
|
|
502
|
+
[itemExp]: arr[i]
|
|
503
|
+
}
|
|
504
|
+
);
|
|
505
|
+
} else {
|
|
506
|
+
const rawData = itemExp(arr[i]);
|
|
507
|
+
if (indexName) {
|
|
508
|
+
rawData[indexName] = i;
|
|
509
|
+
}
|
|
510
|
+
data = aoye.$(rawData);
|
|
511
|
+
}
|
|
512
|
+
Object.setPrototypeOf(data, parentData);
|
|
513
|
+
forItemNode = {
|
|
514
|
+
id: this.forItemId++,
|
|
515
|
+
__logicType: FakeType.ForItem,
|
|
516
|
+
realParent: null,
|
|
517
|
+
realBefore: null,
|
|
518
|
+
realAfter: null,
|
|
519
|
+
forNode,
|
|
520
|
+
key: getKey == null ? void 0 : getKey(data),
|
|
521
|
+
effect: null,
|
|
522
|
+
data
|
|
523
|
+
};
|
|
524
|
+
forItemNode.effect = effect2;
|
|
525
|
+
return forItemNode;
|
|
526
|
+
}
|
|
307
527
|
getData() {
|
|
308
528
|
const { node } = this.ctx.stack.peekByType(NodeSort.CtxProvider);
|
|
309
529
|
return node.data || node.owner.data;
|
|
@@ -335,10 +555,6 @@ class Interpreter {
|
|
|
335
555
|
}
|
|
336
556
|
componentOrFragmentDeclaration(ComponentOrRender, ctx) {
|
|
337
557
|
let Component, render, child;
|
|
338
|
-
const data = this.getData();
|
|
339
|
-
if (typeof ComponentOrRender === "string") {
|
|
340
|
-
ComponentOrRender = data[ComponentOrRender];
|
|
341
|
-
}
|
|
342
558
|
const isCC = ComponentOrRender.prototype instanceof aoye.Store;
|
|
343
559
|
if (isCC) {
|
|
344
560
|
Component = ComponentOrRender;
|
|
@@ -352,89 +568,76 @@ class Interpreter {
|
|
|
352
568
|
const node = {
|
|
353
569
|
__logicType: isCC ? FakeType.Component : FakeType.Fragment,
|
|
354
570
|
realParent: ctx.realParent,
|
|
571
|
+
realBefore: null,
|
|
572
|
+
realAfter: null,
|
|
355
573
|
data: child,
|
|
356
574
|
tokenizer: render ? render(true) : child["ui"](true)
|
|
357
575
|
};
|
|
358
|
-
this.onePropParsed = (
|
|
576
|
+
this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
|
|
359
577
|
if (isFn) {
|
|
360
578
|
child[aoye.Keys.Raw][key] = value;
|
|
361
579
|
} else if (valueIsMapKey) {
|
|
362
|
-
aoye.shareSignal(
|
|
363
|
-
} else
|
|
580
|
+
aoye.shareSignal(data, value, child, key);
|
|
581
|
+
} else {
|
|
364
582
|
const meta = child[aoye.Keys.Meta];
|
|
365
583
|
const cells = meta.cells;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
584
|
+
if (typeof value === "function") {
|
|
585
|
+
const computed = aoye.$(value);
|
|
586
|
+
cells.set(key, computed);
|
|
587
|
+
child[aoye.Keys.Raw][key] = void 0;
|
|
588
|
+
} else {
|
|
589
|
+
cells.set(key, { v: value });
|
|
590
|
+
child[aoye.Keys.Raw][key] = value;
|
|
591
|
+
}
|
|
371
592
|
}
|
|
372
593
|
};
|
|
373
|
-
node.realAfter = this.insertAfterAnchor(
|
|
594
|
+
node.realAfter = this.insertAfterAnchor("component-after");
|
|
374
595
|
return node;
|
|
375
596
|
}
|
|
597
|
+
getFn(data, expression) {
|
|
598
|
+
return new Function("data", `let v;with(data){v=${expression}};return v;`).bind(void 0, data);
|
|
599
|
+
}
|
|
376
600
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
377
601
|
condDeclaration(ctx) {
|
|
378
602
|
var _a;
|
|
379
603
|
const { prevSibling } = ctx;
|
|
380
|
-
const snapbackUp = this.tokenizer.snapshot();
|
|
381
604
|
const keyWord = this.tokenizer.token;
|
|
382
|
-
this.tokenizer.
|
|
383
|
-
const
|
|
384
|
-
const [hookType, value] = this.tokenizer._hook({});
|
|
605
|
+
const expToken = this.tokenizer.condExp();
|
|
606
|
+
const value = expToken.value;
|
|
385
607
|
const isElse = keyWord.value === "else";
|
|
386
608
|
const isIf = keyWord.value === "if";
|
|
387
609
|
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
|
|
388
|
-
const needCalcWithPrevIf = isElse && preIsCond;
|
|
389
610
|
const data = this.getData();
|
|
611
|
+
const noCond = value === true;
|
|
612
|
+
const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
|
|
390
613
|
const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
391
614
|
const ifNode = {
|
|
392
615
|
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
393
|
-
|
|
394
|
-
|
|
616
|
+
// 此时 token 是 exp, 下次解析 从 \n 开始
|
|
617
|
+
snapshot: this.tokenizer.snapshot(),
|
|
395
618
|
realParent: null,
|
|
619
|
+
realBefore: null,
|
|
620
|
+
realAfter: null,
|
|
621
|
+
condition: null,
|
|
396
622
|
preCond: preIsCond ? prevSibling : null,
|
|
397
623
|
isFirstRender: true,
|
|
398
624
|
effect: null,
|
|
399
625
|
owner
|
|
400
626
|
};
|
|
401
627
|
let signal;
|
|
402
|
-
|
|
403
|
-
if
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
return true;
|
|
416
|
-
});
|
|
417
|
-
} else {
|
|
418
|
-
signal = aoye.$(() => {
|
|
419
|
-
let point = ifNode.preCond;
|
|
420
|
-
while (point) {
|
|
421
|
-
if (point.condition.v) {
|
|
422
|
-
return false;
|
|
423
|
-
}
|
|
424
|
-
point = point.preCond;
|
|
425
|
-
}
|
|
426
|
-
return true;
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
} else {
|
|
430
|
-
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
431
|
-
if (valueIsMapKey && !needCalcWithPrevIf) {
|
|
432
|
-
aoye.runWithPulling(() => data[value], null);
|
|
433
|
-
const { cells } = data[aoye.Keys.Meta];
|
|
434
|
-
signal = cells.get(value);
|
|
435
|
-
} else {
|
|
436
|
-
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
437
|
-
if (needCalcWithPrevIf) {
|
|
628
|
+
switch (keyWord.value) {
|
|
629
|
+
case "if":
|
|
630
|
+
if (valueIsMapKey) {
|
|
631
|
+
aoye.runWithPulling(() => data[value], null);
|
|
632
|
+
const { cells } = data[aoye.Keys.Meta];
|
|
633
|
+
signal = cells.get(value);
|
|
634
|
+
} else {
|
|
635
|
+
const fn = this.getFn(data, value);
|
|
636
|
+
signal = aoye.$(fn);
|
|
637
|
+
}
|
|
638
|
+
break;
|
|
639
|
+
case "else":
|
|
640
|
+
if (noCond) {
|
|
438
641
|
signal = aoye.$(() => {
|
|
439
642
|
let point = ifNode.preCond;
|
|
440
643
|
while (point) {
|
|
@@ -446,43 +649,57 @@ class Interpreter {
|
|
|
446
649
|
}
|
|
447
650
|
point = point.preCond;
|
|
448
651
|
}
|
|
449
|
-
return
|
|
652
|
+
return true;
|
|
450
653
|
});
|
|
451
654
|
} else {
|
|
452
|
-
|
|
655
|
+
const fn = valueIsMapKey ? null : this.getFn(data, value);
|
|
656
|
+
signal = aoye.$(() => {
|
|
657
|
+
let point = ifNode.preCond;
|
|
658
|
+
while (point) {
|
|
659
|
+
if (point.condition.v) {
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
if (point.__logicType === FakeType.If) {
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
point = point.preCond;
|
|
666
|
+
}
|
|
667
|
+
return valueIsMapKey ? data[value] : fn();
|
|
668
|
+
});
|
|
453
669
|
}
|
|
454
|
-
|
|
670
|
+
break;
|
|
671
|
+
case "fail":
|
|
672
|
+
signal = aoye.$(() => {
|
|
673
|
+
let point = ifNode.preCond;
|
|
674
|
+
while (point) {
|
|
675
|
+
if (point.condition.v) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
point = point.preCond;
|
|
679
|
+
}
|
|
680
|
+
return true;
|
|
681
|
+
});
|
|
682
|
+
break;
|
|
455
683
|
}
|
|
456
684
|
ifNode.condition = signal;
|
|
457
|
-
ifNode.realAfter = this.insertAfterAnchor(
|
|
685
|
+
ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
|
|
458
686
|
ifNode.effect = aoye.effect(
|
|
459
687
|
({ val }) => {
|
|
460
688
|
if (val) {
|
|
461
689
|
if (ifNode.isFirstRender) {
|
|
462
|
-
|
|
463
|
-
this.tokenizer.nextToken();
|
|
464
|
-
}
|
|
690
|
+
this.tokenizer.nextToken();
|
|
465
691
|
this.tokenizer.nextToken();
|
|
466
692
|
} else {
|
|
467
693
|
this.tokenizer = ifNode.owner.tokenizer;
|
|
468
694
|
this.tokenizer.resume(ifNode.snapshot);
|
|
469
|
-
this.
|
|
695
|
+
this.tokenizer.useDedentAsEof = false;
|
|
696
|
+
this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
|
|
470
697
|
}
|
|
471
698
|
} else {
|
|
472
699
|
if (ifNode.isFirstRender) {
|
|
473
|
-
if (noSelfCond) {
|
|
474
|
-
this.tokenizer.i = this.tokenizer.i - 1;
|
|
475
|
-
this.tokenizer.needIndent = false;
|
|
476
|
-
}
|
|
477
700
|
this.tokenizer.skip();
|
|
478
701
|
} else {
|
|
479
|
-
|
|
480
|
-
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
481
|
-
while (point !== realAfter) {
|
|
482
|
-
const next = this.nextSib(point);
|
|
483
|
-
this.remove(point, realParent, realBefore);
|
|
484
|
-
point = next;
|
|
485
|
-
}
|
|
702
|
+
this.removeLogicNode(ifNode);
|
|
486
703
|
}
|
|
487
704
|
}
|
|
488
705
|
ifNode.isFirstRender = false;
|
|
@@ -491,6 +708,15 @@ class Interpreter {
|
|
|
491
708
|
);
|
|
492
709
|
return ifNode;
|
|
493
710
|
}
|
|
711
|
+
removeLogicNode(node) {
|
|
712
|
+
const { realBefore, realAfter, realParent } = node;
|
|
713
|
+
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
714
|
+
while (point !== realAfter) {
|
|
715
|
+
const next = this.nextSib(point);
|
|
716
|
+
this.remove(point, realParent, realBefore);
|
|
717
|
+
point = next;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
494
720
|
/**
|
|
495
721
|
* <extensionLines> ::= PIPE <attributeList> NEWLINE <extensionLines>
|
|
496
722
|
* | ε
|
|
@@ -541,7 +767,7 @@ class Interpreter {
|
|
|
541
767
|
const isFn = typeof rawVal === "function";
|
|
542
768
|
if (hookType === "dynamic") {
|
|
543
769
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
544
|
-
const fn = isFn ? rawVal : valueIsMapKey ? value :
|
|
770
|
+
const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
|
|
545
771
|
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
546
772
|
} else if (hookType === "static") {
|
|
547
773
|
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
@@ -571,14 +797,9 @@ class Interpreter {
|
|
|
571
797
|
firstChild(node) {
|
|
572
798
|
return node.firstChild;
|
|
573
799
|
}
|
|
574
|
-
|
|
575
|
-
const anchor = this.createAnchor();
|
|
576
|
-
anchor[IsAnchor] = true;
|
|
577
|
-
return anchor;
|
|
578
|
-
}
|
|
579
|
-
createAnchor() {
|
|
800
|
+
createAnchor(name) {
|
|
580
801
|
return {
|
|
581
|
-
name
|
|
802
|
+
name,
|
|
582
803
|
nextSibling: null
|
|
583
804
|
};
|
|
584
805
|
}
|
|
@@ -634,9 +855,9 @@ var __spreadValues = (a, b) => {
|
|
|
634
855
|
};
|
|
635
856
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
636
857
|
const _Tokenizer = class _Tokenizer {
|
|
637
|
-
constructor(hook,
|
|
858
|
+
constructor(hook, useDedentAsEof) {
|
|
638
859
|
this.hook = hook;
|
|
639
|
-
this.
|
|
860
|
+
this.useDedentAsEof = useDedentAsEof;
|
|
640
861
|
/** 缩进大小 默认 2 */
|
|
641
862
|
this.TabSize = 2;
|
|
642
863
|
/** 缩进字符 */
|
|
@@ -681,7 +902,7 @@ const _Tokenizer = class _Tokenizer {
|
|
|
681
902
|
}
|
|
682
903
|
return [hookType, value];
|
|
683
904
|
};
|
|
684
|
-
if (
|
|
905
|
+
if (useDedentAsEof) {
|
|
685
906
|
this.setToken(TokenType.Indent, "");
|
|
686
907
|
this.isFirstToken = true;
|
|
687
908
|
}
|
|
@@ -699,11 +920,20 @@ const _Tokenizer = class _Tokenizer {
|
|
|
699
920
|
this.dentStack = [0];
|
|
700
921
|
Object.assign(this, _snapshot);
|
|
701
922
|
}
|
|
702
|
-
snapshot() {
|
|
703
|
-
|
|
923
|
+
snapshot(keys) {
|
|
924
|
+
const snap = {
|
|
704
925
|
i: this.i,
|
|
705
926
|
waitingTokens: this.waitingTokens.clone()
|
|
706
927
|
};
|
|
928
|
+
if (keys) {
|
|
929
|
+
for (const k of keys) {
|
|
930
|
+
snap[k] = this[k];
|
|
931
|
+
if (k === "dentStack") {
|
|
932
|
+
snap[k] = this[k].slice();
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
return snap;
|
|
707
937
|
}
|
|
708
938
|
skip() {
|
|
709
939
|
const logicDentLen = this.dentStack[this.dentStack.length - 1];
|
|
@@ -817,17 +1047,21 @@ ${_Tokenizer.EofId}`;
|
|
|
817
1047
|
this.str(char);
|
|
818
1048
|
break;
|
|
819
1049
|
case "{":
|
|
820
|
-
this.brace();
|
|
1050
|
+
const braceToken = this.brace();
|
|
1051
|
+
this.setToken(TokenType.InsertionExp, braceToken);
|
|
821
1052
|
break;
|
|
822
1053
|
case "$":
|
|
823
1054
|
const handled = this.dynamic(char);
|
|
824
1055
|
if (handled) break;
|
|
1056
|
+
case ";":
|
|
1057
|
+
this.setToken(TokenType.Semicolon, ";");
|
|
1058
|
+
break;
|
|
825
1059
|
default:
|
|
826
1060
|
if (bobeShared.isNum(char)) {
|
|
827
1061
|
this.number(char);
|
|
828
1062
|
break;
|
|
829
1063
|
}
|
|
830
|
-
if (typeof char === "string" && bobeShared.
|
|
1064
|
+
if (typeof char === "string" && bobeShared.matchIdStart2(char, 0)) {
|
|
831
1065
|
this.identifier(char);
|
|
832
1066
|
}
|
|
833
1067
|
break;
|
|
@@ -846,6 +1080,58 @@ ${_Tokenizer.EofId}`;
|
|
|
846
1080
|
this.handledTokens.push(this.token);
|
|
847
1081
|
}
|
|
848
1082
|
}
|
|
1083
|
+
condExp() {
|
|
1084
|
+
let value = "";
|
|
1085
|
+
this.token = null;
|
|
1086
|
+
while (1) {
|
|
1087
|
+
const char = this.code[this.i];
|
|
1088
|
+
if (char === "\n") {
|
|
1089
|
+
break;
|
|
1090
|
+
}
|
|
1091
|
+
value += char;
|
|
1092
|
+
this.i++;
|
|
1093
|
+
}
|
|
1094
|
+
value = value.trim();
|
|
1095
|
+
this.setToken(TokenType.Identifier, value || true);
|
|
1096
|
+
return this.token;
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* 解析到 for 时使用这个方法获取 for 后方的子表达式
|
|
1100
|
+
* 表达式通过 “;” 分割
|
|
1101
|
+
* // 最多可有三个表达式
|
|
1102
|
+
* for arr ; item index; item.key
|
|
1103
|
+
* @returns {boolean} 是否含有 key
|
|
1104
|
+
*/
|
|
1105
|
+
forLoopSubExp() {
|
|
1106
|
+
this.token = null;
|
|
1107
|
+
let value = "";
|
|
1108
|
+
let count = 0;
|
|
1109
|
+
while (1) {
|
|
1110
|
+
const char = this.code[this.i];
|
|
1111
|
+
const isSemicolon = char === ";";
|
|
1112
|
+
if (isSemicolon || char === "\n") {
|
|
1113
|
+
value = value.trim();
|
|
1114
|
+
if (!this.token) {
|
|
1115
|
+
this.setToken(TokenType.Identifier, value);
|
|
1116
|
+
} else {
|
|
1117
|
+
this.waitingTokens.push({
|
|
1118
|
+
type: TokenType.Identifier,
|
|
1119
|
+
typeName: TokenType[TokenType.Identifier],
|
|
1120
|
+
value
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
value = "";
|
|
1124
|
+
count++;
|
|
1125
|
+
if (count > 3) {
|
|
1126
|
+
throw SyntaxError(`for \u5FAA\u73AF\u6700\u591A\u53EF\u5305\u542B\u4E09\u4E2A\u8868\u8FBE\u5F0F, \u5206\u522B\u4E3A arr ; item index [; key]`);
|
|
1127
|
+
}
|
|
1128
|
+
if (!isSemicolon) return count === 3;
|
|
1129
|
+
} else {
|
|
1130
|
+
value += char;
|
|
1131
|
+
}
|
|
1132
|
+
this.i++;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
849
1135
|
assignment() {
|
|
850
1136
|
this.setToken(TokenType.Assign, "=");
|
|
851
1137
|
}
|
|
@@ -911,8 +1197,7 @@ ${_Tokenizer.EofId}`;
|
|
|
911
1197
|
}
|
|
912
1198
|
}
|
|
913
1199
|
if (count === 0 && inString == null && inComment == null) {
|
|
914
|
-
|
|
915
|
-
return;
|
|
1200
|
+
return value.slice(1);
|
|
916
1201
|
}
|
|
917
1202
|
value += this.code[this.i];
|
|
918
1203
|
this.i++;
|
|
@@ -1017,13 +1302,13 @@ ${_Tokenizer.EofId}`;
|
|
|
1017
1302
|
const yes = this.dentStack.length === 1;
|
|
1018
1303
|
if (yes) {
|
|
1019
1304
|
if (!this.token) {
|
|
1020
|
-
if (this.
|
|
1305
|
+
if (this.useDedentAsEof) {
|
|
1021
1306
|
this.setToken(TokenType.Dedent, "");
|
|
1022
1307
|
} else {
|
|
1023
1308
|
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
1024
1309
|
}
|
|
1025
1310
|
} else {
|
|
1026
|
-
if (this.
|
|
1311
|
+
if (this.useDedentAsEof) {
|
|
1027
1312
|
this.waitingTokens.push({
|
|
1028
1313
|
type: TokenType.Dedent,
|
|
1029
1314
|
typeName: TokenType[TokenType.Dedent],
|
|
@@ -1045,13 +1330,13 @@ ${_Tokenizer.EofId}`;
|
|
|
1045
1330
|
let nextC;
|
|
1046
1331
|
while (1) {
|
|
1047
1332
|
nextC = this.code[this.i + 1];
|
|
1048
|
-
if (typeof nextC !== "string" || !bobeShared.
|
|
1333
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart2(nextC, 0)) {
|
|
1049
1334
|
break;
|
|
1050
1335
|
}
|
|
1051
1336
|
value += nextC;
|
|
1052
1337
|
this.i++;
|
|
1053
1338
|
}
|
|
1054
|
-
if (value === _Tokenizer.EofId && this.
|
|
1339
|
+
if (value === _Tokenizer.EofId && this.useDedentAsEof) {
|
|
1055
1340
|
this.setToken(TokenType.Dedent, "");
|
|
1056
1341
|
return;
|
|
1057
1342
|
}
|