skooma-js/domLense.js

78 lines
1.9 KiB
JavaScript
Raw Normal View History

2024-01-10 14:01:46 +00:00
class ChildObserver extends MutationObserver {
constructor() {
super(mutations => {
for (const mutation of mutations) {
mutation.target.dispatchEvent(new CustomEvent("change", {detail: mutation}))
}
})
}
observe(element) {
MutationObserver.prototype.observe.call(this, element, { childList: true })
}
}
export const lense = (methods, extra) => {
2024-01-08 12:37:36 +00:00
if (extra) return lense(extra)(methods)
const traps = {
get(target, prop) {
if (prop === "length") {
return target.children.length
} else if (prop === Symbol.iterator) {
return function*() {
for (const child of target.children) {
2024-01-20 14:06:23 +00:00
yield methods.get.call(child)
2024-01-08 12:37:36 +00:00
}
}
} else if (prop.match?.call(prop, /^[0-9]+$/)) {
const child = target.children[prop]
2024-01-20 14:06:23 +00:00
if (child) return methods.get.call(child)
2024-01-08 12:37:36 +00:00
return child
} else {
return Array.prototype[prop]
}
},
set(target, prop, value) {
if (prop.match?.call(prop, /^[0-9]+$/)) {
const child = target.children[prop]
if (child) {
2024-01-20 14:06:23 +00:00
methods.set.call(child, value)
2024-01-08 12:37:36 +00:00
return true
2024-01-08 13:27:14 +00:00
} else {
for (let i = target.children.length; i < Number(prop); i++) {
target.appendChild(methods.new(undefined))
}
2024-01-08 12:37:36 +00:00
const element = methods.new(value)
target.appendChild(element)
2024-01-20 14:06:23 +00:00
if (methods.get.call(element) !== value)
methods.set.call(element, value)
2024-01-08 12:37:36 +00:00
return true
}
} else if (prop == "length") {
if (value == target.children.length)
return true
else
return false
}
},
deleteProperty(target, prop) {
if (prop.match?.call(prop, /^[0-9]+$/)) {
const child = target.children[prop]
if (child) child.remove()
return true
}
},
has(target, prop) {
return (prop === Symbol.iterator) || (prop in target.children) || (prop in Array.prototype)
}
}
return element => {
if (!(element instanceof Element)) throw(new Error("Creating domLense on non-element"))
return new Proxy(element, traps)
}
2024-01-08 12:37:36 +00:00
}
export default lense