mnfst 0.5.150 → 0.5.151
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/lib/manifest.combobox.js +8 -0
- package/lib/manifest.integrity.json +2 -2
- package/lib/manifest.js +30 -14
- package/package.json +1 -1
package/lib/manifest.combobox.js
CHANGED
|
@@ -101,6 +101,14 @@ function initializeComboboxPlugin() {
|
|
|
101
101
|
if (el.__mnfstCombobox) return;
|
|
102
102
|
el.__mnfstCombobox = true;
|
|
103
103
|
|
|
104
|
+
// Sweep generated menus left orphaned by a prior render — their controlling
|
|
105
|
+
// editor is gone (a SPA x-markdown re-render) or never hydrated (duplicates
|
|
106
|
+
// an old prerender baked into <body>). Either way, no connected editor points
|
|
107
|
+
// at them, so they can only sit as stale, sometimes-open duplicates.
|
|
108
|
+
document.querySelectorAll('body > menu[id^="combobox-menu-"]').forEach(m => {
|
|
109
|
+
if (!document.querySelector('[aria-controls="' + m.id + '"]')) m.remove();
|
|
110
|
+
});
|
|
111
|
+
|
|
104
112
|
// ----- Prerender hydration -----
|
|
105
113
|
// A prerendered page bakes in the wrapper this plugin generated. On load we
|
|
106
114
|
// adopt that wrapper and re-derive the selection from the baked chips, rather
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"manifest.code.js": "sha384-nP6DncLx/UuJtloyVKMCOXwIBAq32DshTb/Lc0vVRBWX7kSbxiBnY5aEyqqvK8Kg",
|
|
7
7
|
"manifest.color.js": "sha384-6Rv3LxyTcZNjrhtayQfqRdCx0uSZ4BiEbgEI98I62eTvp8Aw7LBIoNJ0Je1oktwL",
|
|
8
8
|
"manifest.colorpicker.js": "sha384-Wqz0ZIbeIi7KarqqqSLsQk+7E/fMaKhb32hrq5/eWzX1yjqMrpPZKH8y+jZ3mfg+",
|
|
9
|
-
"manifest.combobox.js": "sha384-
|
|
9
|
+
"manifest.combobox.js": "sha384-oGZIgHsizehYUu3m7VrZkwOadrwm5MfAA4PkN0l5W3FU8LHcuSmWn7XLzmt97jfo",
|
|
10
10
|
"manifest.components.js": "sha384-mzPFoM0vqL9dnTVLMN3OrmO+KCgSqGknM1fd7bM1xzYeCco5OaZi56IMR5RS5oad",
|
|
11
11
|
"manifest.data.js": "sha384-bCYTYyAYNVkg5pSwGcoe07Dgf5B7JDN7GtOIQdS+BtrBStQwvjZtskiQ38Bncvrf",
|
|
12
12
|
"manifest.datepicker.js": "sha384-NEb/H4vuR3CFtRcodHsm3jJjrcYW2JMpDlQKlgwTrzpMMTcDkFKYXzAYJD0gZ7Ov",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"manifest.url.parameters.js": "sha384-FIufiClqDx1rJpU/QUc9z/D43qClQ6Qm8rBahipbJl9BDHUvhrOsUDegmTWW7Tuf",
|
|
29
29
|
"manifest.utilities.js": "sha384-HWyVkjQoDRlWFKDBQw4RQOYODkBcU72NHW6l1p4bhQv1RtN0/XtnjwIb+lQK6+zv",
|
|
30
30
|
"manifest.virtual.js": "sha384-J2+MpRskVH39R2DmHUib2bItuGsvSLEhPM+83iznrdfQFMZ63Ea6xwLeCsG04jOl",
|
|
31
|
-
"manifest.js": "sha384-
|
|
31
|
+
"manifest.js": "sha384-zPXrym9jwpYVdg4TJ1XPQVxQhz7uezdDubaO/MZDvLeiTufor+6lNJsTG75cYPXm"
|
|
32
32
|
}
|
package/lib/manifest.js
CHANGED
|
@@ -141,28 +141,44 @@
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/*
|
|
144
|
-
*
|
|
145
|
-
* <template> is still live, so Alpine
|
|
146
|
-
*
|
|
147
|
-
* data-hydrate islands keep their baked DOM.
|
|
144
|
+
* Reconcile baked x-for/x-if clones the prerender kept for crawlers. Their
|
|
145
|
+
* <template> is still live, so without intervention Alpine renders a second
|
|
146
|
+
* copy on boot (a duplicate). data-hydrate islands keep their baked DOM.
|
|
148
147
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
148
|
+
* - x-if clones are ADOPTED: we point the template's Alpine x-if state
|
|
149
|
+
* (`_x_currentIfEl`) at the baked element, so Alpine treats the
|
|
150
|
+
* condition as already-rendered and leaves the baked DOM in place. Heavy
|
|
151
|
+
* x-if content (e.g. an x-markdown article) would otherwise be torn down
|
|
152
|
+
* and re-rendered — flashing raw text and re-fetching $x data — even
|
|
153
|
+
* though the prerendered output is already correct. A genuine
|
|
154
|
+
* route/condition change later still re-renders normally.
|
|
155
|
+
* - x-for clones are REMOVED: lists are light, often interactive, and
|
|
156
|
+
* Alpine re-renders them from the live template, so the baked copies are
|
|
157
|
+
* dropped to avoid a duplicate.
|
|
158
|
+
*
|
|
159
|
+
* Deliberately NOT part of hydratePrerenderedPage(): it runs at the last
|
|
160
|
+
* safe moment — `alpine:init`, which Alpine dispatches after its script has
|
|
161
|
+
* executed but BEFORE it walks the DOM. If Alpine never arrives (CDN
|
|
162
|
+
* failure, offline), the listener never fires and the page keeps its
|
|
163
|
+
* complete baked content.
|
|
156
164
|
*/
|
|
157
|
-
function
|
|
165
|
+
function reconcilePrerenderClones() {
|
|
158
166
|
if (typeof document === 'undefined' || !document.querySelectorAll) return;
|
|
159
167
|
document.querySelectorAll('[data-mnfst-prerender-clone]').forEach((el) => {
|
|
160
168
|
if (el.closest && el.closest('[data-hydrate]')) return;
|
|
161
|
-
el.
|
|
169
|
+
el.removeAttribute('data-mnfst-prerender-clone');
|
|
170
|
+
const tpl = el.previousElementSibling;
|
|
171
|
+
if (tpl && tpl.tagName === 'TEMPLATE' && tpl.hasAttribute('x-if')) {
|
|
172
|
+
// Adopt: Alpine's x-if `show()` returns early when _x_currentIfEl
|
|
173
|
+
// is set, so the baked element stays and is not re-rendered.
|
|
174
|
+
tpl._x_currentIfEl = el;
|
|
175
|
+
} else {
|
|
176
|
+
el.remove();
|
|
177
|
+
}
|
|
162
178
|
});
|
|
163
179
|
}
|
|
164
180
|
if (typeof document !== 'undefined') {
|
|
165
|
-
document.addEventListener('alpine:init',
|
|
181
|
+
document.addEventListener('alpine:init', reconcilePrerenderClones, { once: true });
|
|
166
182
|
}
|
|
167
183
|
|
|
168
184
|
// Run hydration BEFORE Alpine's deferred script executes.
|