mnfst-render 0.1.1 → 0.1.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.
@@ -384,8 +384,10 @@ function stripPrerenderDynamicBindings(html) {
384
384
  const bindingRegex = /(?:^|\s)(?::|x-bind:)(\w+)=(?:"([^"]*)"|'([^']*)')/g;
385
385
  let m;
386
386
  while ((m = bindingRegex.exec(attrsStr)) !== null) {
387
+ const attrName = (m[1] || '').toLowerCase();
388
+ if (attrName === 'class' || attrName === 'style') continue;
387
389
  const val = (m[2] !== undefined ? m[2] : m[3]) || '';
388
- if (val.indexOf('$x') === -1) toStrip.add(m[1].toLowerCase());
390
+ if (val.indexOf('$x') === -1) toStrip.add(attrName);
389
391
  }
390
392
  if (toStrip.size === 0) return match;
391
393
  let newAttrs = attrsStr;
@@ -946,6 +948,50 @@ async function runPrerender(config) {
946
948
  });
947
949
  });
948
950
 
951
+ // Remove orphan x-for clones that still reference loop-scope vars (e.g. image/index)
952
+ // outside their template scope. These throw Alpine errors in live static hosting.
953
+ await page.evaluate(() => {
954
+ const loopVarRegex = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
955
+ const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-on:|@)/;
956
+
957
+ document.querySelectorAll('template[x-for]').forEach((tpl) => {
958
+ const xFor = (tpl.getAttribute('x-for') || '').trim();
959
+ const m = xFor.match(loopVarRegex);
960
+ const itemVar = m ? (m[1] || m[3] || '') : '';
961
+ const indexVar = m ? (m[2] || '') : '';
962
+ if (!itemVar && !indexVar) return;
963
+
964
+ const first = tpl.content?.firstElementChild;
965
+ if (!first) return;
966
+ const tag = first.tagName;
967
+
968
+ let next = tpl.nextElementSibling;
969
+ while (next) {
970
+ const sameTag = next.tagName === tag;
971
+ if (!sameTag) break;
972
+
973
+ let referencesLoopScope = false;
974
+ const attrNodes = next.attributes ? Array.from(next.attributes) : [];
975
+ for (const attr of attrNodes) {
976
+ if (!bindingAttrRegex.test(attr.name)) continue;
977
+ const expr = attr.value || '';
978
+ if (
979
+ (itemVar && new RegExp(`\\b${itemVar}\\b`).test(expr)) ||
980
+ (indexVar && new RegExp(`\\b${indexVar}\\b`).test(expr))
981
+ ) {
982
+ referencesLoopScope = true;
983
+ break;
984
+ }
985
+ }
986
+
987
+ const toRemove = next;
988
+ next = next.nextElementSibling;
989
+ if (referencesLoopScope) toRemove.remove();
990
+ else break;
991
+ }
992
+ });
993
+ });
994
+
949
995
  // Remove elements marked data-dynamic (so they are not in static HTML; client will render them).
950
996
  // Skip <template> since we only collapse those above; other elements and their subtree are removed.
951
997
  await page.evaluate(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst-render",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Render Manifest sites to static HTML for SEO",
5
5
  "type": "module",
6
6
  "bin": {