1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2024-11-21 23:39:37 +01:00

💥 append, elNS, el.mark, el.later

This commit is contained in:
Jan Andrle 2023-11-08 13:44:37 +01:00
parent caa4cd84ed
commit 0f511d1791
Signed by: jaandrle
GPG Key ID: B3A25AED155AFFAB
18 changed files with 255 additions and 520 deletions

View File

@ -29,7 +29,7 @@ In the meaning of size, complexity and usability.
An another goal is making clear library logic. Starting from pure native JavaScript (DOM API), An another goal is making clear library logic. Starting from pure native JavaScript (DOM API),
then using small utils (`assign`, `S`, …, `el`, …) and end up with way to write complex code. then using small utils (`assign`, `S`, …, `el`, …) and end up with way to write complex code.
Therefore, you can use any „internal” function to make live with native JavaScript easier Therefore, you can use any „internal” function to make live with native JavaScript easier
(`assign`, `classListDeclarative`, `on`, `dispatchEvent`, …, `S`, …) regarding if you dont (`assign`, `classListDeclarative`, `on`, `dispatchEvent`, …, `S`, …) regarding if you
need complex library/framework. need complex library/framework.
As consequence of that, it shouldnt be hard to incorporate the library into existing projects. As consequence of that, it shouldnt be hard to incorporate the library into existing projects.

File diff suppressed because one or more lines are too long

