DarkWiiPlayer
f612273632
This is partly to avoid confusion with the skooma `bind` function, but also to make it clearer that only the inner content of an element is being bound to the listener. This function may also disappear entirely in the future if it turns out it doesn't provide any benefits over the skooma bind function.
60 lines
1.5 KiB
JavaScript
60 lines
1.5 KiB
JavaScript
/*
|
|
A somewhat refined Proxy generator that lets you selectively listen to changed
|
|
properties and react accordingly.
|
|
|
|
Example:
|
|
const l = listener()
|
|
l.listen("contract", contract => speaker.handle(contract))
|
|
l.contract = new Contract()
|
|
*/
|
|
|
|
export const listener = (target={}) => {
|
|
let callbacks = new Map()
|
|
function listen(prop, callback) {
|
|
if ("object" == typeof prop && "forEach" in prop) {
|
|
prop.forEach(prop => this.listen(prop, callback))
|
|
} else if (callback) {
|
|
let list = callbacks.get(prop)
|
|
if (!list) callbacks.set(prop, list=[])
|
|
list.push(callback)
|
|
} else {
|
|
callbacks.delete(prop)
|
|
}
|
|
}
|
|
let proxy = new Proxy(target, {
|
|
set: (target, prop, value) => {
|
|
if (callbacks.has("*")) callbacks.get("*").forEach(callback => callback(value, prop, target[prop]))
|
|
if (callbacks.has(prop)) callbacks.get(prop).forEach(callback => callback(value, prop, target[prop]))
|
|
return Reflect.set(target, prop, value)
|
|
},
|
|
get: (target, prop, value) => {
|
|
if (prop == "listen")
|
|
return listen
|
|
else if (prop == "__raw")
|
|
return target
|
|
else
|
|
return Reflect.get(target, prop)
|
|
}
|
|
})
|
|
return proxy
|
|
}
|
|
|
|
export const bindContent = (listener, prop="value", target=document.createTextNode(""), filter) => {
|
|
const run = data => {
|
|
data = filter
|
|
? filter(data)
|
|
: data
|
|
if ("innerText" in target)
|
|
if (typeof data == "string")
|
|
target.innerText = data
|
|
else
|
|
target.replaceChildren(data)
|
|
else
|
|
target.data = data
|
|
}
|
|
listener.listen(prop, run)
|
|
run(listener[prop])
|
|
return target
|
|
}
|
|
|
|
export default listener
|