mnfst-render 0.3.1 → 0.3.3
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/manifest.render.mjs +19 -6
- package/package.json +1 -1
package/manifest.render.mjs
CHANGED
|
@@ -895,25 +895,37 @@ function stripPrerenderedXDataDirectives(html) {
|
|
|
895
895
|
|
|
896
896
|
// --- Don't bake Alpine-only state into the snapshot; only $x-driven content should be prerendered.
|
|
897
897
|
// For any :attr or x-bind:attr whose expression does NOT contain $x, remove the literal attr from the tag
|
|
898
|
-
// so Alpine re-evaluates on load. Bindings that use $x are left as-is (content stays for SEO)
|
|
898
|
+
// so Alpine re-evaluates on load. Bindings that use $x are left as-is (content stays for SEO), except
|
|
899
|
+
// :style / x-bind:style with $x: those must be removed when a baked inline style exists, or Alpine will
|
|
900
|
+
// overwrite prerendered values (e.g. mask-image) on hydrate when $x is briefly empty in production.
|
|
899
901
|
// Use (?<!:) so we only strip literal attr=, not :attr= (e.g. class= not :class=).
|
|
900
902
|
// Never touch <script> tags (loader + injected plugins must be preserved; static HTML still runs them).
|
|
901
903
|
function stripPrerenderDynamicBindings(html) {
|
|
902
904
|
return html.replace(/<(\w+)([^>]*)>/g, (match, tagName, attrsStr) => {
|
|
903
905
|
if (tagName.toLowerCase() === 'script') return match;
|
|
904
906
|
const isAnchor = tagName.toLowerCase() === 'a';
|
|
907
|
+
let workAttrs = attrsStr;
|
|
908
|
+
workAttrs = workAttrs.replace(/\s+:style=(?:"([^"]*)"|'([^']*)')/gi, (sub, d, s) => {
|
|
909
|
+
const val = (d !== undefined ? d : s) || '';
|
|
910
|
+
return val.indexOf('$x') !== -1 ? '' : sub;
|
|
911
|
+
});
|
|
912
|
+
workAttrs = workAttrs.replace(/\s+x-bind:style=(?:"([^"]*)"|'([^']*)')/gi, (sub, d, s) => {
|
|
913
|
+
const val = (d !== undefined ? d : s) || '';
|
|
914
|
+
return val.indexOf('$x') !== -1 ? '' : sub;
|
|
915
|
+
});
|
|
916
|
+
|
|
905
917
|
const toStrip = new Set();
|
|
906
918
|
const bindingRegex = /(?:^|\s)(?::|x-bind:)(\w+)=(?:"([^"]*)"|'([^']*)')/g;
|
|
907
919
|
let m;
|
|
908
|
-
while ((m = bindingRegex.exec(
|
|
920
|
+
while ((m = bindingRegex.exec(workAttrs)) !== null) {
|
|
909
921
|
const attrName = (m[1] || '').toLowerCase();
|
|
910
922
|
// Keep href on anchors so prerendered static navigation stays valid.
|
|
911
923
|
if (attrName === 'class' || attrName === 'style' || (isAnchor && attrName === 'href')) continue;
|
|
912
924
|
const val = (m[2] !== undefined ? m[2] : m[3]) || '';
|
|
913
925
|
if (val.indexOf('$x') === -1) toStrip.add(attrName);
|
|
914
926
|
}
|
|
915
|
-
if (toStrip.size === 0) return match;
|
|
916
|
-
let newAttrs =
|
|
927
|
+
if (toStrip.size === 0 && workAttrs === attrsStr) return match;
|
|
928
|
+
let newAttrs = workAttrs;
|
|
917
929
|
for (const attr of toStrip) {
|
|
918
930
|
const esc = attr.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
919
931
|
newAttrs = newAttrs.replace(new RegExp(`\\s*(?<!:)${esc}="[^"]*"`, 'gi'), '');
|
|
@@ -1785,7 +1797,8 @@ async function runPrerender(config) {
|
|
|
1785
1797
|
// keep x-text/x-bind referencing card/item — Alpine then mutates or errors on the static HTML.)
|
|
1786
1798
|
await page.evaluate(() => {
|
|
1787
1799
|
const loopVarRegex = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
|
|
1788
|
-
|
|
1800
|
+
// Include x-init: expanded clones still had x-init="getDescription(article)" etc.; Alpine then throws (article undefined).
|
|
1801
|
+
const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-on:|@)/;
|
|
1789
1802
|
const hasVar = (expr, varName) => varName && new RegExp(`\\b${varName}\\b`).test(expr || '');
|
|
1790
1803
|
const stripLoopBindings = (el, itemVar, indexVar) => {
|
|
1791
1804
|
const nodes = [el, ...Array.from(el.querySelectorAll('*'))];
|
|
@@ -1879,7 +1892,7 @@ async function runPrerender(config) {
|
|
|
1879
1892
|
// outside their template scope. These throw Alpine errors in live static hosting.
|
|
1880
1893
|
await page.evaluate(() => {
|
|
1881
1894
|
const loopVarRegex = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
|
|
1882
|
-
const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-on:|@)/;
|
|
1895
|
+
const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-on:|@)/;
|
|
1883
1896
|
const hasVar = (expr, varName) => varName && new RegExp(`\\b${varName}\\b`).test(expr || '');
|
|
1884
1897
|
const elementReferencesLoopScope = (el, itemVar, indexVar) => {
|
|
1885
1898
|
if (!el) return false;
|