bobe 0.0.18 → 0.0.20
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 +397 -109
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +399 -111
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +48 -19
- package/dist/index.umd.js +397 -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,104 +556,89 @@
|
|
|
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;
|
|
346
562
|
child = Component.new();
|
|
347
563
|
} else {
|
|
348
564
|
render = ComponentOrRender;
|
|
565
|
+
const boundStore = render.boundStore;
|
|
349
566
|
child = aoye.deepSignal({}, aoye.getPulling(), true);
|
|
350
|
-
Object.setPrototypeOf(child,
|
|
567
|
+
Object.setPrototypeOf(child, boundStore);
|
|
351
568
|
}
|
|
352
569
|
const node = {
|
|
353
570
|
__logicType: isCC ? FakeType.Component : FakeType.Fragment,
|
|
354
571
|
realParent: ctx.realParent,
|
|
572
|
+
realBefore: null,
|
|
573
|
+
realAfter: null,
|
|
355
574
|
data: child,
|
|
356
575
|
tokenizer: render ? render(true) : child["ui"](true)
|
|
357
576
|
};
|
|
358
|
-
this.onePropParsed = (
|
|
577
|
+
this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
|
|
359
578
|
if (isFn) {
|
|
360
579
|
child[aoye.Keys.Raw][key] = value;
|
|
361
580
|
} else if (valueIsMapKey) {
|
|
362
|
-
aoye.shareSignal(
|
|
363
|
-
} else
|
|
581
|
+
aoye.shareSignal(data, value, child, key);
|
|
582
|
+
} else {
|
|
364
583
|
const meta = child[aoye.Keys.Meta];
|
|
365
584
|
const cells = meta.cells;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
+
}
|
|
370
593
|
}
|
|
371
594
|
};
|
|
372
|
-
node.realAfter = this.insertAfterAnchor(
|
|
595
|
+
node.realAfter = this.insertAfterAnchor("component-after");
|
|
373
596
|
return node;
|
|
374
597
|
}
|
|
598
|
+
getFn(data, expression) {
|
|
599
|
+
return new Function("data", `let v;with(data){v=${expression}};return v;`).bind(void 0, data);
|
|
600
|
+
}
|
|
375
601
|
// TODO: 优化代码逻辑,拆分 if elseif else
|
|
376
602
|
condDeclaration(ctx) {
|
|
377
603
|
var _a;
|
|
378
604
|
const { prevSibling } = ctx;
|
|
379
|
-
const snapbackUp = this.tokenizer.snapshot();
|
|
380
605
|
const keyWord = this.tokenizer.token;
|
|
381
|
-
this.tokenizer.
|
|
382
|
-
const
|
|
383
|
-
const [hookType, value] = this.tokenizer._hook({});
|
|
606
|
+
const expToken = this.tokenizer.condExp();
|
|
607
|
+
const value = expToken.value;
|
|
384
608
|
const isElse = keyWord.value === "else";
|
|
385
609
|
const isIf = keyWord.value === "if";
|
|
386
610
|
const preIsCond = (prevSibling == null ? void 0 : prevSibling.__logicType) & CondBit;
|
|
387
|
-
const needCalcWithPrevIf = isElse && preIsCond;
|
|
388
611
|
const data = this.getData();
|
|
612
|
+
const noCond = value === true;
|
|
613
|
+
const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
|
|
389
614
|
const owner = (_a = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)) == null ? void 0 : _a.node;
|
|
390
615
|
const ifNode = {
|
|
391
616
|
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
392
|
-
|
|
393
|
-
|
|
617
|
+
// 此时 token 是 exp, 下次解析 从 \n 开始
|
|
618
|
+
snapshot: this.tokenizer.snapshot(),
|
|
394
619
|
realParent: null,
|
|
620
|
+
realBefore: null,
|
|
621
|
+
realAfter: null,
|
|
622
|
+
condition: null,
|
|
395
623
|
preCond: preIsCond ? prevSibling : null,
|
|
396
624
|
isFirstRender: true,
|
|
397
625
|
effect: null,
|
|
398
626
|
owner
|
|
399
627
|
};
|
|
400
628
|
let signal;
|
|
401
|
-
|
|
402
|
-
if
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return true;
|
|
415
|
-
});
|
|
416
|
-
} else {
|
|
417
|
-
signal = aoye.$(() => {
|
|
418
|
-
let point = ifNode.preCond;
|
|
419
|
-
while (point) {
|
|
420
|
-
if (point.condition.v) {
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
point = point.preCond;
|
|
424
|
-
}
|
|
425
|
-
return true;
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
} else {
|
|
429
|
-
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
430
|
-
if (valueIsMapKey && !needCalcWithPrevIf) {
|
|
431
|
-
aoye.runWithPulling(() => data[value], null);
|
|
432
|
-
const { cells } = data[aoye.Keys.Meta];
|
|
433
|
-
signal = cells.get(value);
|
|
434
|
-
} else {
|
|
435
|
-
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, data);
|
|
436
|
-
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) {
|
|
437
642
|
signal = aoye.$(() => {
|
|
438
643
|
let point = ifNode.preCond;
|
|
439
644
|
while (point) {
|
|
@@ -445,43 +650,57 @@
|
|
|
445
650
|
}
|
|
446
651
|
point = point.preCond;
|
|
447
652
|
}
|
|
448
|
-
return
|
|
653
|
+
return true;
|
|
449
654
|
});
|
|
450
655
|
} else {
|
|
451
|
-
|
|
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
|
+
});
|
|
452
670
|
}
|
|
453
|
-
|
|
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;
|
|
454
684
|
}
|
|
455
685
|
ifNode.condition = signal;
|
|
456
|
-
ifNode.realAfter = this.insertAfterAnchor(
|
|
686
|
+
ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
|
|
457
687
|
ifNode.effect = aoye.effect(
|
|
458
688
|
({ val }) => {
|
|
459
689
|
if (val) {
|
|
460
690
|
if (ifNode.isFirstRender) {
|
|
461
|
-
|
|
462
|
-
this.tokenizer.nextToken();
|
|
463
|
-
}
|
|
691
|
+
this.tokenizer.nextToken();
|
|
464
692
|
this.tokenizer.nextToken();
|
|
465
693
|
} else {
|
|
466
694
|
this.tokenizer = ifNode.owner.tokenizer;
|
|
467
695
|
this.tokenizer.resume(ifNode.snapshot);
|
|
468
|
-
this.
|
|
696
|
+
this.tokenizer.useDedentAsEof = false;
|
|
697
|
+
this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
|
|
469
698
|
}
|
|
470
699
|
} else {
|
|
471
700
|
if (ifNode.isFirstRender) {
|
|
472
|
-
if (noSelfCond) {
|
|
473
|
-
this.tokenizer.i = this.tokenizer.i - 1;
|
|
474
|
-
this.tokenizer.needIndent = false;
|
|
475
|
-
}
|
|
476
701
|
this.tokenizer.skip();
|
|
477
702
|
} else {
|
|
478
|
-
|
|
479
|
-
let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
|
|
480
|
-
while (point !== realAfter) {
|
|
481
|
-
const next = this.nextSib(point);
|
|
482
|
-
this.remove(point, realParent, realBefore);
|
|
483
|
-
point = next;
|
|
484
|
-
}
|
|
703
|
+
this.removeLogicNode(ifNode);
|
|
485
704
|
}
|
|
486
705
|
}
|
|
487
706
|
ifNode.isFirstRender = false;
|
|
@@ -490,6 +709,15 @@
|
|
|
490
709
|
);
|
|
491
710
|
return ifNode;
|
|
492
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
|
+
}
|
|
493
721
|
/**
|
|
494
722
|
* <extensionLines> ::= PIPE <attributeList> NEWLINE <extensionLines>
|
|
495
723
|
* | ε
|
|
@@ -540,7 +768,7 @@
|
|
|
540
768
|
const isFn = typeof rawVal === "function";
|
|
541
769
|
if (hookType === "dynamic") {
|
|
542
770
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
543
|
-
const fn = isFn ? rawVal : valueIsMapKey ? value :
|
|
771
|
+
const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
|
|
544
772
|
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
545
773
|
} else if (hookType === "static") {
|
|
546
774
|
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
@@ -570,14 +798,9 @@
|
|
|
570
798
|
firstChild(node) {
|
|
571
799
|
return node.firstChild;
|
|
572
800
|
}
|
|
573
|
-
|
|
574
|
-
const anchor = this.createAnchor();
|
|
575
|
-
anchor[IsAnchor] = true;
|
|
576
|
-
return anchor;
|
|
577
|
-
}
|
|
578
|
-
createAnchor() {
|
|
801
|
+
createAnchor(name) {
|
|
579
802
|
return {
|
|
580
|
-
name
|
|
803
|
+
name,
|
|
581
804
|
nextSibling: null
|
|
582
805
|
};
|
|
583
806
|
}
|
|
@@ -633,9 +856,9 @@
|
|
|
633
856
|
};
|
|
634
857
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
635
858
|
const _Tokenizer = class _Tokenizer {
|
|
636
|
-
constructor(hook,
|
|
859
|
+
constructor(hook, useDedentAsEof) {
|
|
637
860
|
this.hook = hook;
|
|
638
|
-
this.
|
|
861
|
+
this.useDedentAsEof = useDedentAsEof;
|
|
639
862
|
/** 缩进大小 默认 2 */
|
|
640
863
|
this.TabSize = 2;
|
|
641
864
|
/** 缩进字符 */
|
|
@@ -680,7 +903,7 @@
|
|
|
680
903
|
}
|
|
681
904
|
return [hookType, value];
|
|
682
905
|
};
|
|
683
|
-
if (
|
|
906
|
+
if (useDedentAsEof) {
|
|
684
907
|
this.setToken(TokenType.Indent, "");
|
|
685
908
|
this.isFirstToken = true;
|
|
686
909
|
}
|
|
@@ -698,11 +921,20 @@
|
|
|
698
921
|
this.dentStack = [0];
|
|
699
922
|
Object.assign(this, _snapshot);
|
|
700
923
|
}
|
|
701
|
-
snapshot() {
|
|
702
|
-
|
|
924
|
+
snapshot(keys) {
|
|
925
|
+
const snap = {
|
|
703
926
|
i: this.i,
|
|
704
927
|
waitingTokens: this.waitingTokens.clone()
|
|
705
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;
|
|
706
938
|
}
|
|
707
939
|
skip() {
|
|
708
940
|
const logicDentLen = this.dentStack[this.dentStack.length - 1];
|
|
@@ -816,17 +1048,21 @@ ${_Tokenizer.EofId}`;
|
|
|
816
1048
|
this.str(char);
|
|
817
1049
|
break;
|
|
818
1050
|
case "{":
|
|
819
|
-
this.brace();
|
|
1051
|
+
const braceToken = this.brace();
|
|
1052
|
+
this.setToken(TokenType.InsertionExp, braceToken);
|
|
820
1053
|
break;
|
|
821
1054
|
case "$":
|
|
822
1055
|
const handled = this.dynamic(char);
|
|
823
1056
|
if (handled) break;
|
|
1057
|
+
case ";":
|
|
1058
|
+
this.setToken(TokenType.Semicolon, ";");
|
|
1059
|
+
break;
|
|
824
1060
|
default:
|
|
825
1061
|
if (bobeShared.isNum(char)) {
|
|
826
1062
|
this.number(char);
|
|
827
1063
|
break;
|
|
828
1064
|
}
|
|
829
|
-
if (typeof char === "string" && bobeShared.
|
|
1065
|
+
if (typeof char === "string" && bobeShared.matchIdStart2(char, 0)) {
|
|
830
1066
|
this.identifier(char);
|
|
831
1067
|
}
|
|
832
1068
|
break;
|
|
@@ -845,6 +1081,58 @@ ${_Tokenizer.EofId}`;
|
|
|
845
1081
|
this.handledTokens.push(this.token);
|
|
846
1082
|
}
|
|
847
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
|
+
}
|
|
848
1136
|
assignment() {
|
|
849
1137
|
this.setToken(TokenType.Assign, "=");
|
|
850
1138
|
}
|
|
@@ -910,8 +1198,7 @@ ${_Tokenizer.EofId}`;
|
|
|
910
1198
|
}
|
|
911
1199
|
}
|
|
912
1200
|
if (count === 0 && inString == null && inComment == null) {
|
|
913
|
-
|
|
914
|
-
return;
|
|
1201
|
+
return value.slice(1);
|
|
915
1202
|
}
|
|
916
1203
|
value += this.code[this.i];
|
|
917
1204
|
this.i++;
|
|
@@ -1016,13 +1303,13 @@ ${_Tokenizer.EofId}`;
|
|
|
1016
1303
|
const yes = this.dentStack.length === 1;
|
|
1017
1304
|
if (yes) {
|
|
1018
1305
|
if (!this.token) {
|
|
1019
|
-
if (this.
|
|
1306
|
+
if (this.useDedentAsEof) {
|
|
1020
1307
|
this.setToken(TokenType.Dedent, "");
|
|
1021
1308
|
} else {
|
|
1022
1309
|
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
1023
1310
|
}
|
|
1024
1311
|
} else {
|
|
1025
|
-
if (this.
|
|
1312
|
+
if (this.useDedentAsEof) {
|
|
1026
1313
|
this.waitingTokens.push({
|
|
1027
1314
|
type: TokenType.Dedent,
|
|
1028
1315
|
typeName: TokenType[TokenType.Dedent],
|
|
@@ -1044,13 +1331,13 @@ ${_Tokenizer.EofId}`;
|
|
|
1044
1331
|
let nextC;
|
|
1045
1332
|
while (1) {
|
|
1046
1333
|
nextC = this.code[this.i + 1];
|
|
1047
|
-
if (typeof nextC !== "string" || !bobeShared.
|
|
1334
|
+
if (typeof nextC !== "string" || !bobeShared.matchIdStart2(nextC, 0)) {
|
|
1048
1335
|
break;
|
|
1049
1336
|
}
|
|
1050
1337
|
value += nextC;
|
|
1051
1338
|
this.i++;
|
|
1052
1339
|
}
|
|
1053
|
-
if (value === _Tokenizer.EofId && this.
|
|
1340
|
+
if (value === _Tokenizer.EofId && this.useDedentAsEof) {
|
|
1054
1341
|
this.setToken(TokenType.Dedent, "");
|
|
1055
1342
|
return;
|
|
1056
1343
|
}
|
|
@@ -1119,6 +1406,7 @@ ${_Tokenizer.EofId}`;
|
|
|
1119
1406
|
tokenizer.init(Array.from(fragments));
|
|
1120
1407
|
return tokenizer;
|
|
1121
1408
|
};
|
|
1409
|
+
ui.boundStore = aoye.Store.Current;
|
|
1122
1410
|
return ui;
|
|
1123
1411
|
}
|
|
1124
1412
|
function customRender(option) {
|