malinajs 0.7.0-alpha → 0.7.1-alpha

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 CHANGED
@@ -6122,7 +6122,7 @@
6122
6122
  return {event, fn, rootModifier};
6123
6123
  }
6124
6124
 
6125
- const version = '0.7.0-alpha';
6125
+ const version = '0.7.1-alpha';
6126
6126
 
6127
6127
 
6128
6128
  async function compile(source, config = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "malinajs",
3
- "version": "0.7.0-alpha",
3
+ "version": "0.7.1-alpha",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "prepare": "npm run build",
@@ -34,7 +34,6 @@
34
34
  "main": "malina",
35
35
  "files": [
36
36
  "malina.js",
37
- "compile.js",
38
37
  "runtime.js",
39
38
  "malina-rollup.js",
40
39
  "malina-esbuild.js",
package/readme.md CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  ## Malina.js
3
3
 
4
- <img align="right" width="200" height="200" src="malinajs2.png" />
4
+ <img align="right" width="200" height="200" src="https://github.com/malinajs/malinajs/raw/master/malinajs2.png" />
5
5
 
6
6
  Malina.js builds your web-application to use it **without framework on frontend side**. Therefore your web-app becomes thinner and faster, and the application itself consist of **vanilla JavaScript**, look at [examples](https://malinajs.github.io/repl/). [TodoMVC example](https://malina-todomvc.surge.sh) **2.7kb** (gzipped) and [source code](https://github.com/malinajs/todomvc)
7
7
 
package/runtime.js CHANGED
@@ -86,11 +86,16 @@ const cd_attach = (parent, cd) => {
86
86
  }
87
87
  };
88
88
 
89
+ let destroyResults = null;
90
+
89
91
  const cd_destroy$1 = (cd, option) => {
90
92
  if(option !== false && cd.parent) $$removeItem(cd.parent.children, cd);
91
93
  cd.watchers.length = 0;
92
94
  cd.prefix.length = 0;
93
- cd._d.map(safeCall);
95
+ cd._d.forEach(fn => {
96
+ let p = safeCall(fn);
97
+ p && destroyResults && destroyResults.push(p);
98
+ });
94
99
  cd._d.length = 0;
95
100
  cd.children.map(cd => cd.destroy(false));
96
101
  cd.children.length = 0;
@@ -287,15 +292,21 @@ function svgToFragment(content) {
287
292
  templatecacheSvg[content] = result.cloneNode(true);
288
293
  return result;
289
294
  }
290
- function $$removeElements(el, last) {
295
+
296
+ const iterNodes = (el, last, fn) => {
291
297
  let next;
292
298
  while(el) {
293
299
  next = el.nextSibling;
294
- el.remove();
300
+ fn(el);
295
301
  if(el == last) break;
296
302
  el = next;
297
303
  }
298
- }
304
+ };
305
+
306
+
307
+ const $$removeElements = (el, last) => iterNodes(el, last, n => n.remove());
308
+
309
+
299
310
  function removeElementsBetween(el, stop) {
300
311
  let next;
301
312
  el = el.nextSibling;
@@ -563,7 +574,7 @@ const bindAction = (cd, element, action, fn, subscribe) => {
563
574
  value = fn();
564
575
  handler = action.apply(null, [element].concat(value));
565
576
  } else handler = action(element);
566
- if(handler?.destroy) cd_onDestroy(cd, handler.destroy);
577
+ cd_onDestroy(cd, handler?.destroy);
567
578
  subscribe?.(cd, fn, handler, value);
568
579
  });
569
580
  };
@@ -778,23 +789,19 @@ const makeRootEvent = (root) => {
778
789
  }
779
790
  });
