malinajs 0.7.2-a9 → 0.7.3
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 +96 -46
- package/package.json +3 -3
- package/plugins/sass.js +28 -10
- package/plugins/static-text.js +46 -0
- package/runtime.js +42 -17
- package/CHANGELOG.md +0 -79
package/malina.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
let prev = current_context;
|
|
20
20
|
try {
|
|
21
21
|
current_context = context;
|
|
22
|
-
fn();
|
|
22
|
+
return fn();
|
|
23
23
|
} finally {
|
|
24
24
|
current_context = prev;
|
|
25
25
|
}
|
|
@@ -671,6 +671,42 @@
|
|
|
671
671
|
}
|
|
672
672
|
};
|
|
673
673
|
|
|
674
|
+
const walk = (node, fn) => {
|
|
675
|
+
switch(node.type) {
|
|
676
|
+
case 'node':
|
|
677
|
+
case 'slot':
|
|
678
|
+
case 'block':
|
|
679
|
+
case 'fragment':
|
|
680
|
+
case 'root':
|
|
681
|
+
if(node.body) fn(node.body, node);
|
|
682
|
+
break
|
|
683
|
+
case 'each':
|
|
684
|
+
if(node.mainBlock) fn(node.mainBlock, node);
|
|
685
|
+
if(node.elseBlock) fn(node.elseBlock, node);
|
|
686
|
+
break
|
|
687
|
+
case 'await':
|
|
688
|
+
if(node.parts.main) fn(node.parts.main, node);
|
|
689
|
+
if(node.parts.then) fn(node.parts.then, node);
|
|
690
|
+
if(node.parts.catch) fn(node.parts.catch, node);
|
|
691
|
+
break
|
|
692
|
+
case 'if':
|
|
693
|
+
node.parts.forEach(p => {
|
|
694
|
+
if(p.body) fn(p.body, node);
|
|
695
|
+
});
|
|
696
|
+
if(node.elsePart) fn(node.elsePart, node);
|
|
697
|
+
break
|
|
698
|
+
case 'text':
|
|
699
|
+
case 'comment':
|
|
700
|
+
case 'script':
|
|
701
|
+
case 'style':
|
|
702
|
+
case 'systag':
|
|
703
|
+
case 'template':
|
|
704
|
+
break
|
|
705
|
+
default:
|
|
706
|
+
throw `Not implemented: ${node.type}`;
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
|
|
674
710
|
function compactDOM() {
|
|
675
711
|
let data = this.DOM;
|
|
676
712
|
|
|
@@ -710,29 +746,7 @@
|
|
|
710
746
|
}
|
|
711
747
|
} else {
|
|
712
748
|
if(node.type == 'node' && (node.name == 'pre' || node.name == 'textarea')) continue;
|
|
713
|
-
|
|
714
|
-
case 'node':
|
|
715
|
-
case 'slot':
|
|
716
|
-
case 'block':
|
|
717
|
-
case 'fragment':
|
|
718
|
-
if(node.body) go(node.body, node);
|
|
719
|
-
break
|
|
720
|
-
case 'each':
|
|
721
|
-
if(node.mainBlock) go(node.mainBlock, node);
|
|
722
|
-
if(node.elseBlock) go(node.elseBlock, node);
|
|
723
|
-
break
|
|
724
|
-
case 'await':
|
|
725
|
-
if(node.parts.main) go(node.parts.main, node);
|
|
726
|
-
if(node.parts.then) go(node.parts.then, node);
|
|
727
|
-
if(node.parts.catch) go(node.parts.catch, node);
|
|
728
|
-
break
|
|
729
|
-
case 'if':
|
|
730
|
-
node.parts.forEach(p => {
|
|
731
|
-
if(p.body) go(p.body, node);
|
|
732
|
-
});
|
|
733
|
-
if(node.elsePart) go(node.elsePart, node);
|
|
734
|
-
break
|
|
735
|
-
}
|
|
749
|
+
walk(node, go);
|
|
736
750
|
}
|
|
737
751
|
}
|
|
738
752
|
|
|
@@ -763,8 +777,9 @@
|
|
|
763
777
|
if(prev && next) {
|
|
764
778
|
if(prev.type == 'node' && next.type == 'node') {
|
|
765
779
|
if(isTable(prev) && isTable(next) ||
|
|
766
|
-
|
|
767
|
-
|
|
780
|
+
prev.name == 'li' && next.name == 'li' ||
|
|
781
|
+
parentNode?.type == 'node' && parentNode?.name == 'select' && prev.name == 'option' && next.name == 'option' ||
|
|
782
|
+
prev.name == 'div' && next.name == 'div') {
|
|
768
783
|
body.splice(i, 1);
|
|
769
784
|
continue;
|
|
770
785
|
}
|
|
@@ -785,6 +800,10 @@
|
|
|
785
800
|
body.splice(i, 1);
|
|
786
801
|
continue;
|
|
787
802
|
}
|
|
803
|
+
if((p == 'option' || n == 'option') && (parentNode.type == 'node' && parentNode.name == 'select')) {
|
|
804
|
+
body.splice(i, 1);
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
788
807
|
if(parentNode.type == 'node' && ['div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7'].includes(parentNode.name)) {
|
|
789
808
|
body.splice(i, 1);
|
|
790
809
|
continue;
|
|
@@ -836,6 +855,25 @@
|
|
|
836
855
|
go(data.body);
|
|
837
856
|
}
|
|
838
857
|
|
|
858
|
+
function compactFull() {
|
|
859
|
+
const go = (body) => {
|
|
860
|
+
let i = 0;
|
|
861
|
+
while (i < body.length) {
|
|
862
|
+
let n = body[i];
|
|
863
|
+
if(n.type == 'text') {
|
|
864
|
+
n.value = n.value.trim();
|
|
865
|
+
if(!n.value) {
|
|
866
|
+
body.splice(i, 1);
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
} else walk(n, go);
|
|
870
|
+
i++;
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
walk(this.DOM, go);
|
|
875
|
+
}
|
|
876
|
+
|
|
839
877
|
class Reader {
|
|
840
878
|
constructor(source) {
|
|
841
879
|
if(source instanceof Reader) return source;
|
|
@@ -1277,18 +1315,28 @@
|
|
|
1277
1315
|
assert(step == 0, 'Wrong expression: ' + source);
|
|
1278
1316
|
let staticText = null;
|
|
1279
1317
|
if(!parts.some(p => p.type == 'exp')) staticText = parts.map(p => p.type == 'text' ? p.value : '').join('');
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1318
|
+
|
|
1319
|
+
let pe = {
|
|
1320
|
+
parts,
|
|
1321
|
+
staticText,
|
|
1322
|
+
binding: parts.length == 1 && parts[0].type == 'exp' ? parts[0].value : null,
|
|
1323
|
+
getResult() {
|
|
1324
|
+
let result = [];
|
|
1325
|
+
this.parts.forEach(p => {
|
|
1326
|
+
if(p.type == 'js') return;
|
|
1327
|
+
if(p.type == 'exp') result.push(p);
|
|
1328
|
+
else {
|
|
1329
|
+
let l = last(result);
|
|
1330
|
+
if(l?.type == 'text') l.value += p.value;
|
|
1331
|
+
else result.push({ ...p });
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
return '`' + result.map(p => p.type == 'text' ? Q(p.value) : '${' + p.value + '}').join('') + '`';
|
|
1288
1336
|
}
|
|
1289
|
-
}
|
|
1290
|
-
result =
|
|
1291
|
-
return
|
|
1337
|
+
};
|
|
1338
|
+
pe.result = pe.getResult();
|
|
1339
|
+
return pe;
|
|
1292
1340
|
}
|
|
1293
1341
|
|
|
1294
1342
|
|
|
@@ -1374,7 +1422,7 @@
|
|
|
1374
1422
|
const value = raw.substring(1, raw.length - 1);
|
|
1375
1423
|
result.push({name, value, raw, content: r.sub(start)});
|
|
1376
1424
|
} else {
|
|
1377
|
-
const value = r.readIf(
|
|
1425
|
+
const value = r.readIf(/^[^\s<>]+/);
|
|
1378
1426
|
result.push({name, value, raw: value, content: r.sub(start)});
|
|
1379
1427
|
}
|
|
1380
1428
|
} else {
|
|
@@ -2175,7 +2223,8 @@
|
|
|
2175
2223
|
let bindText = xNode('bindText', {
|
|
2176
2224
|
$wait: ['apply'],
|
|
2177
2225
|
el: textNode.bindName(),
|
|
2178
|
-
exp: pe.result
|
|
2226
|
+
exp: pe.result,
|
|
2227
|
+
parsedExpression: pe
|
|
2179
2228
|
}, (ctx, n) => {
|
|
2180
2229
|
if(this.inuse.apply) {
|
|
2181
2230
|
ctx.writeLine(`$runtime.bindText(${n.el}, () => ${n.exp});`);
|
|
@@ -5722,13 +5771,13 @@
|
|
|
5722
5771
|
|
|
5723
5772
|
if(node.spreading) return node.spreading.push(`${name}: ${exp}`);
|
|
5724
5773
|
|
|
5725
|
-
if(node.name == 'option' && name == 'value') {
|
|
5774
|
+
if(node.name == 'option' && name == 'value' && parsed.binding) {
|
|
5726
5775
|
return {
|
|
5727
5776
|
bind: xNode('bindOptionValue', {
|
|
5728
5777
|
el: element.bindName(),
|
|
5729
|
-
|
|
5778
|
+
value: parsed.binding
|
|
5730
5779
|
}, (ctx, n) => {
|
|
5731
|
-
ctx.write(true, `$runtime.selectOption(${n.el}, () => (${n.
|
|
5780
|
+
ctx.write(true, `$runtime.selectOption(${n.el}, () => (${n.value}));`);
|
|
5732
5781
|
})
|
|
5733
5782
|
}
|
|
5734
5783
|
}
|
|
@@ -5741,6 +5790,7 @@
|
|
|
5741
5790
|
selected: true,
|
|
5742
5791
|
innerHTML: true,
|
|
5743
5792
|
innerText: true,
|
|
5793
|
+
multiple: node.name == 'select',
|
|
5744
5794
|
src: true,
|
|
5745
5795
|
readonly: 'readOnly'
|
|
5746
5796
|
};
|
|
@@ -5748,7 +5798,7 @@
|
|
|
5748
5798
|
let n = xNode('bindAttribute', {
|
|
5749
5799
|
$wait: ['apply'],
|
|
5750
5800
|
name,
|
|
5751
|
-
exp,
|
|
5801
|
+
exp: propList[name] && parsed.binding ? parsed.binding : exp,
|
|
5752
5802
|
hasElement,
|
|
5753
5803
|
el: element.bindName()
|
|
5754
5804
|
}, (ctx, data) => {
|
|
@@ -6822,7 +6872,7 @@
|
|
|
6822
6872
|
});
|
|
6823
6873
|
}
|
|
6824
6874
|
|
|
6825
|
-
const version = '0.7.2-
|
|
6875
|
+
const version = '0.7.2-a12';
|
|
6826
6876
|
|
|
6827
6877
|
|
|
6828
6878
|
async function compile(source, config = {}) {
|
|
@@ -6902,7 +6952,7 @@
|
|
|
6902
6952
|
parseHTML: function() {
|
|
6903
6953
|
this.DOM = parseHTML(this.source);
|
|
6904
6954
|
},
|
|
6905
|
-
compactDOM,
|
|
6955
|
+
compactDOM: config.compact == 'full' ? compactFull : compactDOM,
|
|
6906
6956
|
|
|
6907
6957
|
script: null,
|
|
6908
6958
|
scriptNodes: null,
|
|
@@ -7003,7 +7053,7 @@
|
|
|
7003
7053
|
async function hook(ctx, name) {
|
|
7004
7054
|
for(let i = 0; i < ctx.config.plugins.length; i++) {
|
|
7005
7055
|
const fn = ctx.config.plugins[i][name];
|
|
7006
|
-
if(fn) await fn(ctx);
|
|
7056
|
+
if(fn) await use_context(ctx, () => fn(ctx));
|
|
7007
7057
|
}
|
|
7008
7058
|
}
|
|
7009
7059
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "malinajs",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"prepare": "npm run build",
|
|
7
6
|
"build": "npm run build_runtime && rollup -c",
|
|
8
7
|
"build_runtime": "rollup -c ./rollup.config.runtime.js",
|
|
9
8
|
"build_app": "NODE_PATH=.. rollup -c rollup.config.app.js && uglifyjs ./example/public/app.js -o ./example/public/app.min.js -m -c",
|
|
@@ -39,6 +38,7 @@
|
|
|
39
38
|
"runtime.js",
|
|
40
39
|
"malina-rollup.js",
|
|
41
40
|
"malina-esbuild.js",
|
|
42
|
-
"plugins/sass.js"
|
|
41
|
+
"plugins/sass.js",
|
|
42
|
+
"plugins/static-text.js"
|
|
43
43
|
]
|
|
44
44
|
}
|
package/plugins/sass.js
CHANGED
|
@@ -8,17 +8,35 @@ module.exports = function sassPlugin() {
|
|
|
8
8
|
let type = node.attributes.filter(a => a.name == 'type' || a.name == 'lang')[0];
|
|
9
9
|
if(!type || type.value != 'sass' && type.value != 'scss') continue;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
let sass;
|
|
12
|
+
try {
|
|
13
|
+
sass = require('sass');
|
|
14
|
+
} catch (e) {
|
|
15
|
+
if(e.code == 'MODULE_NOT_FOUND') sass = require('node-sass');
|
|
16
|
+
else throw e;
|
|
17
|
+
}
|
|
12
18
|
node.content = await (new Promise((resolve, reject) => {
|
|
13
|
-
sass.render
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
if(sass.render) {
|
|
20
|
+
sass.render({ // node-sass
|
|
21
|
+
file: ctx.config.path,
|
|
22
|
+
data: node.content,
|
|
23
|
+
indentedSyntax: type.value == 'sass'
|
|
24
|
+
}, function(e, result) {
|
|
25
|
+
if(e) return reject(e);
|
|
26
|
+
resolve(result.css.toString());
|
|
27
|
+
type.value = 'css';
|
|
28
|
+
});
|
|
29
|
+
} else {
|
|
30
|
+
sass.compileStringAsync(node.content, {
|
|
31
|
+
syntax: type.value == 'sass' ? 'indented' : 'scss',
|
|
32
|
+
url: 'file://' + ctx.config.path
|
|
33
|
+
}).then((r) => {
|
|
34
|
+
resolve(r.css);
|
|
35
|
+
}, (e) => {
|
|
36
|
+
console.error('SCSS Error', e);
|
|
37
|
+
reject(e);
|
|
38
|
+
})
|
|
39
|
+
}
|
|
22
40
|
}));
|
|
23
41
|
};
|
|
24
42
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = function staticTextPlugin() {
|
|
3
|
+
/*
|
|
4
|
+
Build static text for text binding
|
|
5
|
+
Usage: {=variable}
|
|
6
|
+
*/
|
|
7
|
+
return {
|
|
8
|
+
name: 'static-text',
|
|
9
|
+
'build:before': (ctx) => {
|
|
10
|
+
const walk = (n) => {
|
|
11
|
+
if (!n) return;
|
|
12
|
+
|
|
13
|
+
// Modify AST-node
|
|
14
|
+
if (n.$type == 'bindText') {
|
|
15
|
+
let hasStatic, hasDynamic;
|
|
16
|
+
n.parsedExpression.parts.forEach(p => {
|
|
17
|
+
if(p.type == 'exp') {
|
|
18
|
+
if(p.value[0] == '=') {
|
|
19
|
+
p.value = p.value.substring(1);
|
|
20
|
+
hasStatic = true;
|
|
21
|
+
} else hasDynamic = true;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if(hasStatic) n.exp = n.parsedExpression.getResult();
|
|
26
|
+
|
|
27
|
+
if(hasStatic && !hasDynamic) {
|
|
28
|
+
n.$handler = function (ctx, n) {
|
|
29
|
+
ctx.write(true, `${n.el}.textContent = ${n.exp};`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// traversal AST
|
|
35
|
+
if (Array.isArray(n)) n.forEach(walk);
|
|
36
|
+
else if (n.$type) {
|
|
37
|
+
for (let k in n) {
|
|
38
|
+
if (k[0] == '$') continue;
|
|
39
|
+
walk(n[k]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
walk(ctx.module.body);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
package/runtime.js
CHANGED
|
@@ -28,10 +28,10 @@ const safeGroupCall = list => {
|
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
const safeGroupCall2 = (list, resultList) => {
|
|
31
|
+
const safeGroupCall2 = (list, resultList, onlyFunction) => {
|
|
32
32
|
list?.forEach(fn => {
|
|
33
33
|
let r = safeCall(fn);
|
|
34
|
-
r && resultList.push(r);
|
|
34
|
+
r && (!onlyFunction || isFunction(r)) && resultList.push(r);
|
|
35
35
|
});
|
|
36
36
|
};
|
|
37
37
|
|
|
@@ -895,7 +895,7 @@ function ifBlock(label, fn, parts, parentLabel) {
|
|
|
895
895
|
} else first = last = $dom;
|
|
896
896
|
if(parentLabel) label.appendChild($dom);
|
|
897
897
|
else label.parentNode.insertBefore($dom, label);
|
|
898
|
-
safeGroupCall2(mountList, destroyList);
|
|
898
|
+
safeGroupCall2(mountList, destroyList, 1);
|
|
899
899
|
}
|
|
900
900
|
|
|
901
901
|
function destroyBlock() {
|
|
@@ -969,7 +969,7 @@ function awaitBlock(label, parentLabel, relation, fn, build_main, build_then, bu
|
|
|
969
969
|
} else first = last = $dom;
|
|
970
970
|
if(parentLabel) label.appendChild($dom);
|
|
971
971
|
else label.parentNode.insertBefore($dom, label);
|
|
972
|
-
safeGroupCall2(mountList, destroyList);
|
|
972
|
+
safeGroupCall2(mountList, destroyList, 1);
|
|
973
973
|
cd_component(parentCD).$apply();
|
|
974
974
|
}
|
|
975
975
|
|
|
@@ -1026,7 +1026,7 @@ const makeEachElseBlock = (fn) => {
|
|
|
1026
1026
|
} else first = last = $dom;
|
|
1027
1027
|
cd_attach(parentCD, $cd);
|
|
1028
1028
|
parentNode.insertBefore($dom, mode ? null : label);
|
|
1029
|
-
safeGroupCall2(current_mountList, destroyList);
|
|
1029
|
+
safeGroupCall2(current_mountList, destroyList, 1);
|
|
1030
1030
|
} finally {
|
|
1031
1031
|
current_destroyList = current_mountList = current_cd = null;
|
|
1032
1032
|
}
|
|
@@ -1187,7 +1187,7 @@ function $$eachBlock(label, mode, fn, getKey, bind, buildElseBlock) {
|
|
|
1187
1187
|
} else ctx.first = ctx.last = $dom;
|
|
1188
1188
|
parentNode.insertBefore($dom, nextNode);
|
|
1189
1189
|
nextNode = ctx.first;
|
|
1190
|
-
safeGroupCall2(m, d);
|
|
1190
|
+
safeGroupCall2(m, d, 1);
|
|
1191
1191
|
if(d.length) {
|
|
1192
1192
|
ctx.d = d;
|
|
1193
1193
|
p_destroy = 1;
|
|
@@ -1287,26 +1287,51 @@ const keepAlive = (store, keyFn, builder) => {
|
|
|
1287
1287
|
|
|
1288
1288
|
const selectElement = (el, getter, setter) => {
|
|
1289
1289
|
addEvent(el, 'change', () => {
|
|
1290
|
-
let
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1290
|
+
let value = [];
|
|
1291
|
+
el.querySelectorAll(':checked').forEach(o => {
|
|
1292
|
+
value.push(o.$$value ? o.$$value() : o.value);
|
|
1293
|
+
});
|
|
1294
|
+
value = el.multiple ? value : value[0];
|
|
1295
|
+
setter(value);
|
|
1296
|
+
w.value = value;
|
|
1296
1297
|
});
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1298
|
+
const update = () => {
|
|
1299
|
+
let value = w.value;
|
|
1300
|
+
if(el.multiple) {
|
|
1301
|
+
if(isArray(value)) {
|
|
1302
|
+
for(let o of el.options) {
|
|
1303
|
+
const option_value = o.$$value ? o.$$value() : o.value;
|
|
1304
|
+
o.selected = value.indexOf(option_value) != -1;
|
|
1305
|
+
}
|
|
1301
1306
|
return;
|
|
1302
1307
|
}
|
|
1308
|
+
} else {
|
|
1309
|
+
for(let o of el.options) {
|
|
1310
|
+
if((o.$$value ? o.$$value() : o.value) === value) {
|
|
1311
|
+
o.selected = true;
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1303
1315
|
}
|
|
1304
1316
|
el.selectedIndex = -1;
|
|
1305
|
-
}
|
|
1317
|
+
};
|
|
1318
|
+
const w = $watch(getter, update);
|
|
1319
|
+
|
|
1320
|
+
let debounce = 0;
|
|
1321
|
+
el.$$update = () => {
|
|
1322
|
+
if(debounce) return;
|
|
1323
|
+
debounce = 1;
|
|
1324
|
+
$tick(() => {
|
|
1325
|
+
debounce = 0;
|
|
1326
|
+
update();
|
|
1327
|
+
});
|
|
1328
|
+
};
|
|
1306
1329
|
};
|
|
1307
1330
|
|
|
1308
1331
|
const selectOption = (op, getter) => {
|
|
1309
1332
|
op.$$value = getter;
|
|
1333
|
+
if(op.parentElement?.$$update) op.parentElement.$$update();
|
|
1334
|
+
else $tick(() => op.parentElement?.$$update?.());
|
|
1310
1335
|
};
|
|
1311
1336
|
|
|
1312
1337
|
const radioButton = (el, getValue, getter, setter) => {
|
package/CHANGELOG.md
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
## 0.7.x
|
|
3
|
-
* refactoring, optimization, fixes
|
|
4
|
-
* export function
|
|
5
|
-
* manual event delegation @click|root
|
|
6
|
-
* able to delay destroying block (for animations)
|
|
7
|
-
* be able to off autosubscribe for import: !no-autosubscribe
|
|
8
|
-
* destructuring array/object for each
|
|
9
|
-
* functions mount, mountStatic
|
|
10
|
-
* each, index variable is not included by default
|
|
11
|
-
* reference to element is removed on destroying
|
|
12
|
-
* config.useGroupReferencing
|
|
13
|
-
* action can return destroy function (not only object)
|
|
14
|
-
* each-else
|
|
15
|
-
* else-if
|
|
16
|
-
* refactoring $onMount
|
|
17
|
-
* optional deep checking for passed props: prop={value} prop|deep={value}
|
|
18
|
-
* keep-alive
|
|
19
|
-
* malina:self
|
|
20
|
-
* handler for element "select"
|
|
21
|
-
* handler for "radio" input
|
|
22
|
-
|
|
23
|
-
## 0.6.x
|
|
24
|
-
|
|
25
|
-
* style's attribute "global"
|
|
26
|
-
* compound classes (handle mix of class and class directives)
|
|
27
|
-
* new passing class
|
|
28
|
-
* mark a class as external "$className"
|
|
29
|
-
* Deprecated: passing class from 0.5
|
|
30
|
-
* plugins
|
|
31
|
-
* esbuild-plugin (by AlexxNB)
|
|
32
|
-
* $context
|
|
33
|
-
* onError
|
|
34
|
-
* $onMount
|
|
35
|
-
* $onDestroy
|
|
36
|
-
* alias for import: malinajs -> malinajs/runtime.js
|
|
37
|
-
* alias @click -> @click={click}, @@click is forwarding
|
|
38
|
-
* local config "malina.config.js"
|
|
39
|
-
* plugin sass/scss
|
|
40
|
-
* key "auto" for each-block
|
|
41
|
-
* anchors for components
|
|
42
|
-
* style templates, e.g. style:color={color}, style:border-color="red", style:border="1px solid {color}"
|
|
43
|
-
* compile option "css"
|
|
44
|
-
* event modifier: stop, prevent
|
|
45
|
-
* script option "read-only"
|
|
46
|
-
* constant props - "export const prop;"
|
|
47
|
-
* compile option: debugLabel
|
|
48
|
-
* slot for fragment
|
|
49
|
-
* exported fragments (inverted slots)
|
|
50
|
-
* <malina:head>, <malina:body>, <malina:window>
|
|
51
|
-
* option: passClass
|
|
52
|
-
* option: immutable
|
|
53
|
-
* event modifiers: prevent, stop, ctrl, alt, shift, meta. key-events: enter, tab, esc, space, up, down, left, right, delete
|
|
54
|
-
* inline actions for text-node and elements
|
|
55
|
-
* portals: <malina:portal>
|
|
56
|
-
* autoimport
|
|
57
|
-
|
|
58
|
-
## 0.5.x
|
|
59
|
-
|
|
60
|
-
* input with type "range"/"number" - value as number
|
|
61
|
-
* improve reactive expression
|
|
62
|
-
* unwrap object in each
|
|
63
|
-
* dynamic component
|
|
64
|
-
* named slot
|
|
65
|
-
* fix for dynamic import
|
|
66
|
-
* option.onerror
|
|
67
|
-
* autosubscribe for imported objects
|
|
68
|
-
* compile time optinoption !no-check
|
|
69
|
-
* fragments
|
|
70
|
-
* event modifier: stopPropagation
|
|
71
|
-
* $props, $attributes, $restProps
|
|
72
|
-
* await-then-catch
|
|
73
|
-
* :global classes
|
|
74
|
-
* spreading props and objects {...obj}
|
|
75
|
-
* forwarding events, forward all @@
|
|
76
|
-
* onMount, onDestroy, $onDestroy
|
|
77
|
-
* shortcuts for bindings and actions
|
|
78
|
-
* scoped-css
|
|
79
|
-
* conrol directives: each, if
|