@asimojs/lml
Version:
LML - List Markup Language
80 lines (79 loc) • 2.92 kB
TypeScript
/// <reference types="react" />
export type LML = LmlTextNode | LmlNode | LmlFragment;
export type LmlTextNode = string;
export type LmlFragment = LML[];
export type LmlNodeList = LML[];
export type LmlNode = (LmlNodeName | LmlAttributeMap | LML)[];
export type LmlNodeName = string;
export type LmlAttributeMap = LmlObject;
export type LmlNodeType = "text" | "element" | "component" | "fragment" | "invalid";
export interface LmlObject {
[key: string]: LmlValue | LmlValue[];
}
export type LmlValue = string | number | boolean | LmlObject | LML;
export type LmlNodeInfo = LmlNodeInfoString | LmlNodeInfoElement | LmlNodeInfoComponent | LmlNodeInfoDecorator | LmlNodeInfoOther;
export interface LmlNodeInfoString {
type: "text";
value: string;
}
export interface LmlNodeInfoElement {
type: "element";
tagName: string;
ns: string;
}
export interface LmlNodeInfoComponent {
type: "component";
tagName: string;
ns: string;
}
export interface LmlNodeInfoDecorator {
type: "decorator";
tagName: string;
ns: string;
}
export interface LmlNodeInfoOther {
type: "other";
}
/** JSX-compatible output produced by lml2jsx */
export type JsxContent = JSX.Element | string | (JSX.Element | string)[];
export interface LmlFormatter {
format(ndi: LmlNodeInfo, attributes?: LmlAttributeMap, children?: (JSX.Element | string)[]): JsxContent;
error?(m: string): void;
}
export type LmlUpdate = LmlNodeUpdate | LmlNodeListUpdate | LmlNodeDelete;
/** Key attribute of a node - e.g. XXX in ["#span.msg!XXX", "Hello"] */
export type LmlNodeKey = string;
/** Path from a node to a child node through an attribute path - e.g. "children" or "footer/sections" */
export type LmlNodePath = string;
export interface LmlNodeUpdate {
action: "insertBefore" | "insertAfter" | "replace";
node: LmlNodeKey;
path?: LmlNodePath;
content: LML;
}
export interface LmlNodeListUpdate {
action: "append" | "prepend" | "replace";
/** target node: root node if not provided */
node?: LmlNodeKey;
/** target path: default = empty for root node, "children" for "append" or "prepend", empty for "replace" */
path?: LmlNodePath;
content: LML;
}
export interface LmlNodeDelete {
action: "delete";
/** target node: root node if not provided */
node?: LmlNodeKey;
path?: LmlNodePath;
}
export interface LmlSanitizationRules {
/** Allowed element names */
allowedElements: Set<string>;
/** Forbidden eleement attributes - e.g. forbid style, srcset */
forbiddenElementAttributes: Set<string>;
/** Forbid onXXXX attributes on elements */
forbidEventHandlers: boolean;
/** URL attributes used in allowedElements, will be checked against allowedUrlPrefixes */
urlAttributes: Set<string>;
/** Allowed URLs - DO NOT PUT "data:text" -> data:text/html can contain malicious scripts */
allowedUrlPrefixes: string[];
}