mnfst-render 0.3.3 → 0.3.5
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 +32 -2
- package/package.json +1 -1
package/manifest.render.mjs
CHANGED
|
@@ -904,6 +904,7 @@ function stripPrerenderDynamicBindings(html) {
|
|
|
904
904
|
return html.replace(/<(\w+)([^>]*)>/g, (match, tagName, attrsStr) => {
|
|
905
905
|
if (tagName.toLowerCase() === 'script') return match;
|
|
906
906
|
const isAnchor = tagName.toLowerCase() === 'a';
|
|
907
|
+
const isImg = tagName.toLowerCase() === 'img';
|
|
907
908
|
let workAttrs = attrsStr;
|
|
908
909
|
workAttrs = workAttrs.replace(/\s+:style=(?:"([^"]*)"|'([^']*)')/gi, (sub, d, s) => {
|
|
909
910
|
const val = (d !== undefined ? d : s) || '';
|
|
@@ -919,8 +920,9 @@ function stripPrerenderDynamicBindings(html) {
|
|
|
919
920
|
let m;
|
|
920
921
|
while ((m = bindingRegex.exec(workAttrs)) !== null) {
|
|
921
922
|
const attrName = (m[1] || '').toLowerCase();
|
|
922
|
-
// Keep href on anchors
|
|
923
|
-
|
|
923
|
+
// Keep href on anchors and src on images: :href / :src often reference x-for iterators (e.g.
|
|
924
|
+
// article?.banner). Stripping the baked literal leaves only :src/:href and breaks static HTML.
|
|
925
|
+
if (attrName === 'class' || attrName === 'style' || (isAnchor && attrName === 'href') || (isImg && attrName === 'src')) continue;
|
|
924
926
|
const val = (m[2] !== undefined ? m[2] : m[3]) || '';
|
|
925
927
|
if (val.indexOf('$x') === -1) toStrip.add(attrName);
|
|
926
928
|
}
|
|
@@ -937,6 +939,32 @@ function stripPrerenderDynamicBindings(html) {
|
|
|
937
939
|
});
|
|
938
940
|
}
|
|
939
941
|
|
|
942
|
+
// Drop :src / x-bind:src when img already has a baked src= (x-for / iterator expressions break hydrate).
|
|
943
|
+
function stripRedundantImgSrcBindings(html) {
|
|
944
|
+
return html.replace(/<img\b([^>]*)>/gi, (full, attrs) => {
|
|
945
|
+
const srcM = attrs.match(/\ssrc=(["'])([\s\S]*?)\1/i);
|
|
946
|
+
if (!srcM || !String(srcM[2] || '').trim()) return full;
|
|
947
|
+
if (!/\s:src\s*=|\sx-bind:src\s*=/i.test(attrs)) return full;
|
|
948
|
+
let next = attrs.replace(/\s:src=(?:"[^"]*"|'[^']*')/gi, '');
|
|
949
|
+
next = next.replace(/\sx-bind:src=(?:"[^"]*"|'[^']*')/gi, '');
|
|
950
|
+
return `<img${next}>`;
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* Manifest runtime replaces <x-*> component placeholders by fetching source .html, which wipes
|
|
956
|
+
* prerender-baked markup (stripped :style, expanded lists, etc.). Tag opens with data-pre-rendered
|
|
957
|
+
* are skipped by manifest.components.processor — required for static prerender output to hydrate correctly.
|
|
958
|
+
*/
|
|
959
|
+
function markPrerenderedManifestComponents(html) {
|
|
960
|
+
return html.replace(/<(x-[a-z][\w-]*)([^>]*)>/gi, (full, tag, attrs) => {
|
|
961
|
+
const a = attrs || '';
|
|
962
|
+
if (/\bdata-pre-rendered\s*=/i.test(a) || /\bdata-processed\s*=/i.test(a)) return full;
|
|
963
|
+
const spacer = /\S/.test(a) ? ' ' : '';
|
|
964
|
+
return `<${tag}${a}${spacer}data-pre-rendered="1">`;
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
|
|
940
968
|
// Remove empty inline mask-image styles emitted before data resolves
|
|
941
969
|
// (e.g. style="mask-image: url()"), while keeping any :style/x-bind:style bindings.
|
|
942
970
|
function stripEmptyInlineMaskStyles(html) {
|
|
@@ -1993,6 +2021,7 @@ async function runPrerender(config) {
|
|
|
1993
2021
|
const xData = { manifest, content };
|
|
1994
2022
|
html = resolveHeadXBindings(html, xData);
|
|
1995
2023
|
html = stripPrerenderDynamicBindings(html);
|
|
2024
|
+
html = stripRedundantImgSrcBindings(html);
|
|
1996
2025
|
html = stripEmptyInlineMaskStyles(html);
|
|
1997
2026
|
html = rewriteHtmlAssetPaths(html, fileSegments.length);
|
|
1998
2027
|
const liveBase = config.liveUrl.replace(/\/$/, '');
|
|
@@ -2004,6 +2033,7 @@ async function runPrerender(config) {
|
|
|
2004
2033
|
const routeDepth = fileSegments.length;
|
|
2005
2034
|
const prerenderedMeta = `<meta name="manifest:prerendered" content="1">\n`;
|
|
2006
2035
|
html = html.replace('</head>', `${canonicalHreflang}${injectOgLocale ? ogLocale : ''}${baseMeta}${prerenderedMeta}<meta name="manifest:router-base-depth" content="${routeDepth}">\n</head>`);
|
|
2036
|
+
html = markPrerenderedManifestComponents(html);
|
|
2007
2037
|
mkdirSync(outDir, { recursive: true });
|
|
2008
2038
|
writeFileSync(outFile, html, 'utf8');
|
|
2009
2039
|
pushDebug({
|