mnfst 0.5.227 → 0.5.229

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.227';
5
+ const MANIFEST_BUILD_VERSION = '0.5.229';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.227';
5
+ const MANIFEST_BUILD_VERSION = '0.5.229';
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-gyEWaIe2Vk2k+OZL3d1YHsn2GUzso/3+L0z5a5hsRvc6yisJxCqBu+TCcJaq1qgT",
3
+ "manifest.appwrite.data.js": "sha384-dLaV5W1wDtVkrfE2k5BwFL3TCCybtkAjgi+lc9GaZ2OnTdC0pmXPYBOxX64TqG9I",
4
4
  "manifest.appwrite.presences.js": "sha384-JyVDWFT69b7Svq8J8p9tNWe2v9PZNQBY5UyhtOl1vnuHFAX0CRQ3MA9SiKq5wzNh",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
6
  "manifest.charts.js": "sha384-gEAv/98+29RbhvNkiNWTNyBPbLTFr2Ld15wLu29FLCL57j1cwGChRrL9Pfk7dBtT",
@@ -11,7 +11,7 @@
11
11
  "manifest.combobox.js": "sha384-MILTkrgsTzsYUjGo4ZuADqV85Xs4GmfB4xexfe9vbJMIoQTZ42W4zs+DTaVSPEsx",
12
12
  "manifest.components.js": "sha384-4bc3HgPvF9DHMiOG08w+nWXI7Hho01RuAPAUL9xyLxOiS2igeZpulCVcvr5aT9v6",
13
13
  "manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
14
- "manifest.data.js": "sha384-nvTvY+1kswCEbVi8QZIpQHbWVUDipctUqRgv4yZCe2qbGmsGRGA4yK/UHVAEY3N8",
14
+ "manifest.data.js": "sha384-Ry718yAA50wEXkWObL/41NDB7XFa2tMMxlwcrRnbK5ycYGApz2zD9/9SBPqRJY1R",
15
15
  "manifest.datepicker.js": "sha384-XnbeURni2X91ozVzatQcSjYYIS4MoW12dBRJnYAGBr0nCQ624heH5s+xtQSpLZX6",
16
16
  "manifest.defer.js": "sha384-WcCf8YQ1bKIXCLSZ24a0bJwepbYntYc8TzQM50hklo5VMIH8AtzDnwl6WU4prRv1",
17
17
  "manifest.device.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
@@ -20,19 +20,19 @@
20
20
  "manifest.export.js": "sha384-Rx6XvqBZc4apzP/FwcDr6yIln4/zNa08Q4ZqBZcEqUz1aNZQfl4h0+Ae7mqCQyuG",
21
21
  "manifest.icons.js": "sha384-kKOINpX70YzNO3FvkV6umrmO3f0KIu0DNbwB+ej55a7y/lhU7v/myQtXL0bwCTbt",
22
22
  "manifest.localization.js": "sha384-EImsIw8Z3l13V5eH9ZJF/yfsOfIvR1oPRNSArANkPji7V8O3IRf6zMwsNiAGj3Hk",
23
- "manifest.markdown.js": "sha384-JWUxlUZADxk1hZY7NpDX051UhtXt/ofpfsCDBRcweU6JhLbN8B832yPLgCatxFdl",
23
+ "manifest.markdown.js": "sha384-heyDR40LXHaAmAuA+fa381uFwShk1oAqpFFY6E2Qq4T3VN0TQfRqyc++MF40K5Hj",
24
24
  "manifest.native.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
25
25
  "manifest.payments.js": "sha384-8pofk2zhxtapPMpwnFyTelPMrYhShNhDCE722uQh/EYFvZFuPLmSdgunqsarVQjv",
26
26
  "manifest.router.js": "sha384-xkQaHO60lMQwtnqGPxPJJ646eyqBjINs4AFesrQbe2dWqPIoIcJ9RD5wsjqjak7w",
27
27
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
28
28
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
29
29
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
30
- "manifest.sw.js": "sha384-T29dPFWytpZW4ijBtvLGT4WZ0YPbF1whjHQbNVRw6RLYs5LMdO6LOcRlLPTC62CM",
30
+ "manifest.sw.js": "sha384-FHy5ttfRVY2p/uI3dD8Pd2j/7YOOeTaHgKwdpR0UVJdBS2Tg2t9jzo8iHt7O8mTF",
31
31
  "manifest.tabs.js": "sha384-OIIcyaQnGS0eNYk4zgAFEDboNYect7THvUd9D0V6nqCeDOxQcoiqLrBEmmWVTTet",
