@sola-air-ui/compiler 1.5.2 → 1.5.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sola-air-ui/compiler",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Compiler for Sola single-file components (.sola) \u2014 transforms template + script + style to ES modules",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/check-cli.js CHANGED
File without changes
package/src/check.js CHANGED
@@ -105,7 +105,7 @@ export function checkSource(source, filename = 'component.sola') {
105
105
  add(at, 'error', 'SOLA001', '`{:else if}` is missing a condition. It renders as literal text.');
106
106
  }
107
107
  } else {
108
- add(at, 'error', 'SOLA001', '`{:else}` unexpected token (use `{:else}` or `{:else if <condition>}`). It renders as literal text.');
108
+ add(at, 'error', 'SOLA001', '`{:else}` has extra text after it (use `{:else}` or `{:else if <condition>}`). It renders as literal text.');
109
109
  }
110
110
  }
111
111
  }
package/src/index.js CHANGED
@@ -73,9 +73,9 @@ function addScopeToCompound(compound, scopeHash) {
73
73
  // :global(body) → body
74
74
  // The scope class always goes on the last compound that is not global.
75
75
  function scopeSelector(selector, scopeHash) {
76
- const tokens = []; // alternating compounds and combinators
76
+ const pieces = []; // alternating compounds and combinators
77
77
  let depth = 0, cur = '', comb = '';
78
- const flushCompound = () => { if (cur) { tokens.push({ compound: cur }); cur = ''; } };
78
+ const flushCompound = () => { if (cur) { pieces.push({ compound: cur }); cur = ''; } };
79
79
  for (let i = 0; i < selector.length; i++) {
80
80
  const c = selector[i];
81
81
  if (c === '(' || c === '[') depth++;
@@ -85,15 +85,15 @@ function scopeSelector(selector, scopeHash) {
85
85
  comb += c;
86
86
  continue;
87
87
  }
88
- if (comb) { tokens.push({ comb }); comb = ''; }
88
+ if (comb) { pieces.push({ comb }); comb = ''; }
89
89
  cur += c;
90
90
  }
91
91
  flushCompound();
92
- if (comb) tokens.push({ comb });
92
+ if (comb) pieces.push({ comb });
93
93
 
94
94
  let last = -1;
95
- for (let i = 0; i < tokens.length; i++) {
96
- const t = tokens[i];
95
+ for (let i = 0; i < pieces.length; i++) {
96
+ const t = pieces[i];
97
97
  if (t.compound === undefined) continue;
98
98
  const m = t.compound.match(/^:global\(([\s\S]*)\)$/);
99
99
  // A comma list must stay grouped, or `.a :global(.x, .y)` would turn into
@@ -105,8 +105,8 @@ function scopeSelector(selector, scopeHash) {
105
105
  t.global = true;
106
106
  } else { last = i; }
107
107
  }
108
- if (last >= 0) tokens[last].compound = addScopeToCompound(tokens[last].compound, scopeHash);
109
- return tokens.map(t => t.compound ?? t.comb).join('');
108
+ if (last >= 0) pieces[last].compound = addScopeToCompound(pieces[last].compound, scopeHash);
109
+ return pieces.map(t => t.compound ?? t.comb).join('');
110
110
  }
111
111
 
112
112
  function scopeSelectorList(selector, scopeHash) {
@@ -1504,12 +1504,24 @@ export function compile(source, options = {}) {
1504
1504
  domCode += ` const _key = String(${keyExpr});\n`;
1505
1505
  domCode += ` _seen.add(_key);\n`;
1506
1506
  domCode += ` let _entry = ${eid}_keyMap.get(_key);\n`;
1507
+ // A row's bindings read the item it was built with. When the list hands
1508
+ // back a different object for the same key (an immutable update such as
1509
+ // items.map(i => i.id === id ? { ...i, done: true } : i)), or the index the
1510
+ // row shows has changed, rebuild that row; rows whose item is the same
1511
+ // object are kept as they are.
1512
+ domCode += ` if (_entry && (_entry.item !== ${node.attribs.item}${node.attribs.index ? ` || _entry.index !== _i` : ''})) {\n`;
1513
+ domCode += ` __flush_destroys(_entry.ctx);\n`;
1514
+ domCode += ` const _old = _entry.nodes;\n`;
1515
+ domCode += ` if (_old.includes(_cursor)) _cursor = _old[_old.length - 1].nextSibling;\n`;
1516
+ domCode += ` _old.forEach(n => n.remove());\n`;
1517
+ domCode += ` _entry = null;\n`;
1518
+ domCode += ` }\n`;
1507
1519
  domCode += ` if (!_entry) {\n`;
1508
1520
  domCode += ` const _kctx = pushContext();\n`;
1509
1521
  domCode += ` try {\n`;
1510
1522
  domCode += ` const f = document.createDocumentFragment();\n`;
1511
1523
  node.children.forEach(child => emitNode(child, 'f', eachLocals, inSvg));
1512
- domCode += ` _entry = { nodes: Array.from(f.childNodes), ctx: _kctx };\n`;
1524
+ domCode += ` _entry = { nodes: Array.from(f.childNodes), ctx: _kctx, item: ${node.attribs.item}${node.attribs.index ? ', index: _i' : ''} };\n`;
1513
1525
  domCode += ` } finally { popContext(_kctx); }\n`;
1514
1526
  domCode += ` ${eid}_keyMap.set(_key, _entry);\n`;
1515
1527
  domCode += ` }\n`;