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