32
32
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
33
33
  "manifest.text.edit.js": "sha384-RzOvLQE8GbmI6gntAwiotDewYT/08OHcd7sJ5hLon8e8u1Xbq1D7VfEGuaRVd2CE",
34
34
  "manifest.toasts.js": "sha384-/OV32LLMJl0Iw8NoNQJ+5lgntLxjIJq/YNj5JAKS/+nUhVx4MMB9h1FOqP7zuj2M",
35
- "manifest.tooltips.js": "sha384-uXVVQADl6pY2Pj9i/UaSclZN7dzbKhLkmevv7Ad0+wXR8LgqodALNFrc5jZJjlwm",
35
+ "manifest.tooltips.js": "sha384-sOWANzXAWeZYMJ+fVtx7dH5CpPMso10T+Oyau5wDCwYbAxI2n3adwCoq7PQp2RAE",
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",
@@ -769,9 +769,17 @@ async function initializeMarkdownPlugin() {
769
769
  }, 0);
770
770
  }
771
771
  }
772
- }
773
772
 
774
- // Code highlighting is handled by manifest.code.js plugin
773
+ // Notify the code plugin to scan the new subtree — copy-only
774
+ // inline codespans have no directive, so initTree misses them.
775
+ if (window.ManifestCode?.observeAll) {
776
+ window.ManifestCode.observeAll(el);
777
+ }
778
+ document.dispatchEvent(new CustomEvent('manifest:code-blocks-converted', {
779
+ bubbles: true,
780
+ detail: { root: el }
781
+ }));
782
+ }
775
783
 
776
784
  // Show content with fade-in
777
785
  hasContent = true;
@@ -835,6 +843,9 @@ async function initializeMarkdownPlugin() {
835
843
  // Post-process HTML to enable checkboxes (remove disabled attribute)
836
844
  html = html.replace(/<input type="checkbox"([^>]*?)disabled([^>]*?)>/g, '<input type="checkbox"$1$2>');
837
845
 
846
+ // Promote inline `foo`{copy} blocks to real attributes.
847
+ html = applyInlineCodeAttributes(html);
848
+
838
849
  // Apply opt-in DOMPurify sanitization for x-markdown.safe
839
850
  html = await maybeSanitizeMarkdownHtml(html, safe);
840
851
 
@@ -888,8 +899,15 @@ async function initializeMarkdownPlugin() {
888
899
  // Start initialization
889
900
  initAlpine();
890
901
 
891
- // Re-highlight code blocks after content update
892
- // Code highlighting is handled by manifest.code.js plugin
902
+ // Notify the code plugin to scan the new subtree — copy-only
903
+ // inline codespans have no directive, so initTree misses them.
904
+ if (window.ManifestCode?.observeAll) {
905
+ window.ManifestCode.observeAll(element);
906
+ }
907
+ document.dispatchEvent(new CustomEvent('manifest:code-blocks-converted', {
908
+ bubbles: true,
909
+ detail: { root: element }
910
+ }));
893
911
  } catch (error) {
894
912
  console.error('[Manifest Markdown] Failed to process element:', error);
895
913
  }
@@ -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.227';
19
+ const BUILD_VERSION = '0.5.229';
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)
@@ -157,55 +157,77 @@ function initializeTooltipPlugin() {
157
157
  if (wasOpen) markTooltipHidden();
158
158
  }
159
159
 
160
- // ---- Directive ----
160
+ // ---- Content classification ----
161
+ // Any JS expression evaluates; text that isn't one renders verbatim.
161
162
 
