package.html-element.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scoped-elements Show documentation
Show all versions of scoped-elements Show documentation
Allows to auto define custom elements scoping them
The newest version!
import { dedupeMixin } from '@open-wc/dedupe-mixin';
/**
* @typedef {import('./types.js').ScopedElementsHost} ScopedElementsHost
* @typedef {import('./types.js').ScopedElementsMap} ScopedElementsMap
*/
const version = '3.0.0';
const versions = window.scopedElementsVersions || (window.scopedElementsVersions = []);
if (!versions.includes(version)) {
versions.push(version);
}
/**
* @template {import('./types.js').Constructor} T
* @param {T} superclass
* @return {T & import('./types.js').Constructor}
*/
const ScopedElementsMixinImplementation = superclass =>
/** @type {ScopedElementsHost} */
class ScopedElementsHost extends superclass {
/**
* Obtains the scoped elements definitions map if specified.
*
* @type {ScopedElementsMap=}
*/
static scopedElements;
static get scopedElementsVersion() {
return version;
}
/** @type {CustomElementRegistry=} */
static __registry;
/**
* Obtains the CustomElementRegistry associated to the ShadowRoot.
*
* @returns {CustomElementRegistry=}
*/
get registry() {
return /** @type {typeof ScopedElementsHost} */ (this.constructor).__registry;
}
/**
* Set the CustomElementRegistry associated to the ShadowRoot
*
* @param {CustomElementRegistry} registry
*/
set registry(registry) {
/** @type {typeof ScopedElementsHost} */ (this.constructor).__registry = registry;
}
/**
* @param {ShadowRootInit} options
* @returns {ShadowRoot}
*/
attachShadow(options) {
const { scopedElements } = /** @type {typeof ScopedElementsHost} */ (this.constructor);
const shouldCreateRegistry =
!this.registry ||
// @ts-ignore
(this.registry === this.constructor.__registry &&
!Object.prototype.hasOwnProperty.call(this.constructor, '__registry'));
/**
* Create a new registry if:
* - the registry is not defined
* - this class doesn't have its own registry *AND* has no shared registry
* This is important specifically for superclasses/inheritance
*/
if (shouldCreateRegistry) {
this.registry = new CustomElementRegistry();
for (const [tagName, klass] of Object.entries(scopedElements ?? {})) {
this.registry.define(tagName, klass);
}
}
return super.attachShadow({
...options,
// The polyfill currently expects the registry to be passed as `customElements`
customElements: this.registry,
// But the proposal has moved forward, and renamed it to `registry`
// For backwards compatibility, we pass it as both
registry: this.registry,
});
}
};
export const ScopedElementsMixin = dedupeMixin(ScopedElementsMixinImplementation);