malinajs 0.7.2-a1 → 0.7.2-a5

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-esbuild.js CHANGED
@@ -59,10 +59,25 @@ function malinaPlugin(options={}){
59
59
  const cssModules = new Map();
60
60
 
61
61
  if(options.displayVersion !== false) console.log('! Malina.js', malina.version);
62
-
62
+
63
63
  return {
64
64
  name: 'malina-plugin',
65
- setup(build) {
65
+ setup(build) {
66
+ build.onResolve({ filter: /^malinajs$/ }, async (args) => {
67
+ const runtime = await build.resolve('malinajs/runtime.js', {resolveDir: args.resolveDir});
68
+ return {
69
+ path: runtime.path,
70
+ sideEffects: false
71
+ };
72
+ });
73
+
74
+ build.onResolve({ filter: /\.(xht|ma|html)$/ }, (arg) => {
75
+ return {
76
+ path: path.resolve(arg.resolveDir,arg.path),
77
+ sideEffects: false
78
+ }
79
+ });
80
+
66
81
  build.onLoad(
67
82
  { filter: /\.(xht|ma|html)$/ },
68
83
  async (args) => {
package/malina.js CHANGED
@@ -290,6 +290,7 @@
290
290
 
291
291
  this.isEmpty = function(n) {
292
292
  if(n == null) return true;
293
+ if(n.$type == 'if:bind') return false;
293
294
  assert(n.$done, 'Node is not built');
294
295
  return !n.$result.some(r => {
295
296
  if(typeof (r) == 'string') return true;
@@ -1245,6 +1246,9 @@
1245
1246
  assert(parent.type === 'fragment', 'Fragment error: /fragment');
1246
1247
  return;
1247
1248
  } else throw 'Error binding: ' + bind.value;
1249
+ } else {
1250
+ addText(readBinding().raw);
1251
+ continue;
1248
1252
  }
1249
1253
  }
1250
1254
 
@@ -1807,8 +1811,13 @@
1807
1811
  }
1808
1812
  }));
1809
1813
 
1810
- this.module.head.push(xNode('$context', (ctx) => {
1811
- if(this.inuse.$context) ctx.write(true, 'const $context = $option.context || {};');
1814
+ this.module.head.push(xNode('$context', {
1815
+ $hold: ['componentFn']
1816
+ }, (ctx) => {
1817
+ if(this.inuse.$context) {
1818
+ this.require('componentFn');
1819
+ ctx.write(true, 'const $context = $runtime.$context;');
1820
+ }
1812
1821
  }));
1813
1822
 
1814
1823
  this.module.top.push(xNode(this.glob.$onMount, {
@@ -1851,7 +1860,6 @@
1851
1860
 
1852
1861
  let bb = this.buildBlock(this.DOM, {
1853
1862
  inline: true,
1854
- protectLastTag: true,
1855
1863
  allowSingleBlock: true,
1856
1864
  template: {
1857
1865
  name: '$parentElement',
@@ -1938,7 +1946,6 @@
1938
1946
  let binds = xNode('block');
1939
1947
  let result = {};
1940
1948
  let inuse = Object.assign({}, this.inuse);
1941
- let lastTagDynamic = false;
1942
1949
 
1943
1950
  if(!option.parentElement) option.parentElement = '$parentElement';
1944
1951
 
@@ -2021,26 +2028,51 @@
2021
2028
  if(svg && !other) rootSVG = true;
2022
2029
  }
2023
2030
 
2024
- let lastStatic;
2031
+ let labelRequest;
2025
2032
 
2026
- const placeLabel = name => {
2027
- let el;
2028
- if(lastStatic) {
2029
- el = lastStatic;
2030
- el.label = true;
2031
- lastStatic = null;
2032
- } else {
2033
- el = xNode('node:comment', { label: true, value: name });
2034
- tpl.push(el);
2033
+ const requireLabel = (final, noParent) => {
2034
+ if(labelRequest) {
2035
+ if(labelRequest.final) {
2036
+ labelRequest.set(tpl.push(xNode('node:comment', { label: true, value: '' })));
2037
+ } else {
2038
+ if(final) labelRequest.final = true;
2039
+ if(noParent) labelRequest.noParent = true;
2040
+ return labelRequest;
2041
+ }
2035
2042
  }
2036
- return el;
2043
+ labelRequest = {
2044
+ name: null,
2045
+ node: null,
2046
+ final,
2047
+ noParent,
2048
+ set(n) {
2049
+ labelRequest.name = n.bindName();
2050
+ labelRequest.node = n;
2051
+ labelRequest = null;
2052
+ },
2053
+ resolve() {
2054
+ assert(!labelRequest.node);
2055
+ if(labelRequest.noParent) {
2056
+ labelRequest.set(tpl.push(xNode('node:comment', { label: true, value: '' })));
2057
+ } else if(isRoot) {
2058
+ assert(!tpl._boundName);
2059
+ labelRequest.name = tpl._boundName = option.parentElement;
2060
+ } else {
2061
+ labelRequest.name = tpl.bindName();
2062
+ }
2063
+ labelRequest = null;
2064
+ }
2065
+ };
2066
+ return labelRequest;
2037
2067
  };
2038
2068
 
2039
2069
  const bindNode = (n, nodeIndex) => {
2040
2070
  if(n.type === 'text') {
2041
- if(isRoot) lastTagDynamic = false;
2042
2071
  let prev = tpl.getLast();
2043
- if(prev?.$type == 'node:text' && prev._boundName) tpl.push(xNode('node:comment', { label: true }));
2072
+ // if(prev?.$type == 'node:text' && prev._boundName) tpl.push(xNode('node:comment', { label: true }));
2073
+ if(prev?.$type == 'node:text' && labelRequest) {
2074
+ labelRequest.set(tpl.push(xNode('node:comment', { label: true })));
2075
+ }
2044
2076
 
2045
2077
  if(n.value.indexOf('{') >= 0) {
2046
2078
  const pe = this.parseText(n.value);
@@ -2074,16 +2106,22 @@
2074
2106
  }));
2075
2107
  });
2076
2108
 
2077
- lastStatic = textNode;
2109
+ labelRequest?.set(textNode);
2078
2110
  } else {
2079
- lastStatic = tpl.push(n.value);
2111
+ const textNode = tpl.push(n.value);
2112
+ labelRequest?.set(textNode);
2080
2113
  }
2114
+
2081
2115
  } else if(n.type === 'template') {
2082
- if(isRoot) lastTagDynamic = false;
2083
- lastStatic = null;
2084
- tpl.push(n.openTag);
2085
- tpl.push(n.content);
2086
- tpl.push('</template>');
2116
+ const templateNode = xNode('node', {
2117
+ openTag: n.openTag,
2118
+ content: n.content
2119
+ });
2120
+ templateNode.$handler = (ctx, n) => {
2121
+ ctx.write(n.openTag, n.content, '</template>');
2122
+ };
2123
+ tpl.push(templateNode);
2124
+ labelRequest?.set(templateNode);
2087
2125
  } else if(n.type === 'node') {
2088
2126
  if(n.name == 'malina' && !option.malinaElement) {
2089
2127
  let b;
@@ -2092,29 +2130,35 @@
2092
2130
  b && binds.push(b);
2093
2131
  return;
2094
2132
  }
2095
- if(isRoot) lastTagDynamic = false;
2096
2133
  if(n.name == 'component' || n.name.match(/^[A-Z]/)) {
2097
2134
  if(n.name == 'component' || !n.elArg) {
2098
2135
  // component
2099
2136
  if(isRoot) requireFragment = true;
2100
- let el = placeLabel(n.name);
2101
2137
 
2102
2138
  if(n.name == 'component') {
2103
2139
  // dyn-component
2104
- binds.push(this.makeComponentDyn(n, el));
2140
+ if(isRoot) {
2141
+ requireFragment = true;
2142
+ if(!tpl.getLast()) tpl.push(xNode('node:comment', { label: true }));
2143
+ }
2144
+ const label = requireLabel(true, isRoot);
2145
+ binds.push(this.makeComponentDyn(n, label));
2105
2146
  } else {
2147
+ const label = requireLabel();
2106
2148
  let component = this.makeComponent(n);
2107
2149
  binds.push(xNode('insert-component', {
2108
2150
  component: component.bind,
2109
2151
  reference: component.reference,
2110
- el: el.bindName()
2152
+ label
2111
2153
  }, (ctx, n) => {
2112
2154
  if(n.reference) {
2113
2155
  ctx.write(true, `${n.reference} = `);
2114
2156
  ctx.add(n.component);
2115
- ctx.write(true, `$runtime.attachBlock(${n.el}, ${n.reference});`);
2157
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, ${n.reference});`);
2158
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, ${n.reference});`);
2116
2159
  } else {
2117
- ctx.write(true, `$runtime.attachBlock(${n.el}, `);
2160
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, `);
2161
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, `);
2118
2162
  ctx.add(n.component);
2119
2163
  ctx.write(');');
2120
2164
  }
@@ -2122,9 +2166,7 @@
2122
2166
  }
2123
2167
  } else {
2124
2168
  if(isRoot) requireFragment = true;
2125
- let el = placeLabel(`exported ${n.elArg}`);
2126
- let b = this.attchExportedFragment(n, el, n.name);
2127
- b && binds.push(b);
2169
+ binds.push(this.attchExportedFragment(n, requireLabel(), n.name));
2128
2170
  }
2129
2171
  return;
2130
2172
  }
@@ -2133,21 +2175,20 @@
2133
2175
  let slotName = n.elArg;
2134
2176
  if(!slotName) {
2135
2177
  if(option.context == 'fragment') {
2136
- let el = placeLabel('fragment-slot');
2137
- binds.push(this.attachFragmentSlot(el));
2178
+ binds.push(this.attachFragmentSlot(requireLabel()));
2138
2179
  return;
2139
2180
  } else slotName = 'default';
2140
2181
  }
2141
2182
 
2142
- let el = placeLabel(slotName);
2143
2183
  let slot = this.attachSlot(slotName, n);
2144
2184
 
2145
2185
  binds.push(xNode('attach-slot', {
2146
2186
  $compile: [slot],
2147
- el: el.bindName(),
2187
+ label: requireLabel(),
2148
2188
  slot
2149
2189
  }, (ctx, n) => {
2150
- ctx.write(true, `$runtime.attachBlock(${n.el}, `);
2190
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, `);
2191
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, `);
2151
2192
  ctx.add(n.slot);
2152
2193
  ctx.write(');', true);
2153
2194
  }));
@@ -2155,12 +2196,13 @@
2155
2196
  }
2156
2197
  if(n.name == 'fragment') {
2157
2198
  assert(n.elArg, 'Fragment name is required');
2158
- let el = placeLabel(`fragment ${n.elArg}`);
2199
+ if(isRoot) requireFragment = true;
2159
2200
  binds.push(xNode('attach-fragment', {
2160
- el: el.bindName(),
2201
+ label: requireLabel(),
2161
2202
  fragment: this.attachFragment(n)
2162
2203
  }, (ctx, n) => {
2163
- ctx.write(true, `$runtime.attachBlock(${n.el}, `);
2204
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, `);
2205
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, `);
2164
2206
  ctx.add(n.fragment);
2165
2207
  ctx.write(')');
2166
2208
  }));
@@ -2170,7 +2212,7 @@
2170
2212
  let el = xNode('node', { name: n.name });
2171
2213
  if(option.oneElement) el._boundName = option.oneElement;
2172
2214
  tpl.push(el);
2173
- lastStatic = el;
2215
+ labelRequest?.set(el);
2174
2216
 
2175
2217
  if(n.attributes.some(a => a.name.startsWith('{...'))) {
2176
2218
  this.require('rootCD');
@@ -2217,9 +2259,8 @@
2217
2259
  }
2218
2260
  } else if(n.type === 'each') {
2219
2261
  if(data.type == 'node' && data.body.length == 1) {
2220
- lastStatic = null;
2221
2262
  let eachBlock = this.makeEachBlock(n, {
2222
- elName: tpl.bindName(),
2263
+ label: tpl.bindName(),
2223
2264
  onlyChild: true
2224
2265
  });
2225
2266
  binds.push(eachBlock.source);
@@ -2227,20 +2268,18 @@
2227
2268
  } else {
2228
2269
  if(isRoot) {
2229
2270
  requireFragment = true;
2230
- lastTagDynamic = true;
2271
+ if(!tpl.getLast()) tpl.push(xNode('node:comment', { label: true }));
2231
2272
  }
2232
- let element = placeLabel(n.value);
2233
- let eachBlock = this.makeEachBlock(n, { elName: element.bindName() });
2273
+ let eachBlock = this.makeEachBlock(n, { label: requireLabel(true, isRoot) });
2234
2274
  binds.push(eachBlock.source);
2235
2275
  return;
2236
2276
  }
2237
2277
  } else if(n.type === 'if') {
2238
2278
  if(isRoot) {
2239
2279
  requireFragment = true;
2240
- lastTagDynamic = true;
2280
+ if(!tpl.getLast()) tpl.push(xNode('node:comment', { label: true }));
2241
2281
  }
2242
- if(nodeIndex == 0 && !isRoot) binds.push(this.makeifBlock(n, tpl, true));
2243
- else binds.push(this.makeifBlock(n, placeLabel(n.value)));
2282
+ binds.push(this.makeifBlock(n, requireLabel(true, isRoot)));
2244
2283
  return;
2245
2284
  } else if(n.type === 'systag') {
2246
2285
  let r = n.value.match(/^@(\w+)\s+(.*)$/s);
@@ -2250,24 +2289,21 @@
2250
2289
  if(name == 'html') {
2251
2290
  if(isRoot) {
2252
2291
  requireFragment = true;
2253
- lastTagDynamic = true;
2292
+ if(!tpl.getLast()) tpl.push(xNode('node:comment', { label: true }));
2254
2293
  }
2255
- let el = placeLabel('html');
2256
- binds.push(this.makeHtmlBlock(exp, el));
2294
+ binds.push(this.makeHtmlBlock(exp, requireLabel(true, true)));
2257
2295
  return;
2258
2296
  } else throw 'Wrong tag';
2259
2297
  } else if(n.type === 'await') {
2260
2298
  if(isRoot) {
2261
2299
  requireFragment = true;
2262
- lastTagDynamic = true;
2300
+ if(!tpl.getLast()) tpl.push(xNode('node:comment', { label: true }));
2263
2301
  }
2264
- let el = placeLabel(n.value);
2265
- let r = this.makeAwaitBlock(n, el);
2266
- r && binds.push(r);
2302
+ binds.push(this.makeAwaitBlock(n, requireLabel(true, isRoot)));
2267
2303
  return;
2268
2304
  } else if(n.type === 'comment') {
2269
- if(isRoot) lastTagDynamic = false;
2270
- lastStatic = tpl.push(n.content);
2305
+ const commentNode = tpl.push(n.content);
2306
+ labelRequest?.set(commentNode);
2271
2307
  }
2272
2308
  };
2273
2309
  body.forEach((node, i) => {
@@ -2277,11 +2313,10 @@
2277
2313
  wrapException(e, node);
2278
2314
  }
2279
2315
  });
2316
+ labelRequest?.resolve();
2280
2317
  };
2318
+
2281
2319
  go(data, true, rootTemplate);
2282
- if(option.protectLastTag && lastTagDynamic) {
2283
- rootTemplate.push(xNode('node:comment', { value: '' }));
2284
- }
2285
2320
 
2286
2321
  let innerBlock = null;
2287
2322
  if(binds.body.length) {
@@ -2529,7 +2564,7 @@
2529
2564
  if(n.type == 'text') e.details = n.value.trim();
2530
2565
  else if(n.type == 'node') e.details = n.openTag.trim();
2531
2566
  else if(n.type == 'each') e.details = n.value.trim();
2532
- else if(n.type == 'if') e.details = n.value.trim();
2567
+ else if(n.type == 'if') e.details = n.parts?.[0]?.value.trim() || 'if-block';
2533
2568
  }
2534
2569
  throw e;
2535
2570
  }
@@ -5128,7 +5163,7 @@
5128
5163
  return { bind: result, reference };
5129
5164
  }
5130
5165
 
5131
- function makeComponentDyn(node, element) {
5166
+ function makeComponentDyn(node, label) {
5132
5167
  let dynamicComponent;
5133
5168
 
5134
5169
  if(node.elArg) {
@@ -5150,15 +5185,16 @@
5150
5185
 
5151
5186
  component.componentName = '$ComponentConstructor';
5152
5187
  return xNode('dyn-component', {
5153
- el: element.bindName(),
5188
+ label,
5154
5189
  exp: dynamicComponent,
5155
5190
  component,
5156
5191
  reference
5157
5192
  }, (ctx, n) => {
5158
- ctx.write(true, `$runtime.attachDynComponent(${n.el}, () => ${n.exp}, ($ComponentConstructor) => `);
5193
+ ctx.write(true, `$runtime.attachDynComponent(${n.label.name}, () => ${n.exp}, ($ComponentConstructor) => `);
5159
5194
  if(n.reference) ctx.write(`${n.reference} = `);
5160
5195
  ctx.add(n.component);
5161
- ctx.write(')');
5196
+ if(n.label.node) ctx.write(')');
5197
+ else ctx.write(', true)');
5162
5198
  });
5163
5199
  }
5164
5200
 
@@ -5322,7 +5358,7 @@
5322
5358
  })
5323
5359
  };
