obsize
Version:
🧐 Element size observer based on ResizeObserver
84 lines (74 loc) • 2.2 kB
JavaScript
;
var crypto = require('crypto');
var urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
var POOL_SIZE_MULTIPLIER = 128;
var pool, poolOffset;
var fillPool = function fillPool(bytes) {
if (!pool || pool.length < bytes) {
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
crypto.randomFillSync(pool);
poolOffset = 0;
} else if (poolOffset + bytes > pool.length) {
crypto.randomFillSync(pool);
poolOffset = 0;
}
poolOffset += bytes;
};
var nanoid = function nanoid() {
var size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 21;
fillPool(size -= 0);
var id = '';
for (var i = poolOffset - size; i < poolOffset; i++) {
id += urlAlphabet[pool[i] & 63];
}
return id;
};
const map = new Map();
const obs = new ResizeObserver((entries) => {
entries.forEach((entry) => {
const { target } = entry;
const fns = map.get(target);
if (fns?.length) {
const newFns = [];
fns.forEach((item) => {
const { fn, once } = item;
fn();
if (!once) {
newFns.push(item);
}
});
map.set(target, newFns);
}
});
});
function observe(element, fn, options = { once: false }) {
const isElementObserver = map.has(element);
const elementFns = isElementObserver ? map.get(element) : [];
const key = nanoid();
const { once } = options;
elementFns.push({ key, once, fn });
if (!isElementObserver) {
obs.observe(element);
map.set(element, elementFns);
}
return () => {
if (map.has(element)) {
const fns = map.get(element).filter((item) => {
return item.key !== key;
});
if (fns.length === 0) {
map.delete(element);
obs.unobserve(element);
}
else {
map.set(element, fns);
}
}
};
}
function clear() {
map.clear();
obs.disconnect();
}
exports.clear = clear;
exports.observe = observe;