From c1054993c6a2c8b6d45babd3edf252fd6aef0f28 Mon Sep 17 00:00:00 2001 From: doxa-maps Date: Mon, 28 Sep 2026 07:04:02 +0000 Subject: [PATCH] /embed-test: mounted plugins follow a language switch; each card records the locale it was given (data-locale) --- app/pages/embed-test.vue | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/app/pages/embed-test.vue b/app/pages/embed-test.vue index 4dc00974..bf0547f8 100644 --- a/app/pages/embed-test.vue +++ b/app/pages/embed-test.vue @@ -21,6 +21,7 @@ interface Card { integrity: string description: string production: boolean + locale: string // the language handed to the element (data-locale, for a probe) state: 'idle' | 'loading' | 'mounted' | 'error' error: string } @@ -56,6 +57,28 @@ function loadScript(src: string, integrity: string): Promise { return scripts.get(src)! } +// The element's config, in the site's CURRENT language: set on mount and again on every language switch, +// so a mounted plugin follows the switcher (profile-config.locale for the maps, the language attribute for +// the shells). +function applyLocale(el: Element, card: Card) { + const token = (runtimeConfig.public as { mapboxToken?: string }).mapboxToken || '' + el.setAttribute('profile-config', JSON.stringify({ + profile: card.profile, + assetsBase: `${treeBase()}/assets`, + locale: locale.value, + // with a Mapbox token the maps use it; without one they use the keyless MapLibre engine + ...(token ? { tk: token } : { provider: 'maplibre' }) + })) + el.setAttribute('language', locale.value) + card.locale = locale.value +} +watch(locale, () => { + for (const c of cards.value) { + const el = c.state === 'mounted' ? hosts.get(c.key)?.firstElementChild : null + if (el) applyLocale(el, c) + } +}) + async function mount(card: Card) { const host = hosts.get(card.key) if (!host || card.state === 'mounted' || card.state === 'loading') return @@ -63,18 +86,10 @@ async function mount(card: Card) { try { await loadScript(card.script, card.integrity) if (!customElements.get(card.tag)) throw new Error(`<${card.tag}> was not defined by its bundle`) - const token = (runtimeConfig.public as { mapboxToken?: string }).mapboxToken || '' const el = document.createElement(card.tag) - el.setAttribute('profile-config', JSON.stringify({ - profile: card.profile, - assetsBase: `${treeBase()}/assets`, - locale: locale.value, - // with a Mapbox token the maps use it; without one they use the keyless MapLibre engine - ...(token ? { tk: token } : { provider: 'maplibre' }) - })) // shells (the Research Gallery, Plugin Studio) find their child maps through the tree's manifest el.setAttribute('tree-base', treeBase()) - el.setAttribute('language', locale.value) // the shells read their language from this attribute + applyLocale(el, card) host.replaceChildren(el) card.state = 'mounted' } catch (e) { @@ -115,7 +130,7 @@ onMounted(async () => { // the tag the bundle actually defines (a profile's own element name can name one it does not) const tag = p.element && (!defined.length || defined.includes(p.element)) ? p.element : defined[0] || p.element out.push({ key, bundle: b.bundle, profile: p.profile, tag, script: resolveUrl(base, b.scriptUrl || `${b.bundle}/${b.bundle}.js`), - integrity: b.integrity || '', description: p.description || '', production: (p.stage || b.stage) === 'production', + integrity: b.integrity || '', description: p.description || '', production: (p.stage || b.stage) === 'production', locale: '', state: 'idle', error: '' }) } } @@ -149,7 +164,7 @@ const setHost = (key: string) => (el: unknown) => { if (el) hosts.set(key, el as