import type { Formattable } from '../blot/abstract/blot.js'; import Registry from '../registry.js'; import Scope from '../scope.js'; import Attributor from './attributor.js'; import ClassAttributor from './class.js'; import StyleAttributor from './style.js'; class AttributorStore { private attributes: { [key: string]: Attributor } = {}; private domNode: HTMLElement; constructor(domNode: HTMLElement) { this.domNode = domNode; this.build(); } public attribute(attribute: Attributor, value: any): void { // verb if (value) { if (attribute.add(this.domNode, value)) { if (attribute.value(this.domNode) != null) { this.attributes[attribute.attrName] = attribute; } else { delete this.attributes[attribute.attrName]; } } } else { attribute.remove(this.domNode); delete this.attributes[attribute.attrName]; } } public build(): void { this.attributes = {}; const blot = Registry.find(this.domNode); if (blot == null) { return; } const attributes = Attributor.keys(this.domNode); const classes = ClassAttributor.keys(this.domNode); const styles = StyleAttributor.keys(this.domNode); attributes .concat(classes) .concat(styles) .forEach((name) => { const attr = blot.scroll.query(name, Scope.ATTRIBUTE); if (attr instanceof Attributor) { this.attributes[attr.attrName] = attr; } }); } public copy(target: Formattable): void { Object.keys(this.attributes).forEach((key) => { const value = this.attributes[key].value(this.domNode); target.format(key, value); }); } public move(target: Formattable): void { this.copy(target); Object.keys(this.attributes).forEach((key) => { this.attributes[key].remove(this.domNode); }); this.attributes = {}; } public values(): { [key: string]: any } { return Object.keys(this.attributes).reduce( (attributes: { [key: string]: any }, name: string) => { attributes[name] = this.attributes[name].value(this.domNode); return attributes; }, {}, ); } } export default AttributorStore;