From 53e2e20a15fb183a773360543744793189557096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Fri, 25 Sep 2026 04:43:43 +0000 Subject: [PATCH] fix(registry): six blocks load their own files and variables when mounted (#4452) * feat(core): a composition's script can load its own files with __hyperframes.assetUrl * test(core): a template composition inside a mounted file resolves assets from that file * docs: assetUrl is for paths beside the composition, not project-root paths * docs: say assetUrl misses a project-root path * fix(core): a mounted composition's import map and module scripts run as such * refactor(core): scope a mounted module script under the same condition as a classic one * fix(core): a mounted module script loaded by src stays a module * fix(core): a mounted import map keeps the trailing slash of a prefix address * fix(registry): six blocks load their own files and variables when mounted * fix(registry): keep frost's variable declarations on its html element * fix(registry): orbit-card uses its own variables; frost font and catalog maps follow * chore(core): keep the module-script helpers' comment share at the base * fix(catalog): frost's payload runs its driving script, not the asset-base one * test(catalog): check import-map keys by membership, not a built regex --- .../canopy-part-title/canopy-part-title.html | 41 +- .../cuboid-carousel/cuboid-carousel.html | 10 +- .../frost-sequence-camera-orbit.html | 10 +- .../lottie-character-walk.html | 7 +- .../blocks/orbit-card/assets/orbit-scene.js | 504 +++++++++--------- registry/blocks/orbit-card/orbit-card.html | 9 +- .../wireframe-portal-title.html | 9 +- scripts/catalog-script-inlining.test.ts | 45 +- scripts/catalog-script-inlining.ts | 14 +- 9 files changed, 364 insertions(+), 285 deletions(-) diff --git a/registry/blocks/canopy-part-title/canopy-part-title.html b/registry/blocks/canopy-part-title/canopy-part-title.html index 0edb59147f..4aafcf8d1b 100644 --- a/registry/blocks/canopy-part-title/canopy-part-title.html +++ b/registry/blocks/canopy-part-title/canopy-part-title.html @@ -106,16 +106,11 @@ document.getElementById("cpt-scene").appendChild(c); })(); - var V = Object.fromEntries( - JSON.parse( - document - .querySelector("[data-composition-variables]") - .getAttribute("data-composition-variables"), - ).map((e) => [e.id, e.default]), - ); + // getVariables carries the declared defaults, standalone and mounted. + var V = {}; try { if (window.__hyperframes && window.__hyperframes.getVariables) - V = Object.assign(V, window.__hyperframes.getVariables() || {}); + V = window.__hyperframes.getVariables() || {}; } catch (e) { /* corrupt declarations must not blank the composition */ } @@ -347,31 +342,26 @@ const W = 1920, H = 1080, DUR = 12; - let V = Object.fromEntries( - JSON.parse( - document - .querySelector("[data-composition-variables]") - .getAttribute("data-composition-variables"), - ).map((e) => [e.id, e.default]), - ); + // Bare __hyperframes is this composition's own in a module; getVariables carries the defaults. + let V = {}; try { - if (window.__hyperframes && window.__hyperframes.getVariables) - V = Object.assign(V, window.__hyperframes.getVariables() || {}); + if (typeof __hyperframes !== "undefined" && __hyperframes.getVariables) + V = __hyperframes.getVariables() || {}; } catch (e) { /* corrupt declarations must not blank the composition */ } const HEADLINE1 = String(V.headline1 ?? "Understory"); - const HEADLINE2 = String(V.headline2 ?? "MOVE SLOWLY"); + const HEADLINE2 = String(V.headline2 ?? "Move slowly"); /* Headline typography is a PARAMETER — never a Design-panel edit. Any Google Fonts family name works; falls back through Gelasio/serif while (or if never) loading. */ - const FONT = (String(V.font || "Gelasio").trim() || "Gelasio").replace(/["']/g, ""); + const FONT = (String(V.font || "Helvetica").trim() || "Helvetica").replace(/["']/g, ""); const FONT_WEIGHT = Math.max( 100, Math.min( 900, Math.round( - isFinite(Number(V.fontWeight)) && Number(V.fontWeight) ? Number(V.fontWeight) : 500, + isFinite(Number(V.fontWeight)) && Number(V.fontWeight) ? Number(V.fontWeight) : 900, ), ), ); @@ -386,7 +376,7 @@ ); const LETTER_SP = Math.max( -0.2, - Math.min(1, isFinite(Number(V.letterSpacing)) ? Number(V.letterSpacing) : 0.1), + Math.min(1, isFinite(Number(V.letterSpacing)) ? Number(V.letterSpacing) : 0.01), ); const FONT_STACK = '"' + FONT + '", Gelasio, Georgia, serif'; if (!/^(Helvetica|Arial|Gelasio|Georgia|serif|sans-serif|monospace)$/i.test(FONT)) { @@ -650,10 +640,15 @@ return { map, bump }; } + // Beside this file when mounted; a runtime without assetUrl keeps the plain path. + const assetUrl = (path) => + typeof __hyperframes !== "undefined" && __hyperframes.assetUrl + ? __hyperframes.assetUrl(path) + : path; const textureLoader = new THREE.TextureLoader(); const [photoSurface, photoNormal] = await Promise.all([ - textureLoader.loadAsync("assets/leaf-surface-color.webp"), - textureLoader.loadAsync("assets/leaf-surface-normal.webp"), + textureLoader.loadAsync(assetUrl("assets/leaf-surface-color.webp")), + textureLoader.loadAsync(assetUrl("assets/leaf-surface-normal.webp")), ]); photoSurface.colorSpace = THREE.SRGBColorSpace; photoSurface.wrapS = photoSurface.wrapT = THREE.RepeatWrapping; diff --git a/registry/blocks/cuboid-carousel/cuboid-carousel.html b/registry/blocks/cuboid-carousel/cuboid-carousel.html index 51e2c034f0..c2c787276f 100644 --- a/registry/blocks/cuboid-carousel/cuboid-carousel.html +++ b/registry/blocks/cuboid-carousel/cuboid-carousel.html @@ -12,7 +12,8 @@ { "imports": { "three": "./assets/three.module.min.js", - "three/addons/": "./assets/addons/" + "three/addons/": "./assets/addons/", + "cuboid-carousel/motion": "./assets/cuboid-motion.js" } } @@ -103,12 +104,13 @@ import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js"; import { mergeVertices } from "three/addons/utils/BufferGeometryUtils.js"; - import { MOTION } from "./assets/cuboid-motion.js"; + import { MOTION } from "cuboid-carousel/motion"; const DUR = MOTION.endFrame / MOTION.fps; + // Bare __hyperframes is this composition's own in a module. const V = - window.__hyperframes && window.__hyperframes.getVariables - ? window.__hyperframes.getVariables() + typeof __hyperframes !== "undefined" && __hyperframes.getVariables + ? __hyperframes.getVariables() : {}; // ---- variable readers (every one clamped to the DialKit range) ---- diff --git a/registry/blocks/frost-sequence-camera-orbit/frost-sequence-camera-orbit.html b/registry/blocks/frost-sequence-camera-orbit/frost-sequence-camera-orbit.html index 9340140229..0757f2d966 100644 --- a/registry/blocks/frost-sequence-camera-orbit/frost-sequence-camera-orbit.html +++ b/registry/blocks/frost-sequence-camera-orbit/frost-sequence-camera-orbit.html @@ -8,6 +8,11 @@ Frost Sequence Rig +