@sola-air-ui/compiler 1.5.0 → 1.5.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +33 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sola-air-ui/compiler",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
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/index.js CHANGED
@@ -1301,7 +1301,7 @@ export function compile(source, options = {}) {
1301
1301
  }
1302
1302
  }
1303
1303
 
1304
- function emitNode(node, parentVar, locals = new Set()) {
1304
+ function emitNode(node, parentVar, locals = new Set(), inSvg = false) {
1305
1305
  if (!node) return;
1306
1306
  // Template-expression rewrite with the current template scope (each-item /
1307
1307
  // each-index names shadow signals of the same name).
@@ -1450,7 +1450,7 @@ export function compile(source, options = {}) {
1450
1450
  domCode += ` ${cid}_ctx = pushContext();\n`;
1451
1451
  domCode += ` try {\n`;
1452
1452
  domCode += ` const f = document.createDocumentFragment();\n`;
1453
- branch.children.forEach(child => emitNode(child, 'f', locals));
1453
+ branch.children.forEach(child => emitNode(child, 'f', locals, inSvg));
1454
1454
  domCode += ` Array.from(f.childNodes).forEach(n => ${cid}_els.push(n));\n`;
1455
1455
  domCode += ` ${cid}_a.parentNode.insertBefore(f, ${cid}_a.nextSibling);\n`;
1456
1456
  domCode += ` } finally { popContext(${cid}_ctx); }\n`;
@@ -1508,7 +1508,7 @@ export function compile(source, options = {}) {
1508
1508
  domCode += ` const _kctx = pushContext();\n`;
1509
1509
  domCode += ` try {\n`;
1510
1510
  domCode += ` const f = document.createDocumentFragment();\n`;
1511
- node.children.forEach(child => emitNode(child, 'f', eachLocals));
1511
+ node.children.forEach(child => emitNode(child, 'f', eachLocals, inSvg));
1512
1512
  domCode += ` _entry = { nodes: Array.from(f.childNodes), ctx: _kctx };\n`;
1513
1513
  domCode += ` } finally { popContext(_kctx); }\n`;
1514
1514
  domCode += ` ${eid}_keyMap.set(_key, _entry);\n`;
@@ -1537,7 +1537,7 @@ export function compile(source, options = {}) {
1537
1537
  domCode += ` for (let _i = 0; _i < _items.length; _i++) {\n`;
1538
1538
  domCode += ` const ${node.attribs.item} = _items[_i];\n`;
1539
1539
  if (node.attribs.index) domCode += ` const ${node.attribs.index} = _i;\n`;
1540
- node.children.forEach(child => emitNode(child, 'f', eachLocals));
1540
+ node.children.forEach(child => emitNode(child, 'f', eachLocals, inSvg));
1541
1541
  domCode += ` }\n`;
1542
1542
  domCode += ` Array.from(f.childNodes).forEach(n => ${eid}_els.push(n));\n`;
1543
1543
  domCode += ` ${eid}_a.parentNode.insertBefore(f, ${eid}_a.nextSibling);\n`;
@@ -1548,8 +1548,14 @@ export function compile(source, options = {}) {
1548
1548
  }
1549
1549
 
1550
1550
  // Normal element
1551
+ const isSvg = inSvg || node.name === 'svg';
1552
+ const childSvg = isSvg && node.name !== 'foreignObject';
1551
1553
  const id = `n${uid++}`;
1552
- domCode += ` const ${id} = document.createElement('${node.name}');\n`;
1554
+ if (isSvg) {
1555
+ domCode += ` const ${id} = document.createElementNS('http://www.w3.org/2000/svg', '${node.name}');\n`;
1556
+ } else {
1557
+ domCode += ` const ${id} = document.createElement('${node.name}');\n`;
1558
+ }
1553
1559
 
1554
1560
  if (hasStyles) {
1555
1561
  domCode += ` ${id}.classList.add('${scopeHash}');\n`;
@@ -1565,7 +1571,11 @@ export function compile(source, options = {}) {
1565
1571
  domCode += ` createEffect(() => { const _v = !!(${expr}); if (_v) ${id}.setAttribute('${key}', ''); else ${id}.removeAttribute('${key}'); });\n`;
1566
1572
  } else if (key === 'class' || key === 'className') {
1567
1573
  const suffix = hasStyles ? ` + ' ${scopeHash}'` : '';
1568
- domCode += ` createEffect(() => { ${id}.className = (${expr})${suffix}; });\n`;
1574
+ if (isSvg) {
1575
+ domCode += ` createEffect(() => { ${id}.setAttribute('class', (${expr})${suffix}); });\n`;
1576
+ } else {
1577
+ domCode += ` createEffect(() => { ${id}.className = (${expr})${suffix}; });\n`;
1578
+ }
1569
1579
  } else {
1570
1580
  domCode += ` createEffect(() => { ${id}.setAttribute('${key}', String(${expr})); });\n`;
1571
1581
  }
@@ -1587,13 +1597,22 @@ export function compile(source, options = {}) {
1587
1597
  domCode += ` ${id}.addEventListener('input', (e) => { set_${bound}(e.target.value); });\n`;
1588
1598
  domCode += ` createEffect(() => { ${id}.value = ${bound}() ?? ''; });\n`;
1589
1599
  } else if (prop === 'this') {
1590
- domCode += ` ${bound} = ${id};\n`;
1600
+ if (stateVars.has(bound)) {
1601
+ domCode += ` set_${bound}(${id});\n`;
1602
+ } else {
1603
+ domCode += ` ${bound} = ${id};\n`;
1604
+ }
1591
1605
  }
1592
1606
  } else if (key === 'class' || key === 'className') {
1593
1607
  // Static values: emit as a plain string literal. A template literal here
1594
1608
  // would let a backtick or ${ in the markup break out into expression
1595
1609
  // position; JSON.stringify cannot.
1596
- domCode += ` ${id}.className += ' ' + ${JSON.stringify(val)};\n`;
1610
+ if (isSvg) {
1611
+ const clsVal = hasStyles ? `${scopeHash} ${val}` : val;
1612
+ domCode += ` ${id}.setAttribute('class', ${JSON.stringify(clsVal)});\n`;
1613
+ } else {
1614
+ domCode += ` ${id}.className += ' ' + ${JSON.stringify(val)};\n`;
1615
+ }
1597
1616
  } else {
1598
1617
  domCode += ` ${id}.setAttribute(${JSON.stringify(key)}, ${JSON.stringify(val)});\n`;
1599
1618
  }
@@ -1603,7 +1622,7 @@ export function compile(source, options = {}) {
1603
1622
 
1604
1623
  if (node.children && !VOID_ELEMENTS.has(node.name)) {
1605
1624
  for (const child of node.children) {
1606
- emitNode(child, id, locals);
1625
+ emitNode(child, id, locals, childSvg);
1607
1626
  }
1608
1627
  }
1609
1628
  }
@@ -1647,7 +1666,8 @@ export function compile(source, options = {}) {
1647
1666
  output += `\n`;
1648
1667
  output += `export default function mount(__target, props = {}) {\n`;
1649
1668
  }
1650
- output += ` const __ctx = pushContext();\n\n`;
1669
+ output += ` const __ctx = pushContext();\n`;
1670
+ output += ` try {\n\n`;
1651
1671
 
1652
1672
  if (hasStyles) {
1653
1673
  // Styles go into whichever root the component actually lives in: the
@@ -1681,9 +1701,11 @@ export function compile(source, options = {}) {
1681
1701
  output += domCode;
1682
1702
 
1683
1703
  output += `\n __flush_mounts(__ctx);\n`;
1704
+ output += ` } finally {\n`;
1705
+ output += ` popContext(__ctx);\n`;
1706
+ output += ` }\n`;
1684
1707
  output += `\n return () => {\n`;
1685
1708
  output += ` __flush_destroys(__ctx);\n`;
1686
- output += ` popContext(__ctx);\n`;
1687
1709
  output += ` __target.innerHTML = '';\n`;
1688
1710
  output += ` };\n`;
1689
1711
  output += `};\n`;