162
- Alpine.directive('tooltip', (el, { modifiers, expression }, { effect, evaluateLater }) => {
163
+ const BARE_IDENTIFIER = /^[\p{ID_Start}$_][\p{ID_Continue}$]*$/u;
164
+ const looksLikeHtml = (s) => s.includes('<') && s.includes('>');
163
165
 
164
- // --- Content evaluator ---
165
- let getContent;
166
- const isDynamic =
167
- expression.startsWith('$x.') ||
168
- (expression.includes('+') || expression.includes('`') || expression.includes('${'));
166
+ function parsesAsExpression(src) {
167
+ try { new Function('return (' + src + '\n)'); return true; } catch { return false; }
168
+ }
169
169
 
170
- // Render as HTML? Default false (escape); author literal HTML or .html/.safe opts in.
171
- let allowHtml = modifiers.includes('html') || modifiers.includes('safe');
170
+ function inScope(el, name) {
171
+ try { return name in Alpine.$data(el); } catch { return false; }
172
+ }
172
173
 
173
- if (expression.startsWith('$x.')) {
174
- const path = expression.substring(3);
175
- const [contentType] = path.split('.');
176
- getContent = evaluateLater(expression);
174
+ // Errors come back as values: unresolved names read as plain text
175
+ // ("Re-run", "Hello, world"); other errors warn against the authored expression
176
+ const guarded = (src) =>
177
+ '(() => { try { return (' + src + '\n) } catch (e) { return { __tooltipError: e } } })()';
178
+
179
+ function unwrapError(v, el, src) {
180
+ const err = v && typeof v === 'object' && v.__tooltipError;
181
+ if (!(err instanceof Error)) return { value: v };
182
+ if (err instanceof ReferenceError) return { value: undefined };
183
+ console.warn(`Alpine Expression Error: ${err.message}\n\nExpression: "${src}"\n\n`, el);
184
+ return { value: null };
185
+ }
186
+
187
+ // ---- Directive ----
188
+
189
+ Alpine.directive('tooltip', (el, { modifiers, expression }, { effect, evaluateLater }) => {
190
+
191
+ // --- Content ---
192
+ // Escape by default; author literal HTML or .html/.safe opts in.
193
+ const htmlOptIn = modifiers.includes('html') || modifiers.includes('safe');
194
+ const literal = expression ? { text: expression, html: htmlOptIn || looksLikeHtml(expression) } : null;
195
+ const src = expression.trim();
196
+ let evaluate = null;
197
+ let fallback = true;
198
+
199
+ if (src.startsWith('$x.')) {
200
+ const [contentType] = src.substring(3).split('.');
201
+ evaluate = evaluateLater(src);
202
+ fallback = false;
177
203
  effect(() => {
178
204
  const store = Alpine.store('collections');
179
205
  if (store && typeof store.loadCollection === 'function' && !store[contentType]) {
180
206
  store.loadCollection(contentType);
181
207
  }
182
208
  });
183
- } else if (expression.includes('<') && expression.includes('>')) {
184
- // Literal HTML in the attribute — author-authored, trusted as the template.
185
- allowHtml = true;
186
- const escaped = expression.replace(/'/g, "\\'");
187
- getContent = evaluateLater(`'${escaped}'`);
188
- } else if (expression.includes('+') || expression.includes('`') || expression.includes('${')) {
189
- getContent = evaluateLater(expression);
190
- } else {
191
- // Static literal — wrap in quotes so evaluateLater returns it verbatim
192
- getContent = evaluateLater(`'${expression}'`);
209
+ } else if (BARE_IDENTIFIER.test(src)) {
210
+ // Single word: a scope value or magic, else text (never a global like Image or close)
211
+ const getValue = evaluateLater(guarded(src));
212
+ evaluate = (cb) => (src.startsWith('$') || inScope(el, src)) ? getValue(cb) : cb(undefined);
213
+ } else if (parsesAsExpression(src)) {
214
+ evaluate = evaluateLater(guarded(src));
193
215
  }
194
216
 
195
217
  // --- Positioning modifiers ---
196
218
  const validPositions = ['top', 'bottom', 'start', 'end', 'center', 'corner'];
197
219
  const positions = modifiers.filter(m => validPositions.includes(m));
198
220
 
199
- // For non-dynamic content, cache once to avoid re-evaluating every show.
200
- let cachedContent = null;
201
- if (!isDynamic) {
202
- getContent(v => { cachedContent = v; });
203
- }
204
-
205
- // Resolves the content to show, calling the provided callback with the HTML string.
221
+ // Static text resolves once; expressions re-evaluate on every show.
222
+ // Empty results (null, false, '') show nothing.
206
223
  const resolveContent = (cb) => {
207
- if (!isDynamic && cachedContent != null) { cb(cachedContent); return; }
208
- getContent(v => cb(v));
224
+ if (!evaluate) { cb(literal); return; }
225
+ evaluate(raw => {
226
+ const v = fallback ? unwrapError(raw, el, src).value : raw;
227
+ if (fallback && (v === undefined || Number.isNaN(v))) { cb(literal); return; }
228
+ if (v == null || v === false || v === '') { cb(null); return; }
229
+ cb({ text: String(v), html: htmlOptIn });
230
+ });
209
231
  };
210
232
 
211
233
  // --- Event handlers ---
@@ -225,8 +247,9 @@ function initializeTooltipPlugin() {
225
247
  const t = document.getElementById(triggerTargetId);
226
248
  if (t && t.matches && t.matches(':popover-open')) return;
227
249
  }
228
- resolveContent(html => {
229
- showSingletonFor(el, html, positions, allowHtml);
250
+ resolveContent(content => {
251
+ if (content) showSingletonFor(el, content.text, positions, content.html);
252
+ else hideAnySingleton();
230
253
  });
231
254
  }, delay);
232
255
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.227",
3
+ "version": "0.5.229",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",