5324
5360
  } else if(name == 'style' && arg) {
5325
- let styleName = toCamelCase(arg);
5361
+ let styleName = arg;
5326
5362
  let exp;
5327
5363
  if(prop.value) {
5328
5364
  if(isExpression(prop.value)) {
@@ -5340,13 +5376,13 @@
5340
5376
  name: styleName,
5341
5377
  value: prop.value
5342
5378
  }, (ctx, n) => {
5343
- ctx.writeLine(`${n.el}.style.${n.name} = \`${Q(n.value)}\`;`);
5379
+ ctx.writeLine(`${n.el}.style.${toCamelCase(n.name)} = \`${Q(n.value)}\`;`);
5344
5380
  })
5345
5381
  };
5346
5382
  }
5347
5383
  }
5348
5384
  } else {
5349
- exp = styleName;
5385
+ exp = toCamelCase(styleName);
5350
5386
  }
5351
5387
 
5352
5388
  let hasElement = exp.includes('$element');
@@ -5363,7 +5399,7 @@
5363
5399
  if(ctx.inuse.apply) {
5364
5400
  ctx.writeLine(`$runtime.bindStyle(${n.el}, '${n.styleName}', () => (${n.exp}));`);
5365
5401
  } else {
5366
- ctx.writeLine(`${n.el}.style.${n.styleName} = ${n.exp};`);
5402
+ ctx.writeLine(`${n.el}.style.${toCamelCase(n.styleName)} = ${n.exp};`);
5367
5403
  }
