diff --git a/internal/plugin-gallery/dev-plugin.mjs b/internal/plugin-gallery/dev-plugin.mjs index 5b6ff2b62..34cece14a 100644 --- a/internal/plugin-gallery/dev-plugin.mjs +++ b/internal/plugin-gallery/dev-plugin.mjs @@ -197,6 +197,16 @@ export function leafRewrite(path, treeName = TREE_NAME) { return '/__leaf/' + segs.join('/') } +// urlOwner 'app' (library/composables/useViewAddress.js) for a dev page that is OURS, the rule generate-tree bakes +// into the built leaf: its shell writes ?tab=, so a clicked tab survives a reload and a copied link opens it. A +// FRAMED page drops it: Plugin Studio iframes its map rows from /__leaf/, and a history push from an iframe lands +// in the top page's Back stack. Write the element unowned and put this classic script right after it; it runs +// before the deferred module script upgrades the element. `<` is escaped: profile/instance come from the URL. +export function ownIfTopScript(cfg = {}) { + const owned = JSON.stringify(JSON.stringify({ ...cfg, urlOwner: 'app' })).replace(/try{if(window.self===window.top)document.currentScript.previousElementSibling.setAttribute('profile-config',${owned})}catch(e){}` +} + export function autoSpaDevPlugin(token = '') { // One generator for both galleries (internal/generate-gallery.mjs), driven by the same build // config the built page bakes. What dev changes: the model comes from discovery, the live @@ -365,7 +375,8 @@ export function autoSpaDevPlugin(token = '') { // renders the SAME view here as in production rather than the bundle's default. // assetsBase too, as the built leaf's BASE_CONFIG carries it ("../../assets" there; root-absolute // here, because a /__leaf/ URL's depth differs from the tree's and the pool is served at /assets). - const pc = JSON.stringify(instance ? { profile, instanceId: instance, assetsBase: '/assets' } : { profile, assetsBase: '/assets' }) + const leafPc = instance ? { profile, instanceId: instance, assetsBase: '/assets' } : { profile, assetsBase: '/assets' } + const pc = JSON.stringify(leafPc) // The composition tier of THIS profile, read from the same discovery the gallery uses. // `nested-elements-mfe` (cap-4) is the StackLayout scroll-stack tier — see the style note // below. An unknown profile falls through to the fixed-viewport leaf, the safe default. @@ -430,6 +441,7 @@ export function autoSpaDevPlugin(token = '') { // live 19-bundle tree. Passing the base makes a nested shell see exactly what the top // level sees. Elements that ignore tree-base simply drop an unknown attribute. `<${tag} tree-base="/__plugin-gallery" profile-config='${pc}'>`, + ownIfTopScript(leafPc), ``, '', ].filter(Boolean).join('\n')) @@ -499,6 +511,7 @@ export function autoSpaDevPlugin(token = '') { // manifest-shaped model the built tree bakes (19 bundles / 30 profiles), so pointing the // studio at it gives dev the same tab list production has. '', + ownIfTopScript(), '', '', ].filter(Boolean).join('\n')) diff --git a/plugin-designs/plugin-studio/index.html b/plugin-designs/plugin-studio/index.html index 5e3eb716a..0dea59ca5 100644 --- a/plugin-designs/plugin-studio/index.html +++ b/plugin-designs/plugin-studio/index.html @@ -35,7 +35,9 @@ real tag; map elements nest as their own SPA. Switch with no page reload.

- + +