UNPKG

domtranslator

Version:
108 lines (106 loc) 3.73 kB
/** * Wrap for MutationObserver with features * - Tracking real changes. You can ignore mutation sequences like [delete, add] who happens with moved DOM nodes * - Adding listeners by event names */ export class XMutationObserver { handlers = new Map(); callHandlers(eventName, params) { const handlers = this.handlers.get(eventName); if (handlers !== undefined) { handlers.forEach((fn) => fn(params)); } } observerHandler = (mutations) => { const nodeCounters = new Map(); mutations.forEach((mutation) => { switch (mutation.type) { case 'characterData': { this.callHandlers('characterData', { target: mutation.target, oldValue: mutation.oldValue, }); break; } case 'attributes': { this.callHandlers('changeAttribute', { target: mutation.target, oldValue: mutation.oldValue, attributeName: mutation.attributeName, }); break; } case 'childList': { // write all changes mutation.removedNodes.forEach((node) => { const counters = nodeCounters.get(node); if (counters !== undefined) { counters.removed++; } else { nodeCounters.set(node, { added: 0, removed: 1, }); } }); mutation.addedNodes.forEach((node) => { const counters = nodeCounters.get(node); if (counters !== undefined) { counters.added++; } else { nodeCounters.set(node, { added: 1, removed: 0, }); } }); break; } } }); // call handlers if have changes nodeCounters.forEach(({ added, removed }, node) => { const data = { target: node, }; if (added > removed) { this.callHandlers('elementAdded', data); } else if (added < removed) { this.callHandlers('elementRemoved', data); } else { this.callHandlers('elementMoved', data); } }); }; observer = new MutationObserver(this.observerHandler); observe(node) { this.observer.observe(node, { attributeOldValue: true, characterDataOldValue: true, childList: true, characterData: true, subtree: true, }); } disconnect() { this.observer.disconnect(); } addHandler(eventName, callback) { if (!this.handlers.has(eventName)) { this.handlers.set(eventName, new Set()); } const handlers = this.handlers.get(eventName); handlers?.add(callback); } removeHandler(eventName, callback) { const handlers = this.handlers.get(eventName); if (handlers !== undefined) { handlers.delete(callback); } } } //# sourceMappingURL=../sourcemaps/utils/XMutationObserver.js.map