infuse.host
Version:
Infuse your HTML with dynamic content.
93 lines (78 loc) • 2.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.queues = undefined;
exports.addCleanupFunction = addCleanupFunction;
exports.sweepElement = sweepElement;
exports.default = sweep;
var _configs = require('./configs.js');
var _configs2 = _interopRequireDefault(_configs);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* 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.
*/
const queues = exports.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`.
*/
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(_configs2.default.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.
*/
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(_configs2.default.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).
*/
function sweep(element, root) {
const selector = `[${_configs2.default.get('sweepFlag')}]`;
const elements = Array.from(root.querySelectorAll(selector));
if (element.matches(selector)) {
elements.push(element);
}
elements.forEach(sweepElement);
}
;