A host page can define a tag name before our bundle loads, and customElements.define is first come, first served. DX Life's own scripts define <doxa-map>, <doxa-simple-map> and <doxa-research-map>, and our bundles defined the same names behind a silent guard, so on those pages our define was skipped and the page drew the host's element under our name (Prayer Progress on the Adopt page, and the Research page). - The doxa-simple-map bundle defines <dxm-simple-map>; doxa-research-map defines <dxm-research-map>. Each is its bundle's first define, so the manifest, the leaf pages and the gallery mount them with no other change. - The older names are defined only when the host asks: data-legacy-tags on the bundle's <script>, or window.DXM_LEGACY_TAGS = true before it loads. Off by default. - library/elements/ownTags.js: a class is branded with its bundle; a re-load is silent; a tag held by a foreign class is reported (console.error), never adopted. whenTagDefined refuses a dxm- tag held by a foreign class rather than mounting it. - research-map-plus-grid mounts <dxm-research-map>; the gallery and studio count the new tags as heavy (WebGL) elements; the studio's and the composite's composes lists name them. - check:element-namespace (gates:pre; self-test in gates:post): no host name by default, each bundle's own tag first, the manifest mounts them, one bundle per tag (people-groups-grid is the one known exception), ownTags and whenTagDefined run against a stub registry.
97 lines
5.2 KiB
JavaScript
97 lines
5.2 KiB
JavaScript
/**
|
|
* plugin-designs/doxa-simple-map/index.js
|
|
*
|
|
* Bundle entry — registers the doxa-simple-map web component.
|
|
*
|
|
* ★ ITS TAG IS <dxm-simple-map>, DX Maps' own name (library/elements/ownTags.js). A host can define the
|
|
* older generic names first (DX Life's own /js/doxa-simple-map.js defines <doxa-map> and <doxa-simple-map>),
|
|
* and the first definition wins, so under those names a page could be drawing the host's element, not this
|
|
* one. The older names are defined only when the host asks for them: a `data-legacy-tags` attribute on this
|
|
* bundle's <script>, or window.DXM_LEGACY_TAGS = true before it loads. Each name gets its own class
|
|
* (separate defineCustomElement calls: one class under two tags is undefined behaviour).
|
|
*
|
|
* Usage:
|
|
* <script src="<tree>/doxa-simple-map/doxa-simple-map.js"></script>
|
|
* <dxm-simple-map profile-config='{"profile":"doxa-simple-map","tk":"pk.eyJ..."}'></dxm-simple-map>
|
|
*
|
|
* An existing embed that still writes <doxa-map> or <doxa-simple-map> adds `data-legacy-tags` to its
|
|
* <script> tag.
|
|
*
|
|
* The profile-config attribute is parsed by ProfileLoader (in @map).
|
|
* `profile` must match a .vue file in this bundle's folder.
|
|
*
|
|
* Profile registry — Q3 contract from the migration plan: ProfileLoader lives
|
|
* inside @map, so it cannot use import.meta.glob to reach into a
|
|
* bundle's folder. The bundle MUST evaluate import.meta.glob('./*.vue')
|
|
* locally and hand the result to the loader via app.provide('profileModules').
|
|
*
|
|
* Mapbox RTL text plugin: registered ONCE at module init (before any map
|
|
* constructs), lazy-loads when Arabic/Hebrew text appears on the basemap.
|
|
*/
|
|
|
|
import { defineMapElement } from '@map/elements/defineMapElement.js'
|
|
import { brand, ownTagFree, legacyTagsRequested } from '@map/elements/ownTags.js'
|
|
import { registerStrategies } from '@map/colors/_registry.js'
|
|
|
|
// Read NOW, at evaluation time: legacyTagsRequested() reads document.currentScript, which is gone later.
|
|
const LEGACY_TAGS = legacyTagsRequested()
|
|
|
|
// ─── 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. Handed to ProfileLoader via
|
|
// app.provide('profileModules', ...) below.
|
|
const profileModules = import.meta.glob('./*.vue')
|
|
|
|
// ─── Bundle-private color strategies ─────────────────────────────────────────
|
|
// Same seam as profileModules, for colors. Any `<name>.js` a contributor drops in
|
|
// this bundle's `src/colors/` folder is merged OVER the shared library set
|
|
// (same mode key = override; new key = profile-private). This bundle inlines its own
|
|
// copy of the registry (IIFE build), so registering here affects THIS bundle only.
|
|
// No-op today: doxa-simple-map ships no local strategies (empty glob).
|
|
registerStrategies(import.meta.glob('./src/colors/*.js', { eager: true }))
|
|
|
|
// RTL text plugin (Arabic/Hebrew/Persian shaping): installed by useMapInstance through
|
|
// library/maps/rtl-text.js, on BOTH engines, before every map is constructed. Do not re-add a
|
|
// hand-rolled mapboxgl-only block here -- it was a strict subset of that call.
|
|
|
|
/**
|
|
* Build a fresh defineCustomElement-wrapped class.
|
|
*
|
|
* Vue's defineCustomElement returns a class that gets registered with
|
|
* customElements.define exactly once per tag name. Reusing a single class
|
|
* across two tags is undefined behavior, so we call defineCustomElement TWICE
|
|
* with the same component to produce two independent classes.
|
|
*
|
|
* Each instance gets its own Pinia + its own i18n via configureApp — that
|
|
* isolation is important when multiple <doxa-map> embeds share a page.
|
|
*/
|
|
function buildDoxaMapElement() {
|
|
return 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.
|
|
// Hand the bundle's profile registry to ProfileLoader (Q3 contract).
|
|
// ProfileLoader inject('profileModules')s this — see ProfileLoader.vue.
|
|
},
|
|
})
|
|
}
|
|
|
|
const BUNDLE = 'doxa-simple-map'
|
|
const DxmSimpleMapElement = brand(buildDoxaMapElement(), BUNDLE)
|
|
|
|
// ─── Register the tag ────────────────────────────────────────────────────────
|
|
// ownTagFree: a second load of this bundle is silent (the first copy serves); a tag already held by
|
|
// anything else is reported, never adopted. The FIRST define in this file is the profile's element:
|
|
// internal/generate-tree.mjs reads it into the manifest, the leaf pages and the gallery.
|
|
if (ownTagFree('dxm-simple-map', BUNDLE)) customElements.define('dxm-simple-map', DxmSimpleMapElement)
|
|
|
|
// The older generic names, ONLY when the host asked (see the header). Never on by default.
|
|
if (LEGACY_TAGS) {
|
|
for (const legacy of ['doxa-map', 'doxa-simple-map']) {
|
|
if (ownTagFree(legacy, BUNDLE)) customElements.define(legacy, brand(buildDoxaMapElement(), BUNDLE))
|
|
}
|
|
}
|
|
|
|
export default DxmSimpleMapElement
|