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
38
skooma.js
38
skooma.js
|
@ -52,7 +52,7 @@ const getCustom = args => args.reduce(
|
||||||
|
|
||||||
const isElement = object => HTMLElement.prototype.isPrototypeOf(object)
|
const isElement = object => HTMLElement.prototype.isPrototypeOf(object)
|
||||||
|
|
||||||
const isReactive = object => !(object instanceof HTMLElement)
|
export const isReactive = object => !(object instanceof HTMLElement)
|
||||||
&& (object instanceof EventTarget)
|
&& (object instanceof EventTarget)
|
||||||
&& ("value" in object)
|
&& ("value" in object)
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ const toChild = arg => {
|
||||||
return arg
|
return arg
|
||||||
} else if (isReactive(arg)) {
|
} else if (isReactive(arg)) {
|
||||||
return reactiveChild(arg)
|
return reactiveChild(arg)
|
||||||
|
} else {
|
||||||
|
return document.createComment("Placeholder for reactive content")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +100,7 @@ const specialAttributes = {
|
||||||
},
|
},
|
||||||
shadowRoot: {
|
shadowRoot: {
|
||||||
set: (element, value) => {
|
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
|
if (element.content) element = element.content
|
||||||
for (const arg of args) if (arg !== empty) {
|
for (const arg of args) if (arg !== empty) {
|
||||||
const child = toChild(arg)
|
if (arg instanceof Array) {
|
||||||
if (child)
|
parseArgs(element, ...arg)
|
||||||
element.insertBefore(child, before)
|
} else {
|
||||||
else if (arg === undefined || arg == null)
|
const child = toChild(arg)
|
||||||
console.warn(`An argument of type ${typeof arg} has been ignored`, element)
|
if (child)
|
||||||
else if (typeof arg == "function")
|
element.append(child)
|
||||||
arg(element)
|
else if (arg === undefined || arg == null)
|
||||||
else if ("length" in arg)
|
console.warn(`An argument of type ${typeof arg} has been ignored`, element)
|
||||||
parseArgs(element, before, ...arg)
|
else if (typeof arg == "function" && arg.length == 0)
|
||||||
else
|
parseArgs(element, arg())
|
||||||
for (const key in arg)
|
else if (typeof arg == "function")
|
||||||
setAttribute(element, key, arg[key])
|
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)
|
element = document.createElementNS(options.xmlns, name, opts)
|
||||||
else
|
else
|
||||||
element = document.createElement(name, opts)
|
element = document.createElement(name, opts)
|
||||||
parseArgs(element, null, args)
|
parseArgs(element, args)
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue