- ONE REGISTRY PER PAGE. Every bundle inlines its own copy of posterTypes.js, and <dxm-poster-section> is defined by whichever bundle loads first, so with a module-level Map that element saw only its own bundle's types: type="upg100-list" rendered "none" when the country-posters bundle had defined it. The registry now lives on the page (globalThis.__DXM_POSTER_TYPES__, created once): every copy registers into it and reads from it; a name registered twice keeps the first (a dev warning; the built-in country is silent); every registration is announced on window (dxm-poster-type-registered), and PosterSectionView looks again when its type arrives after it asked. - COLUMNS (carried from the Poster Sections plugin PR so the element's library lands once): columns="1".."5" maps to profile-config.columns and to PosterWall's existing columns prop; absent or out of range is today's default, and a reader's saved per-row choice still wins. - check:poster-type-registry (gates:pre; self-test in gates:post): two independent copies of the module side by side, as two bundles on one page; a type registered through one is found through the other; first wins; announced. The self-test's per-bundle registry fails.
41 lines
1.9 KiB
JavaScript
41 lines
1.9 KiB
JavaScript
/**
|
|
* posterSectionElement.js — registers <dxm-poster-section>: ONE poster section, any poster type, as an element.
|
|
*
|
|
* <dxm-poster-section type="country" scope="africa" locale="ar"></dxm-poster-section>
|
|
*
|
|
* Attributes: type (default "country"), scope (a region / continent / list key), collapsible (default on;
|
|
* collapsible="false" turns it off), collapsed (start shut), locale, assets-base, api-base-url, is-dark, columns
|
|
* (posters per row, 1-5).
|
|
* They are mapped into the standard element's profile-config, so the element keeps defineMapElement's per-instance
|
|
* i18n and store, and the profile (PosterSectionView.vue) reads them like every other profile reads its config.
|
|
* Any bundle can call registerPosterSectionElement(); a second call is a no-op.
|
|
*/
|
|
import { defineMapElement } from './defineMapElement.js'
|
|
|
|
import { ATTRS, TAG, posterSectionConfig } from './posterSectionConfig.js'
|
|
export { posterSectionConfig }
|
|
|
|
export function registerPosterSectionElement(tag = TAG) {
|
|
if (typeof customElements === 'undefined' || customElements.get(tag)) return
|
|
const Base = defineMapElement({ profileModules: { './poster-section.vue': () => import('../components/poster/PosterSectionView.vue') } })
|
|
class PosterSectionElement extends Base {
|
|
connectedCallback() {
|
|
this.syncConfig()
|
|
if (!this.attrWatch) {
|
|
this.attrWatch = new MutationObserver(() => this.syncConfig())
|
|
this.attrWatch.observe(this, { attributes: true, attributeFilter: ATTRS })
|
|
}
|
|
super.connectedCallback()
|
|
}
|
|
disconnectedCallback() {
|
|
if (this.attrWatch) { this.attrWatch.disconnect(); this.attrWatch = null }
|
|
super.disconnectedCallback()
|
|
}
|
|
syncConfig() {
|
|
const next = JSON.stringify(posterSectionConfig(this))
|
|
if (this.getAttribute('profile-config') !== next) this.setAttribute('profile-config', next)
|
|
}
|
|
}
|
|
customElements.define(tag, PosterSectionElement)
|
|
}
|
|
export default registerPosterSectionElement
|