Goal (c), and it turned into a goal (d) fix. Every profile element is
defineCustomElement(ProfileLoader, { configureApp }), and the configureApp has four
steps. The fourth, app.provide('appI18n', i18n), is the one that gets dropped.
ProfileLoader injects that instance (ProfileLoader.vue:176) to drive its locale from
profile-config. Without the provide the watcher holds null and the drive NEVER RUNS --
while setRuntimeLocale() on the next line still fires, so tStatic strings DO follow the
host. The element renders a convincing MIXTURE of the reader's language and English, and
nothing throws, because the t() shim falls back to its key. It reads as "a few strings
not translated yet".
SHIPPING THAT TODAY: country-posters, key-cities, gospel-resources, cities-internet and
my-upg-100-list. regions-plugin censused all 19 entry files independently and found the
same five and no sixth. The measurement is regions-dashboard's, from when they hit it:
a Spanish catalogue present, es set, and every t() string still English.
All sixteen entries now call library/elements/defineMapElement.js, so the five are fixed
by construction rather than by five separate edits. Behaviour is otherwise identical --
same options, same element names, same per-plugin extras. wall-of-people-groups needed
the helper to hand its pinia back, because it takes a store off its own instance and a
helper that hid pinia would have given it a second one: two stores and a silent state
split.
★ AND THE CENSUS THAT RECOMMENDED THIS SAW FOUR OF SIXTEEN. My detector hashed function
BODIES; eleven sites are not `function buildXElement()` at all, they are
`const El = defineCustomElement(...)`. I wrote "every number here is a lower bound" in
the census as a caveat and it was the headline within the hour -- a 4x undercount of the
item it recommended. So this gate greps for the SHAPE, not for a known list: a check
written around the four that matched would have passed the twelve that did not.
check-element-bootstrap has two arms. No entry may build a profile element by hand, and
the helper itself must provide appI18n -- PLANTED as a negative case, so the regression
cannot return by editing library instead of a plugin. It also fails if it finds fewer
than ten entries, because a detection that stops matching reports the same green as a
tree with no problems.
THE PLANT CAUGHT TWO BUGS IN THIS GATE BEFORE IT CAUGHT ANYTHING ELSE. The predicate
matched the helper's DOCSTRING, so it would have passed a helper that only mentions the
provide in prose -- comments are stripped now, because a check that reads comments is
reading the author's intentions rather than the program. And the plant itself used /m
instead of /gm, so it deleted the documentation and left the code, then reported that it
could not detect an absence that was not there.
50 lines
2.5 KiB
JavaScript
50 lines
2.5 KiB
JavaScript
/**
|
|
* plugin-designs/demo-map/index.js
|
|
*
|
|
* Bundle entry — registers the <demo-map> web component.
|
|
* Adapted from plugin-designs/template-bundle/index.js (the copy-me reference).
|
|
*
|
|
* Folder name = bundle name. This folder builds to exactly one output file:
|
|
* app/doxa-maps/demo-map/demo-map.js
|
|
*
|
|
* Profiles live as FLAT .vue files DIRECTLY in this folder (demo-map.vue) —
|
|
* no profiles/ subfolder. Each `*.vue` here = one profile.
|
|
*
|
|
* Usage from a host page:
|
|
* <script src=".../demo-map/demo-map.js"></script>
|
|
* <demo-map profile-config='{"profile":"demo-map","tk":"pk.eyJ..."}'></demo-map>
|
|
*/
|
|
|
|
import { defineMapElement } from '@map/elements/defineMapElement.js'
|
|
import { registerStrategies } from '@map/colors/_registry.js'
|
|
|
|
// ─── Bundle-private profile registry ─────────────────────────────────────────
|
|
// import.meta.glob is evaluated by Vite at build time relative to THIS file, so
|
|
// it captures only THIS bundle's profiles. ProfileLoader (in @map) cannot run
|
|
// this glob itself, so the bundle hands the result over via app.provide().
|
|
const profileModules = import.meta.glob('./*.vue')
|
|
|
|
// ─── Bundle-private color strategies ─────────────────────────────────────────
|
|
// Merges ./src/colors/*.js OVER the shared library set for THIS bundle
|
|
// only. demo-map ships `single-color.js` → mode `singleColor` — the strategy
|
|
// its "Purple" tab uses. The shared `religion` strategy stays untouched. The
|
|
// glob is `*.js`, so `src/colors/colors.json` (plain values) is ignored by design.
|
|
registerStrategies(import.meta.glob('./src/colors/*.js', { eager: true }))
|
|
|
|
// ─── Register the custom element ─────────────────────────────────────────────
|
|
// One tag per bundle, named after the bundle. The guard prevents an
|
|
// "already registered" error if the IIFE is ever loaded twice on one page.
|
|
const DemoMapElement = defineMapElement({
|
|
profileModules,
|
|
configureApp: (app, { pinia, i18n }) => {
|
|
// Install i18n AND hand the instance to ProfileLoader by reference. The
|
|
// defineCustomElement root cannot use useI18n() (see ProfileLoader.vue);
|
|
// it drives locale through this provided instance instead.
|
|
},
|
|
})
|
|
|
|
if (typeof customElements !== 'undefined' && !customElements.get('demo-map')) {
|
|
customElements.define('demo-map', DemoMapElement)
|
|
}
|
|
|
|
export default DemoMapElement
|