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:
parent
75fc1a7ce7
commit
3f838821e4
1 changed files with 22 additions and 16 deletions
20
skooma.js
20
skooma.js
|
@ -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,22 +147,26 @@ 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) {
|
||||
if (arg instanceof Array) {
|
||||
parseArgs(element, ...arg)
|
||||
} else {
|
||||
const child = toChild(arg)
|
||||
if (child)
|
||||
element.insertBefore(child, before)
|
||||
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 if ("length" in arg)
|
||||
parseArgs(element, before, ...arg)
|
||||
else
|
||||
for (const key in arg)
|
||||
setAttribute(element, key, arg[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const node = (name, args, options) => {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue