@sprlab/wccompiler 0.5.4 → 0.5.6
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 +2 -2
- package/lib/sfc-parser.js +52 -9
- package/lib/tree-walker.js +8 -0
- package/package.json +1 -1
package/lib/codegen.js
CHANGED
|
@@ -473,7 +473,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
|
|
|
473
473
|
lines.push(`${indent} const __sp = { ${propsEntries} };`);
|
|
474
474
|
lines.push(`${indent} let __h = __slotEl.innerHTML;`);
|
|
475
475
|
lines.push(`${indent} for (const [k, v] of Object.entries(__sp)) {`);
|
|
476
|
-
lines.push(`${indent} __h = __h.replace(new RegExp('\\\\{\\\\{\\\\s*' + k + '\\\\s*\\\\}\\\\}', 'g'), v ?? '');`);
|
|
476
|
+
lines.push(`${indent} __h = __h.replace(new RegExp('\\\\{\\\\{\\\\s*' + k + '(\\\\(\\\\))?\\\\s*\\\\}\\\\}', 'g'), v ?? '');`);
|
|
477
477
|
lines.push(`${indent} }`);
|
|
478
478
|
lines.push(`${indent} __slotEl.innerHTML = __h;`);
|
|
479
479
|
lines.push(`${indent} }`);
|
|
@@ -788,7 +788,7 @@ export function generateComponent(parseResult, options = {}) {
|
|
|
788
788
|
lines.push(` const __props = { ${propsObj} };`);
|
|
789
789
|
lines.push(` let __html = this.__slotTpl_${s.name};`);
|
|
790
790
|
lines.push(" for (const [k, v] of Object.entries(__props)) {");
|
|
791
|
-
lines.push(` __html = __html.replace(new RegExp('\\\\{\\\\{\\\\s*' + k + '\\\\s*\\\\}\\\\}', 'g'), v ?? '');`);
|
|
791
|
+
lines.push(` __html = __html.replace(new RegExp('\\\\{\\\\{\\\\s*' + k + '(\\\\(\\\\))?\\\\s*\\\\}\\\\}', 'g'), v ?? '');`);
|
|
792
792
|
lines.push(' }');
|
|
793
793
|
lines.push(` this.${s.varName}.innerHTML = __html;`);
|
|
794
794
|
lines.push(' });');
|
package/lib/sfc-parser.js
CHANGED
|
@@ -57,16 +57,59 @@ function findBlocks(source, blockName) {
|
|
|
57
57
|
let m;
|
|
58
58
|
|
|
59
59
|
while ((m = openRe.exec(source)) !== null) {
|
|
60
|
+
const attrs = m[1] || '';
|
|
61
|
+
|
|
62
|
+
// For template blocks: skip <template #name> (slot content, not SFC block)
|
|
63
|
+
if (blockName === 'template' && /#/.test(attrs)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
60
67
|
const openEnd = m.index + m[0].length;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
|
|
69
|
+
// Use depth counting to find the matching close tag (handles nested <template #name>)
|
|
70
|
+
if (blockName === 'template') {
|
|
71
|
+
let depth = 1;
|
|
72
|
+
let searchPos = openEnd;
|
|
73
|
+
let closeIdx = -1;
|
|
74
|
+
const openTagRe = /<template[\s>]/g;
|
|
75
|
+
const closeTagStr = '</template>';
|
|
76
|
+
|
|
77
|
+
while (depth > 0 && searchPos < source.length) {
|
|
78
|
+
const nextClose = source.indexOf(closeTagStr, searchPos);
|
|
79
|
+
if (nextClose === -1) break;
|
|
80
|
+
|
|
81
|
+
// Check for any opening <template> between searchPos and nextClose
|
|
82
|
+
openTagRe.lastIndex = searchPos;
|
|
83
|
+
let openMatch;
|
|
84
|
+
while ((openMatch = openTagRe.exec(source)) !== null && openMatch.index < nextClose) {
|
|
85
|
+
depth++;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
depth--; // for the </template> we found
|
|
89
|
+
if (depth === 0) {
|
|
90
|
+
closeIdx = nextClose;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
searchPos = nextClose + closeTagStr.length;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (closeIdx === -1) continue;
|
|
97
|
+
matches.push({
|
|
98
|
+
content: source.slice(openEnd, closeIdx),
|
|
99
|
+
attrs,
|
|
100
|
+
start: m.index,
|
|
101
|
+
end: closeIdx + closeTag.length,
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
const closeIdx = source.indexOf(closeTag, openEnd);
|
|
105
|
+
if (closeIdx === -1) continue;
|
|
106
|
+
matches.push({
|
|
107
|
+
content: source.slice(openEnd, closeIdx),
|
|
108
|
+
attrs,
|
|
109
|
+
start: m.index,
|
|
110
|
+
end: closeIdx + closeTag.length,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
70
113
|
}
|
|
71
114
|
|
|
72
115
|
return matches;
|
package/lib/tree-walker.js
CHANGED
|
@@ -74,6 +74,14 @@ export function walkTree(rootEl, signalNames, computedNames, propNames = new Set
|
|
|
74
74
|
if (node.nodeType === 1) {
|
|
75
75
|
const el = /** @type {Element} */ (node);
|
|
76
76
|
|
|
77
|
+
// Skip <template #name> elements — they are slot content passed to child components
|
|
78
|
+
// Their interpolations are resolved by the provider, not the consumer
|
|
79
|
+
if (el.tagName === 'TEMPLATE') {
|
|
80
|
+
for (const attr of Array.from(el.attributes)) {
|
|
81
|
+
if (attr.name.startsWith('#')) return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
// Detect <slot> elements — replace with <span data-slot="..."> placeholder
|
|
78
86
|
if (el.tagName === 'SLOT') {
|
|
79
87
|
const slotName = el.getAttribute('name') || '';
|
package/package.json
CHANGED