malinajs 0.7.0-a11 → 0.7.0-a14

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]);
@@ -5117,7 +5140,7 @@
5117
5140
  return {
5118
5141
  bind: xNode('block', {
5119
5142
  body: [
5120
- replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null)
5143
+ replaceKeyword(exp, (name) => name == '$element' ? element.bindName() : null, true)
5121
5144
  ]
5122
5145
  })
5123
5146
  };
@@ -5600,7 +5623,7 @@
5600
5623
  ctx.write(true, `}`);
5601
5624
  }
5602
5625
  ctx.write(`, [`);
5603
- n.elseBlock && n.parts.push({block: n.elseBlock});
5626
+ n.elseBlock && n.parts.push({ block: n.elseBlock });
5604
5627
  n.parts.forEach((p, i) => {
5605
5628
  if(i) ctx.write(', ');
5606
5629
  ctx.add(p.block);
@@ -6429,7 +6452,7 @@
6429
6452
  exp = unwrapExp(prop.value);
6430
6453
  exp = replaceKeyword(exp, (name) => {
6431
6454
  if(name == '$element') return requireElement();
6432
- });
6455
+ }, true);
6433
6456
  } else if(!handler) handler = event;
6434
6457
 
6435
6458
  this.detectDependency(exp || handler);
@@ -6528,7 +6551,7 @@
6528
6551
  return { event, fn, rootModifier };
6529
6552
  }
6530
6553
 
6531
- const version = '0.7.0-a11';
6554
+ const version = '0.7.0-a14';
6532
6555
 
6533
6556
 
6534
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-a11",
3
+ "version": "0.7.0-a14",
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
@@ -18,14 +18,22 @@ const safeCall = fn => {
18
18
 
19
19
  const safeGroupCall = list => {
20
20
  try {
21
- list.forEach(fn => fn?.());
21
+ list?.forEach(fn => fn?.());
22
22
  } catch (e) {
23
23
  __app_onerror(e);
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
  };
@@ -440,7 +445,7 @@ const callComponent = (context, component, option = {}, propFn, cmp, setter, cla
440
445
  const attachDynComponent = (label, exp, bind) => {
441
446
  let parentCD = current_cd;
442
447
  let active, destroyList, $cd, $dom, finalLabel = getFinalLabel(label);
443
- const destroy = () => destroyList && safeGroupCall(destroyList);
448
+ const destroy = () => safeGroupCall(destroyList);
444
449
  $onDestroy(destroy);
445
450
 
446
451
  $watch(exp, (component) => {
@@ -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
 
@@ -1026,6 +1040,7 @@ const makeEachElseBlock = (fn) => {
1026
1040
  let first, last;
1027
1041
  let destroyList = current_destroyList = [];
1028
1042
  let $cd = current_cd = cd_new();
1043
+ current_mountList = [];
1029
1044
  try {
1030
1045
  let $dom = fn();
1031
1046
  if($dom.nodeType == 11) {
@@ -1035,17 +1050,17 @@ const makeEachElseBlock = (fn) => {
1035
1050
  cd_attach2(parentCD, $cd);
1036
1051
  if(onlyChild) label.appendChild($dom);
1037
1052
  else attachBlock(label, $dom);
1053
+ safeCallMount(current_mountList, destroyList);
1038
1054
  } finally {
1039
- current_destroyList = null;
1040
- current_cd = null;
1055
+ current_destroyList = current_mountList = current_cd = null;
1041
1056
  }
1042
1057
 
1043
1058
  return () => {
1044
1059
  $$removeElements(first, last);
1045
1060
  cd_detach($cd);
1046
1061
  safeGroupCall(destroyList);
1047
- }
1048
- }
1062
+ };
1063
+ };
1049
1064
  };
1050
1065
 
1051
1066
 
@@ -1119,7 +1134,7 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1119
1134
  ctx.$cd && eachCD.children.push(ctx.$cd);
1120
1135
  return;
1121
1136
  }
1122
- ctx.d && safeGroupCall(ctx.d);
1137
+ safeGroupCall(ctx.d);
1123
1138
  iterNodes(ctx.first, ctx.last, n => removedNodes.push(n));
1124
1139
  });
1125
1140
 
@@ -1176,22 +1191,25 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1176
1191
  } else {
1177
1192
  let $dom, rebind,
1178
1193
  d = current_destroyList = [],
1194
+ m = current_mountList = [],
1179
1195
  $cd = current_cd = cd_new();
1180
1196
  try {
1181
1197
  ([$dom, rebind] = bind(item, i));
1182
1198
  } finally {
1183
- current_destroyList = null;
1184
- current_cd = null;
1199
+ current_destroyList = current_mountList = current_cd = null;
1185
1200
  }
1186
- if(d.length) p_destroy = 1;
1187
- else d = null;
1188
- ctx = { $cd, d, rebind };
1201
+ ctx = { $cd, rebind };
1189
1202
  cd_attach2(eachCD, $cd);
1190
1203
  if($dom.nodeType == 11) {
1191
1204
  ctx.first = $dom.firstChild;
1192
1205
  ctx.last = $dom.lastChild;
1193
1206
  } else ctx.first = ctx.last = $dom;
1194
1207
  parentNode.insertBefore($dom, prevNode?.nextSibling);
1208
+ safeCallMount(m, d);
1209
+ if(d.length) {
1210
+ ctx.d = d;
1211
+ p_destroy = 1;
1212
+ }
1195
1213
  }
1196
1214
  prevNode = ctx.last;
1197
1215
  newMapping.set(key, ctx);
@@ -1245,4 +1263,4 @@ const makeSlot = (fr, fn) => {
1245
1263
  };
1246
1264
  };
1247
1265
 
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 };
1266
+ 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 };