780
791
  return (target, eventName, callback) => {
781
- let handler = events[eventName];
782
- if(!handler) {
783
- handler = events[eventName] = ($event) => {
792
+ const key = `_$$${eventName}`;
793
+ if(!events[eventName]) {
794
+ let handler = events[eventName] = ($event) => {
784
795
  let top = $event.currentTarget;
785
796
  let el = $event.target;
786
797
  while(el) {
787
- if(el.__cb?.[eventName]) {
788
- el.__cb[eventName]($event);
789
- return;
790
- }
791
- if(el == top) break;
798
+ el[key]?.($event);
799
+ if(el == top || $event.cancelBubble) break;
792
800
  el = el.parentNode;
793
801
  }
794
802
  };
795
803
  nodes.forEach(n => n.addEventListener(eventName, handler));
796
- } if(!target.__cb) target.__cb = {};
797
- target.__cb[eventName] = callback;
804
+ } target[key] = callback;
798
805
  }
799
806
  };
800
807
 
@@ -836,14 +843,21 @@ function ifBlock(parentCD, label, fn, build, buildElse) {
836
843
  }
837
844
  function destroyBlock() {
838
845
  if(!first) return;
846
+ destroyResults = [];
839
847
  destroy?.();
840
848
  destroy = null;
841
849
  if($cd) {
842
850
  cd_destroy$1($cd);
843
851
  $cd = null;
844
852
  }
845
- $$removeElements(first, last);
853
+ if(destroyResults.length) {
854
+ let f = first, l = last;
855
+ Promise.allSettled(destroyResults).then(() => {
856
+ $$removeElements(f, l);
857
+ });
858
+ } else $$removeElements(first, last);
846
859
  first = last = null;
860
+ destroyResults = null;
847
861
  }
