neocomp.js

template registry

export interface Template {
	node: LiteNode;
	actions: Action[];
}

export const templates = { 
	add (name: string, template: Template): void,
	get (name: string): Template,
	has (name: string): boolean
}

export const onAddTemplate: Event<(name: string, template: Template) => void>;

Template

Template: is an object that represent a template of DOM tree.
it is used to capture a DOM tree and reconstruct it when needed.
it consists of:

each LiteNode has a unique id stored in meta['neocomp:id'] of each node.

templates

it is the global registry of Templates.

add: add the given Template to the registry.

get: returns the Template registered as name.

has: returns whether a Template is registered as the given name.

builtin templates:

onAddTemplate: an event triggered when adding a Template to the registry

template generation

export const tempGen = {
	toDom (
	  comp: PureComp, template: Template, converters: Record<string, (lite: LiteNode) => Node> = {}
	): HTMLElement,
	generateFromDom (root: HTMLElement, plugins?: Plugin[], walkOptions?: Partial<WalkOptions>)
	  : Template,
	generateFromLite (root: LiteNode, plugins?: Plugin[], walkOptions?: Partial<WalkOptions>)
	  : Template,
	generateFromString (source: string, plugins?: Plugin[], walkOptions?: Partial<WalkOptions>)
	  : Record<string, Template | Supplement>,
}

export interface Supplement {
	type: symbol
}
export interface Plugin {
	onSource?: (source: string, options: Partial<ParseOptions>) => void;
	onDom?: (root: HTMLElement) => void;
	onRoot?: (root: LiteNode) => void;
	onTemplate?: (template: Template) => void;
	onSupplement?: (name: string, top: LiteNode) => undefined | Supplement;
}

