@sprlab/wccompiler 0.16.10 → 0.16.12

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/lib/codegen.js CHANGED
@@ -1138,14 +1138,25 @@ export function generateComponent(parseResult, options = {}) {
1138
1138
  if (slots.length > 0) {
1139
1139
  lines.push(' const __slotMap = {};');
1140
1140
  lines.push(' const __defaultSlotNodes = [];');
1141
+ lines.push(' const __templatesToRemove = [];');
1141
1142
  lines.push(' for (const child of Array.from(this.childNodes)) {');
1142
1143
  lines.push(" if (child.nodeName === 'TEMPLATE') {");
1144
+ lines.push(' let handled = false;');
1143
1145
  lines.push(' for (const attr of child.attributes) {');
1144
1146
  lines.push(" if (attr.name.startsWith('#')) {");
1145
1147
  lines.push(' const slotName = attr.name.slice(1);');
1146
1148
  lines.push(' __slotMap[slotName] = { content: child.innerHTML, propsExpr: attr.value };');
1149
+ lines.push(' handled = true;');
1150
+ lines.push(' } else if (attr.name === "slot") {');
1151
+ // NEW: <template slot="name"> syntax (Vue standard)
1152
+ lines.push(' const slotName = attr.value;');
1153
+ lines.push(" const propsExpr = child.getAttribute('slot-props') || '';");
1154
+ lines.push(" child.removeAttribute('slot-props');");
1155
+ lines.push(' __slotMap[slotName] = { content: child.innerHTML, propsExpr };');
1156
+ lines.push(' handled = true;');
1147
1157
  lines.push(' }');
1148
1158
  lines.push(' }');
1159
+ lines.push(' if (handled) __templatesToRemove.push(child);');
1149
1160
  lines.push(" } else if (child.nodeType === 1 && child.getAttribute('slot')) {");
1150
1161
  // NEW: regular element with slot="name" (cross-framework support)
1151
1162
  lines.push(" const slotName = child.getAttribute('slot');");
@@ -1154,21 +1165,15 @@ export function generateComponent(parseResult, options = {}) {
1154
1165
  lines.push(" child.removeAttribute('slot-props');");
1155
1166
  lines.push(" __slotMap[slotName] = { content: propsExpr ? child.innerHTML : child.outerHTML, propsExpr };");
1156
1167
  lines.push(" } else if (child.nodeType === 1) {");
1157
- // NEW: check for slot-template-<name> attributes (React/Angular string attribute pattern)
1158
- lines.push(" for (const attr of Array.from(child.attributes)) {");
1159
- lines.push(" if (attr.name.startsWith('slot-template-')) {");
1160
- lines.push(" const slotName = attr.name.slice('slot-template-'.length);");
1161
- lines.push(" if (!__slotMap[slotName]) {");
1162
- lines.push(" __slotMap[slotName] = { content: attr.value, propsExpr: '' };");
1163
- lines.push(" }");
1164
- lines.push(" child.removeAttribute(attr.name);");
1165
- lines.push(" }");
1166
- lines.push(" }");
1167
1168
  lines.push(" __defaultSlotNodes.push(child);");
1168
1169
  lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {");
1169
1170
  lines.push(' __defaultSlotNodes.push(child);');
1170
1171
  lines.push(' }');
1171
1172
  lines.push(' }');
1173
+ // Remove processed template elements to prevent them from appearing in default slot
1174
+ lines.push(' for (const tpl of __templatesToRemove) {');
1175
+ lines.push(' if (tpl.parentNode) tpl.parentNode.removeChild(tpl);');
1176
+ lines.push(' }');
1172
1177
  }
1173
1178
 
1174
1179
  // Clone template
@@ -1312,15 +1317,8 @@ export function generateComponent(parseResult, options = {}) {
1312
1317
  lines.push(" __sm[sn] = { content: pe ? child.innerHTML : child.outerHTML, propsExpr: pe };");
1313
1318
  lines.push(" child.remove();");
1314
1319
  lines.push(" } else if (child.nodeType === 1) {");
1315
- lines.push(" for (const attr of Array.from(child.attributes)) {");
1316
- lines.push(" if (attr.name.startsWith('slot-template-')) {");
1317
- lines.push(" const sn = attr.name.slice('slot-template-'.length);");
1318
- lines.push(" if (!__sm[sn]) { __sm[sn] = { content: attr.value, propsExpr: '' }; }");
1319
- lines.push(" child.removeAttribute(attr.name);");
1320
- lines.push(" }");
1321
- lines.push(" }");
1322
1320
  lines.push(" __dn.push(child);");
1323
- lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {");
1321
+ lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {",);
1324
1322
  lines.push(" __dn.push(child);");
1325
1323
  lines.push(' }');
1326
1324
  lines.push(' }');
package/lib/sfc-parser.js CHANGED
@@ -287,16 +287,21 @@ export function parseSFC(source, fileName = '<unknown>') {
287
287
  }
288
288
 
289
289
  // Collect all block ranges for unexpected-content check
290
+ // Use filtered templateBlocks (main SFC template only, not nested slot templates)
291
+ // The main template's range already covers all nested content including <template slot="name">
290
292
  /** @type {Array<{start: number, end: number}>} */
291
293
  const allRanges = [
292
294
  ...scriptBlocks,
293
- ...templateBlocks,
295
+ ...templateBlocks, // Only main SFC blocks (filtered to exclude slot templates)
294
296
  ...styleBlocks,
295
297
  ].sort((a, b) => a.start - b.start);
296
298
 
297
- // Temporarily disable unexpected content validation due to issues with nested slot templates
298
- // TODO: Fix validateNoUnexpectedContent to properly handle nested <template slot="name"> elements
299
- // validateNoUnexpectedContent(source, allRanges, fileName);
299
+ // Validate unexpected content ONLY if there are no nested slot templates
300
+ // Nested <template slot="name"> elements can cause false positives in range validation
301
+ const hasNestedSlotTemplates = allTemplateBlocks.length > templateBlocks.length;
302
+ if (!hasNestedSlotTemplates) {
303
+ validateNoUnexpectedContent(source, allRanges, fileName);
304
+ }
300
305
 
301
306
  // Extract block contents
302
307
  const scriptContent = scriptBlocks[0].content;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprlab/wccompiler",
3
- "version": "0.16.10",
3
+ "version": "0.16.12",
4
4
  "description": "Zero-runtime compiler that transforms .wcc single-file components into native web components with signals-based reactivity",
5
5
  "type": "module",
6
6
  "exports": {