malinajs 0.7.0-a7 → 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 +120 -62
- package/package.json +1 -1
- package/runtime.js +12 -1
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
|
};
|
|
@@ -1556,6 +1558,8 @@
|
|
|
1556
1558
|
});
|
|
1557
1559
|
}
|
|
1558
1560
|
|
|
1561
|
+
let exportedFunctions = [];
|
|
1562
|
+
|
|
1559
1563
|
ast.body.forEach(n => {
|
|
1560
1564
|
if(n.type == 'ImportDeclaration') {
|
|
1561
1565
|
imports.push(n);
|
|
@@ -1571,8 +1575,14 @@
|
|
|
1571
1575
|
});
|
|
1572
1576
|
return;
|
|
1573
1577
|
} else if(n.type == 'ExportNamedDeclaration') {
|
|
1574
|
-
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
|
+
|
|
1575
1584
|
assert(n.declaration.type == 'VariableDeclaration', 'Wrong export');
|
|
1585
|
+
if(n.declaration.kind != 'const') constantProps = false;
|
|
1576
1586
|
n.declaration.declarations.forEach(d => {
|
|
1577
1587
|
assert(d.type == 'VariableDeclarator', 'Wrong export');
|
|
1578
1588
|
let p = { name: d.id.name };
|
|
@@ -1674,6 +1684,16 @@
|
|
|
1674
1684
|
});
|
|
1675
1685
|
}));
|
|
1676
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
|
+
}));
|
|
1677
1697
|
}
|
|
1678
1698
|
|
|
1679
1699
|
|
|
@@ -1785,17 +1805,37 @@
|
|
|
1785
1805
|
let bb = this.buildBlock(this.DOM, {
|
|
1786
1806
|
inline: true,
|
|
1787
1807
|
protectLastTag: true,
|
|
1808
|
+
allowSingleBlock: true,
|
|
1788
1809
|
template: {
|
|
1789
1810
|
name: '$parentElement',
|
|
1790
1811
|
cloneNode: true
|
|
1791
1812
|
}
|
|
1792
1813
|
});
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
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
|
+
|
|
1799
1839
|
|
|
1800
1840
|
if(this.script.onMount) runtime.push('$runtime.$onMount(onMount);');
|
|
1801
1841
|
if(this.script.onDestroy) runtime.push('$runtime.$onDestroy(onDestroy);');
|
|
@@ -1857,13 +1897,21 @@
|
|
|
1857
1897
|
|
|
1858
1898
|
if(option.each?.blockPrefix) binds.push(option.each.blockPrefix);
|
|
1859
1899
|
|
|
1860
|
-
if(option.allowSingleBlock
|
|
1861
|
-
let
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
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
|
+
}
|
|
1867
1915
|
}
|
|
1868
1916
|
}
|
|
1869
1917
|
|
|
@@ -1969,7 +2017,7 @@
|
|
|
1969
2017
|
if(!exp.endsWith(';')) exp += ';';
|
|
1970
2018
|
binds.push(xNode('block', {
|
|
1971
2019
|
body: [
|
|
1972
|
-
|
|
2020
|
+
replaceKeyword(exp, (name) => name == '$element' ? textNode.bindName() : null)
|
|
1973
2021
|
]
|
|
1974
2022
|
}));
|
|
1975
2023
|
});
|
|
@@ -2006,11 +2054,18 @@
|
|
|
2006
2054
|
let component = this.makeComponent(n);
|
|
2007
2055
|
binds.push(xNode('insert-component', {
|
|
2008
2056
|
component: component.bind,
|
|
2057
|
+
reference: component.reference,
|
|
2009
2058
|
el: el.bindName()
|
|
2010
2059
|
}, (ctx, n) => {
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
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
|
+
}
|
|
2014
2069
|
}));
|
|
2015
2070
|
}
|
|
2016
2071
|
} else {
|
|
@@ -4427,7 +4482,10 @@
|
|
|
4427
4482
|
let n = new Node(e.name, { __node: e });
|
|
4428
4483
|
e.attributes.forEach(a => {
|
|
4429
4484
|
if(a.name == 'class') {
|
|
4430
|
-
if(a.value != null)
|
|
4485
|
+
if(a.value != null) {
|
|
4486
|
+
if(a.value.includes('{')) n.dynClass = true;
|
|
4487
|
+
else n.className += ' ' + a.value;
|
|
4488
|
+
}
|
|
4431
4489
|
n.attributes[a.name] = a.value;
|
|
4432
4490
|
} else if(a.name == 'id') n.attributes.id = n.id = a.value;
|
|
4433
4491
|
else if(a.name.startsWith('class:')) {
|
|
@@ -4507,18 +4565,20 @@
|
|
|
4507
4565
|
if(names.length != 1) throw 'Not supported';
|
|
4508
4566
|
let cls = names[0];
|
|
4509
4567
|
|
|
4568
|
+
let rx = RegExp('(^|\\s)' + cls + '(\\s|$)', 'i');
|
|
4510
4569
|
let result = [];
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
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);
|
|
4516
4578
|
return result;
|
|
4517
4579
|
};
|
|
4518
4580
|
|
|
4519
4581
|
function makeComponent(node) {
|
|
4520
|
-
this.require('apply');
|
|
4521
|
-
|
|
4522
4582
|
let propList = node.attributes;
|
|
4523
4583
|
|
|
4524
4584
|
this.require('$context');
|
|
@@ -4531,7 +4591,7 @@
|
|
|
4531
4591
|
let componentName = node.name;
|
|
4532
4592
|
if(componentName != 'component' && this.config.autoimport) {
|
|
4533
4593
|
let imported = this.script.autoimport[componentName] || this.script.importedNames.includes(componentName) ||
|
|
4534
|
-
|
|
4594
|
+
this.script.rootVariables[componentName] || this.script.rootFunctions[componentName];
|
|
4535
4595
|
|
|
4536
4596
|
if(!imported) {
|
|
4537
4597
|
let r = this.config.autoimport(componentName, this.config.path, this);
|
|
@@ -4758,14 +4818,12 @@
|
|
|
4758
4818
|
staticProps,
|
|
4759
4819
|
props: propsFn,
|
|
4760
4820
|
propsSetter,
|
|
4761
|
-
reference,
|
|
4762
4821
|
$class,
|
|
4763
4822
|
forwardAllEvents,
|
|
4764
4823
|
events,
|
|
4765
4824
|
slots: slotBlocks.length ? slotBlocks : null,
|
|
4766
4825
|
anchors: anchorBlocks.length ? anchorBlocks : null
|
|
4767
4826
|
}, (ctx, n) => {
|
|
4768
|
-
if(n.reference) throw 'not implemented'; // FIXME
|
|
4769
4827
|
let comma = false;
|
|
4770
4828
|
ctx.write(`$runtime.callComponent($context, ${n.componentName}, {`);
|
|
4771
4829
|
|
|
@@ -4829,6 +4887,11 @@
|
|
|
4829
4887
|
ctx.indent--;
|
|
4830
4888
|
ctx.write(true, '}');
|
|
4831
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
|
+
}
|
|
4832
4895
|
ctx.write('}');
|
|
4833
4896
|
|
|
4834
4897
|
let other = '';
|
|
@@ -4850,7 +4913,7 @@
|
|
|
4850
4913
|
ctx.write(',\n', true, `($$_value) => ({${n.propsSetter.join(', ')}} = $$_value)`);
|
|
4851
4914
|
} else other += ', null';
|
|
4852
4915
|
|
|
4853
|
-
if(n.$class.length) {
|
|
4916
|
+
if(n.$class.length && ctx.inuse.apply) {
|
|
4854
4917
|
if(other) ctx.write(other);
|
|
4855
4918
|
other = '';
|
|
4856
4919
|
ctx.write(',\n', true, `() => ({${n.$class.join(', ')}})`);
|
|
@@ -4860,7 +4923,7 @@
|
|
|
4860
4923
|
ctx.write(true, ')');
|
|
4861
4924
|
});
|
|
4862
4925
|
|
|
4863
|
-
return { bind: result };
|
|
4926
|
+
return { bind: result, reference };
|
|
4864
4927
|
}
|
|
4865
4928
|
|
|
4866
4929
|
function makeComponentDyn(node, element) {
|
|
@@ -4878,17 +4941,20 @@
|
|
|
4878
4941
|
}
|
|
4879
4942
|
|
|
4880
4943
|
assert(dynamicComponent);
|
|
4944
|
+
this.require('apply');
|
|
4881
4945
|
this.detectDependency(dynamicComponent);
|
|
4882
4946
|
|
|
4883
|
-
let component = this.makeComponent(node)
|
|
4947
|
+
let {bind: component, reference} = this.makeComponent(node);
|
|
4884
4948
|
|
|
4885
4949
|
component.componentName = '$ComponentConstructor';
|
|
4886
4950
|
return xNode('dyn-component', {
|
|
4887
4951
|
el: element.bindName(),
|
|
4888
4952
|
exp: dynamicComponent,
|
|
4889
|
-
component
|
|
4953
|
+
component,
|
|
4954
|
+
reference
|
|
4890
4955
|
}, (ctx, n) => {
|
|
4891
4956
|
ctx.write(true, `$runtime.attachDynComponent(${n.el}, () => ${n.exp}, ($ComponentConstructor) => `);
|
|
4957
|
+
if(n.reference) ctx.write(`${n.reference} = `);
|
|
4892
4958
|
ctx.add(n.component);
|
|
4893
4959
|
ctx.write(')');
|
|
4894
4960
|
});
|
|
@@ -4905,7 +4971,7 @@
|
|
|
4905
4971
|
return {
|
|
4906
4972
|
bind: xNode('block', {
|
|
4907
4973
|
body: [
|
|
4908
|
-
|
|
4974
|
+
replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null)
|
|
4909
4975
|
]
|
|
4910
4976
|
})
|
|
4911
4977
|
};
|
|
@@ -5408,15 +5474,8 @@
|
|
|
5408
5474
|
right = right.trim();
|
|
5409
5475
|
|
|
5410
5476
|
const makeKeyFunction = (keyLink) => {
|
|
5411
|
-
const e = parseJS(keyName).transform((n, pk) => {
|
|
5412
|
-
if(n.type != 'Identifier') return;
|
|
5413
|
-
if(pk == 'property') return;
|
|
5414
|
-
let r = keyLink[n.name];
|
|
5415
|
-
if(r) n.name = r;
|
|
5416
|
-
});
|
|
5417
|
-
let exp = e.build(e.ast.body[0].expression);
|
|
5418
5477
|
keyFunction = xNode('key-function', {
|
|
5419
|
-
exp
|
|
5478
|
+
exp: replaceKeyword(keyName, n => keyLink[n])
|
|
5420
5479
|
}, (ctx, n) => {
|
|
5421
5480
|
ctx.write(`($$item, $index) => ${n.exp}`);
|
|
5422
5481
|
});
|
|
@@ -5428,22 +5487,19 @@
|
|
|
5428
5487
|
try {
|
|
5429
5488
|
let exp = `[${right}]`;
|
|
5430
5489
|
let e = parseJS(exp);
|
|
5431
|
-
assert(e.ast.
|
|
5432
|
-
|
|
5490
|
+
assert(e.ast.elements.length == 1 || e.ast.elements.length == 2);
|
|
5433
5491
|
itemName = '$$item';
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
if(n.expression.elements.length == 2) {
|
|
5440
|
-
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];
|
|
5441
5497
|
assert(b.type == 'Identifier');
|
|
5442
|
-
indexName =
|
|
5498
|
+
indexName = e.build(b);
|
|
5443
5499
|
}
|
|
5444
5500
|
|
|
5445
5501
|
e = parseJS(`(${unwrap} = $$item)`);
|
|
5446
|
-
let l = e.ast.
|
|
5502
|
+
let l = e.ast.left;
|
|
5447
5503
|
if(l.type == 'ArrayPattern') {
|
|
5448
5504
|
keywords = l.elements.map(p => p.name);
|
|
5449
5505
|
|
|
@@ -6197,7 +6253,9 @@
|
|
|
6197
6253
|
if(prop.value) {
|
|
6198
6254
|
assert$1(!handler);
|
|
6199
6255
|
exp = unwrapExp(prop.value);
|
|
6200
|
-
exp =
|
|
6256
|
+
exp = replaceKeyword(exp, (name) => {
|
|
6257
|
+
if(name == '$element') return requireElement();
|
|
6258
|
+
});
|
|
6201
6259
|
} else if(!handler) handler = event;
|
|
6202
6260
|
|
|
6203
6261
|
this.detectDependency(exp || handler);
|
|
@@ -6296,7 +6354,7 @@
|
|
|
6296
6354
|
return { event, fn, rootModifier };
|
|
6297
6355
|
}
|
|
6298
6356
|
|
|
6299
|
-
const version = '0.7.0-
|
|
6357
|
+
const version = '0.7.0-a8';
|
|
6300
6358
|
|
|
6301
6359
|
|
|
6302
6360
|
async function compile(source, config = {}) {
|
package/package.json
CHANGED
package/runtime.js
CHANGED
|
@@ -806,6 +806,17 @@ const mount = (label, component, option) => {
|
|
|
806
806
|
return app;
|
|
807
807
|
};
|
|
808
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
|
+
|
|
809
820
|
let create = (tag, html) => {
|
|
810
821
|
let fr;
|
|
811
822
|
if(tag.parentElement instanceof SVGElement) {
|
|
@@ -1160,4 +1171,4 @@ const makeSlot = (fr, fn) => {
|
|
|
1160
1171
|
};
|
|
1161
1172
|
};
|
|
1162
1173
|
|
|
1163
|
-
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 };
|