malinajs 0.7.0-a5 → 0.7.0-a8
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/malina.js +164 -80
- package/package.json +1 -1
- package/runtime.js +34 -21
package/malina.js
CHANGED
|
@@ -179,22 +179,24 @@
|
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
|
|
182
|
-
const
|
|
182
|
+
const replaceKeyword = (exp, fn) => {
|
|
183
183
|
let changed = false;
|
|
184
184
|
let r = parseJS(exp).transform((n, pk) => {
|
|
185
185
|
if(n.type != 'Identifier') return;
|
|
186
186
|
if(pk == 'property' || pk == 'params') return;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
let name = fn(n.name);
|
|
188
|
+
if(name) {
|
|
189
|
+
n.name = name;
|
|
190
|
+
changed = true;
|
|
191
|
+
}
|
|
190
192
|
});
|
|
191
|
-
return changed ? r.build()
|
|
193
|
+
return changed ? r.build() : exp;
|
|
192
194
|
};
|
|
193
195
|
|
|
194
196
|
|
|
195
197
|
const parseJS = (exp) => {
|
|
196
198
|
let self = {};
|
|
197
|
-
self.ast = acorn.
|
|
199
|
+
self.ast = acorn.parseExpressionAt(exp, 0, {ecmaVersion: 12});
|
|
198
200
|
|
|
199
201
|
self.transform = function(fn) {
|
|
200
202
|
const rec = (n, pk) => {
|
|
@@ -225,7 +227,7 @@
|
|
|
225
227
|
};
|
|
226
228
|
|
|
227
229
|
self.build = function(data) {
|
|
228
|
-
return astring.generate(data || self.ast);
|
|
230
|
+
return astring.generate(data || self.ast, {indent: '', lineEnd: ''});
|
|
229
231
|
};
|
|
230
232
|
return self;
|
|
231
233
|
};
|
|
@@ -1277,7 +1279,6 @@
|
|
|
1277
1279
|
let source = this.scriptNodes.length ? this.scriptNodes[0].content : null;
|
|
1278
1280
|
this.script = {
|
|
1279
1281
|
source,
|
|
1280
|
-
watchers: [],
|
|
1281
1282
|
imports: [],
|
|
1282
1283
|
importedNames: [],
|
|
1283
1284
|
autosubscribeNames: [],
|
|
@@ -1429,7 +1430,7 @@
|
|
|
1429
1430
|
function walk(node, parent, fn) {
|
|
1430
1431
|
if(typeof node !== 'object') return;
|
|
1431
1432
|
|
|
1432
|
-
if(node._apply) return;
|
|
1433
|
+
if(node._apply && node.type == 'ExpressionStatement') return;
|
|
1433
1434
|
node._parent = parent;
|
|
1434
1435
|
let forParent = parent;
|
|
1435
1436
|
if(node.type) {
|
|
@@ -1467,6 +1468,8 @@
|
|
|
1467
1468
|
};
|
|
1468
1469
|
}
|
|
1469
1470
|
|
|
1471
|
+
let watchers = xNode('block');
|
|
1472
|
+
|
|
1470
1473
|
const makeWatch = (n) => {
|
|
1471
1474
|
function assertExpression(n) {
|
|
1472
1475
|
if(['Identifier', 'TemplateLiteral', 'Literal'].includes(n.type)) return;
|
|
@@ -1483,15 +1486,22 @@
|
|
|
1483
1486
|
target = ex.left.name;
|
|
1484
1487
|
if(!(target in rootVariables)) resultBody.push(makeVariable(target));
|
|
1485
1488
|
} else if(ex.left.type == 'MemberExpression') {
|
|
1486
|
-
target =
|
|
1489
|
+
target = astring.generate(ex.left);
|
|
1487
1490
|
} else throw 'Error';
|
|
1488
1491
|
assertExpression(ex.right);
|
|
1489
|
-
const exp =
|
|
1490
|
-
|
|
1492
|
+
const exp = astring.generate(ex.right);
|
|
1493
|
+
watchers.push(xNode('watch-assign', {
|
|
1494
|
+
$wait: ['apply'],
|
|
1495
|
+
target,
|
|
1496
|
+
exp
|
|
1497
|
+
}, (ctx, n) => {
|
|
1498
|
+
if(this.inuse.apply) ctx.write(true, `$runtime.prefixPush(() => {${n.target} = ${n.exp};});`);
|
|
1499
|
+
else ctx.write(true, `${n.target} = ${n.exp};`);
|
|
1500
|
+
}));
|
|
1491
1501
|
} else if(n.body.expression.type == 'SequenceExpression') {
|
|
1492
1502
|
const ex = n.body.expression.expressions;
|
|
1493
|
-
const handler = ex
|
|
1494
|
-
let callback =
|
|
1503
|
+
const handler = last(ex);
|
|
1504
|
+
let callback = astring.generate(handler);
|
|
1495
1505
|
if(handler.type == 'ArrowFunctionExpression' || handler.type == 'FunctionExpression') ; else if(detectExpressionType(callback) == 'identifier') {
|
|
1496
1506
|
callback = `(v) => { ${callback}(v); }`;
|
|
1497
1507
|
} else {
|
|
@@ -1500,13 +1510,33 @@
|
|
|
1500
1510
|
|
|
1501
1511
|
if(ex.length == 2) {
|
|
1502
1512
|
assertExpression(ex[0]);
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1513
|
+
watchers.push(xNode('watch-expression', {
|
|
1514
|
+
$wait: ['apply'],
|
|
1515
|
+
exp: astring.generate(ex[0]),
|
|
1516
|
+
callback
|
|
1517
|
+
}, (ctx, n) => {
|
|
1518
|
+
if(this.inuse.apply) {
|
|
1519
|
+
if(this.config.immutable) ctx.write(true, `$watch(() => (${n.exp}), ${n.callback});`);
|
|
1520
|
+
else ctx.write(true, `$watch(() => (${n.exp}), ${n.callback}, {cmp: $runtime.$$deepComparator(0)});`);
|
|
1521
|
+
} else {
|
|
1522
|
+
ctx.write(true, `(${n.callback})(${n.exp});`);
|
|
1523
|
+
}
|
|
1524
|
+
}));
|
|
1506
1525
|
} else if(ex.length > 2) {
|
|
1507
1526
|
for(let i = 0; i < ex.length - 1; i++) assertExpression(ex[i]);
|
|
1508
|
-
let exp =
|
|
1509
|
-
|
|
1527
|
+
let exp = {
|
|
1528
|
+
type: 'ArrayExpression',
|
|
1529
|
+
elements: ex.slice(0, ex.length - 1)
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1532
|
+
watchers.push(xNode('watch-expression', {
|
|
1533
|
+
$wait: ['apply'],
|
|
1534
|
+
exp: astring.generate(exp),
|
|
1535
|
+
callback
|
|
1536
|
+
}, (ctx, n) => {
|
|
1537
|
+
if(this.inuse.apply) ctx.write(true, `$watch(() => ${n.exp}, ($args) => { (${n.callback}).apply(null, $args); }, {cmp: $runtime.$$deepComparator(1)});`);
|
|
1538
|
+
else ctx.write(true, `(${n.callback}).apply(null, ${n.exp})`);
|
|
1539
|
+
}));
|
|
1510
1540
|
} else throw 'Error';
|
|
1511
1541
|
} else throw 'Error';
|
|
1512
1542
|
};
|
|
@@ -1528,6 +1558,8 @@
|
|
|
1528
1558
|
});
|
|
1529
1559
|
}
|
|
1530
1560
|
|
|
1561
|
+
let exportedFunctions = [];
|
|
1562
|
+
|
|
1531
1563
|
ast.body.forEach(n => {
|
|
1532
1564
|
if(n.type == 'ImportDeclaration') {
|
|
1533
1565
|
imports.push(n);
|
|
@@ -1543,8 +1575,14 @@
|
|
|
1543
1575
|
});
|
|
1544
1576
|
return;
|
|
1545
1577
|
} else if(n.type == 'ExportNamedDeclaration') {
|
|
1546
|
-
if(n.declaration.
|
|
1578
|
+
if(n.declaration.type == 'FunctionDeclaration') {
|
|
1579
|
+
exportedFunctions.push(n.declaration.id.name);
|
|
1580
|
+
resultBody.push(n.declaration);
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1547
1584
|
assert(n.declaration.type == 'VariableDeclaration', 'Wrong export');
|
|
1585
|
+
if(n.declaration.kind != 'const') constantProps = false;
|
|
1548
1586
|
n.declaration.declarations.forEach(d => {
|
|
1549
1587
|
assert(d.type == 'VariableDeclarator', 'Wrong export');
|
|
1550
1588
|
let p = { name: d.id.name };
|
|
@@ -1634,6 +1672,7 @@
|
|
|
1634
1672
|
}));
|
|
1635
1673
|
|
|
1636
1674
|
this.module.top.push(xNode('ast', { body: imports }));
|
|
1675
|
+
this.module.code.push(watchers);
|
|
1637
1676
|
|
|
1638
1677
|
if(this.scriptNodes[0] && this.scriptNodes[0].attributes.some(a => a.name == 'property') && this.script.props.length && !this.script.readOnly) {
|
|
1639
1678
|
this.require('apply');
|
|
@@ -1645,6 +1684,16 @@
|
|
|
1645
1684
|
});
|
|
1646
1685
|
}));
|
|
1647
1686
|
}
|
|
1687
|
+
|
|
1688
|
+
this.module.code.push(xNode('exported-functions', {
|
|
1689
|
+
$hold: ['$component'],
|
|
1690
|
+
list: exportedFunctions
|
|
1691
|
+
}, (ctx, n) => {
|
|
1692
|
+
if(!n.list.length) return;
|
|
1693
|
+
this.require('$component');
|
|
1694
|
+
for(let name of n.list)
|
|
1695
|
+
ctx.write(true, `$component.${name} = ${name};`);
|
|
1696
|
+
}));
|
|
1648
1697
|
}
|
|
1649
1698
|
|
|
1650
1699
|
|
|
@@ -1756,23 +1805,40 @@
|
|
|
1756
1805
|
let bb = this.buildBlock(this.DOM, {
|
|
1757
1806
|
inline: true,
|
|
1758
1807
|
protectLastTag: true,
|
|
1808
|
+
allowSingleBlock: true,
|
|
1759
1809
|
template: {
|
|
1760
1810
|
name: '$parentElement',
|
|
1761
1811
|
cloneNode: true
|
|
1762
1812
|
}
|
|
1763
1813
|
});
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1814
|
+
if(bb.singleBlock) {
|
|
1815
|
+
runtime.push(xNode('attach-block', {
|
|
1816
|
+
block: bb.singleBlock,
|
|
1817
|
+
reference: bb.reference
|
|
1818
|
+
}, (ctx, n) => {
|
|
1819
|
+
if(n.reference) {
|
|
1820
|
+
ctx.write(true, `${n.reference} = `);
|
|
1821
|
+
ctx.add(n.block);
|
|
1822
|
+
ctx.write(';');
|
|
1823
|
+
ctx.write(true, `let $parentElement = ${n.reference}.$dom;`);
|
|
1824
|
+
} else {
|
|
1825
|
+
ctx.write(true, `let $parentElement = `);
|
|
1826
|
+
ctx.add(n.block);
|
|
1827
|
+
ctx.write('.$dom;');
|
|
1828
|
+
}
|
|
1829
|
+
}));
|
|
1830
|
+
} else {
|
|
1831
|
+
runtime.push(bb.template);
|
|
1832
|
+
runtime.push(xNode('root-event', (ctx) => {
|
|
1833
|
+
if(!this.inuse.rootEvent) return;
|
|
1834
|
+
ctx.write(true, 'const $$addRootEvent = $runtime.makeRootEvent($parentElement);');
|
|
1835
|
+
}));
|
|
1836
|
+
runtime.push(bb.source);
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1770
1839
|
|
|
1771
1840
|
if(this.script.onMount) runtime.push('$runtime.$onMount(onMount);');
|
|
1772
1841
|
if(this.script.onDestroy) runtime.push('$runtime.$onDestroy(onDestroy);');
|
|
1773
|
-
if(this.script.watchers.length) {
|
|
1774
|
-
this.script.watchers.forEach(n => runtime.push(n));
|
|
1775
|
-
}
|
|
1776
1842
|
|
|
1777
1843
|
runtime.push(xNode('addStyle', ctx => {
|
|
1778
1844
|
if(!this.css.active()) return;
|
|
@@ -1831,13 +1897,21 @@
|
|
|
1831
1897
|
|
|
1832
1898
|
if(option.each?.blockPrefix) binds.push(option.each.blockPrefix);
|
|
1833
1899
|
|
|
1834
|
-
if(option.allowSingleBlock
|
|
1835
|
-
let
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1900
|
+
if(option.allowSingleBlock) {
|
|
1901
|
+
let nodesForSingleBlock = data.body.filter(n => {
|
|
1902
|
+
if(n.type == 'comment' && !this.config.preserveComments) return false;
|
|
1903
|
+
return true;
|
|
1904
|
+
});
|
|
1905
|
+
|
|
1906
|
+
if(nodesForSingleBlock.length == 1) {
|
|
1907
|
+
let n = nodesForSingleBlock[0];
|
|
1908
|
+
if(n.type == 'node' && n.name.match(/^[A-Z]/)) {
|
|
1909
|
+
let component = this.makeComponent(n);
|
|
1910
|
+
return {
|
|
1911
|
+
singleBlock: component.bind,
|
|
1912
|
+
reference: component.reference
|
|
1913
|
+
};
|
|
1914
|
+
}
|
|
1841
1915
|
}
|
|
1842
1916
|
}
|
|
1843
1917
|
|
|
@@ -1943,7 +2017,7 @@
|
|
|
1943
2017
|
if(!exp.endsWith(';')) exp += ';';
|
|
1944
2018
|
binds.push(xNode('block', {
|
|
1945
2019
|
body: [
|
|
1946
|
-
|
|
2020
|
+
replaceKeyword(exp, (name) => name == '$element' ? textNode.bindName() : null)
|
|
1947
2021
|
]
|
|
1948
2022
|
}));
|
|
1949
2023
|
});
|
|
@@ -1980,11 +2054,18 @@
|
|
|
1980
2054
|
let component = this.makeComponent(n);
|
|
1981
2055
|
binds.push(xNode('insert-component', {
|
|
1982
2056
|
component: component.bind,
|
|
2057
|
+
reference: component.reference,
|
|
1983
2058
|
el: el.bindName()
|
|
1984
2059
|
}, (ctx, n) => {
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2060
|
+
if(n.reference) {
|
|
2061
|
+
ctx.write(true, `${n.reference} = `);
|
|
2062
|
+
ctx.add(n.component);
|
|
2063
|
+
ctx.write(true, `$runtime.attachBlock(${n.el}, ${n.reference});`);
|
|
2064
|
+
} else {
|
|
2065
|
+
ctx.write(true, `$runtime.attachBlock(${n.el}, `);
|
|
2066
|
+
ctx.add(n.component);
|
|
2067
|
+
ctx.write(');');
|
|
2068
|
+
}
|
|
1988
2069
|
}));
|
|
1989
2070
|
}
|
|
1990
2071
|
} else {
|
|
@@ -4401,7 +4482,10 @@
|
|
|
4401
4482
|
let n = new Node(e.name, { __node: e });
|
|
4402
4483
|
e.attributes.forEach(a => {
|
|
4403
4484
|
if(a.name == 'class') {
|
|
4404
|
-
if(a.value != null)
|
|
4485
|
+
if(a.value != null) {
|
|
4486
|
+
if(a.value.includes('{')) n.dynClass = true;
|
|
4487
|
+
else n.className += ' ' + a.value;
|
|
4488
|
+
}
|
|
4405
4489
|
n.attributes[a.name] = a.value;
|
|
4406
4490
|
} else if(a.name == 'id') n.attributes.id = n.id = a.value;
|
|
4407
4491
|
else if(a.name.startsWith('class:')) {
|
|
@@ -4481,18 +4565,20 @@
|
|
|
4481
4565
|
if(names.length != 1) throw 'Not supported';
|
|
4482
4566
|
let cls = names[0];
|
|
4483
4567
|
|
|
4568
|
+
let rx = RegExp('(^|\\s)' + cls + '(\\s|$)', 'i');
|
|
4484
4569
|
let result = [];
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4570
|
+
const walk = (node) => {
|
|
4571
|
+
node.childNodes.forEach(n => {
|
|
4572
|
+
if(n.dynClass) result.push(n);
|
|
4573
|
+
else if(rx.test(n.className)) result.push(n);
|
|
4574
|
+
walk(n);
|
|
4575
|
+
});
|
|
4576
|
+
};
|
|
4577
|
+
walk(this);
|
|
4490
4578
|
return result;
|
|
4491
4579
|
};
|
|
4492
4580
|
|
|
4493
4581
|
function makeComponent(node) {
|
|
4494
|
-
this.require('apply');
|
|
4495
|
-
|
|
4496
4582
|
let propList = node.attributes;
|
|
4497
4583
|
|
|
4498
4584
|
this.require('$context');
|
|
@@ -4505,7 +4591,7 @@
|
|
|
4505
4591
|
let componentName = node.name;
|
|
4506
4592
|
if(componentName != 'component' && this.config.autoimport) {
|
|
4507
4593
|
let imported = this.script.autoimport[componentName] || this.script.importedNames.includes(componentName) ||
|
|
4508
|
-
|
|
4594
|
+
this.script.rootVariables[componentName] || this.script.rootFunctions[componentName];
|
|
4509
4595
|
|
|
4510
4596
|
if(!imported) {
|
|
4511
4597
|
let r = this.config.autoimport(componentName, this.config.path, this);
|
|
@@ -4590,7 +4676,7 @@
|
|
|
4590
4676
|
if(n.props) ctx.write(', $localProps');
|
|
4591
4677
|
ctx.write(') => {', true);
|
|
4592
4678
|
ctx.indent++;
|
|
4593
|
-
if(n.props) ctx.write(true, `let {${n.props.join(', ')}} = $localProps;`);
|
|
4679
|
+
if(n.props) ctx.write(true, `let {${n.props.join(', ')}} = $localProps || {};`);
|
|
4594
4680
|
ctx.add(n.bind);
|
|
4595
4681
|
|
|
4596
4682
|
if(n.props && this.inuse.apply) ctx.write(true, `return ($localProps) => ({${n.props.join(', ')}} = $localProps, $$apply());`);
|
|
@@ -4732,14 +4818,12 @@
|
|
|
4732
4818
|
staticProps,
|
|
4733
4819
|
props: propsFn,
|
|
4734
4820
|
propsSetter,
|
|
4735
|
-
reference,
|
|
4736
4821
|
$class,
|
|
4737
4822
|
forwardAllEvents,
|
|
4738
4823
|
events,
|
|
4739
4824
|
slots: slotBlocks.length ? slotBlocks : null,
|
|
4740
4825
|
anchors: anchorBlocks.length ? anchorBlocks : null
|
|
4741
4826
|
}, (ctx, n) => {
|
|
4742
|
-
if(n.reference) throw 'not implemented'; // FIXME
|
|
4743
4827
|
let comma = false;
|
|
4744
4828
|
ctx.write(`$runtime.callComponent($context, ${n.componentName}, {`);
|
|
4745
4829
|
|
|
@@ -4803,6 +4887,11 @@
|
|
|
4803
4887
|
ctx.indent--;
|
|
4804
4888
|
ctx.write(true, '}');
|
|
4805
4889
|
}
|
|
4890
|
+
if(n.$class.length && !ctx.inuse.apply) {
|
|
4891
|
+
if(comma) ctx.write(', ');
|
|
4892
|
+
comma = true;
|
|
4893
|
+
ctx.write(`$class: {${n.$class.join(', ')}}`);
|
|
4894
|
+
}
|
|
4806
4895
|
ctx.write('}');
|
|
4807
4896
|
|
|
4808
4897
|
let other = '';
|
|
@@ -4824,7 +4913,7 @@
|
|
|
4824
4913
|
ctx.write(',\n', true, `($$_value) => ({${n.propsSetter.join(', ')}} = $$_value)`);
|
|
4825
4914
|
} else other += ', null';
|
|
4826
4915
|
|
|
4827
|
-
if(n.$class.length) {
|
|
4916
|
+
if(n.$class.length && ctx.inuse.apply) {
|
|
4828
4917
|
if(other) ctx.write(other);
|
|
4829
4918
|
other = '';
|
|
4830
4919
|
ctx.write(',\n', true, `() => ({${n.$class.join(', ')}})`);
|
|
@@ -4834,7 +4923,7 @@
|
|
|
4834
4923
|
ctx.write(true, ')');
|
|
4835
4924
|
});
|
|
4836
4925
|
|
|
4837
|
-
return { bind: result };
|
|
4926
|
+
return { bind: result, reference };
|
|
4838
4927
|
}
|
|
4839
4928
|
|
|
4840
4929
|
function makeComponentDyn(node, element) {
|
|
@@ -4852,17 +4941,20 @@
|
|
|
4852
4941
|
}
|
|
4853
4942
|
|
|
4854
4943
|
assert(dynamicComponent);
|
|
4944
|
+
this.require('apply');
|
|
4855
4945
|
this.detectDependency(dynamicComponent);
|
|
4856
4946
|
|
|
4857
|
-
let component = this.makeComponent(node)
|
|
4947
|
+
let {bind: component, reference} = this.makeComponent(node);
|
|
4858
4948
|
|
|
4859
4949
|
component.componentName = '$ComponentConstructor';
|
|
4860
4950
|
return xNode('dyn-component', {
|
|
4861
4951
|
el: element.bindName(),
|
|
4862
4952
|
exp: dynamicComponent,
|
|
4863
|
-
component
|
|
4953
|
+
component,
|
|
4954
|
+
reference
|
|
4864
4955
|
}, (ctx, n) => {
|
|
4865
4956
|
ctx.write(true, `$runtime.attachDynComponent(${n.el}, () => ${n.exp}, ($ComponentConstructor) => `);
|
|
4957
|
+
if(n.reference) ctx.write(`${n.reference} = `);
|
|
4866
4958
|
ctx.add(n.component);
|
|
4867
4959
|
ctx.write(')');
|
|
4868
4960
|
});
|
|
@@ -4879,7 +4971,7 @@
|
|
|
4879
4971
|
return {
|
|
4880
4972
|
bind: xNode('block', {
|
|
4881
4973
|
body: [
|
|
4882
|
-
|
|
4974
|
+
replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null)
|
|
4883
4975
|
]
|
|
4884
4976
|
})
|
|
4885
4977
|
};
|
|
@@ -5382,15 +5474,8 @@
|
|
|
5382
5474
|
right = right.trim();
|
|
5383
5475
|
|
|
5384
5476
|
const makeKeyFunction = (keyLink) => {
|
|
5385
|
-
const e = parseJS(keyName).transform((n, pk) => {
|
|
5386
|
-
if(n.type != 'Identifier') return;
|
|
5387
|
-
if(pk == 'property') return;
|
|
5388
|
-
let r = keyLink[n.name];
|
|
5389
|
-
if(r) n.name = r;
|
|
5390
|
-
});
|
|
5391
|
-
let exp = e.build(e.ast.body[0].expression);
|
|
5392
5477
|
keyFunction = xNode('key-function', {
|
|
5393
|
-
exp
|
|
5478
|
+
exp: replaceKeyword(keyName, n => keyLink[n])
|
|
5394
5479
|
}, (ctx, n) => {
|
|
5395
5480
|
ctx.write(`($$item, $index) => ${n.exp}`);
|
|
5396
5481
|
});
|
|
@@ -5402,22 +5487,19 @@
|
|
|
5402
5487
|
try {
|
|
5403
5488
|
let exp = `[${right}]`;
|
|
5404
5489
|
let e = parseJS(exp);
|
|
5405
|
-
assert(e.ast.
|
|
5406
|
-
|
|
5490
|
+
assert(e.ast.elements.length == 1 || e.ast.elements.length == 2);
|
|
5407
5491
|
itemName = '$$item';
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
if(n.expression.elements.length == 2) {
|
|
5414
|
-
let b = n.expression.elements[1];
|
|
5492
|
+
|
|
5493
|
+
unwrap = e.build(e.ast.elements[0]);
|
|
5494
|
+
|
|
5495
|
+
if(e.ast.elements.length == 2) {
|
|
5496
|
+
let b = e.ast.elements[1];
|
|
5415
5497
|
assert(b.type == 'Identifier');
|
|
5416
|
-
indexName =
|
|
5498
|
+
indexName = e.build(b);
|
|
5417
5499
|
}
|
|
5418
5500
|
|
|
5419
5501
|
e = parseJS(`(${unwrap} = $$item)`);
|
|
5420
|
-
let l = e.ast.
|
|
5502
|
+
let l = e.ast.left;
|
|
5421
5503
|
if(l.type == 'ArrayPattern') {
|
|
5422
5504
|
keywords = l.elements.map(p => p.name);
|
|
5423
5505
|
|
|
@@ -5653,7 +5735,7 @@
|
|
|
5653
5735
|
}, (ctx, n) => {
|
|
5654
5736
|
let dynamicProps = this.inuse.apply && !n.staticProps;
|
|
5655
5737
|
|
|
5656
|
-
let missed = '', slotName = n.name == 'default' ? 'null' : n.name
|
|
5738
|
+
let missed = '', slotName = n.name == 'default' ? 'null' : `'${n.name}'`;
|
|
5657
5739
|
if(dynamicProps) ctx.write(`$runtime.invokeSlot($component, ${slotName}, $context`);
|
|
5658
5740
|
else ctx.write(`$runtime.invokeSlotBase($component, ${slotName}, $context`);
|
|
5659
5741
|
|
|
@@ -6171,7 +6253,9 @@
|
|
|
6171
6253
|
if(prop.value) {
|
|
6172
6254
|
assert$1(!handler);
|
|
6173
6255
|
exp = unwrapExp(prop.value);
|
|
6174
|
-
exp =
|
|
6256
|
+
exp = replaceKeyword(exp, (name) => {
|
|
6257
|
+
if(name == '$element') return requireElement();
|
|
6258
|
+
});
|
|
6175
6259
|
} else if(!handler) handler = event;
|
|
6176
6260
|
|
|
6177
6261
|
this.detectDependency(exp || handler);
|
|
@@ -6270,7 +6354,7 @@
|
|
|
6270
6354
|
return { event, fn, rootModifier };
|
|
6271
6355
|
}
|
|
6272
6356
|
|
|
6273
|
-
const version = '0.7.0-
|
|
6357
|
+
const version = '0.7.0-a8';
|
|
6274
6358
|
|
|
6275
6359
|
|
|
6276
6360
|
async function compile(source, config = {}) {
|
|
@@ -6395,7 +6479,7 @@
|
|
|
6395
6479
|
await hook(ctx, 'js:before');
|
|
6396
6480
|
ctx.js_parse();
|
|
6397
6481
|
await hook(ctx, 'js');
|
|
6398
|
-
ctx.js_transform();
|
|
6482
|
+
use_context(ctx, () => ctx.js_transform());
|
|
6399
6483
|
await hook(ctx, 'js:after');
|
|
6400
6484
|
|
|
6401
6485
|
await hook(ctx, 'css:before');
|
package/package.json
CHANGED
package/runtime.js
CHANGED
|
@@ -30,7 +30,6 @@ const $onDestroy = fn => fn && current_destroyList.push(fn);
|
|
|
30
30
|
function WatchObject(fn, cb) {
|
|
31
31
|
this.fn = fn;
|
|
32
32
|
this.cb = cb;
|
|
33
|
-
this.ro = true;
|
|
34
33
|
this.value = NaN;
|
|
35
34
|
this.cmp = null;
|
|
36
35
|
}
|
|
@@ -101,7 +100,6 @@ function $$compareArray(w, value) {
|
|
|
101
100
|
if(isArray(value)) w.value = value.slice();
|
|
102
101
|
else w.value = value;
|
|
103
102
|
w.cb(w.value);
|
|
104
|
-
return w.ro ? 0 : 1;
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
|
|
@@ -159,7 +157,6 @@ function $$deepComparator(depth) {
|
|
|
159
157
|
let diff = compareDeep(w.value, value, depth);
|
|
160
158
|
diff && (w.value = cloneDeep(value, depth), !w.idle && w.cb(value));
|
|
161
159
|
w.idle = false;
|
|
162
|
-
return !w.ro && diff ? 1 : 0;
|
|
163
160
|
};
|
|
164
161
|
}
|
|
165
162
|
|
|
@@ -174,7 +171,6 @@ const keyComparator = (w, value) => {
|
|
|
174
171
|
}
|
|
175
172
|
diff && !w.idle && w.cb(value);
|
|
176
173
|
w.idle = false;
|
|
177
|
-
return !w.ro && diff ? 1 : 0;
|
|
178
174
|
};
|
|
179
175
|
|
|
180
176
|
|
|
@@ -186,27 +182,26 @@ const fire = w => {
|
|
|
186
182
|
}
|
|
187
183
|
};
|
|
188
184
|
|
|
189
|
-
function $digest($cd) {
|
|
185
|
+
function $digest($cd, flag) {
|
|
190
186
|
let loop = 10;
|
|
191
187
|
let w;
|
|
192
188
|
while(loop >= 0) {
|
|
193
|
-
let changes = 0;
|
|
194
189
|
let index = 0;
|
|
195
190
|
let queue = [];
|
|
196
|
-
let i, value, cd = $cd;
|
|
191
|
+
let i, value, cd = $cd, changes = 0;
|
|
197
192
|
while(cd) {
|
|
198
193
|
for(i = 0; i < cd.prefix.length; i++) cd.prefix[i]();
|
|
199
194
|
for(i = 0; i < cd.watchers.length; i++) {
|
|
200
195
|
w = cd.watchers[i];
|
|
201
196
|
value = w.fn();
|
|
202
197
|
if(w.value !== value) {
|
|
198
|
+
flag[0] = 0;
|
|
203
199
|
if(w.cmp) {
|
|
204
|
-
|
|
200
|
+
w.cmp(w, value);
|
|
205
201
|
} else {
|
|
206
|
-
w.value = value;
|
|
207
|
-
if(!w.ro) changes++;
|
|
208
|
-
w.cb(w.value);
|
|
202
|
+
w.cb(w.value = value);
|
|
209
203
|
}
|
|
204
|
+
changes += flag[0];
|
|
210
205
|
}
|
|
211
206
|
}
|
|
212
207
|
if(cd.children.length) queue.push.apply(queue, cd.children);
|
|
@@ -356,13 +351,14 @@ const makeApply = () => {
|
|
|
356
351
|
let $cd = current_component.$cd = current_cd = cd_new();
|
|
357
352
|
$cd.component = current_component;
|
|
358
353
|
|
|
359
|
-
let planned;
|
|
354
|
+
let planned, flag = [0];
|
|
360
355
|
let apply = r => {
|
|
356
|
+
flag[0]++;
|
|
361
357
|
if(planned) return r;
|
|
362
358
|
planned = true;
|
|
363
359
|
$tick(() => {
|
|
364
360
|
try {
|
|
365
|
-
$digest($cd);
|
|
361
|
+
$digest($cd, flag);
|
|
366
362
|
} finally {
|
|
367
363
|
planned = false;
|
|
368
364
|
}
|
|
@@ -550,7 +546,7 @@ const bindAction = (element, action, fn, subscribe) => {
|
|
|
550
546
|
} else handler = action(element);
|
|
551
547
|
$onDestroy(handler?.destroy);
|
|
552
548
|
subscribe?.(fn, handler, value);
|
|
553
|
-
handler
|
|
549
|
+
handler?.init && $tick(handler.init);
|
|
554
550
|
};
|
|
555
551
|
|
|
556
552
|
|
|
@@ -558,7 +554,7 @@ const __bindActionSubscribe = (fn, handler, value) => {
|
|
|
558
554
|
if(handler?.update && fn) {
|
|
559
555
|
$watch(fn, args => {
|
|
560
556
|
handler.update.apply(handler, args);
|
|
561
|
-
}, {
|
|
557
|
+
}, { cmp: $$deepComparator(1), value: cloneDeep(value, 1) });
|
|
562
558
|
}
|
|
563
559
|
};
|
|
564
560
|
|
|
@@ -810,6 +806,17 @@ const mount = (label, component, option) => {
|
|
|
810
806
|
return app;
|
|
811
807
|
};
|
|
812
808
|
|
|
809
|
+
const mountStatic = (label, component, option) => {
|
|
810
|
+
current_destroyList = [];
|
|
811
|
+
try {
|
|
812
|
+
let app = component(option);
|
|
813
|
+
label.appendChild(app.$dom);
|
|
814
|
+
return app;
|
|
815
|
+
} finally {
|
|
816
|
+
current_destroyList = null;
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
|
|
813
820
|
let create = (tag, html) => {
|
|
814
821
|
let fr;
|
|
815
822
|
if(tag.parentElement instanceof SVGElement) {
|
|
@@ -1134,12 +1141,17 @@ const invokeSlot = ($component, slotName, $context, propsFn, placeholder, cmp) =
|
|
|
1134
1141
|
let $slot = $component.$option.slots?.[slotName || 'default'];
|
|
1135
1142
|
|
|
1136
1143
|
if($slot) {
|
|
1137
|
-
let push,
|
|
1138
|
-
w = new WatchObject(propsFn, value => push(value));
|
|
1144
|
+
let push, w = new WatchObject(propsFn, value => push(value));
|
|
1139
1145
|
Object.assign(w, {value: {}, cmp, idle: true});
|
|
1140
1146
|
fire(w);
|
|
1141
|
-
|
|
1142
|
-
if(
|
|
1147
|
+
let $dom = $slot($component, $context, w.value);
|
|
1148
|
+
if($dom.$dom) {
|
|
1149
|
+
if($dom.push) {
|
|
1150
|
+
push = $dom.push;
|
|
1151
|
+
current_cd.watchers.push(w);
|
|
1152
|
+
}
|
|
1153
|
+
$dom = $dom.$dom;
|
|
1154
|
+
}
|
|
1143
1155
|
return $dom;
|
|
1144
1156
|
} else return placeholder?.();
|
|
1145
1157
|
};
|
|
@@ -1150,12 +1162,13 @@ const makeSlot = (fr, fn) => {
|
|
|
1150
1162
|
let $dom = fr.cloneNode(true), prev = current_cd, $cd = current_cd = cd_new();
|
|
1151
1163
|
cd_attach2(parentCD, $cd);
|
|
1152
1164
|
$onDestroy(() => cd_detach($cd));
|
|
1165
|
+
parentCD.component.apply();
|
|
1153
1166
|
try {
|
|
1154
|
-
return
|
|
1167
|
+
return {$dom, push: fn($dom, $context, callerComponent, props)};
|
|
1155
1168
|
} finally {
|
|
1156
1169
|
current_cd = prev;
|
|
1157
1170
|
}
|
|
1158
1171
|
};
|
|
1159
1172
|
};
|
|
1160
1173
|
|
|
1161
|
-
export { $$addEventForComponent, $$awaitBlock, $$cloneDeep, $$compareArray, $$compareDeep, $$deepComparator, $$eachBlock, $$htmlBlock, $$htmlBlockStatic, $$htmlToFragment, $$htmlToFragmentClean, $$removeElements, $$removeItem, $context, $digest, $makeEmitter, $onDestroy, $onMount, $tick, $watch, WatchObject, __app_onerror, __bindActionSubscribe, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callExportedFragment, cd_attach, cd_attach2, cd_component, cd_detach, cd_new, childNodes, cloneDeep, configure, createTextNode, current_cd, current_component, current_destroyList, destroyResults, eachDefaultKey, exportFragment, fire, firstChild, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, mergeEvents, mount, noop, prefixPush, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };
|
|
1174
|
+
export { $$addEventForComponent, $$awaitBlock, $$cloneDeep, $$compareArray, $$compareDeep, $$deepComparator, $$eachBlock, $$htmlBlock, $$htmlBlockStatic, $$htmlToFragment, $$htmlToFragmentClean, $$removeElements, $$removeItem, $context, $digest, $makeEmitter, $onDestroy, $onMount, $tick, $watch, WatchObject, __app_onerror, __bindActionSubscribe, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callExportedFragment, cd_attach, cd_attach2, cd_component, cd_detach, cd_new, childNodes, cloneDeep, configure, createTextNode, current_cd, current_component, current_destroyList, destroyResults, eachDefaultKey, exportFragment, fire, firstChild, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, mergeEvents, mount, mountStatic, noop, prefixPush, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };
|