Plugin Studio: a nested composite's pane and place reach the address

Studio owns the page address and writes ?tab=. A composite nested in a
tab announces its own choice (its open pane, its selected place); Studio
now records that beside ?tab=, while it owns the address, so a reload
or a sent link opens the same pane and place. Only pane and place: the
tab stays Studio's own. The listener is released on unmount, before the
hot-update return.
This commit is contained in:
Doxa Maps 2026-10-03 06:30:07 +00:00
parent c963a2a9fa
commit 5a3194bd08

View file

@ -225,7 +225,7 @@ import StudioTree from './src/StudioTree.vue'
import { LANGUAGES, loadLocale, saveLocale, getLanguage, normaliseLocale } from '@map/layouts/app-wrapper-material/languages.js'
import { publishMapToken, clearMapToken } from '@map/composables/useSharedMapToken.js'
import { loadScriptOnce, whenTagDefined } from '@map/utils/embedScript.js'
import { readViewKeys, writeViewKeys, onAddressChange, urlOwnerOf, commitUrl } from '@map/composables/useViewAddress.js'
import { readViewKeys, writeViewKeys, onAddressChange, urlOwnerOf, commitUrl, ownAddress } from '@map/composables/useViewAddress.js'
// The reader's own map token / token-service URL. localStorage only: never written into the build,
// never sent anywhere but Mapbox (the token) or the URL the reader typed (the service).
@ -769,6 +769,9 @@ export default defineComponent({
if (key) this.select(key, { fromHistory: true })
else if (this.rows.length) this.select(this.rows[0].key, { fromHistory: true })
})
// A nested composite's own choice (its open pane, its place) is announced up to here and written beside ?tab=,
// while this page owns its address. Only pane and place: the tab is Studio's own.
this._offOwn = ownAddress(this.$el, () => urlOwnerOf(this.cfg))
},
// The corner-widget hosts live on window.__doxaStudioWidgets so a HOT UPDATE remounts Studio onto
// the same hosts and a live widget (Rudder) keeps its state. A real unmount must release them, or
@ -777,6 +780,7 @@ export default defineComponent({
// FIRST, before the hot-update return below: a remounted Studio adds its own listener, and a kept one would
// re-apply every Back twice.
if (this._offAddress) { this._offAddress(); this._offAddress = null }
if (this._offOwn) { this._offOwn(); this._offOwn = null }
if (import.meta.hot) return
const W = window.__doxaStudioWidgets
if (W && W.hosts) for (const h of Object.values(W.hosts)) { try { h.remove() } catch (_) {} }