Replace mechanism for creating customized built-in elements

This commit is contained in:
Talia 2022-04-12 22:36:35 +02:00
parent 2a4b7d88dd
commit 77cf51f06d
Signed by: darkwiiplayer
GPG key ID: 7808674088232B3E
2 changed files with 36 additions and 13 deletions

View file

@ -139,15 +139,6 @@
return div
</code-block>
<p>Custom elements with hyphenated names can be created easily</p>
<p></p>
<code-block>
return html.myComponent()
</code-block>
<code-block>
return document.createElement("my-component")
</code-block>
<p>
Function arguments will be called on the new element.<br>
This can be used to easily add custom initialisation logic to elements.
@ -163,6 +154,27 @@
element.innerText += ", world!"
return element
</code-block>
<p>Custom elements with hyphenated names can be created easily</p>
<p></p>
<code-block>
return html.myComponent()
</code-block>
<code-block>
return document.createElement("my-component")
</code-block>
<p>Custom built-ins can be created with the <code>is</code> attribute.</p>
<p></p>
<code-block>
return html.span({is: "my-span"})
// Also sets the `is` attribute, useful for selectors
// like span[is="my-span"]
</code-block>
<code-block>
return document.createElement("span", {is: "my-span"})
// No actual `is` attribute. GL styling these.
</code-block>
</div>
</section>

View file

@ -31,6 +31,19 @@ const parseAttribute = (attribute) => {
return JSON.stringify(attribute)
}
const defined = (value, fallback) => typeof value != "undefined" ? value : fallback
const getCustom = args => String(
args.reduce(
(current, argument) => Array.isArray(argument)
? defined(getCustom(argument), current)
: (argument && typeof argument == "object")
? defined(argument.is, current)
: current
,null
)
)
const parseArgs = (element, before, ...args) => {
if (element.content) element = element.content
for (let arg of args) if (arg !== empty)
@ -64,11 +77,9 @@ const parseArgs = (element, before, ...args) => {
}
const nop = object => object
const node = (_name, args, options) => {
const node = (name, args, options) => {
let element
const [name, custom] = _name
.match(/[^$]+/g)
.map(options.nameFilter ?? nop)
let custom = getCustom(args)
if (options.xmlns)
element = document.createElementNS(options.xmlns, name, {is: custom})
else