UNPKG

infuse.host

Version:

Infuse your HTML with dynamic content.

80 lines (68 loc) 2.52 kB
import configs from './configs.js'; /** * Keys will be elements and values will be a `Set` of callbacks that will be executed, by the * `sweepElement` function (which is meant to be executed when the elements are removed from the * DOM), to clean up data associated with the element. */ export const queues = new WeakMap(); /** * Adds a callback to the element's queue of callbacks. * * @function add * @param {Element} element The element. * @param {Function} callback A function that cleans up some data associated with the `element`. */ export function addCleanupFunction(element, callback) { // Get the `queue` of callbacks for the given `element`. let queue = queues.get(element); // If there's no `queue`, create a new one, add it to `queues`, and set the flag attribute. if (!queue) { queue = new Set(); queues.set(element, queue); element.setAttribute(configs.get('sweepFlag'), ''); } // Add the given `callback` to the element's `queue`. queue.add(callback); } /** * Executes all callbacks in the element's queue to clean up data associated with the element. * This is meant to be called when an element is removed from the DOM. * * @function sweepElement * @param {Element} element The element. */ export function sweepElement(element) { // Get the `queue` of callbacks for the given `element`. const queue = queues.get(element); // End execution if there's no `queue`. if (!queue) { return; } // Execute each `callback` in the `queue`. for (const callback of queue) { callback(); } // Clear the `queue`, remove it from `queues`, and remove the flag attribute. queue.clear(); queues.delete(element); element.removeAttribute(configs.get('sweepFlag')); } /** * Searches for all elements, descendants of `element`, that have the flag attribute and "sweeps" * them (using `sweepElement`). The given `element` will also be sweept if it has the flag * attribute. * * @function sweep * @param {Element} element Descendants of this `element` that have the flag attribute will be * "sweept". The `element` itself will also be sweept if it has the flag attribute. * @param {(ShadowRoot|Element)} root The element's shadow root or the element itself (if it * doesn't use a Shadow DOM). */ export default function sweep(element, root) { const selector = `[${ configs.get('sweepFlag') }]`; const elements = Array.from(root.querySelectorAll(selector)); if (element.matches(selector)) { elements.push(element); } elements.forEach(sweepElement); }