Add support for child generators as skooma args

Function arguments to skooma generators are now only treated as
initialisers if they take at least one named argument. Otherwise they
are called and their return value is evaluated as their replacement.

The process is recursive and can happen repeatedly for functions that
themselves return functions.
This commit is contained in:
Talia 2024-01-22 10:35:20 +01:00
parent 75fc1a7ce7
commit 3f838821e4

View file

@ -52,7 +52,7 @@ const getCustom = args => args.reduce(
const isElement = object => HTMLElement.prototype.isPrototypeOf(object)
const isReactive = object => !(object instanceof HTMLElement)
export const isReactive = object => !(object instanceof HTMLElement)
&& (object instanceof EventTarget)
&& ("value" in object)
@ -63,6 +63,8 @@ const toChild = arg => {
return arg
} else if (isReactive(arg)) {
return reactiveChild(arg)
} else {
return document.createComment("Placeholder for reactive content")
}
}
@ -98,7 +100,7 @@ const specialAttributes = {
},
shadowRoot: {
set: (element, value) => {
parseArgs((element.shadowRoot || element.attachShadow({mode: "open"})), null, value)
parseArgs((element.shadowRoot || element.attachShadow({mode: "open"})), value)
}
}
}
@ -145,21 +147,25 @@ const setReactiveAttribute = (element, attribute, reactive, abortController) =>
}
}
const parseArgs = (element, before, ...args) => {
const parseArgs = (element, ...args) => {
if (element.content) element = element.content
for (const arg of args) if (arg !== empty) {
const child = toChild(arg)
if (child)
element.insertBefore(child, before)
else if (arg === undefined || arg == null)
console.warn(`An argument of type ${typeof arg} has been ignored`, element)
else if (typeof arg == "function")
arg(element)
else if ("length" in arg)
parseArgs(element, before, ...arg)
else
for (const key in arg)
setAttribute(element, key, arg[key])
if (arg instanceof Array) {
parseArgs(element, ...arg)
} else {
const child = toChild(arg)
if (child)
element.append(child)
else if (arg === undefined || arg == null)
console.warn(`An argument of type ${typeof arg} has been ignored`, element)
else if (typeof arg == "function" && arg.length == 0)
parseArgs(element, arg())
else if (typeof arg == "function")
arg(element)
else
for (const key in arg)
setAttribute(element, key, arg[key])
}
}
}
@ -173,7 +179,7 @@ const node = (name, args, options) => {
element = document.createElementNS(options.xmlns, name, opts)
else
element = document.createElement(name, opts)
parseArgs(element, null, args)
parseArgs(element, args)
return element
}