UNPKG

@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
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); } }