tutuca 0.9.26 → 0.9.27
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/tutuca-cli.js +85 -85
- package/dist/tutuca-dev.js +84 -84
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-extra.js +84 -84
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca.js +84 -84
- package/dist/tutuca.min.js +2 -2
- package/package.json +1 -1
package/dist/tutuca-cli.js
CHANGED
|
@@ -739,13 +739,10 @@ class ValParser {
|
|
|
739
739
|
switch (charCode) {
|
|
740
740
|
case 94: {
|
|
741
741
|
const newS = px.frame.macroVars?.[s.slice(1)];
|
|
742
|
-
if (newS !== undefined)
|
|
742
|
+
if (newS !== undefined)
|
|
743
743
|
return this.parse(newS, px);
|
|
744
|
-
}
|
|
745
744
|
return null;
|
|
746
745
|
}
|
|
747
|
-
case 126:
|
|
748
|
-
return this.okStrTpl ? parseConst(s.slice(1), px) : null;
|
|
749
746
|
case 39:
|
|
750
747
|
return this.okStrTpl ? parseConst(s.slice(1, -1), px) : null;
|
|
751
748
|
case 64:
|
|
@@ -858,7 +855,7 @@ function getValSubType(s) {
|
|
|
858
855
|
return open === 1 && close === 1 ? VAL_SUB_TYPE_SEQ_ACCESS : VAL_SUB_TYPE_INVALID;
|
|
859
856
|
return -1;
|
|
860
857
|
}
|
|
861
|
-
var VALID_VAL_ID_RE, isValidValId = (name) => VALID_VAL_ID_RE.test(name), VALID_FLOAT_RE, parseStrTemplate = (v, px) => StrTplVal.parse(v, px), parseConst = (v, _) => new ConstVal(v), parseName = (v, _) => isValidValId(v) ? new NameVal(v) : null, parseType = (v, _) => isValidValId(v) ? new TypeVal(v) : null, parseBind = (v, _) => isValidValId(v) ? new BindVal(v) : null, parseDyn = (v, _) => isValidValId(v) ? new DynVal(v) : null, parseField = (v, _) => isValidValId(v) ? new FieldVal(v) : null, parseComp = (v, _) => isValidValId(v) ? new ComputedVal(v) : null, parseReq = (v, _) => isValidValId(v) ? new RequestVal(v) : null, ConstVal, VarVal, StrTplVal, NameVal, InputHandlerNameVal, AlterHandlerNameVal, mk404Handler = (type, name) => function(...args) {
|
|
858
|
+
var VALID_VAL_ID_RE, isValidValId = (name) => VALID_VAL_ID_RE.test(name), VALID_FLOAT_RE, STR_TPL_SPLIT_RE, parseStrTemplate = (v, px) => StrTplVal.parse(v, px), parseConst = (v, _) => new ConstVal(v), parseName = (v, _) => isValidValId(v) ? new NameVal(v) : null, parseType = (v, _) => isValidValId(v) ? new TypeVal(v) : null, parseBind = (v, _) => isValidValId(v) ? new BindVal(v) : null, parseDyn = (v, _) => isValidValId(v) ? new DynVal(v) : null, parseField = (v, _) => isValidValId(v) ? new FieldVal(v) : null, parseComp = (v, _) => isValidValId(v) ? new ComputedVal(v) : null, parseReq = (v, _) => isValidValId(v) ? new RequestVal(v) : null, ConstVal, VarVal, StrTplVal, NameVal, InputHandlerNameVal, AlterHandlerNameVal, mk404Handler = (type, name) => function(...args) {
|
|
862
859
|
console.warn("handler not found", { type, name, args }, this);
|
|
863
860
|
return this;
|
|
864
861
|
}, TypeVal, RequestVal, RawFieldVal, RenderVal, RenderNameVal, BindVal, DynVal, FieldVal, ComputedVal, SeqAccessVal, VAL_SUB_TYPE_STRING_TEMPLATE = 0, VAL_SUB_TYPE_SEQ_ACCESS = 1, VAL_SUB_TYPE_INVALID = 2, VAL_SUB_TYPE_CONST_STRING = 3, vp;
|
|
@@ -866,6 +863,7 @@ var init_value = __esm(() => {
|
|
|
866
863
|
init_path();
|
|
867
864
|
VALID_VAL_ID_RE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
868
865
|
VALID_FLOAT_RE = /^-?[0-9]+(\.[0-9]+)?$/;
|
|
866
|
+
STR_TPL_SPLIT_RE = /(\{[^}]+\})/g;
|
|
869
867
|
ConstVal = class ConstVal extends BaseVal {
|
|
870
868
|
constructor(val) {
|
|
871
869
|
super();
|
|
@@ -899,7 +897,7 @@ var init_value = __esm(() => {
|
|
|
899
897
|
return strs.join("");
|
|
900
898
|
}
|
|
901
899
|
static parse(s, px) {
|
|
902
|
-
const parts = s.split(
|
|
900
|
+
const parts = s.split(STR_TPL_SPLIT_RE);
|
|
903
901
|
const vals = new Array(parts.length);
|
|
904
902
|
let allConsts = true;
|
|
905
903
|
for (let i = 0;i < parts.length; i++) {
|
|
@@ -1333,9 +1331,8 @@ function optimizeChilds(childs) {
|
|
|
1333
1331
|
}
|
|
1334
1332
|
}
|
|
1335
1333
|
function optimizeNode(node) {
|
|
1336
|
-
if (node.isConstant())
|
|
1334
|
+
if (node.isConstant())
|
|
1337
1335
|
return new RenderOnceNode(node);
|
|
1338
|
-
}
|
|
1339
1336
|
node.optimize();
|
|
1340
1337
|
return node;
|
|
1341
1338
|
}
|
|
@@ -1401,12 +1398,6 @@ class ParseContext {
|
|
|
1401
1398
|
newDOMParser() {
|
|
1402
1399
|
return new this.DOMParser;
|
|
1403
1400
|
}
|
|
1404
|
-
isTextNode(v) {
|
|
1405
|
-
return v instanceof this.Text;
|
|
1406
|
-
}
|
|
1407
|
-
isCommentNode(v) {
|
|
1408
|
-
return v instanceof this.Comment;
|
|
1409
|
-
}
|
|
1410
1401
|
addNodeIf(Class, val, extra) {
|
|
1411
1402
|
if (val !== null) {
|
|
1412
1403
|
const nodeId = this.nodes.length;
|
|
@@ -1425,21 +1416,18 @@ class ParseContext {
|
|
|
1425
1416
|
newMacroNode(macroName, mAttrs, childs) {
|
|
1426
1417
|
const anySlot = [];
|
|
1427
1418
|
const slots = { _: new FragmentNode(anySlot) };
|
|
1428
|
-
for (const child of childs)
|
|
1429
|
-
if (child instanceof SlotNode)
|
|
1419
|
+
for (const child of childs)
|
|
1420
|
+
if (child instanceof SlotNode)
|
|
1430
1421
|
slots[child.val.val] = child.node;
|
|
1431
|
-
|
|
1422
|
+
else if (!(child instanceof TextNode) || !child.isWhiteSpace())
|
|
1432
1423
|
anySlot.push(child);
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
1424
|
const node = new MacroNode(macroName, mAttrs, slots, this);
|
|
1436
1425
|
this.macroNodes.push(node);
|
|
1437
1426
|
return node;
|
|
1438
1427
|
}
|
|
1439
1428
|
compile(scope) {
|
|
1440
|
-
for (let i = 0;i < this.macroNodes.length; i++)
|
|
1429
|
+
for (let i = 0;i < this.macroNodes.length; i++)
|
|
1441
1430
|
this.macroNodes[i].compile(scope);
|
|
1442
|
-
}
|
|
1443
1431
|
}
|
|
1444
1432
|
*genEventNames() {
|
|
1445
1433
|
for (const event of this.events)
|
|
@@ -1490,12 +1478,11 @@ class NodeEvents {
|
|
|
1490
1478
|
}
|
|
1491
1479
|
getHandlersFor(eventName) {
|
|
1492
1480
|
let r = null;
|
|
1493
|
-
for (const handler of this.handlers)
|
|
1481
|
+
for (const handler of this.handlers)
|
|
1494
1482
|
if (handler.handlesEventName(eventName)) {
|
|
1495
1483
|
r ??= [];
|
|
1496
1484
|
r.push(handler);
|
|
1497
1485
|
}
|
|
1498
|
-
}
|
|
1499
1486
|
return r;
|
|
1500
1487
|
}
|
|
1501
1488
|
}
|
|
@@ -1629,9 +1616,9 @@ var init_anode = __esm(() => {
|
|
|
1629
1616
|
return ANode.fromDOM(nodes[0] ?? new px.Text(""), px);
|
|
1630
1617
|
}
|
|
1631
1618
|
static fromDOM(node, px) {
|
|
1632
|
-
if (px.
|
|
1619
|
+
if (node instanceof px.Text)
|
|
1633
1620
|
return new TextNode(node.textContent);
|
|
1634
|
-
else if (px.
|
|
1621
|
+
else if (node instanceof px.Comment)
|
|
1635
1622
|
return new CommentNode(node.textContent);
|
|
1636
1623
|
const { childNodes, attributes: attrs, tagName: tag } = node;
|
|
1637
1624
|
const childs = new Array(childNodes.length);
|
|
@@ -1697,9 +1684,9 @@ var init_anode = __esm(() => {
|
|
|
1697
1684
|
if (this.px.isInsideMacro(name))
|
|
1698
1685
|
throw new Error(`Recursive macro expansion: ${name}`);
|
|
1699
1686
|
const macro = scope.lookupMacro(name);
|
|
1700
|
-
if (macro === null)
|
|
1687
|
+
if (macro === null)
|
|
1701
1688
|
this.node = new CommentNode(`bad macro: ${name}`);
|
|
1702
|
-
|
|
1689
|
+
else {
|
|
1703
1690
|
const vars = { ...macro.defaults, ...attrs };
|
|
1704
1691
|
this.node = macro.expand(this.px.enterMacro(name, vars, slots));
|
|
1705
1692
|
for (const key in this.dataAttrs)
|
|
@@ -1870,10 +1857,8 @@ var init_anode = __esm(() => {
|
|
|
1870
1857
|
|
|
1871
1858
|
// src/cache.js
|
|
1872
1859
|
class NullDomCache {
|
|
1873
|
-
get(
|
|
1874
|
-
set(
|
|
1875
|
-
get2(_k1, _k2, _cacheKey) {}
|
|
1876
|
-
set2(_k1, _k2, _cacheKey, _v) {}
|
|
1860
|
+
get(_keys, _cacheKey) {}
|
|
1861
|
+
set(_keys, _cacheKey, _v) {}
|
|
1877
1862
|
evict() {
|
|
1878
1863
|
return { hit: 0, miss: 0, badKey: 0 };
|
|
1879
1864
|
}
|
|
@@ -1882,7 +1867,7 @@ class NullDomCache {
|
|
|
1882
1867
|
class WeakMapDomCache {
|
|
1883
1868
|
constructor() {
|
|
1884
1869
|
this.hit = this.miss = this.badKey = 0;
|
|
1885
|
-
this.
|
|
1870
|
+
this.keysByLen = new Map;
|
|
1886
1871
|
}
|
|
1887
1872
|
_returnValue(r) {
|
|
1888
1873
|
if (r === undefined)
|
|
@@ -1891,41 +1876,51 @@ class WeakMapDomCache {
|
|
|
1891
1876
|
this.hit += 1;
|
|
1892
1877
|
return r;
|
|
1893
1878
|
}
|
|
1894
|
-
get(
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
cur
|
|
1901
|
-
|
|
1902
|
-
|
|
1879
|
+
get(keys, cacheKey) {
|
|
1880
|
+
const len = keys.length;
|
|
1881
|
+
let cur = this.keysByLen.get(len);
|
|
1882
|
+
if (!cur)
|
|
1883
|
+
return this._returnValue(undefined);
|
|
1884
|
+
for (let i = 0;i < len - 1; i++) {
|
|
1885
|
+
cur = cur.get(keys[i]);
|
|
1886
|
+
if (!cur)
|
|
1887
|
+
return this._returnValue(undefined);
|
|
1888
|
+
}
|
|
1889
|
+
return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
|
|
1890
|
+
}
|
|
1891
|
+
set(keys, cacheKey, v) {
|
|
1892
|
+
const len = keys.length;
|
|
1893
|
+
let cur = this.keysByLen.get(len);
|
|
1894
|
+
if (!cur) {
|
|
1895
|
+
cur = new WeakMap;
|
|
1896
|
+
this.keysByLen.set(len, cur);
|
|
1897
|
+
}
|
|
1898
|
+
for (let i = 0;i < len - 1; i++) {
|
|
1899
|
+
const key = keys[i];
|
|
1900
|
+
let next = cur.get(key);
|
|
1901
|
+
if (!next) {
|
|
1902
|
+
if (typeof key !== "object") {
|
|
1903
|
+
this.badKey += 1;
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
next = new WeakMap;
|
|
1907
|
+
cur.set(key, next);
|
|
1908
|
+
}
|
|
1909
|
+
cur = next;
|
|
1910
|
+
}
|
|
1911
|
+
const lastKey = keys[len - 1];
|
|
1912
|
+
const leaf = cur.get(lastKey);
|
|
1913
|
+
if (leaf)
|
|
1914
|
+
leaf[cacheKey] = v;
|
|
1915
|
+
else if (typeof lastKey === "object")
|
|
1916
|
+
cur.set(lastKey, { [cacheKey]: v });
|
|
1903
1917
|
else
|
|
1904
1918
|
this.badKey += 1;
|
|
1905
1919
|
}
|
|
1906
|
-
get2(k1, k2, cacheKey) {
|
|
1907
|
-
return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
|
|
1908
|
-
}
|
|
1909
|
-
set2(k1, k2, cacheKey, v) {
|
|
1910
|
-
const cur1 = this.map.get(k1);
|
|
1911
|
-
if (cur1) {
|
|
1912
|
-
const cur = cur1.get(k2);
|
|
1913
|
-
if (cur)
|
|
1914
|
-
cur[cacheKey] = v;
|
|
1915
|
-
else
|
|
1916
|
-
cur1.set(k2, { [cacheKey]: v });
|
|
1917
|
-
} else if (typeof k1 === "object" && typeof k2 === "object") {
|
|
1918
|
-
const cur = new WeakMap;
|
|
1919
|
-
cur.set(k2, { [cacheKey]: v });
|
|
1920
|
-
this.map.set(k1, cur);
|
|
1921
|
-
} else {
|
|
1922
|
-
this.badKey += 1;
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
1920
|
evict() {
|
|
1926
1921
|
const { hit, miss, badKey } = this;
|
|
1927
1922
|
this.hit = this.miss = this.badKey = 0;
|
|
1928
|
-
this.
|
|
1923
|
+
this.keysByLen = new Map;
|
|
1929
1924
|
return { hit, miss, badKey };
|
|
1930
1925
|
}
|
|
1931
1926
|
}
|
|
@@ -2047,8 +2042,8 @@ class ComponentStack {
|
|
|
2047
2042
|
return this.macros[name] ?? this.parent?.lookupMacro(name) ?? null;
|
|
2048
2043
|
}
|
|
2049
2044
|
}
|
|
2050
|
-
function defaultOnStackEnter(
|
|
2051
|
-
return
|
|
2045
|
+
function defaultOnStackEnter() {
|
|
2046
|
+
return null;
|
|
2052
2047
|
}
|
|
2053
2048
|
var init_components = __esm(() => {
|
|
2054
2049
|
init_attribute();
|
|
@@ -2466,7 +2461,7 @@ class Stack {
|
|
|
2466
2461
|
this.ctx = ctx;
|
|
2467
2462
|
}
|
|
2468
2463
|
_enrichOnEnter() {
|
|
2469
|
-
return this.comps.getOnEnterFor(this.it).call(this.it
|
|
2464
|
+
return this.withDynamicBindings(this.comps.getOnEnterFor(this.it).call(this.it));
|
|
2470
2465
|
}
|
|
2471
2466
|
upToFrameBinds() {
|
|
2472
2467
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
@@ -2481,7 +2476,8 @@ class Stack {
|
|
|
2481
2476
|
enter(it, bindings = {}, isFrame = true) {
|
|
2482
2477
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
2483
2478
|
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
2484
|
-
|
|
2479
|
+
const stack = new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
2480
|
+
return isFrame ? stack._enrichOnEnter() : stack;
|
|
2485
2481
|
}
|
|
2486
2482
|
pushViewName(name) {
|
|
2487
2483
|
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
@@ -2489,17 +2485,26 @@ class Stack {
|
|
|
2489
2485
|
return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
2490
2486
|
}
|
|
2491
2487
|
withDynamicBindings(dynamics) {
|
|
2488
|
+
if (dynamics == null || dynamics.length === 0)
|
|
2489
|
+
return this;
|
|
2492
2490
|
const dynObj = {};
|
|
2493
2491
|
const comp = this.comps.getCompFor(this.it);
|
|
2494
2492
|
for (const dynName of dynamics)
|
|
2495
2493
|
comp.dynamic[dynName].evalAndBind(this, dynObj);
|
|
2496
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
2497
2494
|
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
2495
|
+
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
2498
2496
|
return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
2499
2497
|
}
|
|
2498
|
+
_pushDynBindValuesToArray(arr, dyns) {
|
|
2499
|
+
for (const k in dyns)
|
|
2500
|
+
arr.push(this._lookupDynamicWithDynVal(dyns[k]));
|
|
2501
|
+
}
|
|
2502
|
+
_lookupDynamicWithDynVal(d) {
|
|
2503
|
+
return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this);
|
|
2504
|
+
}
|
|
2500
2505
|
lookupDynamic(name) {
|
|
2501
2506
|
const d = this.comps.getCompFor(this.it)?.dynamic[name];
|
|
2502
|
-
return d ?
|
|
2507
|
+
return d ? this._lookupDynamicWithDynVal(d) : null;
|
|
2503
2508
|
}
|
|
2504
2509
|
lookupBind(name) {
|
|
2505
2510
|
return lookup(this.binds, name);
|
|
@@ -7740,13 +7745,15 @@ class Renderer {
|
|
|
7740
7745
|
}
|
|
7741
7746
|
_rValComp(stack, val, comp, nid, key, viewName) {
|
|
7742
7747
|
const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
|
|
7743
|
-
const
|
|
7748
|
+
const cachePath = [val];
|
|
7749
|
+
stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
|
|
7750
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
7744
7751
|
if (cachedNode)
|
|
7745
7752
|
return cachedNode;
|
|
7746
7753
|
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
7747
7754
|
const meta = this._renderMetadata({ $: "Comp", nid });
|
|
7748
7755
|
const dom = new VFragment([meta, this.renderView(view, stack)]);
|
|
7749
|
-
this.cache.set(
|
|
7756
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
7750
7757
|
return dom;
|
|
7751
7758
|
}
|
|
7752
7759
|
pushEachEntry(r, nid, attrName, key, dom) {
|
|
@@ -7758,8 +7765,7 @@ class Renderer {
|
|
|
7758
7765
|
const iterData = loopWith.call(stack.it, seq);
|
|
7759
7766
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
7760
7767
|
if (filter.call(stack.it, key, value, iterData)) {
|
|
7761
|
-
const
|
|
7762
|
-
const dom = this.renderIt(newStack, nodeId, key, viewName);
|
|
7768
|
+
const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
|
|
7763
7769
|
this.pushEachEntry(r, nodeId, attrName, key, dom);
|
|
7764
7770
|
}
|
|
7765
7771
|
});
|
|
@@ -7772,25 +7778,19 @@ class Renderer {
|
|
|
7772
7778
|
const it = stack.it;
|
|
7773
7779
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
7774
7780
|
if (filter.call(it, key, value, iterData)) {
|
|
7781
|
+
const cachePath = enricher ? [it, value] : [value];
|
|
7775
7782
|
const bindings = { key, value };
|
|
7776
7783
|
const cacheKey = `${nid}-${key}`;
|
|
7777
|
-
|
|
7778
|
-
if (enricher) {
|
|
7784
|
+
if (enricher)
|
|
7779
7785
|
enricher.call(it, bindings, key, value, iterData);
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
cachedNode = this.cache.get(value, cacheKey);
|
|
7783
|
-
if (cachedNode) {
|
|
7786
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
7787
|
+
if (cachedNode)
|
|
7784
7788
|
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
7785
|
-
|
|
7789
|
+
else {
|
|
7790
|
+
const dom = this.renderView(view, stack.enter(value, bindings, false));
|
|
7791
|
+
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
7792
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
7786
7793
|
}
|
|
7787
|
-
const newStack = stack.enter(value, bindings, false);
|
|
7788
|
-
const dom = this.renderView(view, newStack);
|
|
7789
|
-
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
7790
|
-
if (enricher)
|
|
7791
|
-
this.cache.set2(it, value, cacheKey, dom);
|
|
7792
|
-
else
|
|
7793
|
-
this.cache.set(value, cacheKey, dom);
|
|
7794
7794
|
}
|
|
7795
7795
|
});
|
|
7796
7796
|
return r;
|
package/dist/tutuca-dev.js
CHANGED
|
@@ -245,6 +245,7 @@ class PathBuilder {
|
|
|
245
245
|
var VALID_VAL_ID_RE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
246
246
|
var isValidValId = (name) => VALID_VAL_ID_RE.test(name);
|
|
247
247
|
var VALID_FLOAT_RE = /^-?[0-9]+(\.[0-9]+)?$/;
|
|
248
|
+
var STR_TPL_SPLIT_RE = /(\{[^}]+\})/g;
|
|
248
249
|
var parseStrTemplate = (v, px) => StrTplVal.parse(v, px);
|
|
249
250
|
var parseConst = (v, _) => new ConstVal(v);
|
|
250
251
|
var parseName = (v, _) => isValidValId(v) ? new NameVal(v) : null;
|
|
@@ -293,13 +294,10 @@ class ValParser {
|
|
|
293
294
|
switch (charCode) {
|
|
294
295
|
case 94: {
|
|
295
296
|
const newS = px.frame.macroVars?.[s.slice(1)];
|
|
296
|
-
if (newS !== undefined)
|
|
297
|
+
if (newS !== undefined)
|
|
297
298
|
return this.parse(newS, px);
|
|
298
|
-
}
|
|
299
299
|
return null;
|
|
300
300
|
}
|
|
301
|
-
case 126:
|
|
302
|
-
return this.okStrTpl ? parseConst(s.slice(1), px) : null;
|
|
303
301
|
case 39:
|
|
304
302
|
return this.okStrTpl ? parseConst(s.slice(1, -1), px) : null;
|
|
305
303
|
case 64:
|
|
@@ -423,7 +421,7 @@ class StrTplVal extends VarVal {
|
|
|
423
421
|
return strs.join("");
|
|
424
422
|
}
|
|
425
423
|
static parse(s, px) {
|
|
426
|
-
const parts = s.split(
|
|
424
|
+
const parts = s.split(STR_TPL_SPLIT_RE);
|
|
427
425
|
const vals = new Array(parts.length);
|
|
428
426
|
let allConsts = true;
|
|
429
427
|
for (let i = 0;i < parts.length; i++) {
|
|
@@ -944,9 +942,8 @@ function optimizeChilds(childs) {
|
|
|
944
942
|
}
|
|
945
943
|
}
|
|
946
944
|
function optimizeNode(node) {
|
|
947
|
-
if (node.isConstant())
|
|
945
|
+
if (node.isConstant())
|
|
948
946
|
return new RenderOnceNode(node);
|
|
949
|
-
}
|
|
950
947
|
node.optimize();
|
|
951
948
|
return node;
|
|
952
949
|
}
|
|
@@ -1013,9 +1010,9 @@ class ANode extends BaseNode {
|
|
|
1013
1010
|
return ANode.fromDOM(nodes[0] ?? new px.Text(""), px);
|
|
1014
1011
|
}
|
|
1015
1012
|
static fromDOM(node, px) {
|
|
1016
|
-
if (px.
|
|
1013
|
+
if (node instanceof px.Text)
|
|
1017
1014
|
return new TextNode(node.textContent);
|
|
1018
|
-
else if (px.
|
|
1015
|
+
else if (node instanceof px.Comment)
|
|
1019
1016
|
return new CommentNode(node.textContent);
|
|
1020
1017
|
const { childNodes, attributes: attrs, tagName: tag } = node;
|
|
1021
1018
|
const childs = new Array(childNodes.length);
|
|
@@ -1104,9 +1101,9 @@ class MacroNode extends BaseNode {
|
|
|
1104
1101
|
if (this.px.isInsideMacro(name))
|
|
1105
1102
|
throw new Error(`Recursive macro expansion: ${name}`);
|
|
1106
1103
|
const macro = scope.lookupMacro(name);
|
|
1107
|
-
if (macro === null)
|
|
1104
|
+
if (macro === null)
|
|
1108
1105
|
this.node = new CommentNode(`bad macro: ${name}`);
|
|
1109
|
-
|
|
1106
|
+
else {
|
|
1110
1107
|
const vars = { ...macro.defaults, ...attrs };
|
|
1111
1108
|
this.node = macro.expand(this.px.enterMacro(name, vars, slots));
|
|
1112
1109
|
for (const key in this.dataAttrs)
|
|
@@ -1325,12 +1322,6 @@ class ParseContext {
|
|
|
1325
1322
|
newDOMParser() {
|
|
1326
1323
|
return new this.DOMParser;
|
|
1327
1324
|
}
|
|
1328
|
-
isTextNode(v) {
|
|
1329
|
-
return v instanceof this.Text;
|
|
1330
|
-
}
|
|
1331
|
-
isCommentNode(v) {
|
|
1332
|
-
return v instanceof this.Comment;
|
|
1333
|
-
}
|
|
1334
1325
|
addNodeIf(Class, val, extra) {
|
|
1335
1326
|
if (val !== null) {
|
|
1336
1327
|
const nodeId = this.nodes.length;
|
|
@@ -1349,21 +1340,18 @@ class ParseContext {
|
|
|
1349
1340
|
newMacroNode(macroName, mAttrs, childs) {
|
|
1350
1341
|
const anySlot = [];
|
|
1351
1342
|
const slots = { _: new FragmentNode(anySlot) };
|
|
1352
|
-
for (const child of childs)
|
|
1353
|
-
if (child instanceof SlotNode)
|
|
1343
|
+
for (const child of childs)
|
|
1344
|
+
if (child instanceof SlotNode)
|
|
1354
1345
|
slots[child.val.val] = child.node;
|
|
1355
|
-
|
|
1346
|
+
else if (!(child instanceof TextNode) || !child.isWhiteSpace())
|
|
1356
1347
|
anySlot.push(child);
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
1348
|
const node = new MacroNode(macroName, mAttrs, slots, this);
|
|
1360
1349
|
this.macroNodes.push(node);
|
|
1361
1350
|
return node;
|
|
1362
1351
|
}
|
|
1363
1352
|
compile(scope) {
|
|
1364
|
-
for (let i = 0;i < this.macroNodes.length; i++)
|
|
1353
|
+
for (let i = 0;i < this.macroNodes.length; i++)
|
|
1365
1354
|
this.macroNodes[i].compile(scope);
|
|
1366
|
-
}
|
|
1367
1355
|
}
|
|
1368
1356
|
*genEventNames() {
|
|
1369
1357
|
for (const event of this.events)
|
|
@@ -1438,12 +1426,11 @@ class NodeEvents {
|
|
|
1438
1426
|
}
|
|
1439
1427
|
getHandlersFor(eventName) {
|
|
1440
1428
|
let r = null;
|
|
1441
|
-
for (const handler of this.handlers)
|
|
1429
|
+
for (const handler of this.handlers)
|
|
1442
1430
|
if (handler.handlesEventName(eventName)) {
|
|
1443
1431
|
r ??= [];
|
|
1444
1432
|
r.push(handler);
|
|
1445
1433
|
}
|
|
1446
|
-
}
|
|
1447
1434
|
return r;
|
|
1448
1435
|
}
|
|
1449
1436
|
}
|
|
@@ -1942,10 +1929,8 @@ function lintIdToMessage(id, info) {
|
|
|
1942
1929
|
|
|
1943
1930
|
// src/cache.js
|
|
1944
1931
|
class NullDomCache {
|
|
1945
|
-
get(
|
|
1946
|
-
set(
|
|
1947
|
-
get2(_k1, _k2, _cacheKey) {}
|
|
1948
|
-
set2(_k1, _k2, _cacheKey, _v) {}
|
|
1932
|
+
get(_keys, _cacheKey) {}
|
|
1933
|
+
set(_keys, _cacheKey, _v) {}
|
|
1949
1934
|
evict() {
|
|
1950
1935
|
return { hit: 0, miss: 0, badKey: 0 };
|
|
1951
1936
|
}
|
|
@@ -1954,7 +1939,7 @@ class NullDomCache {
|
|
|
1954
1939
|
class WeakMapDomCache {
|
|
1955
1940
|
constructor() {
|
|
1956
1941
|
this.hit = this.miss = this.badKey = 0;
|
|
1957
|
-
this.
|
|
1942
|
+
this.keysByLen = new Map;
|
|
1958
1943
|
}
|
|
1959
1944
|
_returnValue(r) {
|
|
1960
1945
|
if (r === undefined)
|
|
@@ -1963,41 +1948,51 @@ class WeakMapDomCache {
|
|
|
1963
1948
|
this.hit += 1;
|
|
1964
1949
|
return r;
|
|
1965
1950
|
}
|
|
1966
|
-
get(
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
cur
|
|
1973
|
-
|
|
1974
|
-
|
|
1951
|
+
get(keys, cacheKey) {
|
|
1952
|
+
const len = keys.length;
|
|
1953
|
+
let cur = this.keysByLen.get(len);
|
|
1954
|
+
if (!cur)
|
|
1955
|
+
return this._returnValue(undefined);
|
|
1956
|
+
for (let i = 0;i < len - 1; i++) {
|
|
1957
|
+
cur = cur.get(keys[i]);
|
|
1958
|
+
if (!cur)
|
|
1959
|
+
return this._returnValue(undefined);
|
|
1960
|
+
}
|
|
1961
|
+
return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
|
|
1962
|
+
}
|
|
1963
|
+
set(keys, cacheKey, v) {
|
|
1964
|
+
const len = keys.length;
|
|
1965
|
+
let cur = this.keysByLen.get(len);
|
|
1966
|
+
if (!cur) {
|
|
1967
|
+
cur = new WeakMap;
|
|
1968
|
+
this.keysByLen.set(len, cur);
|
|
1969
|
+
}
|
|
1970
|
+
for (let i = 0;i < len - 1; i++) {
|
|
1971
|
+
const key = keys[i];
|
|
1972
|
+
let next = cur.get(key);
|
|
1973
|
+
if (!next) {
|
|
1974
|
+
if (typeof key !== "object") {
|
|
1975
|
+
this.badKey += 1;
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
next = new WeakMap;
|
|
1979
|
+
cur.set(key, next);
|
|
1980
|
+
}
|
|
1981
|
+
cur = next;
|
|
1982
|
+
}
|
|
1983
|
+
const lastKey = keys[len - 1];
|
|
1984
|
+
const leaf = cur.get(lastKey);
|
|
1985
|
+
if (leaf)
|
|
1986
|
+
leaf[cacheKey] = v;
|
|
1987
|
+
else if (typeof lastKey === "object")
|
|
1988
|
+
cur.set(lastKey, { [cacheKey]: v });
|
|
1975
1989
|
else
|
|
1976
1990
|
this.badKey += 1;
|
|
1977
1991
|
}
|
|
1978
|
-
get2(k1, k2, cacheKey) {
|
|
1979
|
-
return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
|
|
1980
|
-
}
|
|
1981
|
-
set2(k1, k2, cacheKey, v) {
|
|
1982
|
-
const cur1 = this.map.get(k1);
|
|
1983
|
-
if (cur1) {
|
|
1984
|
-
const cur = cur1.get(k2);
|
|
1985
|
-
if (cur)
|
|
1986
|
-
cur[cacheKey] = v;
|
|
1987
|
-
else
|
|
1988
|
-
cur1.set(k2, { [cacheKey]: v });
|
|
1989
|
-
} else if (typeof k1 === "object" && typeof k2 === "object") {
|
|
1990
|
-
const cur = new WeakMap;
|
|
1991
|
-
cur.set(k2, { [cacheKey]: v });
|
|
1992
|
-
this.map.set(k1, cur);
|
|
1993
|
-
} else {
|
|
1994
|
-
this.badKey += 1;
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
1992
|
evict() {
|
|
1998
1993
|
const { hit, miss, badKey } = this;
|
|
1999
1994
|
this.hit = this.miss = this.badKey = 0;
|
|
2000
|
-
this.
|
|
1995
|
+
this.keysByLen = new Map;
|
|
2001
1996
|
return { hit, miss, badKey };
|
|
2002
1997
|
}
|
|
2003
1998
|
}
|
|
@@ -2219,8 +2214,8 @@ class Component {
|
|
|
2219
2214
|
`);
|
|
2220
2215
|
}
|
|
2221
2216
|
}
|
|
2222
|
-
function defaultOnStackEnter(
|
|
2223
|
-
return
|
|
2217
|
+
function defaultOnStackEnter() {
|
|
2218
|
+
return null;
|
|
2224
2219
|
}
|
|
2225
2220
|
|
|
2226
2221
|
// src/stack.js
|
|
@@ -2281,7 +2276,7 @@ class Stack {
|
|
|
2281
2276
|
this.ctx = ctx;
|
|
2282
2277
|
}
|
|
2283
2278
|
_enrichOnEnter() {
|
|
2284
|
-
return this.comps.getOnEnterFor(this.it).call(this.it
|
|
2279
|
+
return this.withDynamicBindings(this.comps.getOnEnterFor(this.it).call(this.it));
|
|
2285
2280
|
}
|
|
2286
2281
|
upToFrameBinds() {
|
|
2287
2282
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
@@ -2296,7 +2291,8 @@ class Stack {
|
|
|
2296
2291
|
enter(it, bindings = {}, isFrame = true) {
|
|
2297
2292
|
const { comps, binds, dynBinds, views, viewsId, ctx } = this;
|
|
2298
2293
|
const newBinds = [new BindFrame(it, bindings, isFrame), binds];
|
|
2299
|
-
|
|
2294
|
+
const stack = new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
|
|
2295
|
+
return isFrame ? stack._enrichOnEnter() : stack;
|
|
2300
2296
|
}
|
|
2301
2297
|
pushViewName(name) {
|
|
2302
2298
|
const { comps, it, binds, dynBinds, views, ctx } = this;
|
|
@@ -2304,17 +2300,26 @@ class Stack {
|
|
|
2304
2300
|
return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
|
|
2305
2301
|
}
|
|
2306
2302
|
withDynamicBindings(dynamics) {
|
|
2303
|
+
if (dynamics == null || dynamics.length === 0)
|
|
2304
|
+
return this;
|
|
2307
2305
|
const dynObj = {};
|
|
2308
2306
|
const comp = this.comps.getCompFor(this.it);
|
|
2309
2307
|
for (const dynName of dynamics)
|
|
2310
2308
|
comp.dynamic[dynName].evalAndBind(this, dynObj);
|
|
2311
|
-
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
2312
2309
|
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
2310
|
+
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
2313
2311
|
return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
2314
2312
|
}
|
|
2313
|
+
_pushDynBindValuesToArray(arr, dyns) {
|
|
2314
|
+
for (const k in dyns)
|
|
2315
|
+
arr.push(this._lookupDynamicWithDynVal(dyns[k]));
|
|
2316
|
+
}
|
|
2317
|
+
_lookupDynamicWithDynVal(d) {
|
|
2318
|
+
return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this);
|
|
2319
|
+
}
|
|
2315
2320
|
lookupDynamic(name) {
|
|
2316
2321
|
const d = this.comps.getCompFor(this.it)?.dynamic[name];
|
|
2317
|
-
return d ?
|
|
2322
|
+
return d ? this._lookupDynamicWithDynVal(d) : null;
|
|
2318
2323
|
}
|
|
2319
2324
|
lookupBind(name) {
|
|
2320
2325
|
return lookup(this.binds, name);
|
|
@@ -8112,13 +8117,15 @@ class Renderer {
|
|
|
8112
8117
|
}
|
|
8113
8118
|
_rValComp(stack, val, comp, nid, key, viewName) {
|
|
8114
8119
|
const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
|
|
8115
|
-
const
|
|
8120
|
+
const cachePath = [val];
|
|
8121
|
+
stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
|
|
8122
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
8116
8123
|
if (cachedNode)
|
|
8117
8124
|
return cachedNode;
|
|
8118
8125
|
const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
|
|
8119
8126
|
const meta = this._renderMetadata({ $: "Comp", nid });
|
|
8120
8127
|
const dom = new VFragment([meta, this.renderView(view, stack)]);
|
|
8121
|
-
this.cache.set(
|
|
8128
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
8122
8129
|
return dom;
|
|
8123
8130
|
}
|
|
8124
8131
|
pushEachEntry(r, nid, attrName, key, dom) {
|
|
@@ -8130,8 +8137,7 @@ class Renderer {
|
|
|
8130
8137
|
const iterData = loopWith.call(stack.it, seq);
|
|
8131
8138
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
8132
8139
|
if (filter.call(stack.it, key, value, iterData)) {
|
|
8133
|
-
const
|
|
8134
|
-
const dom = this.renderIt(newStack, nodeId, key, viewName);
|
|
8140
|
+
const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
|
|
8135
8141
|
this.pushEachEntry(r, nodeId, attrName, key, dom);
|
|
8136
8142
|
}
|
|
8137
8143
|
});
|
|
@@ -8144,25 +8150,19 @@ class Renderer {
|
|
|
8144
8150
|
const it = stack.it;
|
|
8145
8151
|
this.getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
8146
8152
|
if (filter.call(it, key, value, iterData)) {
|
|
8153
|
+
const cachePath = enricher ? [it, value] : [value];
|
|
8147
8154
|
const bindings = { key, value };
|
|
8148
8155
|
const cacheKey = `${nid}-${key}`;
|
|
8149
|
-
|
|
8150
|
-
if (enricher) {
|
|
8156
|
+
if (enricher)
|
|
8151
8157
|
enricher.call(it, bindings, key, value, iterData);
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
cachedNode = this.cache.get(value, cacheKey);
|
|
8155
|
-
if (cachedNode) {
|
|
8158
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
8159
|
+
if (cachedNode)
|
|
8156
8160
|
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
8157
|
-
|
|
8161
|
+
else {
|
|
8162
|
+
const dom = this.renderView(view, stack.enter(value, bindings, false));
|
|
8163
|
+
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
8164
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
8158
8165
|
}
|
|
8159
|
-
const newStack = stack.enter(value, bindings, false);
|
|
8160
|
-
const dom = this.renderView(view, newStack);
|
|
8161
|
-
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
8162
|
-
if (enricher)
|
|
8163
|
-
this.cache.set2(it, value, cacheKey, dom);
|
|
8164
|
-
else
|
|
8165
|
-
this.cache.set(value, cacheKey, dom);
|
|
8166
8166
|
}
|
|
8167
8167
|
});
|
|
8168
8168
|
return r;
|