const defaultParseOptions: Partial<ParseOptions> = {
	attrStart: /^[^'"=`<>\s]/,
	attrRest: /^[^'"=`<>\s]+/,
	rawTextTags: new Set(['script', 'style', 'svg']),
	lowerAttr: false,
	lowerTag: false
}

export const onConvertTemplate: Event<(comp: PureComp, template: Template, el: HTMLElement) => void>;

tempGen: provides various functions to generate and convert Template.

construction

toDom: construct a HTMLElement from a given Template, doesnt do actions.
optionally take converters that convert LiteNodes of given tag name to Nodes.

onConvertTemplate: an event triggered when converting a Template into HTMLElement.

generation

generateFromDom: generate a Template from a HTMLElement.

generateFromLite: generate a Template from a LiteNode.

generateFromString: generate a Record of Templates and Supplements from a template file source.

these methods take an optional Plugin[] and WalkOptions.

Plugin

the template generation can be customized using Plugins, each Plugin can have the given hooks:

template file

a template file is a HTML file where each top element represent an item named after its id and typed based on its tags.

a top element with tag neo:template represent a Template, where other tags represent Supplement.

Supplements are defined by the Plugins, it conatins the type of it plus any other properties it needs.

by default, template file attributes and tags are case conserved, and attribute names are more flexible as opposite to HTML.

actions and walking

actions

export interface Action {
	type: string,
	target: number | HTMLElement,
	[unkown: string]: any
}

type Handler = (comp: PureComp, el: HTMLElement, action: Action, context: Record<string, any>) => void;
export function addAction (name: string, handler: Handler): void;

export function doActions (comp: PureComp, actions: Action[], context: Record<string, any> = {}): void;

export function doActionsOfTemplate (
  comp: PureComp, top: HTMLElement, liteTop: LiteNode, 
  actions: Action[], context: Record<string, any> = {}
): void;

Action: is a lightweight storage unit that represent a custom logic for an element.

actions are gathered from the template source and stored for later execution when converting the templates.

they allow the definition of logic once on template generation and executing it effecintly on construction later, also they allow serialization.

every Action contains a type and a target where it can be the live HTMLElement or the id of its LiteNode representation.

addAction: add a handler for a given action type, the handler is called with the Component, HTMLElement, Action and the passed context (an object containing any passed value).

doActions: do the given Actions.

doActionsOfTemplate: do a given Actions from a Template, it requires the native and lite form of the top element the actions defined for.

walking

export function walk (node: WalkNode, options: Partial<WalkOptions>): Action[];
export interface WalkOptions {
	serialize: boolean = false;
	inDom: boolean = false;
}

type Handler = (
  node: WalkNode, attr: string, value: string, 
  addAction: (act: Action, defer?: boolean) => void, options: WalkOptions
) => void;
export function addActionAttr (name: string, handler: Handler): void;

walking is a mechanism where the DOM tree or the template is walked to gather the Actions.

it visits every element and search for action attributes or templated attributes.

walk: walk a given WalkNode and returns the gathered Actions, optionally takes WalkOptions which consists of:

addActionAttr: add a handler for a given action attribute type, the handler is passed with the WalkNode, attribute name and value, addAction and WalkOptions.
addAction is a function that add an Action, added after comp:this action if defer is true (for actions that work with a child component)

walking api

export type WalkNode = HTMLElement | LiteNode;

export const walkFns = {
	getTarget (node: WalkNode): number | HTMLElement,

	*attrsOf (node: WalkNode): Generator<[name: string, value: string]>,
	hasAttr (node: WalkNode, attr: string): boolean,
	getAttr (node: WalkNode, attr: string): string | undefined,
	setAttr (node: WalkNode, attr: string, value: string): void,
	removeAttr (node: WalkNode, attr: string): void,

	*childrenOf (node: WalkNode): Generator<WalkNode>,
	removeChildren (node: WalkNode): void,

	getText (node: WalkNode): string | undefined,
	setText (node: WalkNode, text: string): void,

	toFun (options: WalkOptions, args: string[], source: string): WalkFn,
	decodeAttrArg (value: string, options: WalkOptions): string
}

export type WalkFn = ((...args: any[]) => any) | SerializedFn;
export class SerializedFn {
	args: string[]; 
	source: string
	constructor (args: string[], source: string);
}

these functions provides utilities for action attributes handlers.

WalkNode: represent a node passed for action attribute handler as walk can work with native DOM and Template.

getTarget: return the target of the given WalkNode to set to Action.target.

attributes utilities

attrsOf: returns a Generator that iterates through a given WalkNode attributes.

hasAttr: returns whether a given WalkNode has the given attribute.

getAttr: gets an attribute from a given WalkNode, returns undefined if not found.

setAttr: sets an attribute from a given WalkNode.

removeAttr: removes an attribute from a given WalkNode.

content utilities

childrenOf: returns a Generator that iterates through the children of a given WalkNode.

removeChildren: remove all the children of a given WalkNode.

getText: returns the text of a given WalkNode, returns undefined if has child elements.

setText: set the text of a given WalkNode.

WalkFn

toFun: create a WalkFn from a given args and source, passed with WalkOptions.

WalkFn: it can be normal function if options.serialize is false, else SerializedFn.

SerializedFn: an object that represent a function.


decodeAttrArg: provide a work around when walking in DOM as attributes names are changed to lowercase, so uppercase is not possible.

when options.inDom is true, take a given value and replace all -c to C and every -- to -.

templated attributes

export interface TAttrExp {
	isExp: true;
	fn: WalkFn
	dynamics: string[],
	statics: string[]
}
export interface TAttrProp {
	isExp: false;
	prop: string,
	static: boolean
}
export type TAttrPart = string | TAttrProp | TAttrExp;
export type TAttr = WalkFn | TAttrPart[];

export function parseTAttr (
  source: string, attr: string, options: WalkOptions, globalArgs: string[]
): TAttr;

export function evalTAttr (
	attr: TAttr, comp: PureComp, el: HTMLElement, context: Record<string, any>, props: any[]
): any;

parseTAttr: parses a templated attribute, attr is the attribute name and globalArgs are arguments added to all functions.

evalTAttr: evalute a templated attribute and returns its value, take the passed context and props.
this assume that the globalArgs is of type (comp: PureComp, el: HTMLElement, context: Record<string, any>, ...props: any[]).

TAttr: represent a templated attribute, it can be: