mnfst 0.5.240 → 0.5.242

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.240';
5
+ const MANIFEST_BUILD_VERSION = '0.5.242';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -205,6 +205,46 @@ function escapeForSingleQuotedJsString(s) {
205
205
  // Framework web components (not project components) — never fetched.
206
206
  const FRAMEWORK_COMPONENT_TAGS = new Set(['code', 'code-group']);
207
207
 
208
+ // The <template x-if>/<template x-for> whose tracked clone is `el`, if any.
209
+ function findOwningTemplate(el) {
210
+ if (!el._x_dataStack) return null;
211
+ for (let n = el.previousElementSibling; n; n = n.previousElementSibling) {
212
+ if (n.tagName !== 'TEMPLATE') continue;
213
+ if (n._x_currentIfEl === el) return { tpl: n, type: 'if' };
214
+ const lookup = el._x_refreshXForScope && n._x_lookup;
215
+ if (lookup) {
216
+ // Map since Alpine 3.16, plain object before
217
+ const entries = lookup instanceof Map ? lookup : Object.entries(lookup);
218
+ for (const [key, value] of entries) if (value === el) return { tpl: n, type: 'for', key };
219
+ }
220
+ }
221
+ return null;
222
+ }
223
+
224
+ // Point Alpine's clone bookkeeping at the swapped-in node.
225
+ function repointTemplateClone(owner, placeholder, node) {
226
+ const { tpl } = owner;
227
+ if (owner.type === 'if') {
228
+ const undo = tpl._x_undoIf;
229
+ tpl._x_currentIfEl = node;
230
+ tpl._x_lastRenderedEl = node;
231
+ tpl._x_undoIf = () => {
232
+ const A = window.Alpine;
233
+ const teardown = () => {
234
+ if (A && A.destroyTree) A.destroyTree(node);
235
+ node.remove();
236
+ };
237
+ A && A.mutateDom ? A.mutateDom(teardown) : teardown();
238
+ if (undo) undo();
239
+ };
240
+ } else {
241
+ if (tpl._x_lookup instanceof Map) tpl._x_lookup.set(owner.key, node);
242
+ else tpl._x_lookup[owner.key] = node;
243
+ node._x_refreshXForScope = placeholder._x_refreshXForScope;
244
+ if (tpl._x_lastRenderedEl === placeholder) tpl._x_lastRenderedEl = node;
245
+ }
246
+ }
247
+
208
248
  window.ManifestComponentsProcessor = {
209
249
  async processComponent(element, instanceId) {
210
250
  const name = element.tagName.toLowerCase().replace('x-', '');
@@ -238,7 +278,7 @@ window.ManifestComponentsProcessor = {
238
278
  }
239
279
  const container = document.createElement('div');
240
280
  container.innerHTML = content.trim();
241
- const topLevelElements = Array.from(container.children);
281
+ let topLevelElements = Array.from(container.children);
242
282
  if (topLevelElements.length === 0) {
243
283
  console.debug('[Manifest Components] skipped: empty component template', element);
244
284
  element.replaceWith(document.createComment(` Empty component: ${name} `));
@@ -263,6 +303,7 @@ window.ManifestComponentsProcessor = {
263
303
  }
264
304
  };
265
305
  topLevelElements.forEach(processScripts);
306
+ topLevelElements = Array.from(container.children);
266
307
  // Collect properties from placeholder attributes
267
308
  const props = {};
268
309
  Array.from(element.attributes).forEach(attr => {
@@ -464,7 +505,23 @@ window.ManifestComponentsProcessor = {
464
505
  const fragment = document.createDocumentFragment();
465
506
  topLevelElements.forEach(el => fragment.appendChild(el));
466
507
 
467
- parent.replaceChild(fragment, element);
508
+ // Sole child of x-if/x-for: Alpine tracks one node per clone, so a
509
+ // multi-root component keeps a host; the clone's scope carries over.
510
+ const owner = findOwningTemplate(element);
511
+ let swapped = fragment;
512
+ if (owner && topLevelElements.length) {
513
+ swapped = topLevelElements[0];
514
+ if (topLevelElements.length > 1) {
515
+ swapped = document.createElement(element.tagName.toLowerCase());
516
+ swapped.setAttribute('data-processed', '');
517
+ swapped.style.display = 'contents';
518
+ swapped.appendChild(fragment);
519
+ }
520
+ swapped._x_dataStack = element.hasAttribute('x-data') ? element._x_dataStack.slice(1) : element._x_dataStack;
521
+ repointTemplateClone(owner, element, swapped);
522
+ }
523
+
524
+ parent.replaceChild(swapped, element);
468
525
 
469
526
  // Manually init Alpine on the swapped-in elements once magic methods are
470
527
  // ready — prevents "i is not a function" errors.
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.240';
5
+ const MANIFEST_BUILD_VERSION = '0.5.242';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest.appwrite.auth.js": "sha384-dsIWnH0qCAGSzAXMGrd8fvOrVl4tOIE6j5tC35JPTrQXZ56qLD36ARyvhR7vi3Id",
3
- "manifest.appwrite.data.js": "sha384-F73BvcB8ih1vCMLgrJI6+PQf2KnGIMyuuAldRe5Lv6KFRSyX36nId6T8Su6aXUHF",
3
+ "manifest.appwrite.data.js": "sha384-yDddDjQb6Y+NHca8j6ZNAOM3IPdKYd251cBntU3ZXMMzOuZVruFPft4FsJLUOfBA",
4
4
  "manifest.appwrite.presences.js": "sha384-JyVDWFT69b7Svq8J8p9tNWe2v9PZNQBY5UyhtOl1vnuHFAX0CRQ3MA9SiKq5wzNh",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
6
  "manifest.charts.js": "sha384-gEAv/98+29RbhvNkiNWTNyBPbLTFr2Ld15wLu29FLCL57j1cwGChRrL9Pfk7dBtT",
@@ -9,9 +9,9 @@
9
9
  "manifest.color.js": "sha384-6Rv3LxyTcZNjrhtayQfqRdCx0uSZ4BiEbgEI98I62eTvp8Aw7LBIoNJ0Je1oktwL",
10
10
  "manifest.colorpicker.js": "sha384-BhcCe8cGcd0DTJNwzXWWY+FQNRfSFFl6XqfHIFP8yHg/aXFks1NIC6lVx0Sr1VkM",
11
11
  "manifest.combobox.js": "sha384-MILTkrgsTzsYUjGo4ZuADqV85Xs4GmfB4xexfe9vbJMIoQTZ42W4zs+DTaVSPEsx",
12
- "manifest.components.js": "sha384-JalISaBBWNFl3ggx92Hb3B52EpwwG3gzgra6Q+js0OgZ8vrFKMD48CuBox2N9A5T",
12
+ "manifest.components.js": "sha384-BUFA8h+G5Plr82sV7bKzO42pPoiRZwRQcKj1lt2ROFiKjjlkayU/vmkAFqEsdBA+",
13
13
  "manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
14
- "manifest.data.js": "sha384-1+l0N0eCERH88WwGgklBovPC2VEj5nbdfI6dvvj/lm+t4g6MhMn1XjlRHbJUTMoP",
14
+ "manifest.data.js": "sha384-5uYdQUX2aumbedLjn4wcVA3fWXiyGQbkEBZjGqS0FWxZsIyadhibk9JTqcXys6SN",
15
15
  "manifest.datepicker.js": "sha384-XnbeURni2X91ozVzatQcSjYYIS4MoW12dBRJnYAGBr0nCQ624heH5s+xtQSpLZX6",
16
16
  "manifest.defer.js": "sha384-pMRGqQKiEoJhpUcD40QeM4jEHau7sz9Xn/YCpiUamT1T4xJBZDSiYX+xnVrSWoq+",
17
17
  "manifest.device.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
@@ -24,11 +24,11 @@
24
24
  "manifest.native.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
25
25
  "manifest.payments.js": "sha384-8pofk2zhxtapPMpwnFyTelPMrYhShNhDCE722uQh/EYFvZFuPLmSdgunqsarVQjv",
26
26
  "manifest.rich.text.js": "sha384-ZBV9jXmu2nmprEHicddRE/m7nR4RPZtVc969Jte0+EJYBcVph7itkjcgN/61PyeC",
27
- "manifest.router.js": "sha384-QkKhRaCbdXEOxhj+ojT4jeLUCtQepBnqP+QWTIWdb6kUWD+mVzPN8hf6jhgschpW",
27
+ "manifest.router.js": "sha384-JcKnEb0E9azl6DVSN1DQMysyZOpGkskSQREjD947sMEs87nFEeZpCigB0iq8psz5",
28
28
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
29
29
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
30
30
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
31
- "manifest.sw.js": "sha384-v57876ZQ8S05eevNRKLI9rfeCdiLz1VafEFf4jFtvdnrSt84G7Gb/2dKsiqebszs",
31
+ "manifest.sw.js": "sha384-r7098dpqRjo/UGvvO4FNV5IjJn2/Ipd6YJ419nnrXDe56E67/wvojHshiZoY7gcy",
32
32
  "manifest.tabs.js": "sha384-OIIcyaQnGS0eNYk4zgAFEDboNYect7THvUd9D0V6nqCeDOxQcoiqLrBEmmWVTTet",
33
33
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
34
34
  "manifest.toasts.js": "sha384-3zkWxzw693pxg3QDFsoYCA3CqYaLKmBaMArULXODD66Utolpewl0OAeTB92aWUVv",
@@ -36,5 +36,5 @@
36
36
  "manifest.url.parameters.js": "sha384-J2aSVBOPsoqsbafHndrWLHEDpKb4AKJAoQnVmKA4gZh5P/8HHjFWHO/lkusmG84l",
37
37
  "manifest.utilities.js": "sha384-L5uXMLFBIF6LUM1haRjd4eGjHSWuqsCYSpPZRPYosNfJsMC5U5TnmjBxIhrZRe2d",
38
38
  "manifest.virtual.js": "sha384-ZDNoF9QVhVcVpkjIK6NH15S6I5c6OBshiJpXSOYjNsIB+298I0a7g3aFO+jyq4Vb",
39
- "manifest.js": "sha384-awBD5RsuSptlguWJ5H1+89A9coKlT3lx4+i2PLZdRxeCymaG7SYBeQ7OhbCCnZGA"
39
+ "manifest.js": "sha384-AvD8QPahsOp5hmdBGJtfu2jp/dYrxLgapvAzx0oc2POlfb/Gj1tvFBHG+ct76p3d"
40
40
  }
package/lib/manifest.js CHANGED
@@ -241,8 +241,21 @@
241
241
  adoptedIfs.add(entry);
242
242
  }
243
243
  }
244
+ // Older renders marked placeholders inside x-if/x-for content; clones must swap.
245
+ function unmarkTemplatePlaceholders(root, inside) {
246
+ root.querySelectorAll('template').forEach((tpl) => {
247
+ const authored = inside || tpl.matches('[x-if],[x-for]');
248
+ if (authored) {
249
+ tpl.content.querySelectorAll('[data-pre-rendered]').forEach((el) => {
250
+ if (el.tagName.startsWith('X-')) el.removeAttribute('data-pre-rendered');
251
+ });
252
+ }
253
+ unmarkTemplatePlaceholders(tpl.content, authored);
254
+ });
255
+ }
244
256
  function reconcilePrerenderClones() {
245
257
  if (typeof document === 'undefined' || !document.querySelectorAll) return;
258
+ unmarkTemplatePlaceholders(document);
246
259
  let adopted = 0;
247
260
  document.querySelectorAll('[data-mnfst-prerender-clone]').forEach((el) => {
248
261
  if (el.closest && el.closest('[data-hydrate]')) return;
@@ -484,6 +484,8 @@ function installMpaStickyLocaleLinks() {
484
484
 
485
485
  const link = event.target.closest('a');
486
486
  if (!link || link.closest('[data-manifest-skip-locale-sticky]')) return;
487
+ const target = (link.getAttribute('target') || '').toLowerCase();
488
+ if (target && target !== '_self' && target !== '_blank') return;
487
489
  const editable = link.closest('[contenteditable]');
488
490
  if (link.isContentEditable || (editable && editable.getAttribute('contenteditable') !== 'false')) return; // content in editable text
489
491
  if (link.hasAttribute('download')) return;
@@ -513,11 +515,8 @@ function installMpaStickyLocaleLinks() {
513
515
  : adjusted;
514
516
 
515
517
  const dest = url.toString();
516
- if (link.target === '_blank') {
517
- const features = link.relList?.contains('noopener') || link.relList?.contains('noreferrer')
518
- ? 'noopener,noreferrer'
519
- : undefined;
520
- window.open(dest, '_blank', features);
518
+ if (target === '_blank') {
519
+ window.open(dest, '_blank', link.relList?.contains('noreferrer') ? 'noopener,noreferrer' : 'noopener');
521
520
  } else {
522
521
  window.location.assign(dest);
523
522
  }
@@ -532,6 +531,11 @@ function interceptLinkClicks() {
532
531
  const link = event.target.closest('a');
533
532
  if (!link) return;
534
533
 
534
+ // New tab or window: modifier keys, middle click, or a frame target stay with the browser
535
+ if (event.button > 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
536
+ const target = (link.getAttribute('target') || '').toLowerCase();
537
+ if (target && target !== '_self' && target !== '_blank') return;
538
+
535
539
  // A link inside editable text (x-rich-text, x-edit page text) is content: the click
536
540
  // places the caret, as the browser does natively, and never navigates
537
541
  const host = link.closest('[contenteditable]');
@@ -566,6 +570,16 @@ function interceptLinkClicks() {
566
570
  return;
567
571
  }
568
572
 
573
+ // target=_blank: open the resolved URL (base path, locale) in a new tab
574
+ if (target === '_blank') {
575
+ const [path, hash] = href.split('#');
576
+ event.preventDefault();
577
+ event.stopPropagation();
578
+ event.stopImmediatePropagation();
579
+ window.open(resolveHref(path) + (hash ? '#' + hash : ''), '_blank', 'noopener');
580
+ return;
581
+ }
582
+
569
583
  // Handle links with both route and anchor (e.g., /page#section)
570
584
  if (href.includes('#')) {
571
585
  const [path, hash] = href.split('#');
@@ -16,7 +16,7 @@
16
16
 
17
17
  // Build stamps the published version here; unstamped (dev) falls back to the
18
18
  // registration URL's `v`, then 'dev'.
19
- const BUILD_VERSION = '0.5.240';
19
+ const BUILD_VERSION = '0.5.242';
20
20
  const CACHE_PREFIX = 'mnfst-sw:';
21
21
  const META_CACHE = CACHE_PREFIX + 'meta';
22
22
  // Sized to hold a full precache.json warm-up (PRECACHE_MAX_ENTRIES server-side)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.240",
3
+ "version": "0.5.242",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",