22
dist/dde.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,18 @@
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
type SupportedElement=
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
| CustomElementTagNameMap[keyof CustomElementTagNameMap];
declare global { declare global {
type ddeComponentAttributes= Record<any, any> | undefined | string; type ddeComponentAttributes= Record<any, any> | undefined | string;
type ddeElementModifier<El extends HTMLElement | SVGElement | Comment | DocumentFragment>= (element: El)=> El; type ddeElementModifier<El extends SupportedElement | DocumentFragment>= (element: El)=> El;
} }
type ElementTagNameMap= HTMLElementTagNameMap & { // & SVGElementTagNameMap
'#text': Text
}
type Element= ElementTagNameMap[keyof ElementTagNameMap];
type AttrsModified= { type AttrsModified= {
/** /**
* In fact argumen for `*.setAttribute("style", *)`. * Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
*/ */
style: string style: string | Partial<CSSStyleDeclaration>
/** /**
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others. * Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
*/ */
@ -32,36 +34,59 @@ type AttrsModified= {
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives. * There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
* @private * @private
*/ */
type ElementAttributes<T extends keyof ElementTagNameMap | ElementTagNameMap[keyof ElementTagNameMap]>= type ElementAttributes<T extends SupportedElement>= Omit<T,keyof AttrsModified> & AttrsModified;
T extends keyof ElementTagNameMap ? export function assign<El extends SupportedElement>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El
Omit<ElementTagNameMap[T],"classList"|"className"> & AttrsModified : type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap
Omit<T,"classList"|"className"> & AttrsModified; interface element<el>{
export function assign<El extends Element>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El prototype: el;
export function el<TAG extends keyof ElementTagNameMap>( append(...els: (SupportedElement | DocumentFragment | string | element<SupportedElement | DocumentFragment>)[]): el
}
export function el<TAG extends keyof ExtendedHTMLElementTagNameMap>(
tag_name: TAG, tag_name: TAG,
attrs?: Partial<ElementAttributes<ElementTagNameMap[TAG]>>, attrs?: string | Partial<ElementAttributes<ExtendedHTMLElementTagNameMap[TAG]>>,
...modifiers: ddeElementModifier<ElementTagNameMap[TAG]>[] ...modifiers: ddeElementModifier<ExtendedHTMLElementTagNameMap[TAG]>[]
): ElementTagNameMap[TAG] ): element<ExtendedHTMLElementTagNameMap[TAG]>
export function el<T>( export function el<T>(
tag_name?: "<>", tag_name?: "<>",
): DocumentFragment ): element<DocumentFragment>
export function el< export function el<
A extends ddeComponentAttributes, A extends ddeComponentAttributes,
C extends (attr: A)=> Element | DocumentFragment>( C extends (attr: A)=> SupportedElement | DocumentFragment>(
fComponent: C, fComponent: C,
attrs?: A, attrs?: A,
...modifiers: ddeElementModifier<ReturnType<C>>[] ...modifiers: ddeElementModifier<ReturnType<C>>[]
): ReturnType<C> ): element<ReturnType<C>>
export function el( export function el(
tag_name: string, tag_name: string,
attrs?: Record<string, any>, attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<HTMLElement | SVGElement>[] ...modifiers: ddeElementModifier<HTMLElement>[]
): HTMLElement ): element<HTMLElement>
export function dispatchEvent(element: HTMLElement, name: keyof DocumentEventMap): void; export function elNS(
export function dispatchEvent(element: HTMLElement, name: string, data: any): void; namespace: "http://www.w3.org/2000/svg"
): <TAG extends keyof SVGElementTagNameMap, KEYS extends keyof SVGElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: SVGElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<SVGElementTagNameMap[TAG]>[]
)=> element<SVGElementTagNameMap[TAG]>
export function elNS(
namespace: "http://www.w3.org/1998/Math/MathML"
): <TAG extends keyof MathMLElementTagNameMap, KEYS extends keyof MathMLElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: MathMLElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<MathMLElementTagNameMap[TAG]>[]
)=> element<MathMLElementTagNameMap[TAG]>
export function elNS(
namespace: string
): (
tag_name: string,
attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<SupportedElement>[]
)=> element<SupportedElement>
export function dispatchEvent(element: SupportedElement, name: keyof DocumentEventMap): void;
export function dispatchEvent(element: SupportedElement, name: string, data: any): void;
interface On{ interface On{
< <
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ), El extends ( EE extends ddeElementModifier<infer El> ? El : never ),
Event extends keyof DocumentEventMap>( Event extends keyof DocumentEventMap>(
type: Event, type: Event,
@ -69,14 +94,14 @@ interface On{
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
connected< connected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
disconnected< disconnected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
@ -85,126 +110,8 @@ interface On{
} }
export const on: On; export const on: On;
export const scope: { export const scope: {
namespace: string,
host: ddeElementModifier<any>, host: ddeElementModifier<any>,
elNamespace: (ns: string)=> ({ append(...els: (HTMLElement | SVGElement)[]): HTMLElement | SVGElement | DocumentFragment })
}; };
//TODO for SVG
declare global{
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLAnchorElement{ append(...nodes: (Node | string)[]): HTMLAnchorElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAreaElement{ append(...nodes: (Node | string)[]): HTMLAreaElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAudioElement{ append(...nodes: (Node | string)[]): HTMLAudioElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLBaseElement{ append(...nodes: (Node | string)[]): HTMLBaseElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLBodyElement{ append(...nodes: (Node | string)[]): HTMLBodyElement; }
interface HTMLBRElement{ append(...nodes: (Node | string)[]): HTMLBRElement; }
interface HTMLButtonElement{ append(...nodes: (Node | string)[]): HTMLButtonElement; }
interface HTMLCanvasElement{ append(...nodes: (Node | string)[]): HTMLCanvasElement; }
interface HTMLTableCaptionElement{ append(...nodes: (Node | string)[]): HTMLTableCaptionElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLDataElement{ append(...nodes: (Node | string)[]): HTMLDataElement; }
interface HTMLDataListElement{ append(...nodes: (Node | string)[]): HTMLDataListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLDetailsElement{ append(...nodes: (Node | string)[]): HTMLDetailsElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLDialogElement{ append(...nodes: (Node | string)[]): HTMLDialogElement; }
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLDListElement{ append(...nodes: (Node | string)[]): HTMLDListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLEmbedElement{ append(...nodes: (Node | string)[]): HTMLEmbedElement; }
interface HTMLFieldSetElement{ append(...nodes: (Node | string)[]): HTMLFieldSetElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLFormElement{ append(...nodes: (Node | string)[]): HTMLFormElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadElement{ append(...nodes: (Node | string)[]): HTMLHeadElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLHRElement{ append(...nodes: (Node | string)[]): HTMLHRElement; }
interface HTMLHtmlElement{ append(...nodes: (Node | string)[]): HTMLHtmlElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLIFrameElement{ append(...nodes: (Node | string)[]): HTMLIFrameElement; }
interface HTMLImageElement{ append(...nodes: (Node | string)[]): HTMLImageElement; }
interface HTMLInputElement{ append(...nodes: (Node | string)[]): HTMLInputElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLLabelElement{ append(...nodes: (Node | string)[]): HTMLLabelElement; }
interface HTMLLegendElement{ append(...nodes: (Node | string)[]): HTMLLegendElement; }
interface HTMLLIElement{ append(...nodes: (Node | string)[]): HTMLLIElement; }
interface HTMLLinkElement{ append(...nodes: (Node | string)[]): HTMLLinkElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMapElement{ append(...nodes: (Node | string)[]): HTMLMapElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMenuElement{ append(...nodes: (Node | string)[]): HTMLMenuElement; }
interface HTMLMetaElement{ append(...nodes: (Node | string)[]): HTMLMetaElement; }
interface HTMLMeterElement{ append(...nodes: (Node | string)[]): HTMLMeterElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLObjectElement{ append(...nodes: (Node | string)[]): HTMLObjectElement; }
interface HTMLOListElement{ append(...nodes: (Node | string)[]): HTMLOListElement; }
interface HTMLOptGroupElement{ append(...nodes: (Node | string)[]): HTMLOptGroupElement; }
interface HTMLOptionElement{ append(...nodes: (Node | string)[]): HTMLOptionElement; }
interface HTMLOutputElement{ append(...nodes: (Node | string)[]): HTMLOutputElement; }
interface HTMLParagraphElement{ append(...nodes: (Node | string)[]): HTMLParagraphElement; }
interface HTMLPictureElement{ append(...nodes: (Node | string)[]): HTMLPictureElement; }
interface HTMLPreElement{ append(...nodes: (Node | string)[]): HTMLPreElement; }
interface HTMLProgressElement{ append(...nodes: (Node | string)[]): HTMLProgressElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLScriptElement{ append(...nodes: (Node | string)[]): HTMLScriptElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSelectElement{ append(...nodes: (Node | string)[]): HTMLSelectElement; }
interface HTMLSlotElement{ append(...nodes: (Node | string)[]): HTMLSlotElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSourceElement{ append(...nodes: (Node | string)[]): HTMLSourceElement; }
interface HTMLSpanElement{ append(...nodes: (Node | string)[]): HTMLSpanElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLStyleElement{ append(...nodes: (Node | string)[]): HTMLStyleElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableElement{ append(...nodes: (Node | string)[]): HTMLTableElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTemplateElement{ append(...nodes: (Node | string)[]): HTMLTemplateElement; }
interface HTMLTextAreaElement{ append(...nodes: (Node | string)[]): HTMLTextAreaElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTimeElement{ append(...nodes: (Node | string)[]): HTMLTimeElement; }
interface HTMLTitleElement{ append(...nodes: (Node | string)[]): HTMLTitleElement; }
interface HTMLTableRowElement{ append(...nodes: (Node | string)[]): HTMLTableRowElement; }
interface HTMLTrackElement{ append(...nodes: (Node | string)[]): HTMLTrackElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLUListElement{ append(...nodes: (Node | string)[]): HTMLUListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLVideoElement{ append(...nodes: (Node | string)[]): HTMLVideoElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface DocumentFragment{ append(...nodes: (Node | string)[]): DocumentFragment; }
}
export type Signal<V, A>= (set?: V)=> V & A; export type Signal<V, A>= (set?: V)=> V & A;
type Action<V>= (this: { value: V }, ...a: any[])=> typeof S._ | void; type Action<V>= (this: { value: V }, ...a: any[])=> typeof S._ | void;
type SymbolOnclear= Symbol; type SymbolOnclear= Symbol;

File diff suppressed because one or more lines are too long

199
dist/esm.d.ts vendored
View File

@ -1,16 +1,18 @@
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
type SupportedElement=
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
| CustomElementTagNameMap[keyof CustomElementTagNameMap];
declare global { declare global {
type ddeComponentAttributes= Record<any, any> | undefined | string; type ddeComponentAttributes= Record<any, any> | undefined | string;
type ddeElementModifier<El extends HTMLElement | SVGElement | Comment | DocumentFragment>= (element: El)=> El; type ddeElementModifier<El extends SupportedElement | DocumentFragment>= (element: El)=> El;
} }
type ElementTagNameMap= HTMLElementTagNameMap & { // & SVGElementTagNameMap
'#text': Text
}
type Element= ElementTagNameMap[keyof ElementTagNameMap];
type AttrsModified= { type AttrsModified= {
/** /**
* In fact argumen for `*.setAttribute("style", *)`. * Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
*/ */
style: string style: string | Partial<CSSStyleDeclaration>
/** /**
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others. * Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
*/ */
@ -32,36 +34,59 @@ type AttrsModified= {
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives. * There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
* @private * @private
*/ */
type ElementAttributes<T extends keyof ElementTagNameMap | ElementTagNameMap[keyof ElementTagNameMap]>= type ElementAttributes<T extends SupportedElement>= Omit<T,keyof AttrsModified> & AttrsModified;
T extends keyof ElementTagNameMap ? export function assign<El extends SupportedElement>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El
Omit<ElementTagNameMap[T],"classList"|"className"> & AttrsModified : type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap
Omit<T,"classList"|"className"> & AttrsModified; interface element<el>{
export function assign<El extends Element>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El prototype: el;
export function el<TAG extends keyof ElementTagNameMap>( append(...els: (SupportedElement | DocumentFragment | string | element<SupportedElement | DocumentFragment>)[]): el
}
export function el<TAG extends keyof ExtendedHTMLElementTagNameMap>(
tag_name: TAG, tag_name: TAG,
attrs?: Partial<ElementAttributes<ElementTagNameMap[TAG]>>, attrs?: string | Partial<ElementAttributes<ExtendedHTMLElementTagNameMap[TAG]>>,
...modifiers: ddeElementModifier<ElementTagNameMap[TAG]>[] ...modifiers: ddeElementModifier<ExtendedHTMLElementTagNameMap[TAG]>[]
): ElementTagNameMap[TAG] ): element<ExtendedHTMLElementTagNameMap[TAG]>
export function el<T>( export function el<T>(
tag_name?: "<>", tag_name?: "<>",
): DocumentFragment ): element<DocumentFragment>
export function el< export function el<
A extends ddeComponentAttributes, A extends ddeComponentAttributes,
C extends (attr: A)=> Element | DocumentFragment>( C extends (attr: A)=> SupportedElement | DocumentFragment>(
fComponent: C, fComponent: C,
attrs?: A, attrs?: A,
...modifiers: ddeElementModifier<ReturnType<C>>[] ...modifiers: ddeElementModifier<ReturnType<C>>[]
): ReturnType<C> ): element<ReturnType<C>>
export function el( export function el(
tag_name: string, tag_name: string,
attrs?: Record<string, any>, attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<HTMLElement | SVGElement>[] ...modifiers: ddeElementModifier<HTMLElement>[]
): HTMLElement ): element<HTMLElement>
export function dispatchEvent(element: HTMLElement, name: keyof DocumentEventMap): void; export function elNS(
export function dispatchEvent(element: HTMLElement, name: string, data: any): void; namespace: "http://www.w3.org/2000/svg"
): <TAG extends keyof SVGElementTagNameMap, KEYS extends keyof SVGElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: SVGElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<SVGElementTagNameMap[TAG]>[]
)=> element<SVGElementTagNameMap[TAG]>
export function elNS(
namespace: "http://www.w3.org/1998/Math/MathML"
): <TAG extends keyof MathMLElementTagNameMap, KEYS extends keyof MathMLElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: MathMLElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<MathMLElementTagNameMap[TAG]>[]
)=> element<MathMLElementTagNameMap[TAG]>
export function elNS(
namespace: string
): (
tag_name: string,
attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<SupportedElement>[]
)=> element<SupportedElement>
export function dispatchEvent(element: SupportedElement, name: keyof DocumentEventMap): void;
export function dispatchEvent(element: SupportedElement, name: string, data: any): void;
interface On{ interface On{
< <
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ), El extends ( EE extends ddeElementModifier<infer El> ? El : never ),
Event extends keyof DocumentEventMap>( Event extends keyof DocumentEventMap>(
type: Event, type: Event,
@ -69,14 +94,14 @@ interface On{
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
connected< connected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
disconnected< disconnected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
@ -85,123 +110,5 @@ interface On{
} }
export const on: On; export const on: On;
export const scope: { export const scope: {
namespace: string,
host: ddeElementModifier<any>, host: ddeElementModifier<any>,
elNamespace: (ns: string)=> ({ append(...els: (HTMLElement | SVGElement)[]): HTMLElement | SVGElement | DocumentFragment }) };
};
//TODO for SVG
declare global{
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLAnchorElement{ append(...nodes: (Node | string)[]): HTMLAnchorElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAreaElement{ append(...nodes: (Node | string)[]): HTMLAreaElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAudioElement{ append(...nodes: (Node | string)[]): HTMLAudioElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLBaseElement{ append(...nodes: (Node | string)[]): HTMLBaseElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLBodyElement{ append(...nodes: (Node | string)[]): HTMLBodyElement; }
interface HTMLBRElement{ append(...nodes: (Node | string)[]): HTMLBRElement; }
interface HTMLButtonElement{ append(...nodes: (Node | string)[]): HTMLButtonElement; }
interface HTMLCanvasElement{ append(...nodes: (Node | string)[]): HTMLCanvasElement; }
interface HTMLTableCaptionElement{ append(...nodes: (Node | string)[]): HTMLTableCaptionElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLDataElement{ append(...nodes: (Node | string)[]): HTMLDataElement; }
interface HTMLDataListElement{ append(...nodes: (Node | string)[]): HTMLDataListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLDetailsElement{ append(...nodes: (Node | string)[]): HTMLDetailsElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLDialogElement{ append(...nodes: (Node | string)[]): HTMLDialogElement; }
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLDListElement{ append(...nodes: (Node | string)[]): HTMLDListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLEmbedElement{ append(...nodes: (Node | string)[]): HTMLEmbedElement; }
interface HTMLFieldSetElement{ append(...nodes: (Node | string)[]): HTMLFieldSetElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLFormElement{ append(...nodes: (Node | string)[]): HTMLFormElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadElement{ append(...nodes: (Node | string)[]): HTMLHeadElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLHRElement{ append(...nodes: (Node | string)[]): HTMLHRElement; }
interface HTMLHtmlElement{ append(...nodes: (Node | string)[]): HTMLHtmlElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLIFrameElement{ append(...nodes: (Node | string)[]): HTMLIFrameElement; }
interface HTMLImageElement{ append(...nodes: (Node | string)[]): HTMLImageElement; }
interface HTMLInputElement{ append(...nodes: (Node | string)[]): HTMLInputElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLLabelElement{ append(...nodes: (Node | string)[]): HTMLLabelElement; }
interface HTMLLegendElement{ append(...nodes: (Node | string)[]): HTMLLegendElement; }
interface HTMLLIElement{ append(...nodes: (Node | string)[]): HTMLLIElement; }
interface HTMLLinkElement{ append(...nodes: (Node | string)[]): HTMLLinkElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMapElement{ append(...nodes: (Node | string)[]): HTMLMapElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMenuElement{ append(...nodes: (Node | string)[]): HTMLMenuElement; }
interface HTMLMetaElement{ append(...nodes: (Node | string)[]): HTMLMetaElement; }
interface HTMLMeterElement{ append(...nodes: (Node | string)[]): HTMLMeterElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLObjectElement{ append(...nodes: (Node | string)[]): HTMLObjectElement; }
interface HTMLOListElement{ append(...nodes: (Node | string)[]): HTMLOListElement; }
interface HTMLOptGroupElement{ append(...nodes: (Node | string)[]): HTMLOptGroupElement; }
interface HTMLOptionElement{ append(...nodes: (Node | string)[]): HTMLOptionElement; }
interface HTMLOutputElement{ append(...nodes: (Node | string)[]): HTMLOutputElement; }
interface HTMLParagraphElement{ append(...nodes: (Node | string)[]): HTMLParagraphElement; }
interface HTMLPictureElement{ append(...nodes: (Node | string)[]): HTMLPictureElement; }
interface HTMLPreElement{ append(...nodes: (Node | string)[]): HTMLPreElement; }
interface HTMLProgressElement{ append(...nodes: (Node | string)[]): HTMLProgressElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLScriptElement{ append(...nodes: (Node | string)[]): HTMLScriptElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSelectElement{ append(...nodes: (Node | string)[]): HTMLSelectElement; }
interface HTMLSlotElement{ append(...nodes: (Node | string)[]): HTMLSlotElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSourceElement{ append(...nodes: (Node | string)[]): HTMLSourceElement; }
interface HTMLSpanElement{ append(...nodes: (Node | string)[]): HTMLSpanElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLStyleElement{ append(...nodes: (Node | string)[]): HTMLStyleElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableElement{ append(...nodes: (Node | string)[]): HTMLTableElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTemplateElement{ append(...nodes: (Node | string)[]): HTMLTemplateElement; }
interface HTMLTextAreaElement{ append(...nodes: (Node | string)[]): HTMLTextAreaElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTimeElement{ append(...nodes: (Node | string)[]): HTMLTimeElement; }
interface HTMLTitleElement{ append(...nodes: (Node | string)[]): HTMLTitleElement; }
interface HTMLTableRowElement{ append(...nodes: (Node | string)[]): HTMLTableRowElement; }
interface HTMLTrackElement{ append(...nodes: (Node | string)[]): HTMLTrackElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLUListElement{ append(...nodes: (Node | string)[]): HTMLUListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLVideoElement{ append(...nodes: (Node | string)[]): HTMLVideoElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface DocumentFragment{ append(...nodes: (Node | string)[]): DocumentFragment; }
}

2
dist/esm.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="elements.css"><meta name="description" content="Basic concepts of elements modifications and creations."><!--<dde:mark type="component" name="metaTwitter" host="this"/>--><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="twitter:title" content="deka-dom-el"><meta name="twitter:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="twitter:creator" content="@jaandrle"><!--<dde:mark type="component" name="metaFacebook" host="this"/>--><meta name="og:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="og:title" content="deka-dom-el"><meta name="og:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="og:creator" content="@jaandrle"><title>`deka-dom-el` — Elements</title><script src="https://flems.io/flems.html" type="text/javascript" charset="utf-8"></script></head><body><!--<dde:mark type="component" name="page" host="this"/>--><!--<dde:mark type="component" name="header" host="this"/>--><header><h1>`deka-dom-el` — Elements</h1><p>Basic concepts of elements modifications and creations.</p></header><nav><a href="https://github.com/jaandrle/deka-dom-el"><svg class="icon" viewBox="0 0 32 32"><!--<dde:mark type="component" name="iconGitHub" host="parentElement"/>--><path d="M 16,0.395c -8.836,0 -16,7.163 -16,16c 0,7.069 4.585,13.067 10.942,15.182c 0.8,0.148 1.094,-0.347 1.094,-0.77c 0,-0.381 -0.015,-1.642 -0.022,-2.979c -4.452,0.968 -5.391,-1.888 -5.391,-1.888c -0.728,-1.849 -1.776,-2.341 -1.776,-2.341c -1.452,-0.993 0.11,-0.973 0.11,-0.973c 1.606,0.113 2.452,1.649 2.452,1.649c 1.427,2.446 3.743,1.739 4.656,1.33c 0.143,-1.034 0.558,-1.74 1.016,-2.14c -3.554,-0.404 -7.29,-1.777 -7.29,-7.907c 0,-1.747 0.625,-3.174 1.649,-4.295c -0.166,-0.403 -0.714,-2.03 0.155,-4.234c 0,0 1.344,-0.43 4.401,1.64c 1.276,-0.355 2.645,-0.532 4.005,-0.539c 1.359,0.006 2.729,0.184 4.008,0.539c 3.054,-2.07 4.395,-1.64 4.395,-1.64c 0.871,2.204 0.323,3.831 0.157,4.234c 1.026,1.12 1.647,2.548 1.647,4.295c 0,6.145 -3.743,7.498 -7.306,7.895c 0.574,0.497 1.085,1.47 1.085,2.963c 0,2.141 -0.019,3.864 -0.019,4.391c 0,0.426 0.288,0.925 1.099,0.768c 6.354,-2.118 10.933,-8.113 10.933,-15.18c 0,-8.837 -7.164,-16 -16,-16Z"></path></svg>GitHub</a><a href="./" title="Introducing a&nbsp;library and motivations.">1. Introduction</a><a href="elements" title="Basic concepts of elements modifications and creations." class="current">2. Elements</a></nav><main><h2>Native JavaScript DOM elements creations</h2><p>Lets go through all patterns we would like to use and what needs to be improved for better experience.</p><h3>Creating element(s) (with custom attributes)</h3><p>You can create a native DOM element by using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement" title="MDN documentation for document.createElement()"><code>document.createElement()</code></a>. It is also possible to provide a&nbsp;some attribute(s) declaratively using <code>Object.assign()</code>. More precisely, this way you can sets some <a href="https://developer.mozilla.org/en-US/docs/Glossary/IDL" title="MDN page about Interface Description Language"><abbr title="Interface Description Language">IDL</abbr></a>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-kryno" class="example"><pre><code class="language-javascript">document.body.append( <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="elements.css"><meta name="description" content="Basic concepts of elements modifications and creations."><!--<dde:mark type="component" name="metaTwitter" host="this"/>--><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="twitter:title" content="deka-dom-el"><meta name="twitter:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="twitter:creator" content="@jaandrle"><!--<dde:mark type="component" name="metaFacebook" host="this"/>--><meta name="og:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="og:title" content="deka-dom-el"><meta name="og:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="og:creator" content="@jaandrle"><title>`deka-dom-el` — Elements</title><script src="https://flems.io/flems.html" type="text/javascript" charset="utf-8"></script></head><body><!--<dde:mark type="component" name="page" host="this"/>--><!--<dde:mark type="component" name="header" host="this"/>--><header><h1>`deka-dom-el` — Elements</h1><p>Basic concepts of elements modifications and creations.</p></header><nav><a href="https://github.com/jaandrle/deka-dom-el"><svg class="icon" viewbox="0 0 32 32"><!--<dde:mark type="component" name="iconGitHub" host="parentElement"/>--><path d="M 16,0.395c -8.836,0 -16,7.163 -16,16c 0,7.069 4.585,13.067 10.942,15.182c 0.8,0.148 1.094,-0.347 1.094,-0.77c 0,-0.381 -0.015,-1.642 -0.022,-2.979c -4.452,0.968 -5.391,-1.888 -5.391,-1.888c -0.728,-1.849 -1.776,-2.341 -1.776,-2.341c -1.452,-0.993 0.11,-0.973 0.11,-0.973c 1.606,0.113 2.452,1.649 2.452,1.649c 1.427,2.446 3.743,1.739 4.656,1.33c 0.143,-1.034 0.558,-1.74 1.016,-2.14c -3.554,-0.404 -7.29,-1.777 -7.29,-7.907c 0,-1.747 0.625,-3.174 1.649,-4.295c -0.166,-0.403 -0.714,-2.03 0.155,-4.234c 0,0 1.344,-0.43 4.401,1.64c 1.276,-0.355 2.645,-0.532 4.005,-0.539c 1.359,0.006 2.729,0.184 4.008,0.539c 3.054,-2.07 4.395,-1.64 4.395,-1.64c 0.871,2.204 0.323,3.831 0.157,4.234c 1.026,1.12 1.647,2.548 1.647,4.295c 0,6.145 -3.743,7.498 -7.306,7.895c 0.574,0.497 1.085,1.47 1.085,2.963c 0,2.141 -0.019,3.864 -0.019,4.391c 0,0.426 0.288,0.925 1.099,0.768c 6.354,-2.118 10.933,-8.113 10.933,-15.18c 0,-8.837 -7.164,-16 -16,-16Z"></path></svg>GitHub</a><a href="./" title="Introducing a&nbsp;library and motivations.">1. Introduction</a><a href="elements" title="Basic concepts of elements modifications and creations." class="current">2. Elements</a></nav><main><h2>Native JavaScript DOM elements creations</h2><p>Lets go through all patterns we would like to use and what needs to be improved for better experience.</p><h3>Creating element(s) (with custom attributes)</h3><p>You can create a native DOM element by using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement" title="MDN documentation for document.createElement()"><code>document.createElement()</code></a>. It is also possible to provide a&nbsp;some attribute(s) declaratively using <code>Object.assign()</code>. More precisely, this way you can sets some <a href="https://developer.mozilla.org/en-US/docs/Glossary/IDL" title="MDN page about Interface Description Language"><abbr title="Interface Description Language">IDL</abbr></a>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-yoae9" class="example"><pre><code class="language-javascript">document.body.append(
document.createElement("div") document.createElement("div")
); );
console.log( console.log(
@ -12,7 +12,7 @@ document.body.append(
{ textContent: "Elements text content.", style: "color: coral;" } { textContent: "Elements text content.", style: "color: coral;" }
) )
); );
</code></pre></div><script>Flems(document.getElementById("code-kryno"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"document.body.append(\\n\\tdocument.createElement(\\\"div\\\")\\n);\\nconsole.log(\\n\\t\\\"Emty div is generated inside <body>:\\\",\\n\\tdocument.body.innerHTML.includes(\\\"<div></div>\\\")\\n);\\n\\ndocument.body.append(\\n\\tObject.assign(\\n\\t\\tdocument.createElement(\\\"p\\\"),\\n\\t\\t{ textContent: \\\"Elements text content.\\\", style: \\\"color: coral;\\\" }\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><p>To make this easier, you can use the <code>el</code> function. Internally in basic examples, it is wrapper around <code>assign(document.createElement(…), { … })</code>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-180ua" class="example"><pre><code class="language-javascript">import { el, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; </code></pre></div><script>Flems(document.getElementById("code-yoae9"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"document.body.append(\\n\\tdocument.createElement(\\\"div\\\")\\n);\\nconsole.log(\\n\\t\\\"Emty div is generated inside <body>:\\\",\\n\\tdocument.body.innerHTML.includes(\\\"<div></div>\\\")\\n);\\n\\ndocument.body.append(\\n\\tObject.assign(\\n\\t\\tdocument.createElement(\\\"p\\\"),\\n\\t\\t{ textContent: \\\"Elements text content.\\\", style: \\\"color: coral;\\\" }\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><p>To make this easier, you can use the <code>el</code> function. Internally in basic examples, it is wrapper around <code>assign(document.createElement(…), { … })</code>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-s6gd4" class="example"><pre><code class="language-javascript">import { el, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const color= "lightcoral"; const color= "lightcoral";
document.body.append( document.body.append(
el("p", { textContent: "Hello (first time)", style: { color } }) el("p", { textContent: "Hello (first time)", style: { color } })
@ -23,7 +23,7 @@ document.body.append(
{ textContent: "Hello (second time)", style: { color } } { textContent: "Hello (second time)", style: { color } }
) )
); );
</code></pre></div><script>Flems(document.getElementById("code-180ua"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el, assign } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst color= \\\"lightcoral\\\";\\ndocument.body.append(\\n\\tel(\\\"p\\\", { textContent: \\\"Hello (first time)\\\", style: { color } })\\n);\\ndocument.body.append(\\n\\tassign(\\n\\t\\tdocument.createElement(\\\"p\\\"),\\n\\t\\t{ textContent: \\\"Hello (second time)\\\", style: { color } }\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><p>The <code>assign</code> function provides improved behaviour of <code>Object.assign()</code>. You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the <code>element.setAttribute</code> if there is no writable property in the element prototype.</p><p>You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">HTMLElement</a>. To see all available IDLs for example for paragraphs, see <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLParagraphElement">HTMLParagraphElement</a>. Moreover, the <code>assign</code> provides a&nbsp;way to sets declaratively some convenient properties:</p><ul><li>It is possible to sets <code>data-*</code>/<code>aria-*</code> attributes using object notation.</li><li>In opposite, it is also possible to sets <code>data-*</code>/<code>aria-*</code> attribute using camelCase notation.</li><li>You can use string or object as a&nbsp;value for <code>style</code> property.</li><li><code>className</code> (IDL preffered)/<code>class</code> are ways to add CSS class to the element. You can use string (similarly to <code>class="…"</code> syntax in HTML) or array of strings. This is handy to concat conditional classes.</li><li>Use <code>classList</code> to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.</li><li>The <code>assign</code> also accepts the <code>undefined</code> as a&nbsp;value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. <em>For example, natievly the elements <code>id</code> is removed by setting the IDL to an empty string.</em></li></ul><p>For processing, the <code>assign</code> internally uses <code>assignAttribute</code> and <code>classListDeclarative</code>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-5xffb" class="example"><pre><code class="language-javascript">import { assignAttribute, classListDeclarative } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; </code></pre></div><script>Flems(document.getElementById("code-s6gd4"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el, assign } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst color= \\\"lightcoral\\\";\\ndocument.body.append(\\n\\tel(\\\"p\\\", { textContent: \\\"Hello (first time)\\\", style: { color } })\\n);\\ndocument.body.append(\\n\\tassign(\\n\\t\\tdocument.createElement(\\\"p\\\"),\\n\\t\\t{ textContent: \\\"Hello (second time)\\\", style: { color } }\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><p>The <code>assign</code> function provides improved behaviour of <code>Object.assign()</code>. You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the <code>element.setAttribute</code> if there is no writable property in the element prototype.</p><p>You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">HTMLElement</a>. To see all available IDLs for example for paragraphs, see <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLParagraphElement">HTMLParagraphElement</a>. Moreover, the <code>assign</code> provides a&nbsp;way to sets declaratively some convenient properties:</p><ul><li>It is possible to sets <code>data-*</code>/<code>aria-*</code> attributes using object notation.</li><li>In opposite, it is also possible to sets <code>data-*</code>/<code>aria-*</code> attribute using camelCase notation.</li><li>You can use string or object as a&nbsp;value for <code>style</code> property.</li><li><code>className</code> (IDL preffered)/<code>class</code> are ways to add CSS class to the element. You can use string (similarly to <code>class="…"</code> syntax in HTML) or array of strings. This is handy to concat conditional classes.</li><li>Use <code>classList</code> to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.</li><li>The <code>assign</code> also accepts the <code>undefined</code> as a&nbsp;value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. <em>For example, natievly the elements <code>id</code> is removed by setting the IDL to an empty string.</em></li></ul><p>For processing, the <code>assign</code> internally uses <code>assignAttribute</code> and <code>classListDeclarative</code>.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-kb1l4" class="example"><pre><code class="language-javascript">import { assignAttribute, classListDeclarative } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const paragraph= document.createElement("p"); const paragraph= document.createElement("p");
assignAttribute(paragraph, "textContent", "Hello, world!"); assignAttribute(paragraph, "textContent", "Hello, world!");
@ -48,7 +48,7 @@ console.log(paragraph.outerHTML);
document.body.append( document.body.append(
paragraph paragraph
); );
</code></pre></div><script>Flems(document.getElementById("code-5xffb"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { assignAttribute, classListDeclarative } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst paragraph= document.createElement(\\\"p\\\");\\n\\nassignAttribute(paragraph, \\\"textContent\\\", \\\"Hello, world!\\\");\\nassignAttribute(paragraph, \\\"style\\\", { color: \\\"navy\\\" });\\n\\nassignAttribute(paragraph, \\\"dataTest1\\\", \\\"v1\\\");\\nassignAttribute(paragraph, \\\"dataset\\\", { test2: \\\"v2\\\" });\\n\\nassignAttribute(paragraph, \\\"ariaLabel\\\", \\\"v1\\\");\\nassignAttribute(paragraph, \\\"ariaset\\\", { role: \\\"none\\\" });\\n\\n\\nclassListDeclarative(paragraph, {\\n\\tclassAdd: true,\\n\\tclassRemove: false,\\n\\tclassAdd1: 1,\\n\\tclassRemove1: 0,\\n\\tclassToggle: -1\\n});\\n\\nconsole.log(paragraph.outerHTML);\\ndocument.body.append(\\n\\tparagraph\\n);\\n\"}],\"toolbar\":false}"));</script><h3>Native JavaScript templating</h3><p>By default, the native JS has no good way to define HTML template using DOM API:</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-kpwcn" class="example"><pre><code class="language-javascript">document.body.append( </code></pre></div><script>Flems(document.getElementById("code-kb1l4"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { assignAttribute, classListDeclarative } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst paragraph= document.createElement(\\\"p\\\");\\n\\nassignAttribute(paragraph, \\\"textContent\\\", \\\"Hello, world!\\\");\\nassignAttribute(paragraph, \\\"style\\\", { color: \\\"navy\\\" });\\n\\nassignAttribute(paragraph, \\\"dataTest1\\\", \\\"v1\\\");\\nassignAttribute(paragraph, \\\"dataset\\\", { test2: \\\"v2\\\" });\\n\\nassignAttribute(paragraph, \\\"ariaLabel\\\", \\\"v1\\\");\\nassignAttribute(paragraph, \\\"ariaset\\\", { role: \\\"none\\\" });\\n\\n\\nclassListDeclarative(paragraph, {\\n\\tclassAdd: true,\\n\\tclassRemove: false,\\n\\tclassAdd1: 1,\\n\\tclassRemove1: 0,\\n\\tclassToggle: -1\\n});\\n\\nconsole.log(paragraph.outerHTML);\\ndocument.body.append(\\n\\tparagraph\\n);\\n\"}],\"toolbar\":false}"));</script><h3>Native JavaScript templating</h3><p>By default, the native JS has no good way to define HTML template using DOM API:</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-rxuhl" class="example"><pre><code class="language-javascript">document.body.append(
document.createElement("div"), document.createElement("div"),
document.createElement("span"), document.createElement("span"),
document.createElement("main") document.createElement("main")
@ -59,7 +59,7 @@ const template= document.createElement("main").append(
document.createElement("span"), document.createElement("span"),
); );
console.log(typeof template==="undefined"); console.log(typeof template==="undefined");
</code></pre></div><script>Flems(document.getElementById("code-kpwcn"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"document.body.append(\\n\\tdocument.createElement(\\\"div\\\"),\\n\\tdocument.createElement(\\\"span\\\"),\\n\\tdocument.createElement(\\\"main\\\")\\n);\\nconsole.log(document.body.innerHTML.includes(\\\"<div></div><span></span><main></main>\\\"));\\nconst template= document.createElement(\\\"main\\\").append(\\n\\tdocument.createElement(\\\"div\\\"),\\n\\tdocument.createElement(\\\"span\\\"),\\n);\\nconsole.log(typeof template===\\\"undefined\\\");\\n\"}],\"toolbar\":false}"));</script><p>This library therefore ooverwrites the <code>append</code> method to always return parent element.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-s5v9a" class="example"><pre><code class="language-javascript">import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; </code></pre></div><script>Flems(document.getElementById("code-rxuhl"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"document.body.append(\\n\\tdocument.createElement(\\\"div\\\"),\\n\\tdocument.createElement(\\\"span\\\"),\\n\\tdocument.createElement(\\\"main\\\")\\n);\\nconsole.log(document.body.innerHTML.includes(\\\"<div></div><span></span><main></main>\\\"));\\nconst template= document.createElement(\\\"main\\\").append(\\n\\tdocument.createElement(\\\"div\\\"),\\n\\tdocument.createElement(\\\"span\\\"),\\n);\\nconsole.log(typeof template===\\\"undefined\\\");\\n\"}],\"toolbar\":false}"));</script><p>This library therefore overwrites the <code>append</code> method of created elements to always return parent element.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-c61pb" class="example"><pre><code class="language-javascript">import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
document.head.append( document.head.append(
el("style").append( el("style").append(
"tr, td{ border: 1px solid red; padding: 1em; }", "tr, td{ border: 1px solid red; padding: 1em; }",
@ -83,7 +83,7 @@ document.body.append(
) )
) )
); );
</code></pre></div><script>Flems(document.getElementById("code-s5v9a"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\ndocument.head.append(\\n\\tel(\\\"style\\\").append(\\n\\t\\t\\\"tr, td{ border: 1px solid red; padding: 1em; }\\\",\\n\\t\\t\\\"table{ border-collapse: collapse; }\\\"\\n\\t)\\n);\\ndocument.body.append(\\n\\tel(\\\"p\\\", \\\"Example of a complex template. Using for example nesting lists:\\\"),\\n\\tel(\\\"ul\\\").append(\\n\\t\\tel(\\\"li\\\", \\\"List item 1\\\"),\\n\\t\\tel(\\\"li\\\").append(\\n\\t\\t\\tel(\\\"ul\\\").append(\\n\\t\\t\\t\\tel(\\\"li\\\", \\\"Nested list item 1\\\"),\\n\\t\\t\\t)\\n\\t\\t)\\n\\t),\\n\\tel(\\\"table\\\").append(\\n\\t\\tel(\\\"tr\\\").append(\\n\\t\\t\\tel(\\\"td\\\", \\\"Row 1 Col 1\\\"),\\n\\t\\t\\tel(\\\"td\\\", \\\"Row 1 Col 2\\\")\\n\\t\\t)\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><h2>Creating advanced (reactive) templates and components</h2><h3>Basic components</h3><p>You can use functions for encapsulation (repeating) logic. The <code>el</code> accepts function as first argument. In that case, the function should return dom elements and the second argument for <code>el</code> is argument for given element.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-4m21m" class="example"><pre><code class="language-javascript">import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; </code></pre></div><script>Flems(document.getElementById("code-c61pb"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\ndocument.head.append(\\n\\tel(\\\"style\\\").append(\\n\\t\\t\\\"tr, td{ border: 1px solid red; padding: 1em; }\\\",\\n\\t\\t\\\"table{ border-collapse: collapse; }\\\"\\n\\t)\\n);\\ndocument.body.append(\\n\\tel(\\\"p\\\", \\\"Example of a complex template. Using for example nesting lists:\\\"),\\n\\tel(\\\"ul\\\").append(\\n\\t\\tel(\\\"li\\\", \\\"List item 1\\\"),\\n\\t\\tel(\\\"li\\\").append(\\n\\t\\t\\tel(\\\"ul\\\").append(\\n\\t\\t\\t\\tel(\\\"li\\\", \\\"Nested list item 1\\\"),\\n\\t\\t\\t)\\n\\t\\t)\\n\\t),\\n\\tel(\\\"table\\\").append(\\n\\t\\tel(\\\"tr\\\").append(\\n\\t\\t\\tel(\\\"td\\\", \\\"Row 1 Col 1\\\"),\\n\\t\\t\\tel(\\\"td\\\", \\\"Row 1 Col 2\\\")\\n\\t\\t)\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script><h2>Creating advanced (reactive) templates and components</h2><h3>Basic components</h3><p>You can use functions for encapsulation (repeating) logic. The <code>el</code> accepts function as first argument. In that case, the function should return dom elements and the second argument for <code>el</code> is argument for given element.</p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-9myzj" class="example"><pre><code class="language-javascript">import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
document.head.append( document.head.append(
el("style").append( el("style").append(
".class1{ font-weight: bold; }", ".class1{ font-weight: bold; }",
@ -100,4 +100,4 @@ function component({ className, textContent }){
el("p", textContent) el("p", textContent)
); );
} }
</code></pre></div><script>Flems(document.getElementById("code-4m21m"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\ndocument.head.append(\\n\\tel(\\\"style\\\").append(\\n\\t\\t\\\".class1{ font-weight: bold; }\\\",\\n\\t\\t\\\".class2{ color: purple; }\\\"\\n\\t)\\n);\\ndocument.body.append(\\n\\tel(component, { className: \\\"class2\\\", textContent: \\\"Hello World!\\\" }),\\n\\tcomponent({ className: \\\"class2\\\", textContent: \\\"Hello World!\\\" })\\n);\\n\\nfunction component({ className, textContent }){\\n\\treturn el(\\\"div\\\", { className: [ \\\"class1\\\", className ] }).append(\\n\\t\\tel(\\\"p\\\", textContent)\\n\\t);\\n}\\n\"}],\"toolbar\":false}"));</script><p>It is nice to use similar naming convention as native DOM API.</p></main></body></html> </code></pre></div><script>Flems(document.getElementById("code-9myzj"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\ndocument.head.append(\\n\\tel(\\\"style\\\").append(\\n\\t\\t\\\".class1{ font-weight: bold; }\\\",\\n\\t\\t\\\".class2{ color: purple; }\\\"\\n\\t)\\n);\\ndocument.body.append(\\n\\tel(component, { className: \\\"class2\\\", textContent: \\\"Hello World!\\\" }),\\n\\tcomponent({ className: \\\"class2\\\", textContent: \\\"Hello World!\\\" })\\n);\\n\\nfunction component({ className, textContent }){\\n\\treturn el(\\\"div\\\", { className: [ \\\"class1\\\", className ] }).append(\\n\\t\\tel(\\\"p\\\", textContent)\\n\\t);\\n}\\n\"}],\"toolbar\":false}"));</script><p>It is nice to use similar naming convention as native DOM API.</p></main></body></html>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="index.css"><meta name="description" content="Introducing a&nbsp;library and motivations."><!--<dde:mark type="component" name="metaTwitter" host="this"/>--><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="twitter:title" content="deka-dom-el"><meta name="twitter:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="twitter:creator" content="@jaandrle"><!--<dde:mark type="component" name="metaFacebook" host="this"/>--><meta name="og:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="og:title" content="deka-dom-el"><meta name="og:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="og:creator" content="@jaandrle"><title>`deka-dom-el` — Introduction</title><script src="https://flems.io/flems.html" type="text/javascript" charset="utf-8"></script></head><body><!--<dde:mark type="component" name="page" host="this"/>--><!--<dde:mark type="component" name="header" host="this"/>--><header><h1>`deka-dom-el` — Introduction</h1><p>Introducing a&nbsp;library and motivations.</p></header><nav><a href="https://github.com/jaandrle/deka-dom-el"><svg class="icon" viewBox="0 0 32 32"><!--<dde:mark type="component" name="iconGitHub" host="parentElement"/>--><path d="M 16,0.395c -8.836,0 -16,7.163 -16,16c 0,7.069 4.585,13.067 10.942,15.182c 0.8,0.148 1.094,-0.347 1.094,-0.77c 0,-0.381 -0.015,-1.642 -0.022,-2.979c -4.452,0.968 -5.391,-1.888 -5.391,-1.888c -0.728,-1.849 -1.776,-2.341 -1.776,-2.341c -1.452,-0.993 0.11,-0.973 0.11,-0.973c 1.606,0.113 2.452,1.649 2.452,1.649c 1.427,2.446 3.743,1.739 4.656,1.33c 0.143,-1.034 0.558,-1.74 1.016,-2.14c -3.554,-0.404 -7.29,-1.777 -7.29,-7.907c 0,-1.747 0.625,-3.174 1.649,-4.295c -0.166,-0.403 -0.714,-2.03 0.155,-4.234c 0,0 1.344,-0.43 4.401,1.64c 1.276,-0.355 2.645,-0.532 4.005,-0.539c 1.359,0.006 2.729,0.184 4.008,0.539c 3.054,-2.07 4.395,-1.64 4.395,-1.64c 0.871,2.204 0.323,3.831 0.157,4.234c 1.026,1.12 1.647,2.548 1.647,4.295c 0,6.145 -3.743,7.498 -7.306,7.895c 0.574,0.497 1.085,1.47 1.085,2.963c 0,2.141 -0.019,3.864 -0.019,4.391c 0,0.426 0.288,0.925 1.099,0.768c 6.354,-2.118 10.933,-8.113 10.933,-15.18c 0,-8.837 -7.164,-16 -16,-16Z"></path></svg>GitHub</a><a href="./" title="Introducing a&nbsp;library and motivations." class="current">1. Introduction</a><a href="elements" title="Basic concepts of elements modifications and creations.">2. Elements</a></nav><main><p>The library tries to provide pure JavaScript tool(s) to create reactive interfaces. </p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-5zrzl" class="example"><pre><code class="language-javascript">import { el, S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="index.css"><meta name="description" content="Introducing a&nbsp;library and motivations."><!--<dde:mark type="component" name="metaTwitter" host="this"/>--><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="twitter:title" content="deka-dom-el"><meta name="twitter:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="twitter:creator" content="@jaandrle"><!--<dde:mark type="component" name="metaFacebook" host="this"/>--><meta name="og:url" content="https://github.com/jaandrle/deka-dom-el"><meta name="og:title" content="deka-dom-el"><meta name="og:description" content="A low-code library that simplifies the creation of native DOM elements/components using small wrappers and tweaks."><meta name="og:creator" content="@jaandrle"><title>`deka-dom-el` — Introduction</title><script src="https://flems.io/flems.html" type="text/javascript" charset="utf-8"></script></head><body><!--<dde:mark type="component" name="page" host="this"/>--><!--<dde:mark type="component" name="header" host="this"/>--><header><h1>`deka-dom-el` — Introduction</h1><p>Introducing a&nbsp;library and motivations.</p></header><nav><a href="https://github.com/jaandrle/deka-dom-el"><svg class="icon" viewbox="0 0 32 32"><!--<dde:mark type="component" name="iconGitHub" host="parentElement"/>--><path d="M 16,0.395c -8.836,0 -16,7.163 -16,16c 0,7.069 4.585,13.067 10.942,15.182c 0.8,0.148 1.094,-0.347 1.094,-0.77c 0,-0.381 -0.015,-1.642 -0.022,-2.979c -4.452,0.968 -5.391,-1.888 -5.391,-1.888c -0.728,-1.849 -1.776,-2.341 -1.776,-2.341c -1.452,-0.993 0.11,-0.973 0.11,-0.973c 1.606,0.113 2.452,1.649 2.452,1.649c 1.427,2.446 3.743,1.739 4.656,1.33c 0.143,-1.034 0.558,-1.74 1.016,-2.14c -3.554,-0.404 -7.29,-1.777 -7.29,-7.907c 0,-1.747 0.625,-3.174 1.649,-4.295c -0.166,-0.403 -0.714,-2.03 0.155,-4.234c 0,0 1.344,-0.43 4.401,1.64c 1.276,-0.355 2.645,-0.532 4.005,-0.539c 1.359,0.006 2.729,0.184 4.008,0.539c 3.054,-2.07 4.395,-1.64 4.395,-1.64c 0.871,2.204 0.323,3.831 0.157,4.234c 1.026,1.12 1.647,2.548 1.647,4.295c 0,6.145 -3.743,7.498 -7.306,7.895c 0.574,0.497 1.085,1.47 1.085,2.963c 0,2.141 -0.019,3.864 -0.019,4.391c 0,0.426 0.288,0.925 1.099,0.768c 6.354,-2.118 10.933,-8.113 10.933,-15.18c 0,-8.837 -7.164,-16 -16,-16Z"></path></svg>GitHub</a><a href="./" title="Introducing a&nbsp;library and motivations." class="current">1. Introduction</a><a href="elements" title="Basic concepts of elements modifications and creations.">2. Elements</a></nav><main><p>The library tries to provide pure JavaScript tool(s) to create reactive interfaces. </p><!--<dde:mark type="component" name="example" host="this"/>--><div id="code-fnvst" class="example"><pre><code class="language-javascript">import { el, S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const clicks= S(0); const clicks= S(0);
document.body.append( document.body.append(
el().append( el().append(
@ -12,4 +12,4 @@ document.body.append(
}) })
) )
); );
</code></pre></div><script>Flems(document.getElementById("code-5zrzl"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el, S } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst clicks= S(0);\\ndocument.body.append(\\n\\tel().append(\\n\\t\\tel(\\\"p\\\", S(()=>\\n\\t\\t\\t\\\"Hello World \\\"+\\\"🎉\\\".repeat(clicks())\\n\\t\\t)),\\n\\t\\tel(\\\"button\\\", {\\n\\t\\t\\ttype: \\\"button\\\",\\n\\t\\t\\tonclick: ()=> clicks(clicks()+1),\\n\\t\\t\\ttextContent: \\\"Fire\\\"\\n\\t\\t})\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script></main></body></html> </code></pre></div><script>Flems(document.getElementById("code-fnvst"), JSON.parse("{\"files\":[{\"name\":\".js\",\"content\":\"import { el, S } from \\\"https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js\\\";\\nconst clicks= S(0);\\ndocument.body.append(\\n\\tel().append(\\n\\t\\tel(\\\"p\\\", S(()=>\\n\\t\\t\\t\\\"Hello World \\\"+\\\"🎉\\\".repeat(clicks())\\n\\t\\t)),\\n\\t\\tel(\\\"button\\\", {\\n\\t\\t\\ttype: \\\"button\\\",\\n\\t\\t\\tonclick: ()=> clicks(clicks()+1),\\n\\t\\t\\ttextContent: \\\"Fire\\\"\\n\\t\\t})\\n\\t)\\n);\\n\"}],\"toolbar\":false}"));</script></main></body></html>

View File

@ -88,7 +88,7 @@ export function page({ pkg, info, path_target, pages, registerClientFile }){
el("p", "By default, the native JS has no good way to define HTML template using DOM API:"), el("p", "By default, the native JS has no good way to define HTML template using DOM API:"),
el(example, { src: new URL("./components/examples/nativeAppend.js", import.meta.url), page_id, registerClientFile }), el(example, { src: new URL("./components/examples/nativeAppend.js", import.meta.url), page_id, registerClientFile }),
el("p").append( el("p").append(
"This library therefore ooverwrites the ", el("code", "append"), " method to always return parent element." "This library therefore overwrites the ", el("code", "append"), " method of created elements to always return parent element."
), ),
el(example, { src: new URL("./components/examples/dekaAppend.js", import.meta.url), page_id, registerClientFile }), el(example, { src: new URL("./components/examples/dekaAppend.js", import.meta.url), page_id, registerClientFile }),

View File

@ -1,4 +1,4 @@
import { el, scope } from "deka-dom-el"; import { el, elNS, scope } from "deka-dom-el";
/** /**
* @param {object} def * @param {object} def
* @param {import("../types.d.ts").Info} def.info * @param {import("../types.d.ts").Info} def.info
@ -66,7 +66,7 @@ function stylesheetHref(path_target, name){
return path_target.css.replace(path_target.root, "")+name+".css"; return path_target.css.replace(path_target.root, "")+name+".css";
} }
function iconGitHub(){ function iconGitHub(){
scope.namespace= "svg"; const el= elNS("http://www.w3.org/2000/svg");
return el("svg", { className: "icon", viewBox: "0 0 32 32" }).append( return el("svg", { className: "icon", viewBox: "0 0 32 32" }).append(
el("path", { d: [ //see https://svg-path-visualizer.netlify.app/#M16%200.395c-8.836%200-16%207.163-16%2016%200%207.069%204.585%2013.067%2010.942%2015.182%200.8%200.148%201.094-0.347%201.094-0.77%200-0.381-0.015-1.642-0.022-2.979-4.452%200.968-5.391-1.888-5.391-1.888-0.728-1.849-1.776-2.341-1.776-2.341-1.452-0.993%200.11-0.973%200.11-0.973%201.606%200.113%202.452%201.649%202.452%201.649%201.427%202.446%203.743%201.739%204.656%201.33%200.143-1.034%200.558-1.74%201.016-2.14-3.554-0.404-7.29-1.777-7.29-7.907%200-1.747%200.625-3.174%201.649-4.295-0.166-0.403-0.714-2.030%200.155-4.234%200%200%201.344-0.43%204.401%201.64%201.276-0.355%202.645-0.532%204.005-0.539%201.359%200.006%202.729%200.184%204.008%200.539%203.054-2.070%204.395-1.64%204.395-1.64%200.871%202.204%200.323%203.831%200.157%204.234%201.026%201.12%201.647%202.548%201.647%204.295%200%206.145-3.743%207.498-7.306%207.895%200.574%200.497%201.085%201.47%201.085%202.963%200%202.141-0.019%203.864-0.019%204.391%200%200.426%200.288%200.925%201.099%200.768%206.354-2.118%2010.933-8.113%2010.933-15.18%200-8.837-7.164-16-16-16z el("path", { d: [ //see https://svg-path-visualizer.netlify.app/#M16%200.395c-8.836%200-16%207.163-16%2016%200%207.069%204.585%2013.067%2010.942%2015.182%200.8%200.148%201.094-0.347%201.094-0.77%200-0.381-0.015-1.642-0.022-2.979-4.452%200.968-5.391-1.888-5.391-1.888-0.728-1.849-1.776-2.341-1.776-2.341-1.452-0.993%200.11-0.973%200.11-0.973%201.606%200.113%202.452%201.649%202.452%201.649%201.427%202.446%203.743%201.739%204.656%201.33%200.143-1.034%200.558-1.74%201.016-2.14-3.554-0.404-7.29-1.777-7.29-7.907%200-1.747%200.625-3.174%201.649-4.295-0.166-0.403-0.714-2.030%200.155-4.234%200%200%201.344-0.43%204.401%201.64%201.276-0.355%202.645-0.532%204.005-0.539%201.359%200.006%202.729%200.184%204.008%200.539%203.054-2.070%204.395-1.64%204.395-1.64%200.871%202.204%200.323%203.831%200.157%204.234%201.026%201.12%201.647%202.548%201.647%204.295%200%206.145-3.743%207.498-7.306%207.895%200.574%200.497%201.085%201.47%201.085%202.963%200%202.141-0.019%203.864-0.019%204.391%200%200.426%200.288%200.925%201.099%200.768%206.354-2.118%2010.933-8.113%2010.933-15.18%200-8.837-7.164-16-16-16z
"M 16,0.395", "M 16,0.395",

View File

@ -1,4 +1,4 @@
import { style, el, on, S, scope } from '../exports.js'; import { style, el, elNS, on, S, scope } from '../exports.js';
const className= style.host(fullNameComponent).css` const className= style.host(fullNameComponent).css`
:host form{ :host form{
display: flex; display: flex;
@ -13,6 +13,7 @@ export function fullNameComponent(){
scope.host(on.connected(()=> console.log(fullNameComponent))); scope.host(on.connected(()=> console.log(fullNameComponent)));
scope.host(on.disconnected(()=> console.log(fullNameComponent))) scope.host(on.disconnected(()=> console.log(fullNameComponent)))
const elSVG= elNS("http://www.w3.org/2000/svg");
return el("div", { className }).append( return el("div", { className }).append(
el("h2", "Simple form:"), el("h2", "Simple form:"),
el("form", { onsubmit: ev=> ev.preventDefault() }).append( el("form", { onsubmit: ev=> ev.preventDefault() }).append(
@ -26,11 +27,9 @@ export function fullNameComponent(){
": ", ": ",
el("#text", full_name) el("#text", full_name)
), ),
scope.elNamespace("svg").append( elSVG("svg", { viewBox: "0 0 240 80", style: { height: "80px", display: "block" } }).append(
el("svg", { viewBox: "0 0 240 80", style: { height: "80px", display: "block" } }).append( //elSVG("style", { })
//el("style", { }) elSVG("text", { x: 20, y: 35, textContent: "Text" })
el("text", { x: 20, y: 35, textContent: "Text" })
)
) )
); );
} }

199
index.d.ts vendored
View File

@ -1,16 +1,18 @@
type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
type SupportedElement=
HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
| SVGElementTagNameMap[keyof SVGElementTagNameMap]
| MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
| CustomElementTagNameMap[keyof CustomElementTagNameMap];
declare global { declare global {
type ddeComponentAttributes= Record<any, any> | undefined | string; type ddeComponentAttributes= Record<any, any> | undefined | string;
type ddeElementModifier<El extends HTMLElement | SVGElement | Comment | DocumentFragment>= (element: El)=> El; type ddeElementModifier<El extends SupportedElement | DocumentFragment>= (element: El)=> El;
} }
type ElementTagNameMap= HTMLElementTagNameMap & { // & SVGElementTagNameMap
'#text': Text
}
type Element= ElementTagNameMap[keyof ElementTagNameMap];
type AttrsModified= { type AttrsModified= {
/** /**
* In fact argumen for `*.setAttribute("style", *)`. * Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
*/ */
style: string style: string | Partial<CSSStyleDeclaration>
/** /**
* Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others. * Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1. In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))` for others.
*/ */
@ -32,40 +34,64 @@ type AttrsModified= {
* There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives. * There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
* @private * @private
*/ */
type ElementAttributes<T extends keyof ElementTagNameMap | ElementTagNameMap[keyof ElementTagNameMap]>= type ElementAttributes<T extends SupportedElement>= Omit<T,keyof AttrsModified> & AttrsModified;
T extends keyof ElementTagNameMap ? export function assign<El extends SupportedElement>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El
Omit<ElementTagNameMap[T],"classList"|"className"> & AttrsModified :
Omit<T,"classList"|"className"> & AttrsModified;
export function assign<El extends Element>(element: El, ...attrs_array: Partial<ElementAttributes<El>>[]): El
export function el<TAG extends keyof ElementTagNameMap>( type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap
interface element<el>{
prototype: el;
append(...els: (SupportedElement | DocumentFragment | string | element<SupportedElement | DocumentFragment>)[]): el
}
export function el<TAG extends keyof ExtendedHTMLElementTagNameMap>(
tag_name: TAG, tag_name: TAG,
attrs?: Partial<ElementAttributes<ElementTagNameMap[TAG]>>, attrs?: string | Partial<ElementAttributes<ExtendedHTMLElementTagNameMap[TAG]>>,
...modifiers: ddeElementModifier<ElementTagNameMap[TAG]>[] ...modifiers: ddeElementModifier<ExtendedHTMLElementTagNameMap[TAG]>[]
): ElementTagNameMap[TAG] ): element<ExtendedHTMLElementTagNameMap[TAG]>
export function el<T>( export function el<T>(
tag_name?: "<>", tag_name?: "<>",
): DocumentFragment ): element<DocumentFragment>
export function el< export function el<
A extends ddeComponentAttributes, A extends ddeComponentAttributes,
C extends (attr: A)=> Element | DocumentFragment>( C extends (attr: A)=> SupportedElement | DocumentFragment>(
fComponent: C, fComponent: C,
attrs?: A, attrs?: A,
...modifiers: ddeElementModifier<ReturnType<C>>[] ...modifiers: ddeElementModifier<ReturnType<C>>[]
): ReturnType<C> ): element<ReturnType<C>>
export function el( export function el(
tag_name: string, tag_name: string,
attrs?: Record<string, any>, attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<HTMLElement | SVGElement>[] ...modifiers: ddeElementModifier<HTMLElement>[]
): HTMLElement ): element<HTMLElement>
export function dispatchEvent(element: HTMLElement, name: keyof DocumentEventMap): void; export function elNS(
export function dispatchEvent(element: HTMLElement, name: string, data: any): void; namespace: "http://www.w3.org/2000/svg"
): <TAG extends keyof SVGElementTagNameMap, KEYS extends keyof SVGElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: SVGElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<SVGElementTagNameMap[TAG]>[]
)=> element<SVGElementTagNameMap[TAG]>
export function elNS(
namespace: "http://www.w3.org/1998/Math/MathML"
): <TAG extends keyof MathMLElementTagNameMap, KEYS extends keyof MathMLElementTagNameMap[TAG] & { d: string }>(
tag_name: TAG,
attrs?: string | Partial<{ [key in KEYS]: MathMLElementTagNameMap[TAG][key] | string | number | boolean }>,
...modifiers: ddeElementModifier<MathMLElementTagNameMap[TAG]>[]
)=> element<MathMLElementTagNameMap[TAG]>
export function elNS(
namespace: string
): (
tag_name: string,
attrs?: string | Record<string, any>,
...modifiers: ddeElementModifier<SupportedElement>[]
)=> element<SupportedElement>
export function dispatchEvent(element: SupportedElement, name: keyof DocumentEventMap): void;
export function dispatchEvent(element: SupportedElement, name: string, data: any): void;
interface On{ interface On{
< <
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ), El extends ( EE extends ddeElementModifier<infer El> ? El : never ),
Event extends keyof DocumentEventMap>( Event extends keyof DocumentEventMap>(
type: Event, type: Event,
@ -73,14 +99,14 @@ interface On{
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
connected< connected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
options?: AddEventListenerOptions options?: AddEventListenerOptions
) : EE; ) : EE;
disconnected< disconnected<
EE extends ddeElementModifier<Element>, EE extends ddeElementModifier<SupportedElement>,
El extends ( EE extends ddeElementModifier<infer El> ? El : never ) El extends ( EE extends ddeElementModifier<infer El> ? El : never )
>( >(
listener: (el: El) => any, listener: (el: El) => any,
@ -90,124 +116,5 @@ interface On{
export const on: On; export const on: On;
export const scope: { export const scope: {
namespace: string,
host: ddeElementModifier<any>, host: ddeElementModifier<any>,
elNamespace: (ns: string)=> ({ append(...els: (HTMLElement | SVGElement)[]): HTMLElement | SVGElement | DocumentFragment })
}; };
//TODO for SVG
declare global{
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLAnchorElement{ append(...nodes: (Node | string)[]): HTMLAnchorElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAreaElement{ append(...nodes: (Node | string)[]): HTMLAreaElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLAudioElement{ append(...nodes: (Node | string)[]): HTMLAudioElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLBaseElement{ append(...nodes: (Node | string)[]): HTMLBaseElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLBodyElement{ append(...nodes: (Node | string)[]): HTMLBodyElement; }
interface HTMLBRElement{ append(...nodes: (Node | string)[]): HTMLBRElement; }
interface HTMLButtonElement{ append(...nodes: (Node | string)[]): HTMLButtonElement; }
interface HTMLCanvasElement{ append(...nodes: (Node | string)[]): HTMLCanvasElement; }
interface HTMLTableCaptionElement{ append(...nodes: (Node | string)[]): HTMLTableCaptionElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLTableColElement{ append(...nodes: (Node | string)[]): HTMLTableColElement; }
interface HTMLDataElement{ append(...nodes: (Node | string)[]): HTMLDataElement; }
interface HTMLDataListElement{ append(...nodes: (Node | string)[]): HTMLDataListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLDetailsElement{ append(...nodes: (Node | string)[]): HTMLDetailsElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLDialogElement{ append(...nodes: (Node | string)[]): HTMLDialogElement; }
interface HTMLDivElement{ append(...nodes: (Node | string)[]): HTMLDivElement; }
interface HTMLDListElement{ append(...nodes: (Node | string)[]): HTMLDListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLEmbedElement{ append(...nodes: (Node | string)[]): HTMLEmbedElement; }
interface HTMLFieldSetElement{ append(...nodes: (Node | string)[]): HTMLFieldSetElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLFormElement{ append(...nodes: (Node | string)[]): HTMLFormElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadingElement{ append(...nodes: (Node | string)[]): HTMLHeadingElement; }
interface HTMLHeadElement{ append(...nodes: (Node | string)[]): HTMLHeadElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLHRElement{ append(...nodes: (Node | string)[]): HTMLHRElement; }
interface HTMLHtmlElement{ append(...nodes: (Node | string)[]): HTMLHtmlElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLIFrameElement{ append(...nodes: (Node | string)[]): HTMLIFrameElement; }
interface HTMLImageElement{ append(...nodes: (Node | string)[]): HTMLImageElement; }
interface HTMLInputElement{ append(...nodes: (Node | string)[]): HTMLInputElement; }
interface HTMLModElement{ append(...nodes: (Node | string)[]): HTMLModElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLLabelElement{ append(...nodes: (Node | string)[]): HTMLLabelElement; }
interface HTMLLegendElement{ append(...nodes: (Node | string)[]): HTMLLegendElement; }
interface HTMLLIElement{ append(...nodes: (Node | string)[]): HTMLLIElement; }
interface HTMLLinkElement{ append(...nodes: (Node | string)[]): HTMLLinkElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMapElement{ append(...nodes: (Node | string)[]): HTMLMapElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLMenuElement{ append(...nodes: (Node | string)[]): HTMLMenuElement; }
interface HTMLMetaElement{ append(...nodes: (Node | string)[]): HTMLMetaElement; }
interface HTMLMeterElement{ append(...nodes: (Node | string)[]): HTMLMeterElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLObjectElement{ append(...nodes: (Node | string)[]): HTMLObjectElement; }
interface HTMLOListElement{ append(...nodes: (Node | string)[]): HTMLOListElement; }
interface HTMLOptGroupElement{ append(...nodes: (Node | string)[]): HTMLOptGroupElement; }
interface HTMLOptionElement{ append(...nodes: (Node | string)[]): HTMLOptionElement; }
interface HTMLOutputElement{ append(...nodes: (Node | string)[]): HTMLOutputElement; }
interface HTMLParagraphElement{ append(...nodes: (Node | string)[]): HTMLParagraphElement; }
interface HTMLPictureElement{ append(...nodes: (Node | string)[]): HTMLPictureElement; }
interface HTMLPreElement{ append(...nodes: (Node | string)[]): HTMLPreElement; }
interface HTMLProgressElement{ append(...nodes: (Node | string)[]): HTMLProgressElement; }
interface HTMLQuoteElement{ append(...nodes: (Node | string)[]): HTMLQuoteElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLScriptElement{ append(...nodes: (Node | string)[]): HTMLScriptElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSelectElement{ append(...nodes: (Node | string)[]): HTMLSelectElement; }
interface HTMLSlotElement{ append(...nodes: (Node | string)[]): HTMLSlotElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLSourceElement{ append(...nodes: (Node | string)[]): HTMLSourceElement; }
interface HTMLSpanElement{ append(...nodes: (Node | string)[]): HTMLSpanElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLStyleElement{ append(...nodes: (Node | string)[]): HTMLStyleElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLTableElement{ append(...nodes: (Node | string)[]): HTMLTableElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTemplateElement{ append(...nodes: (Node | string)[]): HTMLTemplateElement; }
interface HTMLTextAreaElement{ append(...nodes: (Node | string)[]): HTMLTextAreaElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTableCellElement{ append(...nodes: (Node | string)[]): HTMLTableCellElement; }
interface HTMLTableSectionElement{ append(...nodes: (Node | string)[]): HTMLTableSectionElement; }
interface HTMLTimeElement{ append(...nodes: (Node | string)[]): HTMLTimeElement; }
interface HTMLTitleElement{ append(...nodes: (Node | string)[]): HTMLTitleElement; }
interface HTMLTableRowElement{ append(...nodes: (Node | string)[]): HTMLTableRowElement; }
interface HTMLTrackElement{ append(...nodes: (Node | string)[]): HTMLTrackElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLUListElement{ append(...nodes: (Node | string)[]): HTMLUListElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface HTMLVideoElement{ append(...nodes: (Node | string)[]): HTMLVideoElement; }
interface HTMLElement{ append(...nodes: (Node | string)[]): HTMLElement; }
interface DocumentFragment{ append(...nodes: (Node | string)[]): DocumentFragment; }
}

View File

@ -1,7 +1,2 @@
if(typeof document.createDocumentFragment().append()==="undefined")
[ HTMLElement, SVGElement, DocumentFragment ].forEach(c=> {
const { append }= c.prototype;
c.prototype.append= function(...els){ append.apply(this, els); return this; };
});
export * from "./src/dom.js"; export * from "./src/dom.js";
export * from "./src/events.js"; export * from "./src/events.js";

View File

@ -19,11 +19,6 @@ export function register(dom, keys_aditional= []){
globalThis.window= w; globalThis.window= w;
w.console= globalThis.console; w.console= globalThis.console;
} }
if(typeof document.createDocumentFragment().append()==="undefined")
[ HTMLElement, SVGElement, DocumentFragment ].forEach(c=> {
const { append }= c.prototype;
c.prototype.append= function(...els){ append.apply(this, els); return this; };
});
dom_last= dom; dom_last= dom;
return import("./index.js"); return import("./index.js");

View File

@ -63,7 +63,7 @@
}, },
{ {
"path": "./signals.js", "path": "./signals.js",
"limit": "8.5 kB", "limit": "11 kB",
"gzip": false "gzip": false
}, },
{ {

View File

@ -1,47 +1,31 @@
import { signals } from "./signals-common.js"; import { signals } from "./signals-common.js";
/** @type {{ scope: object, prevent: boolean, namespace: "html"|string, host: function }[]} */ /** @type {{ scope: object, prevent: boolean, host: function }[]} */
const scopes= [ { const scopes= [ {
scope: document.body, scope: document.body,
namespace: "html",
host: c=> c ? c(document.body) : document.body, host: c=> c ? c(document.body) : document.body,
prevent: true prevent: true
} ]; } ];
const namespaceHelper= ns=> ns==="svg" ? "http://www.w3.org/2000/svg" : ns;
export const scope= { export const scope= {
get current(){ return scopes[scopes.length-1]; }, get current(){ return scopes[scopes.length-1]; },
get host(){ return this.current.host; }, get host(){ return this.current.host; },
get namespace(){ return this.current.namespace; },
set namespace(namespace){ return ( this.current.namespace= namespaceHelper(namespace)); },
preventDefault(){ preventDefault(){
const { current }= this; const { current }= this;
current.prevent= true; current.prevent= true;
return current; return current;
}, },
elNamespace(namespace){
const ns= this.namespace;
this.namespace= namespace;
return {
append(...els){
scope.namespace= ns;
if(els.length===1) return els[0];
const f= document.createDocumentFragment();
return f.append(...els);
}
};
},
get state(){ return [ ...scopes ]; }, get state(){ return [ ...scopes ]; },
push(s= {}){ push(s= {}){
if(s.namespace) s.namespace= namespaceHelper(s.namespace);
return scopes.push(Object.assign({}, this.current, { prevent: false }, s)); return scopes.push(Object.assign({}, this.current, { prevent: false }, s));
}, },
pop(){ return scopes.pop(); }, pop(){ return scopes.pop(); },
}; };
let namespace;
export function createElement(tag, attributes, ...modifiers){ export function createElement(tag, attributes, ...modifiers){
/* jshint maxcomplexity: 15 */
const s= signals(this); const s= signals(this);
const { namespace }= scope;
let scoped= 0; let scoped= 0;
let el, el_host; let el, el_host;
//TODO Array.isArray(tag) ⇒ set key (cache els) //TODO Array.isArray(tag) ⇒ set key (cache els)
@ -53,24 +37,57 @@ export function createElement(tag, attributes, ...modifiers){
scope.push({ scope: tag, host: c=> c ? (scoped===1 ? modifiers.unshift(c) : c(el_host), undefined) : el_host }); scope.push({ scope: tag, host: c=> c ? (scoped===1 ? modifiers.unshift(c) : c(el_host), undefined) : el_host });
el= tag(attributes || undefined); el= tag(attributes || undefined);
const is_fragment= el instanceof DocumentFragment; const is_fragment= el instanceof DocumentFragment;
const el_mark= document.createComment(`<dde:mark type="component" name="${tag.name}" host="${is_fragment ? "this" : "parentElement"}"/>`); const el_mark= createElement.mark({
type: "component",
name: tag.name,
host: is_fragment ? "this" : ( el.nodeName==="#comment" ? "previousLater" : "parentElement" )
});
el.prepend(el_mark); el.prepend(el_mark);
if(is_fragment) el_host= el_mark; if(is_fragment) el_host= el_mark;
break; break;
} }
case tag==="#text": el= assign.call(this, document.createTextNode(""), attributes); break; case tag==="#text": el= assign.call(this, document.createTextNode(""), attributes); break;
case tag==="<>" || !tag: el= assign.call(this, document.createDocumentFragment(), attributes); break; case tag==="<>" || !tag: el= assign.call(this, document.createDocumentFragment(), attributes); break;
case namespace!=="html": el= assign.call(this, document.createElementNS(namespace, tag), attributes); break; case namespace: el= assign.call(this, document.createElementNS(namespace, tag), attributes); break;
case !el: el= assign.call(this, document.createElement(tag), attributes); case !el: el= assign.call(this, document.createElement(tag), attributes);
} }
chainableAppend(el);
if(!el_host) el_host= el; if(!el_host) el_host= el;
modifiers.forEach(c=> c(el_host)); modifiers.forEach(c=> c(el_host));
if(scoped) scope.pop(); if(scoped) scope.pop();
scoped= 2; scoped= 2;
return el; return el;
} }
/**
* @param { { type: "component", name: string, host: "this" | "parentElement" } | { type: "reactive" | "later" } } attrs
* @param {boolean} [is_open=false]
* */
createElement.mark= function(attrs, is_open= false){
attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" ");
const end= is_open ? "" : "/";
const out= document.createComment(`<dde:mark ${attrs}${end}>`);
if(!is_open) out.end= document.createComment("</dde:mark>");
return out;
};
createElement.later= function(){
const el= createElement.mark({ type: "later" });
el.append= el.prepend= function(...els){ el.after(...els); return el; };
return el;
};
export { createElement as el }; export { createElement as el };
//const namespaceHelper= ns=> ns==="svg" ? "http://www.w3.org/2000/svg" : ns;
export function createElementNS(ns){
const _this= this;
return function createElementNSCurried(...rest){
namespace= ns;
const el= createElement.call(_this, ...rest);
namespace= undefined;
return el;
};
}
export { createElementNS as elNS };
import { prop_process } from './dom-common.js'; import { prop_process } from './dom-common.js';
const { setDeleteAttr }= prop_process; const { setDeleteAttr }= prop_process;
const assign_context= new WeakMap(); const assign_context= new WeakMap();
@ -161,3 +178,6 @@ function attrArrToStr(attr){ return Array.isArray(attr) ? attr.filter(Boolean).j
function setRemove(obj, prop, key, val){ return obj[ (isUndef(val) ? "remove" : "set") + prop ](key, attrArrToStr(val)); } function setRemove(obj, prop, key, val){ return obj[ (isUndef(val) ? "remove" : "set") + prop ](key, attrArrToStr(val)); }
function setRemoveNS(obj, prop, key, val, ns= null){ return obj[ (isUndef(val) ? "remove" : "set") + prop + "NS" ](ns, key, attrArrToStr(val)); } function setRemoveNS(obj, prop, key, val, ns= null){ return obj[ (isUndef(val) ? "remove" : "set") + prop + "NS" ](ns, key, attrArrToStr(val)); }
function setDelete(obj, key, val){ Reflect.set(obj, key, val); if(!isUndef(val)) return; return Reflect.deleteProperty(obj, key); } function setDelete(obj, key, val){ Reflect.set(obj, key, val); if(!isUndef(val)) return; return Reflect.deleteProperty(obj, key); }
function append(...els){ this.appendOrig(...els); return this; }
function chainableAppend(el){ if(el.append===append) return el; el.appendOrig= el.append; el.append= append; return el; }

View File

@ -117,9 +117,10 @@ S.clear= function(...signals){
} }
}; };
const key_reactive= "__dde_reactive"; const key_reactive= "__dde_reactive";
import { el } from "./dom.js";
S.el= function(signal, map){ S.el= function(signal, map){
const mark_start= document.createComment(`<dde:mark type="reactive">`); const mark_start= el.mark({ type: "reactive" }, false);
const mark_end= document.createComment("</dde:mark>"); const mark_end= mark_start.end;
const out= document.createDocumentFragment(); const out= document.createDocumentFragment();
out.append(mark_start, mark_end); out.append(mark_start, mark_end);
const { current }= scope; const { current }= scope;