848
862
  $watch(parentCD, fn, (value) => {
849
863
  if(value) {
@@ -945,7 +959,7 @@ function $$eachBlock($parentCD, label, onlyChild, fn, getKey, bind) {
945
959
  cd_attach($parentCD, eachCD);
946
960
 
947
961
  let mapping = new Map();
948
- let lastNode;
962
+ let lastNode, vi = 0;
949
963
 
950
964
  $watch(eachCD, fn, (array) => {
951
965
  if(!array) array = [];
@@ -964,45 +978,72 @@ function $$eachBlock($parentCD, label, onlyChild, fn, getKey, bind) {
964
978
 
965
979
  if(mapping.size) {
966
980
  let ctx, count = 0;
981
+ vi++;
967
982
  for(let i=0;i<array.length;i++) {
968
983
  ctx = mapping.get(getKey(array[i], i, array));
969
984
  if(ctx) {
970
- ctx.a = true;
985
+ ctx.a = vi;
971
986
  count++;
972
987
  }
973
988
  }
974
989
 
975
990
  if(!count && lastNode) {
976
- if(onlyChild) label.textContent = '';
977
- else $$removeElements(label.nextSibling, lastNode);
978
- eachCD.children.forEach(cd => cd.destroy(false));
991
+ destroyResults = [];
992
+ eachCD.children.forEach(cd => cd_destroy$1(cd, false));
979
993
  eachCD.children.length = 0;
980
994
  mapping.forEach(ctx => ctx.destroy?.());
981
995
  mapping.clear();
996
+
997
+ if(destroyResults.length) {
998
+ let removedNodes = [];
999
+ iterNodes(onlyChild ? label.firstChild : label.nextSibling, lastNode, n => {
1000
+ n.$$removing = true;
1001
+ removedNodes.push(n);
1002
+ });
1003
+ Promise.allSettled(destroyResults).then(() => removedNodes.forEach(n => n.remove()));
1004
+ } else {
1005
+ if(onlyChild) label.textContent = '';
1006
+ else $$removeElements(label.nextSibling, lastNode);
1007
+ }
1008
+
1009
+ destroyResults = null;
982
1010
  } else if(count < mapping.size) {
983
1011
  eachCD.children = [];
1012
+ destroyResults = [];
1013
+ let removedNodes = [];
984
1014
  mapping.forEach(ctx => {
985
- if(ctx.a) {
986
- ctx.a = false;
1015
+ if(ctx.a == vi) {
987
1016
  ctx.$cd && eachCD.children.push(ctx.$cd);
988
1017
  return;
989
1018
  }
990
- $$removeElements(ctx.first, ctx.last);
991
- ctx.$cd?.destroy(false);
1019
+ ctx.$cd && cd_destroy$1(ctx.$cd, false);
992
1020
  ctx.destroy?.();
1021
+ iterNodes(ctx.first, ctx.last, n => {
1022
+ n.$$removing = true;
1023
+ removedNodes.push(n);
1024
+ });
993
1025
  });
1026
+
1027
+ if(destroyResults.length) {
1028
+ Promise.allSettled(destroyResults).then(() => removedNodes.forEach(n => n.remove()));
1029
+ } else {
1030
+ removedNodes.forEach(n => n.remove());
1031
+ }
1032
+ destroyResults = null;
994
1033
  }
995
1034
  }
996
1035
 
997
- let i, item, next_ctx, ctx, nextEl;
1036
+ let i, item, next_ctx, ctx, nextEl, key;
998
1037
  for(i=0;i<array.length;i++) {
999
1038
  item = array[i];
1039
+ key = getKey(item, i, array);
1000
1040
  if(next_ctx) {
1001
1041
  ctx = next_ctx;
1002
1042
  next_ctx = null;
1003
- } else ctx = mapping.get(getKey(item, i, array));
1043
+ } else ctx = mapping.get(key);
1004
1044
  if(ctx) {
1005
1045
  nextEl = i == 0 && onlyChild ? parentNode[firstChild] : prevNode.nextSibling;
1046
+ while(nextEl && nextEl.$$removing) nextEl = nextEl.nextSibling;
1006
1047
  if(nextEl != ctx.first) {
1007
1048
  let insert = true;
1008
1049
 
@@ -1037,7 +1078,7 @@ function $$eachBlock($parentCD, label, onlyChild, fn, getKey, bind) {
1037
1078
  parentNode.insertBefore($dom, prevNode?.nextSibling);
1038
1079
  }
1039
1080
  prevNode = ctx.last;
1040
- newMapping.set(getKey(item, i, array), ctx);
1081
+ newMapping.set(key, ctx);
1041
1082
  } lastNode = prevNode;
1042
1083
  mapping.clear();
1043
1084
  mapping = newMapping;
@@ -1079,4 +1120,4 @@ const makeSlot = (parentCD, fr, fn) => {
1079
1120
  };
1080
1121
  };
1081
1122
 
1082
- export { $$addEventForComponent, $$awaitBlock, $$cloneDeep, $$compareArray, $$compareDeep, $$deepComparator, $$eachBlock, $$htmlBlock, $$htmlToFragment, $$htmlToFragmentClean, $$removeElements, $$removeItem, $base, $context, $digest, $makeEmitter, $onDestroy, $onMount, $tick, $watch, $watchReadOnly, __app_onerror, __bindActionSubscribe, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callExportedFragment, cd_attach, cd_component, cd_destroy$1 as cd_destroy, cd_new, cd_onDestroy, cd_watchObject, childNodes, cloneDeep, configure, createTextNode, current_component, eachDefaultKey, exportFragment, fire, firstChild, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, keyComparator, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, makeStaticBlock, makeStaticEachBlock, mergeEvents, noop, prefixPush, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };
1123
+ export { $$addEventForComponent, $$awaitBlock, $$cloneDeep, $$compareArray, $$compareDeep, $$deepComparator, $$eachBlock, $$htmlBlock, $$htmlToFragment, $$htmlToFragmentClean, $$removeElements, $$removeItem, $base, $context, $digest, $makeEmitter, $onDestroy, $onMount, $tick, $watch, $watchReadOnly, __app_onerror, __bindActionSubscribe, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callExportedFragment, cd_attach, cd_component, cd_destroy$1 as cd_destroy, cd_new, cd_onDestroy, cd_watchObject, childNodes, cloneDeep, configure, createTextNode, current_component, destroyResults, eachDefaultKey, exportFragment, fire, firstChild, getFinalLabel, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachSingleBlock, makeExternalProperty, makeRootEvent, makeSlot, makeStaticBlock, makeStaticEachBlock, mergeEvents, noop, prefixPush, removeElementsBetween, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };