@stacksjs/stx 0.2.110 → 0.2.111
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/dist/cli.js +359 -341
- package/dist/expressions.js +6 -1
- package/dist/includes.js +1 -1
- package/dist/parser/directive-parser.d.ts +15 -0
- package/dist/parser/directive-parser.js +10 -0
- package/dist/pwa.js +111 -93
- package/dist/signal-processing.js +62 -56
- package/dist/signals.js +25 -7
- package/dist/ssg.js +340 -322
- package/package.json +5 -5
|
@@ -199,68 +199,74 @@ function isBalancedForTag(inner, tag) {
|
|
|
199
199
|
return !0;
|
|
200
200
|
}
|
|
201
201
|
export function convertSignalDirectivesToAttributes(template, context) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
continue;
|
|
218
|
-
const condition = output.substring(exprStart, i - 1).trim(), afterCondition = i;
|
|
219
|
-
let ifDepth = 1, endIdx = afterCondition;
|
|
220
|
-
const endifRegex = /@(if\s*\(|endif)/g;
|
|
221
|
-
endifRegex.lastIndex = afterCondition;
|
|
222
|
-
let endMatch;
|
|
223
|
-
while ((endMatch = endifRegex.exec(output)) !== null)
|
|
224
|
-
if (endMatch[1].startsWith("if"))
|
|
225
|
-
ifDepth++;
|
|
226
|
-
else if (endMatch[1] === "endif") {
|
|
227
|
-
ifDepth--;
|
|
228
|
-
if (ifDepth === 0) {
|
|
229
|
-
endIdx = endMatch.index + endMatch[0].length;
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
202
|
+
const signalNames = extractClientSignalNames(template);
|
|
203
|
+
function convert(input) {
|
|
204
|
+
let output = input;
|
|
205
|
+
const ifDirectiveStart = /@if\s*\(/g;
|
|
206
|
+
let match;
|
|
207
|
+
const replacements = [];
|
|
208
|
+
while ((match = ifDirectiveStart.exec(output)) !== null) {
|
|
209
|
+
const startIdx = match.index, exprStart = startIdx + match[0].length;
|
|
210
|
+
let depth = 1, i = exprStart;
|
|
211
|
+
while (i < output.length && depth > 0) {
|
|
212
|
+
if (output[i] === "(")
|
|
213
|
+
depth++;
|
|
214
|
+
else if (output[i] === ")")
|
|
215
|
+
depth--;
|
|
216
|
+
i++;
|
|
232
217
|
}
|
|
233
|
-
|
|
234
|
-
continue;
|
|
235
|
-
const content = output.substring(afterCondition, endIdx - 6).trim();
|
|
236
|
-
let replacement;
|
|
237
|
-
if (hasTopLevelElseBranch(content)) {
|
|
238
|
-
const parsed = findIfBlocks(output.substring(startIdx, endIdx));
|
|
239
|
-
if (parsed.length === 0)
|
|
218
|
+
if (depth !== 0)
|
|
240
219
|
continue;
|
|
241
|
-
const
|
|
242
|
-
|
|
220
|
+
const condition = output.substring(exprStart, i - 1).trim(), afterCondition = i;
|
|
221
|
+
let ifDepth = 1, endIdx = afterCondition;
|
|
222
|
+
const endifRegex = /@(if\s*\(|endif)/g;
|
|
223
|
+
endifRegex.lastIndex = afterCondition;
|
|
224
|
+
let endMatch;
|
|
225
|
+
while ((endMatch = endifRegex.exec(output)) !== null)
|
|
226
|
+
if (endMatch[1].startsWith("if"))
|
|
227
|
+
ifDepth++;
|
|
228
|
+
else if (endMatch[1] === "endif") {
|
|
229
|
+
ifDepth--;
|
|
230
|
+
if (ifDepth === 0) {
|
|
231
|
+
endIdx = endMatch.index + endMatch[0].length;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (ifDepth !== 0)
|
|
243
236
|
continue;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
237
|
+
const content = output.substring(afterCondition, endIdx - 6).trim();
|
|
238
|
+
let replacement;
|
|
239
|
+
if (hasTopLevelElseBranch(content)) {
|
|
240
|
+
const parsed = findIfBlocks(output.substring(startIdx, endIdx));
|
|
241
|
+
if (parsed.length === 0)
|
|
242
|
+
continue;
|
|
243
|
+
const valueBranches = parsed[0].branches.filter((b) => b.type !== "else");
|
|
244
|
+
if (!(valueBranches.length > 0 && valueBranches.every((b) => conditionIsClientReactive(b.condition, signalNames, context))))
|
|
245
|
+
continue;
|
|
246
|
+
replacement = parsed[0].branches.map((branch) => {
|
|
247
|
+
const branchContent = convert(branch.content);
|
|
248
|
+
if (branch.type === "elseif")
|
|
249
|
+
return branchToAttrElement(branchContent, "@else-if", branch.condition ?? "");
|
|
250
|
+
if (branch.type === "else")
|
|
251
|
+
return branchToAttrElement(branchContent, "@else");
|
|
252
|
+
return branchToAttrElement(branchContent, "@if", branch.condition ?? "");
|
|
253
|
+
}).join(`
|
|
251
254
|
`);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
255
|
+
} else {
|
|
256
|
+
if (!conditionIsClientReactive(condition, signalNames, context))
|
|
257
|
+
continue;
|
|
258
|
+
replacement = branchToAttrElement(convert(content), "@if", condition);
|
|
259
|
+
}
|
|
260
|
+
replacements.push({ start: startIdx, end: endIdx, replacement });
|
|
261
|
+
ifDirectiveStart.lastIndex = endIdx;
|
|
256
262
|
}
|
|
257
|
-
replacements.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
for (let i = replacements.length - 1;i >= 0; i--) {
|
|
264
|
+
const { start, end, replacement } = replacements[i];
|
|
265
|
+
output = output.substring(0, start) + replacement + output.substring(end);
|
|
266
|
+
}
|
|
267
|
+
return output;
|
|
262
268
|
}
|
|
263
|
-
return
|
|
269
|
+
return convert(template);
|
|
264
270
|
}
|
|
265
271
|
function evalLiteralCondition(expr) {
|
|
266
272
|
const trimmed = expr.trim();
|
package/dist/signals.js
CHANGED
|
@@ -1579,7 +1579,7 @@ catch (e) {
|
|
|
1579
1579
|
if (el.nodeType === Node.TEXT_NODE) {
|
|
1580
1580
|
const text = el.textContent;
|
|
1581
1581
|
if (text && text.includes('{{')) {
|
|
1582
|
-
const parts = text.split(/(\\{\\{[
|
|
1582
|
+
const parts = text.split(/(\\{\\{[\\s\\S]+?\\}\\})/g);
|
|
1583
1583
|
if (parts.length > 1) {
|
|
1584
1584
|
const fragment = document.createDocumentFragment();
|
|
1585
1585
|
const parentEl = el.parentNode;
|
|
@@ -1588,7 +1588,7 @@ catch (e) {
|
|
|
1588
1588
|
// through nested @if/@for processing where componentScope may be restored
|
|
1589
1589
|
const capturedScope = { ...scope, ...(findElementScope(parentEl) || {}), ...globalHelpers };
|
|
1590
1590
|
parts.forEach(part => {
|
|
1591
|
-
const match = part.match(/^\\{\\{\\s*(
|
|
1591
|
+
const match = part.match(/^\\{\\{\\s*([\\s\\S]+?)\\s*\\}\\}$/);
|
|
1592
1592
|
if (match) {
|
|
1593
1593
|
const expr = match[1];
|
|
1594
1594
|
// Skip placeholder expressions like __TITLE__ (build-time placeholders)
|
|
@@ -2775,6 +2775,18 @@ catch (e) {
|
|
|
2775
2775
|
b.placeholder = document.createComment('stx-if-chain');
|
|
2776
2776
|
parent.insertBefore(b.placeholder, b.el);
|
|
2777
2777
|
b.el.removeAttribute(b.attr);
|
|
2778
|
+
// A <template> branch (the wrapper convertSignalDirectivesToAttributes
|
|
2779
|
+
// emits for a multi-child / text branch) is INERT \u2014 inserting the element
|
|
2780
|
+
// renders nothing, its content lives in a document fragment. Clone that
|
|
2781
|
+
// content ONCE into a stable node set we toggle in and out, exactly as
|
|
2782
|
+
// bindIf/bindFor already do for template elements. An element branch is
|
|
2783
|
+
// its own single node. Without this, a multi-element @else / @else-if
|
|
2784
|
+
// branch rendered blank the moment the markup was well-formed enough to
|
|
2785
|
+
// survive as a real <template> (the #1784 markup fix). See #1784.
|
|
2786
|
+
b.isTemplate = b.el.tagName === 'TEMPLATE';
|
|
2787
|
+
b.nodes = b.isTemplate
|
|
2788
|
+
? Array.prototype.slice.call(b.el.content.cloneNode(true).childNodes)
|
|
2789
|
+
: [b.el];
|
|
2778
2790
|
b.el.remove();
|
|
2779
2791
|
b.childrenProcessed = false;
|
|
2780
2792
|
});
|
|
@@ -2858,13 +2870,16 @@ catch (e2) {
|
|
|
2858
2870
|
// components under reactive conditionals (#1737). Permanent disposal is
|
|
2859
2871
|
// still handled by bindFor (item removal) and cleanupContainer (SPA nav).
|
|
2860
2872
|
if (currentIdx !== -1) {
|
|
2861
|
-
chain[currentIdx].
|
|
2873
|
+
chain[currentIdx].nodes.forEach(function (n) { if (n.parentNode) n.parentNode.removeChild(n); });
|
|
2862
2874
|
}
|
|
2863
2875
|
|
|
2864
2876
|
// Insert + process the newly-picked branch.
|
|
2865
2877
|
if (pickedIdx !== -1) {
|
|
2866
2878
|
var pick = chain[pickedIdx];
|
|
2867
|
-
|
|
2879
|
+
// Insert this branch's node(s) before the placeholder's next sibling.
|
|
2880
|
+
// The anchor is captured once so the nodes stack in source order.
|
|
2881
|
+
var anchor = pick.placeholder.nextSibling;
|
|
2882
|
+
pick.nodes.forEach(function (n) { pick.placeholder.parentNode.insertBefore(n, anchor); });
|
|
2868
2883
|
pick.el.__stx_shown_at = performance.now();
|
|
2869
2884
|
if (!pick.childrenProcessed) {
|
|
2870
2885
|
pick.childrenProcessed = true;
|
|
@@ -2874,9 +2889,12 @@ catch (e2) {
|
|
|
2874
2889
|
(function (branch) {
|
|
2875
2890
|
setTimeout(function () {
|
|
2876
2891
|
var childScope = { ...capturedComponentScope, ...(branch.capturedElementScope || {}), ...globalHelpers };
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2892
|
+
branch.nodes.forEach(function (n) {
|
|
2893
|
+
if (n.nodeType !== 1) return; // whitespace/text between template children
|
|
2894
|
+
processElement(n, childScope);
|
|
2895
|
+
n.removeAttribute('x-cloak');
|
|
2896
|
+
n.querySelectorAll('[x-cloak]').forEach(function (c) { c.removeAttribute('x-cloak'); });
|
|
2897
|
+
});
|
|
2880
2898
|
}, 0);
|
|
2881
2899
|
})(pick);
|
|
2882
2900
|
}
|