5368
5404
  })]
5369
5405
  })
@@ -5603,7 +5639,7 @@
5603
5639
  }
5604
5640
  }
5605
5641
 
5606
- function makeifBlock(data, element, parentElement) {
5642
+ function makeifBlock(data, label) {
5607
5643
  const getBlock = b => {
5608
5644
  if(b.singleBlock) {
5609
5645
  return xNode('make-block', {
@@ -5624,22 +5660,21 @@
5624
5660
  this.detectDependency(exp);
5625
5661
  parts.push({
5626
5662
  exp,
5627
- block: getBlock(this.buildBlock(part, { protectLastTag: true, allowSingleBlock: true }))
5663
+ block: getBlock(this.buildBlock(part, { allowSingleBlock: true }))
5628
5664
  });
5629
5665
  });
5630
- if(data.elsePart) elseBlock = getBlock(this.buildBlock({ body: data.elsePart }, { protectLastTag: true, allowSingleBlock: true }));
5666
+ if(data.elsePart) elseBlock = getBlock(this.buildBlock({ body: data.elsePart }, { allowSingleBlock: true }));
5631
5667
 
5632
5668
  return xNode('if:bind', {
5633
5669
  $wait: ['apply'],
5634
- el: element.bindName(),
5635
- parentElement,
5670
+ label,
5636
5671
  parts,
5637
5672
  elseBlock
5638
5673
  }, (ctx, n) => {
5639
5674
  if(this.inuse.apply) {
5640
- ctx.write(true, `$runtime.ifBlock(${n.el}, `);
5675
+ ctx.write(true, `$runtime.ifBlock(${n.label.name}, `);
5641
5676
  } else {
5642
- ctx.write(true, `$runtime.ifBlockReadOnly(${n.el}, `);
5677
+ ctx.write(true, `$runtime.ifBlockReadOnly(${n.label.name}, `);
5643
5678
  }
5644
5679
 
5645
5680
  if(n.parts.length == 1) {
@@ -5665,7 +5700,7 @@
5665
5700
 
5666
5701
  ctx.indent--;
5667
5702
  ctx.write(true);
5668
- if(n.parentElement) ctx.write(', true');
5703
+ if(!n.label.node) ctx.write(', true');
5669
5704
  ctx.write(');', true);
5670
5705
  });
5671
5706
  }
@@ -5783,7 +5818,6 @@
5783
5818
  if(!nodeItems.length) nodeItems = [data.mainBlock[0]];
5784
5819
 
5785
5820
  let itemBlock, block = this.buildBlock({ body: nodeItems }, {
5786
- protectLastTag: true,
5787
5821
  allowSingleBlock: !blockPrefix,
5788
5822
  each: {
5789
5823
  blockPrefix,
@@ -5817,7 +5851,6 @@
5817
5851
  let elseBlock = null;
5818
5852
  if(data.elseBlock) {
5819
5853
  let block = this.buildBlock({ body: data.elseBlock }, {
5820
- protectLastTag: true,
5821
5854
  allowSingleBlock: false
5822
5855
  });
5823
5856
  elseBlock = block.block;
@@ -5826,9 +5859,15 @@
5826
5859
  const source = xNode('each', {
5827
5860
  keyFunction,
5828
5861
  block: itemBlock,
5829
- elseBlock
5862
+ elseBlock,
5863
+ label: option.label,
5864
+ onlyChild: option.onlyChild
5830
5865
  }, (ctx, n) => {
5831
- ctx.writeLine(`$runtime.$$eachBlock(${option.elName}, ${option.onlyChild ? 1 : 0}, () => (${arrayName}),`);
5866
+ let el = n.onlyChild ? n.label : n.label.name;
5867
+ let mode = 0;
5868
+ if(n.onlyChild) mode = 1;
5869
+ else if(!n.label.node) mode = 2;
5870
+ ctx.writeLine(`$runtime.$$eachBlock(${el}, ${mode}, () => (${arrayName}),`);
5832
5871
  ctx.indent++;
5833
5872
  ctx.write(true);
5834
5873
  if(n.keyFunction === 'noop') ctx.write('$runtime.noop');
@@ -5853,15 +5892,15 @@
5853
5892
  this.detectDependency(exp);
5854
5893
  return xNode('block', {
5855
5894
  $wait: ['apply'],
5856
- el: label.bindName(),
5895
+ label,
5857
5896
  exp
5858
5897
  }, (ctx, n) => {
5859
- if(this.inuse.apply) ctx.write(true, `$runtime.htmlBlock(${n.el}, () => (${n.exp}));`);
5860
- else ctx.write(true, `$runtime.htmlBlockStatic(${n.el}, ${n.exp});`);
5898
+ if(this.inuse.apply) ctx.write(true, `$runtime.htmlBlock(${n.label.name}, () => (${n.exp}));`);
5899
+ else ctx.write(true, `$runtime.htmlBlockStatic(${n.label.name}, ${n.exp});`);
5861
5900
  });
5862
5901
  }
5863
5902
 
5864
- function makeAwaitBlock(node, element) {
5903
+ function makeAwaitBlock(node, label) {
5865
5904
  let valueForThen, exp;
5866
5905
 
5867
5906
  let rx = node.value.match(/^#await\s+(.+)\s+then\s+(\S+)\s*$/s);
@@ -5881,7 +5920,7 @@
5881
5920
 
5882
5921
  let parts = [null, null, null];
5883
5922
  if(node.parts.main && node.parts.main.length) {
5884
- parts[0] = this.buildBlock({ body: node.parts.main }, { protectLastTag: true });
5923
+ parts[0] = this.buildBlock({ body: node.parts.main });
5885
5924
  }
5886
5925
  if(node.parts.then && node.parts.then.length) {
5887
5926
  let args = [];
@@ -5895,7 +5934,7 @@
5895
5934
  args.push(rx[1]);
5896
5935
  }
5897
5936
  }
5898
- parts[1] = this.buildBlock({ body: node.parts.then }, { protectLastTag: true, extraArguments: args });
5937
+ parts[1] = this.buildBlock({ body: node.parts.then }, { extraArguments: args });
5899
5938
  }
5900
5939
  if(node.parts.catch && node.parts.catch.length) {
5901
5940
  let args = [];
@@ -5904,7 +5943,7 @@
5904
5943
  assert(isSimpleName(rx[1]));
5905
5944
  args.push(rx[1]);
5906
5945
  }
5907
- parts[2] = this.buildBlock({ body: node.parts.catch }, { protectLastTag: true, extraArguments: args });
5946
+ parts[2] = this.buildBlock({ body: node.parts.catch }, { extraArguments: args });
5908
5947
  }
5909
5948
 
5910
5949
  if(this.script.readOnly) {
@@ -5915,12 +5954,12 @@
5915
5954
  this.require('apply');
5916
5955
 
5917
5956
  return xNode('await', {
5918
- el: element.bindName(),
5957
+ label,
5919
5958
  exp,
5920
5959
  parts,
5921
5960
  keywords
5922
5961
  }, (ctx, n) => {
5923
- ctx.write(true, `$runtime.awaitBlock(${n.el}, () => [${n.keywords.join(', ')}], () => ${n.exp},`);
5962
+ ctx.write(true, `$runtime.awaitBlock(${n.label.name}, ${n.label.node ? 0 : 1}, () => [${n.keywords.join(', ')}], () => ${n.exp},`);
5924
5963
  ctx.indent++;
5925
5964
  n.parts.forEach((part, index) => {
5926
5965
  if(index) ctx.write(', ');
@@ -6192,9 +6231,10 @@
6192
6231
 
6193
6232
  function attachFragmentSlot(label) {
6194
6233
  return xNode('fragment-slot', {
6195
- el: label.bindName()
6234
+ label
6196
6235
  }, (ctx, n) => {
6197
- ctx.write(true, `$runtime.attachBlock(${n.el}, $$fragmentSlot?.())`);
6236
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, $$fragmentSlot?.())`);
6237
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, $$fragmentSlot?.())`);
6198
6238
  });
6199
6239
  }
6200
6240
 
@@ -6203,7 +6243,7 @@
6203
6243
  let data = {
6204
6244
  name: node.elArg,
6205
6245
  componentName,
6206
- label: label.bindName()
6246
+ label
6207
6247
  };
6208
6248
 
6209
6249
  let body = trimEmptyNodes(node.body || []);
@@ -6218,7 +6258,8 @@
6218
6258
  data = { ...pa, ...data };
6219
6259
 
6220
6260
  return xNode('attach-exported-fragment', data, (ctx, n) => {
6221
- ctx.write(true, `$runtime.attachBlock(${n.label}, $runtime.callExportedFragment($instance_${n.componentName}, '${n.name}'`);
6261
+ if(n.label.node) ctx.write(true, `$runtime.insertBlock(${n.label.name}, $runtime.callExportedFragment($instance_${n.componentName}, '${n.name}'`);
6262
+ else ctx.write(true, `$runtime.addBlock(${n.label.name}, $runtime.callExportedFragment($instance_${n.componentName}, '${n.name}'`);
6222
6263
  ctx.indent++;
6223
6264
  let missed = '';
6224
6265
 
@@ -6597,7 +6638,7 @@
6597
6638
  return { event, fn, rootModifier };
6598
6639
  }
6599
6640
 
6600
- const version = '0.7.2-a1';
6641
+ const version = '0.7.2-a5';
6601
6642
 
6602
6643
 
6603
6644
  async function compile(source, config = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "malinajs",
3
- "version": "0.7.2-a1",
3
+ "version": "0.7.2-a5",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "prepare": "npm run build",
package/runtime.js CHANGED
@@ -1,3 +1,7 @@
1
+ let current_destroyList, current_mountList, current_cd, destroyResults;
2
+ const $onDestroy = fn => fn && current_destroyList.push(fn);
3
+ const $onMount = fn => current_mountList.push(fn);
4
+
1
5
  let __app_onerror = console.error;
2
6
 
3
7
  const configure = (option) => {
@@ -24,17 +28,13 @@ const safeGroupCall = list => {
24
28
  }
25
29
  };
26
30
 
27
- const safeCallMount = (mountList, destroyList) => {
28
- mountList.forEach(fn => {
31
+ const safeGroupCall2 = (list, resultList) => {
32
+ list?.forEach(fn => {
29
33
  let r = safeCall(fn);
30
- r && destroyList.push(r);
34
+ r && resultList.push(r);
31
35
  });
32
36
  };
33
37
 
34
- let current_destroyList, current_mountList, current_cd, destroyResults;
35
- const $onDestroy = fn => fn && current_destroyList.push(fn);
36
- const $onMount = fn => current_mountList.push(fn);
37
-
38
38
  function WatchObject(fn, cb) {
39
39
  this.fn = fn;
40
40
  this.cb = cb;
@@ -75,7 +75,7 @@ const cd_component = cd => {
75
75
  return cd.component;
76
76
  };
77
77
 
78
- const cd_new = () => new $ChangeDetector();
78
+ const cd_new = (parent) => new $ChangeDetector(parent);
79
79
 
80
80
  const cd_attach = (parent, cd) => {
81
81
  if(cd) {
@@ -288,25 +288,6 @@ const iterNodes = (el, last, fn) => {
288
288
  const removeElements = (el, last) => iterNodes(el, last, n => n.remove());
289
289
 
290
290
 
291
- function removeElementsBetween(el, stop) {
292
- let next;
293
- el = el.nextSibling;
294
- while(el) {
295
- next = el.nextSibling;
296
- if(el == stop) break;
297
- el.remove();
298
- el = next;
299
- }
300
- }
301
-
302
- const getFinalLabel = n => {
303
- if(n.nextSibling) return n.nextSibling;
304
- let e = document.createTextNode('');
305
- n.parentNode.appendChild(e);
306
- return e;
307
- };
308
-
309
-
310
291
  const resolvedPromise = Promise.resolve();
311
292
 
312
293
  function $tick(fn) {
@@ -326,7 +307,7 @@ function makeEmitter(option) {
326
307
  }
327
308
 
328
309
 
329
- let current_component;
310
+ let current_component, $context;
330
311
 
331
312
 
332
313
  const makeApply = () => {
@@ -357,6 +338,7 @@ const makeApply = () => {
357
338
 
358
339
  const makeComponent = (init) => {
359
340
  return ($option = {}) => {
341
+ $context = $option.context || {};
360
342
  let prev_component = current_component,
361
343
  prev_cd = current_cd,
362
344
  $component = current_component = { $option };
@@ -367,6 +349,7 @@ const makeComponent = (init) => {
367
349
  } finally {
368
350
  current_component = prev_component;
369
351
  current_cd = prev_cd;
352
+ $context = null;
370
353
  }
371
354
 
372
355
  return $component;
@@ -417,34 +400,33 @@ const callComponentDyn = (component, context, option = {}, propFn, cmp, setter,
417
400
  };
418
401
 
419
402
 
420
- const attachDynComponent = (label, exp, bind) => {
403
+ const attachDynComponent = (label, exp, bind, parentLabel) => {
421
404
  let parentCD = current_cd;
422
- let active, destroyList, $cd, $dom, finalLabel = getFinalLabel(label);
405
+ let destroyList, $cd, first;
423
406
  const destroy = () => safeGroupCall(destroyList);
424
407
  $onDestroy(destroy);
425
408
 
426
409
  $watch(exp, (component) => {
427
410
  destroy();
428
411
  if($cd) cd_detach($cd);
429
- if(active) removeElementsBetween(label, finalLabel);
412
+ if(first) removeElements(first, parentLabel ? null : label.previousSibling);
430
413
 
431
414
  if(component) {
432
415
  destroyList = current_destroyList = [];
433
416
  current_mountList = [];
434
- $cd = current_cd = cd_new();
417
+ $cd = current_cd = cd_new(parentCD);
435
418
  try {
436
- $dom = bind(component).$dom;
419
+ const $dom = bind(component).$dom;
437
420
  cd_attach(parentCD, $cd);
438
- insertAfter(label, $dom);
439
- safeCallMount(current_mountList, destroyList);
421
+ first = $dom.nodeType == 11 ? $dom.firstChild : $dom;
422
+ if(parentLabel) label.appendChild($dom);
423
+ else label.parentNode.insertBefore($dom, label);
424
+ safeGroupCall2(current_mountList, destroyList);
440
425
  } finally {
441
426
  current_destroyList = current_mountList = current_cd = null;
442
427
  }
443
- active = true;
444
428
  } else {
445
- $cd = null;
446
- active = false;
447
- destroyList = null;
429
+ $cd = first = destroyList = null;
448
430
  }
449
431
  });
450
432
  };
@@ -647,7 +629,8 @@ const spreadAttributes = (el, fn) => {
647
629
 
648
630
 
649
631
  const callExportedFragment = (childComponent, name, slot, events, props, cmp) => {
650
- let push, $dom;
632
+ let push, $dom, fn = childComponent.$exported?.[name];
633
+ if(!fn) return;
651
634
  if(cmp) {
652
635
  let result;
653
636
  let w = $watch(props, (value) => {
@@ -657,7 +640,6 @@ const callExportedFragment = (childComponent, name, slot, events, props, cmp) =>
657
640
  fire(w);
658
641
  props = () => result;
659
642
  }
660
- let fn = childComponent.$exported?.[name];
661
643
  ([$dom, push] = fn(props, events, slot));
662
644
  return $dom;
663
645
  };
@@ -731,6 +713,16 @@ const attachBlock = (label, $dom) => {
731
713
  insertAfter(label, $dom.$dom || $dom);
732
714
  };
733
715
 
716
+ const addBlock = (parent, $dom) => {
717
+ if(!$dom) return;
718
+ parent.appendChild($dom.$dom || $dom);
719
+ };
720
+
721
+ const insertBlock = (label, $dom) => {
722
+ if(!$dom) return;
723
+ label.parentNode.insertBefore($dom.$dom || $dom, label);
724
+ };
725
+
734
726
  const mergeEvents = (...callbacks) => {
735
727
  callbacks = callbacks.filter(i => i);
736
728
  return (e) => callbacks.forEach(cb => cb(e));
@@ -791,7 +783,7 @@ const mount = (label, component, option) => {
791
783
  last = $dom.lastChild;
792
784
  } else first = last = $dom;
793
785
  label.appendChild($dom);
794
- safeCallMount(current_mountList, destroyList);
786
+ safeGroupCall2(current_mountList, destroyList);
795
787
  } finally {
796
788
  current_destroyList = current_mountList = null;
797
789
  }
@@ -860,21 +852,21 @@ let create = (tag, html) => {
860
852
  t.innerHTML = html;
861
853
  fr = t.content;
862
854
  }
863
- let lastElement = fr.lastChild;
864
- insertAfter(tag, fr);
865
- return lastElement;
855
+ let firstElement = fr.firstChild;
856
+ tag.parentNode.insertBefore(fr, tag);
857
+ return firstElement;
866
858
  };
867
859
 
868
860
  function htmlBlock(tag, fn) {
869
- let lastElement;
861
+ let firstElement;
870
862
  let destroy = () => {
871
- if(!lastElement) return;
872
- removeElements(tag.nextSibling, lastElement);
873
- lastElement = null;
863
+ if(!firstElement) return;
864
+ removeElements(firstElement, tag.previousSibling);
865
+ firstElement = null;
874
866
  };
875
867
  $watch(fn, (html) => {
876
868
  destroy();
877
- if(html) lastElement = create(tag, html);
869
+ if(html) firstElement = create(tag, html);
878
870
  });
879
871
  }
880
872
 
@@ -884,13 +876,13 @@ function htmlBlockStatic(tag, value) {
884
876
 
885
877
  function ifBlock(label, fn, parts, parentLabel) {
886
878
  let first, last, $cd, destroyList, parentCD = current_cd;
887
- $onDestroy(() => safeGroupCall(destroyList));
879
+ $onDestroy(() => safeGroupCall2(destroyList, destroyResults));
888
880
 
889
881
  function createBlock(builder) {
890
882
  let $dom;
891
883
  destroyList = current_destroyList = [];
892
884
  let mountList = current_mountList = [];
893
- $cd = current_cd = cd_new();
885
+ $cd = current_cd = cd_new(parentCD);
894
886
  try {
895
887
  $dom = builder();
896
888
  } finally {
@@ -902,14 +894,14 @@ function ifBlock(label, fn, parts, parentLabel) {
902
894
  last = $dom.lastChild;
903
895
  } else first = last = $dom;
904
896
  if(parentLabel) label.appendChild($dom);
905
- else insertAfter(label, $dom);
906
- safeCallMount(mountList, destroyList);
897
+ else label.parentNode.insertBefore($dom, label);
898
+ safeGroupCall2(mountList, destroyList);
907
899
  }
908
900
 
909
901
  function destroyBlock() {
910
902
  if(!first) return;
911
903
  destroyResults = [];
912
- safeGroupCall(destroyList);
904
+ safeGroupCall2(destroyList, destroyResults);
913
905
  destroyList.length = 0;
914
906
  if($cd) {
915
907
  cd_detach($cd);
@@ -932,12 +924,16 @@ function ifBlock(label, fn, parts, parentLabel) {
932
924
  }
933
925
 
934
926
 
935
- function ifBlockReadOnly(label, fn, parts) {
927
+ function ifBlockReadOnly(label, fn, parts, parentLabel) {
936
928
  let value = fn();
937
- if(value != null) insertAfter(label, parts[value]());
929
+ if(value != null) {
930
+ const $dom = parts[value]();
931
+ if(parentLabel) label.appendChild($dom);
932
+ else label.parentNode.insertBefore($dom, label);
933
+ }
938
934
  }
939
935
 
940
- function awaitBlock(label, relation, fn, build_main, build_then, build_catch) {
936
+ function awaitBlock(label, parentLabel, relation, fn, build_main, build_then, build_catch) {
941
937
  let parentCD = current_cd, first, last, $cd, promise, destroyList, status = 0;
942
938
  $onDestroy(() => safeGroupCall(destroyList));
943
939
 
@@ -959,7 +955,7 @@ function awaitBlock(label, relation, fn, build_main, build_then, build_catch) {
959
955
 
960
956
  if(!builder) return;
961
957
  destroyList = current_destroyList = [];
962
- $cd = current_cd = cd_new();
958
+ $cd = current_cd = cd_new(parentCD);
963
959
  let $dom, mountList = current_mountList = [];
964
960
  try {
965
961
  $dom = builder(value);
@@ -971,8 +967,9 @@ function awaitBlock(label, relation, fn, build_main, build_then, build_catch) {
971
967
  first = $dom.firstChild;
972
968
  last = $dom.lastChild;
973
969
  } else first = last = $dom;
974
- insertAfter(label, $dom);
975
- safeCallMount(mountList, destroyList);
970
+ if(parentLabel) label.appendChild($dom);
971
+ else label.parentNode.insertBefore($dom, label);
972
+ safeGroupCall2(mountList, destroyList);
976
973
  cd_component(parentCD).$apply();
977
974
  }
978
975
 
@@ -1015,11 +1012,12 @@ const makeEachSingleBlock = (fn) => {
1015
1012
 
1016
1013
 
1017
1014
  const makeEachElseBlock = (fn) => {
1018
- return (label, onlyChild, parentCD) => {
1015
+ return (label, mode, parentCD) => {
1019
1016
  let first, last;
1020
1017
  let destroyList = current_destroyList = [];
1021
- let $cd = current_cd = cd_new();
1018
+ let $cd = current_cd = cd_new(parentCD);
1022
1019
  current_mountList = [];
1020
+ const parentNode = mode ? label : label.parentNode;
1023
1021
  try {
1024
1022
  let $dom = fn();
1025
1023
  if($dom.nodeType == 11) {
@@ -1027,32 +1025,41 @@ const makeEachElseBlock = (fn) => {
1027
1025
  last = $dom.lastChild;
1028
1026
  } else first = last = $dom;
1029
1027
  cd_attach(parentCD, $cd);
1030
- if(onlyChild) label.appendChild($dom);
1031
- else attachBlock(label, $dom);
1032
- safeCallMount(current_mountList, destroyList);
1028
+ parentNode.insertBefore($dom, mode ? null : label);
1029
+ safeGroupCall2(current_mountList, destroyList);
1033
1030
  } finally {
1034
1031
  current_destroyList = current_mountList = current_cd = null;
1035
1032
  }
1036
1033
 
1037
1034
  return () => {
1038
- removeElements(first, last);
1039
1035
  cd_detach($cd);
1040
- safeGroupCall(destroyList);
1036
+ destroyResults = [];
1037
+ safeGroupCall2(destroyList, destroyResults);
1038
+
1039
+ if(destroyResults.length) {
1040
+ const f = first, l = last;
1041
+ iterNodes(f, l, n => n.$$removing = true);
1042
+ Promise.allSettled(destroyResults).then(() => iterNodes(f, l, n => n.remove()));
1043
+ } else {
1044
+ removeElements(first, last);
1045
+ }
1046
+ destroyResults = null;
1041
1047
  };
1042
1048
  };
1043
1049
  };
1044
1050
 
1045
1051
 
1046
- function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1052
+ function $$eachBlock(label, mode, fn, getKey, bind, buildElseBlock) {
1047
1053
  let parentCD = current_cd;
1048
1054
  let eachCD = cd_new();
1049
1055
  cd_attach(parentCD, eachCD);
1050
1056
 
1051
1057
  let mapping = new Map();
1052
- let lastNode, vi = 0, p_promise = 0, p_destroy = 0, elseBlock;
1058
+ let firstNode, vi = 0, p_promise = 0, p_destroy = 0, elseBlock;
1059
+ const onlyChild = mode == 1;
1053
1060
 
1054
1061
  const destroyAll = () => {
1055
- p_destroy && safeCall(() => mapping.forEach(ctx => ctx.d?.forEach(fn => fn())));
1062
+ p_destroy && mapping.forEach(ctx => safeGroupCall2(ctx.d, destroyResults));
1056
1063
  mapping.clear();
1057
1064
  };
1058
1065
 
@@ -1065,14 +1072,7 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1065
1072
  else if(!isArray(array)) array = [];
1066
1073
 
1067
1074
  let newMapping = new Map();
1068
- let prevNode, parentNode;
1069
- if(onlyChild) {
1070
- prevNode = null;
1071
- parentNode = label;
1072
- } else {
1073
- prevNode = label;
1074
- parentNode = label.parentNode;
1075
- }
1075
+ let parentNode = mode ? label : label.parentNode;
1076
1076
 
1077
1077
  if(mapping.size) {
1078
1078
  let ctx, count = 0;
@@ -1085,7 +1085,7 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1085
1085
  }
1086
1086
  }
1087
1087
 
1088
- if(!count && lastNode) {
1088
+ if(!count && firstNode) {
1089
1089
  destroyResults = [];
1090
1090
  eachCD.children.length = 0;
1091
1091
  destroyAll();
@@ -1093,14 +1093,14 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1093
1093
  if(destroyResults.length) {
1094
1094
  p_promise = 1;
1095
1095
  let removedNodes = [];
1096
- iterNodes(onlyChild ? label.firstChild : label.nextSibling, lastNode, n => {
1096
+ iterNodes(firstNode, onlyChild ? null : label.previousSibling, n => {
1097
1097
  n.$$removing = true;
1098
1098
  removedNodes.push(n);
1099
1099
  });
1100
1100
  Promise.allSettled(destroyResults).then(() => removedNodes.forEach(n => n.remove()));
1101
1101
  } else {
1102
1102
  if(onlyChild) label.textContent = '';
1103
- else removeElements(label.nextSibling, lastNode);
1103
+ else removeElements(firstNode, label.previousSibling);
1104
1104
  }
1105
1105
 
1106
1106
  destroyResults = null;
@@ -1113,7 +1113,7 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1113
1113
  ctx.$cd && eachCD.children.push(ctx.$cd);
1114
1114
  return;
1115
1115
  }
1116
- safeGroupCall(ctx.d);
1116
+ safeGroupCall2(ctx.d, destroyResults);
1117
1117
  iterNodes(ctx.first, ctx.last, n => removedNodes.push(n));
1118
1118
  });
1119
1119
 
@@ -1134,7 +1134,9 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1134
1134
  }
1135
1135
 
1136
1136
  let i, item, next_ctx, ctx, nextEl, key;
1137
- for(i = 0; i < array.length; i++) {
1137
+ let nextNode = mode ? null : label;
1138
+ i = array.length;
1139
+ while(i--) {
1138
1140
  item = array[i];
1139
1141
  key = getKey(item, i, array);
1140
1142
  if(next_ctx) {
@@ -1142,36 +1144,36 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1142
1144
  next_ctx = null;
1143
1145
  } else ctx = mapping.get(key);
1144
1146
  if(ctx) {
1145
- nextEl = i == 0 && onlyChild ? parentNode.firstChild : prevNode.nextSibling;
1146
- if(p_promise) while(nextEl && nextEl.$$removing) nextEl = nextEl.nextSibling;
1147
- if(nextEl != ctx.first) {
1147
+ nextEl = nextNode ? nextNode.previousSibling : parentNode.lastChild;
1148
+ if(p_promise) while(nextEl && nextEl.$$removing) nextEl = nextEl.previousSibling;
1149
+ if(nextEl != ctx.last) {
1148
1150
  let insert = true;
1149
1151
 
1150
- if(ctx.first == ctx.last && (i + 1 < array.length) && prevNode?.nextSibling) {
1151
- next_ctx = mapping.get(getKey(array[i + 1], i + 1, array));
1152
- if(next_ctx && prevNode.nextSibling.nextSibling === next_ctx.first) {
1153
- parentNode.replaceChild(ctx.first, prevNode.nextSibling);
1152
+ if(ctx.first == ctx.last && (i > 0) && nextEl) {
1153
+ next_ctx = mapping.get(getKey(array[i - 1], i - 1, array));
1154
+ if(next_ctx && nextEl.previousSibling === next_ctx.last) {
1155
+ parentNode.replaceChild(ctx.first, nextEl);
1154
1156
  insert = false;
1155
1157
  }
1156
1158
  }
1157
1159
 
1158
1160
  if(insert) {
1159
- let insertBefore = prevNode?.nextSibling;
1160
1161
  let next, el = ctx.first;
1161
1162
  while(el) {
1162
1163
  next = el.nextSibling;
1163
- parentNode.insertBefore(el, insertBefore);
1164
+ parentNode.insertBefore(el, nextNode);
1164
1165
  if(el == ctx.last) break;
1165
1166
  el = next;
1166
1167
  }
1167
1168
  }
1168
1169
  }
1169
1170
  ctx.rebind?.(item, i);
1171
+ nextNode = ctx.first;
1170
1172
  } else {
1171
1173
  let $dom, rebind,
1172
1174
  d = current_destroyList = [],
1173
1175
  m = current_mountList = [],
1174
- $cd = current_cd = cd_new();
1176
+ $cd = current_cd = cd_new(eachCD);
1175
1177
  try {
1176
1178
  ([$dom, rebind] = bind(item, i));
1177
1179
  } finally {
@@ -1183,22 +1185,22 @@ function $$eachBlock(label, onlyChild, fn, getKey, bind, buildElseBlock) {
1183
1185
  ctx.first = $dom.firstChild;
1184
1186
  ctx.last = $dom.lastChild;
1185
1187
  } else ctx.first = ctx.last = $dom;
1186
- parentNode.insertBefore($dom, prevNode?.nextSibling);
1187
- safeCallMount(m, d);
1188
+ parentNode.insertBefore($dom, nextNode);
1189
+ nextNode = ctx.first;
1190
+ safeGroupCall2(m, d);
1188
1191
  if(d.length) {
1189
1192
  ctx.d = d;
1190
1193
  p_destroy = 1;
1191
1194
  }
1192
1195
  }
1193
- prevNode = ctx.last;
1194
1196
  newMapping.set(key, ctx);
1195
1197
  }
1196
- lastNode = prevNode;
1198
+ firstNode = nextNode;
1197
1199
  mapping.clear();
1198
1200
  mapping = newMapping;
1199
1201
 
1200
1202
  if(!array.length && !elseBlock && buildElseBlock) {
1201
- elseBlock = buildElseBlock(label, onlyChild, parentCD);
1203
+ elseBlock = buildElseBlock(label, mode, parentCD);
1202
1204
  }
1203
1205
  }, { cmp: compareArray });
1204
1206
  }
@@ -1245,4 +1247,4 @@ const makeSlot = (fr, fn) => {
1245
1247
  };
1246
1248
  };
1247
1249
 
1248
- export { $$eachBlock, $digest, $onDestroy, $onMount, $tick, $watch, WatchObject, __app_onerror, __bindActionSubscribe, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, awaitBlock, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callComponentDyn, callExportedFragment, cd_attach, cd_component, cd_detach, cd_new, cloneDeep, compareArray, compareDeep, configure, createTextNode, current_cd, current_component, current_destroyList, current_mountList, deepComparator, destroyResults, eachDefaultKey, exportFragment, fire, getFinalLabel, htmlBlock, htmlBlockStatic, htmlToFragment, htmlToFragmentClean, ifBlock, ifBlockReadOnly, insertAfter, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachElseBlock, makeEachSingleBlock, makeEmitter, makeExternalProperty, makeRootEvent, makeSlot, mergeAllEvents, mergeEvents, mount, mountStatic, noop, prefixPush, refer, removeElements, removeElementsBetween, removeItem, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };
1250
+ export { $$eachBlock, $context, $digest, $onDestroy, $onMount, $tick, $watch, WatchObject, __app_onerror, __bindActionSubscribe, addBlock, addClass, addEvent, addStyles, attachAnchor, attachBlock, attachDynComponent, autoSubscribe, awaitBlock, bindAction, bindAttribute, bindAttributeBase, bindClass, bindClassExp, bindInput, bindStyle, bindText, callComponent, callComponentDyn, callExportedFragment, cd_attach, cd_component, cd_detach, cd_new, cloneDeep, compareArray, compareDeep, configure, createTextNode, current_cd, current_component, current_destroyList, current_mountList, deepComparator, destroyResults, eachDefaultKey, exportFragment, fire, htmlBlock, htmlBlockStatic, htmlToFragment, htmlToFragmentClean, ifBlock, ifBlockReadOnly, insertAfter, insertBlock, invokeSlot, invokeSlotBase, isArray, isFunction, iterNodes, keyComparator, makeAnchor, makeApply, makeBlock, makeBlockBound, makeClassResolver, makeComponent, makeEachBlock, makeEachElseBlock, makeEachSingleBlock, makeEmitter, makeExternalProperty, makeRootEvent, makeSlot, mergeAllEvents, mergeEvents, mount, mountStatic, noop, prefixPush, refer, removeElements, removeItem, setClassToElement, spreadAttributes, svgToFragment, unwrapProps };