/embed-test: mounted plugins follow a language switch; each card records the locale it was given (data-locale)

This commit is contained in:
doxa-maps 2026-09-28 07:04:02 +00:00
parent afb13a151b
commit c1054993c6

View file

@ -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<void> {
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
<template v-for="(c, i) in cards" :key="c.key">
<h2 v-if="i === 0 && c.production" data-embed-section="production">1. Production</h2>
<h2 v-if="!c.production && (i === 0 || cards[i - 1].production)" data-embed-section="other">2. Every other web plugin</h2>
<section class="embed-card" :data-card="c.key" :data-state="c.state" :data-production="c.production">
<section class="embed-card" :data-card="c.key" :data-state="c.state" :data-production="c.production" :data-locale="c.locale">
<header class="embed-card__head">
<strong>{{ c.bundle }} / {{ c.profile }}</strong>
<code>&lt;{{ c.tag }}&gt;</code>