@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
64 lines (63 loc) • 2.56 kB
JavaScript
import { ESLMixinRegistry } from './esl-mixin-registry';
// TODO: fix duplicate in separate scopes (non-critical as only one instance per mixin type is created)
// Singleton cache for ESLMixinAttributesObserver instances
const instances = new Map();
/**
* Internal {@link ESLMixinElement}s observedAttributes mutation listener.
* Creates a single instance per mixin type
* Ignores mixin primary attribute changes (they are observed by {@link ESLMixinRegistry} ootb)
*/
export class ESLMixinAttributesObserver {
constructor(type) {
this.type = type;
this.observer = new MutationObserver((records) => records.forEach(this.handleRecord, this));
if (instances.has(type))
return instances.get(type);
instances.set(type, this);
}
/** Processes single mutation record */
handleRecord(record) {
const name = record.attributeName;
const target = record.target;
if (!name || !target)
return;
const mixin = ESLMixinRegistry.get(target, this.type);
mixin && mixin.attributeChangedCallback(name, record.oldValue, target.getAttribute(name));
}
/** Subscribes to the {@link ESLMixinElement} host instance mutations */
observe(mixin) {
const { is, observedAttributes } = mixin.constructor;
const attributeFilter = observedAttributes.filter((name) => name !== is);
if (!attributeFilter.length)
return;
this.observer.observe(mixin.$host, {
attributes: true,
attributeFilter,
attributeOldValue: true
});
}
/** Unsubscribes from the {@link ESLMixinElement} host instance mutations */
unobserve(mixin) {
this.observer.observe(mixin.$host, {
attributes: true,
attributeFilter: []
});
}
static instanceFor(mixin) {
const { is, observedAttributes } = mixin.constructor;
const attributes = (observedAttributes || []).filter((name) => name !== is);
if (!is || !attributes.length)
return null;
return new ESLMixinAttributesObserver(is);
}
/** Subscribes to the {@link ESLMixinElement} host instance mutations */
static observe(mixin) {
const observer = this.instanceFor(mixin);
observer && observer.observe(mixin);
}
/** Unsubscribes from the {@link ESLMixinElement} host instance mutations */
static unobserve(mixin) {
const observer = this.instanceFor(mixin);
observer && observer.unobserve(mixin);
}
}