malinajs 0.7.0-a10 → 0.7.0-a13

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/CHANGELOG.md CHANGED
@@ -12,6 +12,8 @@
12
12
  * config.useGroupReferencing
13
13
  * action can return destroy function (not only object)
14
14
  * each-else
15
+ * else-if
16
+ * refactoring $onMount
15
17
 
16
18
  ## 0.6.x
17
19
 
package/malina.js CHANGED
@@ -36,9 +36,10 @@
36
36
  }
37
37
 
38
38
  function toCamelCase(name) {
39
- assert(name[name.length - 1] !== '-', 'Wrong name');
40
- return name.replace(/(?<!-)(\-\w)/g, function(part) {
41
- return part[1].toUpperCase();
39
+ assert(last(name) !== '-', 'Wrong name');
40
+ return name.replace(/(.\-\w)/g, function(part) {
41
+ if(part[0] == '-') return part;
42
+ return part[0] + part[2].toUpperCase();
42
43
  });
43
44
  }
44
45
 
@@ -71,7 +72,7 @@
71
72
  function detectExpressionType(name) {
72
73
  if(isSimpleName(name)) return 'identifier';
73
74
 
74
- let ast = acorn.parse(name, { allowReturnOutsideFunction: true });
75
+ let ast = acorn.parse(name, { allowReturnOutsideFunction: true, ecmaVersion: 'latest' });
75
76
 
76
77
  function checkIdentificator(body) {
77
78
  if(body.length != 1) return;
@@ -138,7 +139,7 @@
138
139
 
139
140
 
140
141
  const extractKeywords = (exp) => {
141
- let ast = acorn.parse(exp, { sourceType: 'module', ecmaVersion: 12 });
142
+ let ast = acorn.parse(exp, { sourceType: 'module', ecmaVersion: 12, ecmaVersion: 'latest' });
142
143
 
143
144
  const keys = new Set();
144
145
  const rec = (n) => {
@@ -179,9 +180,9 @@
179
180
  };
180
181
 
181
182
 
182
- const replaceKeyword = (exp, fn) => {
183
+ const replaceKeyword = (exp, fn, option) => {
183
184
  let changed = false;
184
- let r = parseJS(exp).transform((n, pk) => {
185
+ let r = parseJS(exp, option).transform((n, pk) => {
185
186
  if(n.type != 'Identifier') return;
186
187
  if(pk == 'property' || pk == 'params') return;
187
188
  let name = fn(n.name);
@@ -194,9 +195,10 @@
194
195
  };
195
196
 
196
197
 
197
- const parseJS = (exp) => {
198
+ const parseJS = (exp, option) => {
198
199
  let self = {};
199
- self.ast = acorn.parseExpressionAt(exp, 0, { ecmaVersion: 12 });
200
+ if(option === true) self.ast = acorn.parse(exp, { ecmaVersion: 'latest' });
201
+ else self.ast = acorn.parseExpressionAt(exp, 0, { ecmaVersion: 'latest' });
200
202
 
201
203
  self.transform = function(fn) {
202
204
  const rec = (n, pk) => {
@@ -931,6 +933,22 @@
931
933
  const readScript = (tag) => {
932
934
  let endTag = `</${tag}>`;
933
935
  let q, a, p, start = index;
936
+
937
+ const readRegExp = () => {
938
+ while(true) {
939
+ p = a;
940
+ a = readNext();
941
+ if(q) {
942
+ if(a != q) continue;
943
+ if(p == '\\') continue;
944
+ q = null;
945
+ continue;
946
+ }
947
+ if(a == '[' && p != '\\') q = ']';
948
+ if(a == '/' && p != '\\') return;
949
+ }
950
+ };
951
+
934
952
  while(true) {
935
953
  p = a;
936
954
  a = readNext();
@@ -944,6 +962,10 @@
944
962
  q = a;
945
963
  continue;
946
964
  }
965
+ if(a == '/') {
966
+ readRegExp();
967
+ continue;
968
+ }
947
969
  if(a == '<') {
948
970
  if(source.substring(index - 1, index + endTag.length - 1) == endTag) {
949
971
  let end = index - 1;
@@ -1039,7 +1061,7 @@
1039
1061
 
1040
1062
  while(index < source.length) {
1041
1063
  let a = source[index];
1042
- if(a === '<' && source[index+1].match(/\S/)) {
1064
+ if(a === '<' && source[index + 1].match(/\S/)) {
1043
1065
  flushText();
1044
1066
 
1045
1067
  if(source.substring(index, index + 4) === '<!--') {
@@ -1154,7 +1176,7 @@
1154
1176
  let tag = {
1155
1177
  type: 'await',
1156
1178
  value: bind.value,
1157
- parts: {main: []}
1179
+ parts: { main: [] }
1158
1180
  };
1159
1181
  push(tag);
1160
1182
  go(tag, n => tag.parts.main.push(n));
@@ -1314,7 +1336,7 @@
1314
1336
  if(isBlockComment) return;
1315
1337
  this.script.comments.push({ start, end, value });
1316
1338
  };
1317
- this.script.ast = acorn.parse(source, { sourceType: 'module', ecmaVersion: 12, onComment });
1339
+ this.script.ast = acorn.parse(source, { sourceType: 'module', ecmaVersion: 'latest', onComment });
1318
1340
 
1319
1341
  if(source.includes('$props')) this.require('$props');
1320
1342
  if(source.includes('$attributes')) this.require('$attributes');
@@ -2025,7 +2047,7 @@
2025
2047
  if(!exp.endsWith(';')) exp += ';';
2026
2048
  binds.push(xNode('block', {
2027
2049
  body: [
2028
- replaceKeyword(exp, (name) => name == '$element' ? textNode.bindName() : null)
2050
+ replaceKeyword(exp, (name) => name == '$element' ? textNode.bindName() : null, true)
2029
2051
  ]
2030
2052
  }));
2031
2053
  });
@@ -2256,7 +2278,7 @@
2256
2278
 
2257
2279
  if(node.children?.length) {
2258
2280
  let i = node.children.length - 1;
2259
- for(;i >= 0;i--) {
2281
+ for(;i >= 0; i--) {
2260
2282
  let n = node.children[i];
2261
2283
 
2262
2284
  if(mark(n)) {
@@ -2378,7 +2400,8 @@
2378
2400
  }
2379
2401
  } else {
2380
2402
  if(n._boundName) {
2381
- ctx.write(true, `let ${n._boundName} = ${base._boundName}`);
2403
+ if(base) ctx.write(true, `let ${n._boundName} = ${base._boundName}`);
2404
+ else ctx.write(true, `let ${n._boundName} = ${path.join('.')}.firstChild`);
2382
2405
  while(shift--) ctx.write('.nextSibling');
2383
2406
  ctx.write(';');
2384
2407
  walk(n, [n._boundName]);
@@ -4607,12 +4630,16 @@
4607
4630
  function makeDom(data) {
4608
4631
  function build(parent, list) {
4609
4632
  list.forEach(e => {
4610
- if(e.type == 'each' || e.type == 'fragment' || e.type == 'slot') {
4633
+ if(e.type == 'fragment' || e.type == 'slot') {
4611
4634
  if(e.body && e.body.length) build(parent, e.body);
4612
4635
  return;
4636
+ } else if(e.type == 'each') {
4637
+ build(parent, e.mainBlock);
4638
+ e.elseBlock?.length && build(parent, e.elseBlock);
4639
+ return;
4613
4640
  } else if(e.type == 'if') {
4614
- if(e.bodyMain && e.bodyMain.length) build(parent, e.bodyMain);
4615
- if(e.body && e.body.length) build(parent, e.body);
4641
+ e.parts.forEach(p => build(parent, p.body));
4642
+ e.elsePart?.length && build(parent, e.elsePart);
4616
4643
  return;
4617
4644
  } else if(e.type == 'await') {
4618
4645
  if(e.parts.main && e.parts.main.length) build(parent, e.parts.main);
@@ -5113,7 +5140,7 @@
5113
5140
  return {
5114
5141
  bind: xNode('block', {
5115
5142
  body: [
5116
- replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null)
5143
+ replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null, true)
5117
5144
  ]
5118
5145
  })
5119
5146
  };
@@ -5596,7 +5623,7 @@
5596
5623
  ctx.write(true, `}`);
5597
5624
  }
5598
5625
  ctx.write(`, [`);
5599
- n.elseBlock && n.parts.push({block: n.elseBlock});
5626
+ n.elseBlock && n.parts.push({ block: n.elseBlock });
5600
5627
  n.parts.forEach((p, i) => {
5601
5628
  if(i) ctx.write(', ');
5602
5629
  ctx.add(p.block);
@@ -6425,7 +6452,7 @@
6425
6452
  exp = unwrapExp(prop.value);
6426
6453
  exp = replaceKeyword(exp, (name) => {
6427
6454
  if(name == '$element') return requireElement();
6428
- });
6455
+ }, true);
6429
6456
  } else if(!handler) handler = event;
6430
6457
 
6431
6458
  this.detectDependency(exp || handler);
@@ -6524,7 +6551,7 @@
6524
6551
  return { event, fn, rootModifier };
6525
6552
  }
6526
6553
 
6527
- const version = '0.7.0-a10';
6554
+ const version = '0.7.0-a13';
6528
6555
 
6529
6556
 
6530
6557
  async function compile(source, config = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "malinajs",
3
- "version": "0.7.0-a10",
3
+ "version": "0.7.0-a13",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "prepare": "npm run build",
@@ -16,8 +16,8 @@
16
16
  "fix": "npx standardx --fix ./src/"
17
17
  },
18
18
  "dependencies": {
19
- "acorn": "^7.3.1",
20
- "astring": "^1.8.1",
19
+ "acorn": "^8.7.1",
20
+ "astring": "^1.8.3",
21
21
  "css-tree": "^1.0.0-alpha.39"
22
22
  },
23
23
  "devDependencies": {
package/runtime.js CHANGED
@@ -24,8 +24,16 @@ const safeGroupCall = list => {
24
24
  }
25
25
  };
26
26
 
27
- let current_destroyList, current_cd, destroyResults;
27
+ const safeCallMount = (mountList, destroyList) => {
28
+ mountList.forEach(fn => {
29
+ let r = safeCall(fn);
30
+ r && destroyList.push(r);
31
+ });
32
+ };
33
+
34
+ let current_destroyList, current_mountList, current_cd, destroyResults;
28
35
  const $onDestroy = fn => fn && current_destroyList.push(fn);
36
+ const $onMount = fn => current_mountList.push(fn);
29
37
 
30
38
  function WatchObject(fn, cb) {
31
39
  this.fn = fn;
@@ -341,7 +349,6 @@ function $$addEventForComponent(list, event, fn) {
341
349
 
342
350
 
343
351
  let current_component, $context;
344
- const $onMount = fn => current_component._m.push(fn);
345
352
 
346
353
 
347
354
  const makeApply = () => {
@@ -378,8 +385,7 @@ const makeComponent = (init) => {
378
385
  $component = current_component = {
379
386
  $option,
380
387
  context: $context,
381
- exported: {},
382
- _m: []
388
+ exported: {}
383
389
  };
384
390
  current_cd = null;
385
391
 
@@ -391,7 +397,6 @@ const makeComponent = (init) => {
391
397
  current_cd = prev_cd;
392
398
  }
393
399
 
394
- $component._m.forEach(fn => $onDestroy(safeCall(fn)));
395
400
  return $component;
396
401
  };
397
402
  };
@@ -545,7 +550,7 @@ const bindAction = (element, action, fn, subscribe) => {
545
550
  else {
546
551
  $onDestroy(handler?.destroy);
547
552
  subscribe?.(fn, handler, value);
548
- handler?.init && $tick(handler.init);
553
+ handler?.init && $onMount(handler.init);
549
554
  }
550
555
  };
551
556
 
@@ -796,6 +801,7 @@ const makeRootEvent = (root) => {
796
801
 
797
802
  const mount = (label, component, option) => {
798
803
  let app, first, last, destroyList = current_destroyList = [];
804
+ current_mountList = [];
799
805
  try {
800
806
  app = component(option);
801
807
  let $dom = app.$dom;
@@ -805,8 +811,10 @@ const mount = (label, component, option) => {
805
811
  last = $dom.lastChild;
806
812
  } else first = last = $dom;
807
813
  label.appendChild($dom);
814
+ safeCallMount(current_mountList, destroyList);
808
815
  } finally {
809
816
  current_destroyList = null;
817
+ current_mountList = null;
810
818
  }
811
819
  app.destroy = () => {
812
820
  safeGroupCall(destroyList);
@@ -817,12 +825,15 @@ const mount = (label, component, option) => {
817
825
 
818
826
  const mountStatic = (label, component, option) => {
819
827
  current_destroyList = [];
828
+ current_mountList = [];
820
829
  try {
821
830
  let app = component(option);
822
831
  label.appendChild(app.$dom);
832
+ safeGroupCall(current_mountList);
823
833
  return app;
824
834
  } finally {
825
835
  current_destroyList = null;
836
+ current_mountList = null;
826
837
  }
827
838
  };
828
839
 
@@ -900,11 +911,13 @@ function ifBlock(label, fn, parts, parentLabel) {
900
911
  function createBlock(builder) {
901
912
  let $dom;
902
913
  destroyList = current_destroyList = [];
914
+ let mountList = current_mountList = [];
903
915
  $cd = current_cd = cd_new();
904
916
  try {
905
917
  $dom = builder();
906
918
  } finally {
907
919
  current_destroyList = null;
920
+ current_mountList = null;
908
921
  current_cd = null;
909
922
  }
910
923
  cd_attach2(parentCD, $cd);
@@ -914,6 +927,7 @@ function ifBlock(label, fn, parts, parentLabel) {
914
927
  } else first = last = $dom;
915
928
  if(parentLabel) label.appendChild($dom);
916
929
  else insertAfter(label, $dom);
930
+ safeCallMount(mountList, destroyList);
917
931
  }
918
932
 
919
933
  function destroyBlock() {
@@ -970,12 +984,11 @@ function $$awaitBlock(label, relation, fn, build_main, build_then, build_catch)
970
984
  if(!builder) return;
971
985
  destroyList = current_destroyList = [];
972
986
  $cd = current_cd = cd_new();
973
- let $dom;
987
+ let $dom, mountList = current_mountList = [];
974
988
  try {
975
989
  $dom = builder(value);
976
990
  } finally {
977
- current_destroyList = null;
978
- current_cd = null;
991
+ current_destroyList = current_mountList = current_cd = null;
979
992
  }
980
993
  cd_attach2(parentCD, $cd);
981
994
  if($dom.nodeType == 11) {
@@ -983,6 +996,7 @@ function $$awaitBlock(label, relation, fn, build_main, build_then, build_catch)
983
996
  last = $dom.lastChild;
984
997
  } else first = last = $dom;
985
998
  insertAfter(label, $dom);
999
+ safeCallMount(mountList, destroyList);
986
1000
  cd_component(parentCD).apply();
987
1001
  }
988
1002
 
@@ -1044,8 +1058,8 @@ const makeEachElseBlock = (fn) => {
1044
1058
  $$removeElements(first, last);
1045
1059
  cd_detach($cd);
1046
1060
  safeGroupCall(destroyList);
1047
- }
1048
- }
1061
+ };
1062
+ };
1049
1063
  };
1050
1064
 
1051
1065
 
@@ -1176,22 +1190,25 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1176
1190
  } else {
1177
1191
  let $dom, rebind,
1178
1192
  d = current_destroyList = [],
1193
+ m = current_mountList = [],
1179
1194
  $cd = current_cd = cd_new();
1180
1195
  try {
1181
1196
  ([$dom, rebind] = bind(item, i));
1182
1197
  } finally {
1183
- current_destroyList = null;
1184
- current_cd = null;
1198
+ current_destroyList = current_mountList = current_cd = null;
1185
1199
  }
1186
- if(d.length) p_destroy = 1;
1187
- else d = null;
1188
- ctx = { $cd, d, rebind };
1200
+ ctx = { $cd, rebind };
1189
1201
  cd_attach2(eachCD, $cd);
1190
1202
  if($dom.nodeType == 11) {
1191
1203
  ctx.first = $dom.firstChild;
1192
1204
  ctx.last = $dom.lastChild;
1193
1205
  } else ctx.first = ctx.last = $dom;
1194
1206
  parentNode.insertBefore($dom, prevNode?.nextSibling);
1207
+ safeCallMount(m, d);
1208
+ if(d.length) {
1209
+ ctx.d = d;
1210
+ p_destroy = 1;
1211
+ }
1195
1212
  }
1196
1213
  prevNode = ctx.last;
1197
1214
  newMapping.set(key, ctx);
@@ -1245,4 +1262,4 @@ const makeSlot = (fr, fn) => {
1245
1262
  };
1246
1263
  };
1247
1264
 
1248
- 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, cloneDeep, configure, createTextNode, current_cd, current_component, current_destroyList, destroyResults, eachDefaultKey, exportFragment, fire, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachElseBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, mergeAllEvents, mergeEvents, mount, mountStatic, noop, prefixPush, refer, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };
1265
+ 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, cloneDeep, configure, createTextNode, current_cd, current_component, current_destroyList, current_mountList, destroyResults, eachDefaultKey, exportFragment, fire, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachElseBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, mergeAllEvents, mergeEvents, mount, mountStatic, noop, prefixPush, refer, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };