/** * posterSectionElement.js — registers : ONE poster section, any poster type, as an element. * * * * 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), min-card-px (the narrowest a card gets before a row holds one fewer). * 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