viewof odp = {
const attribute = "data-odp";
const hooks = Array(3)
.fill("observablehq")
.map((x, i) => x + ["-root", "", "--error"][i]);
const poll = (function () {
let count = 0;
const callback = (records) => {
for (const record of records) {
if (
record.type === "attributes" &&
record.oldValue.indexOf(hooks[2]) !== -1
) {
stash(record.target, { action: "pop" });
}
}
};
const config = {
attributes: true,
attributeFilter: ["class"],
attributeOldValue: true
};
const observer = new MutationObserver(callback);
return (node) => {
observer.observe(node, config);
node.addEventListener("error", snitch);
node.setAttribute(attribute, ++count);
if (node.classList.contains(hooks[2])) {
stash(node);
}
};
})();
const root = Array.from(document.getElementsByClassName(hooks[0])).pop();
const register = Inputs.input({});
const snitch = (event) => stash(event.target);
const stash = (
node,
{ action = "push", key = node.getAttribute(attribute) } = {}
) => {
if (action === "pop") {
delete register.value[key];
} else {
Object.assign(register.value, {
[key]: node.textContent
});
}
register.dispatchEvent(new Event("input", { bubbles: true }));
};
if (root) {
Array.from(
root.getElementsByClassName(hooks[1])
).forEach(poll);
const observer = new MutationObserver((records) => {
for (const record of records) {
Array.from( record.addedNodes).forEach(poll);
}
});
observer.observe(root, {
childList: true
});
}
return register;
}