@thi.ng/hiccup
Version:
HTML/SVG/XML serialization of nested data structures, iterables & closures
175 lines • 5.99 kB
TypeScript
import type { FnU } from "@thi.ng/api";
/**
* Options to customize the behavior of {@link serialize}.
*/
export interface SerializeOpts {
/**
* Arbitrary user context object
*/
ctx?: any;
/**
* If true, auto-escape entities via {@link SerializeOpts.escapeFn}.
*
* @defaultValue false
*/
escape: boolean;
/**
* Only used if {@link SerializeOpts.escape} is enabled. Function to escape
* entities. By default uses
* [`escapeEntitiesNum`](https://docs.thi.ng/umbrella/strings/functions/escapeEntitiesNum.html).
*/
escapeFn: FnU<string>;
/**
* If true (default: false), all text content will be wrapped in `<span>`
* elements (to ensure DOM compatibility with hdom). The only elements for
* spans are never created are listed in {@link NO_SPANS}.
*
* @defaultValue false
*/
span: boolean;
/**
* If true (default: false), all elements will have an autogenerated `key`
* attribute injected. If {@link SerializeOpts.span} is enabled, `keys` will
* be enabled by default too (since in this case we assume the output is
* meant to be compatible with [`thi.ng/hdom`](https://thi.ng/hdom)).
*
* @defaultValue false
*/
keys: boolean;
/**
* If true, some serialization behaviors will be adjusted to target XML
* output.
*
* @remarks
* Currently, the following aspects are supported:
*
* - boolean attributes are serialized as `name=""` rather than just `name`
*
* @defaultValue false
*/
xml: boolean;
}
/**
* Recursively normalizes and serializes given tree as HTML/SVG/XML string.
* Expands any embedded component functions with their results.
*
* @remarks
* Each node of the input tree can have one of the following input forms:
*
* ```js
* ["tag", ...]
* ["tag#id.class1.class2", ...]
* ["tag", {other: "attrib"}, ...]
* ["tag", {...}, "body", function, ...]
* [function, arg1, arg2, ...]
* [{render: (ctx,...) => [...]}, args...]
* iterable
* ```
*
* Tags can be defined in "Emmet" convention, e.g.
*
* ```js
* ["div#foo.bar.baz", "hi"] // <div id="foo" class="bar baz">hi</div>
* ```
*
* The presence of the attributes object (2nd array index) is optional. Any
* attribute values, incl. functions are allowed. If the latter, the function is
* called with the full attribs object as argument and the return value is used
* for the attribute. This allows for the dynamic creation of attrib values
* based on other attribs. The only exception to this are event attributes, i.e.
* attribute names starting with "on". Function values assigned to event
* attributes will be omitted from the output.
*
* ```js
* ["div#foo", { bar: (attribs) => attribs.id + "-bar" }]
* // <div id="foo" bar="foo-bar"></div>
* ```
*
* The `style` attribute can ONLY be defined as string or object.
*
* ```js
* ["div", { style: { color: "red", background: "#000" } }]
* // <div style="color:red;background:#000;"></div>
* ```
*
* Boolean attribs are serialized in HTML5 syntax (present or not). `null`,
* `undefined` or empty string attrib values are ignored.
*
* Any `null` or `undefined` array values (other than in head position) will
* also be removed, unless a function is in head position.
*
* A function in head position of a node acts as a mechanism for component
* composition & delayed execution. The function will only be executed at
* serialization time. In this case the optional global context object and all
* other elements of that node / array are passed as arguments when that
* function is called. The return value the function MUST be a valid new tree
* (or `undefined`).
*
* If the `ctx` option is given it'll be passed to each embedded component fns.
* Optionally call {@link derefContext} prior to `serialize()` to auto-deref
* context keys with values implementing the
* [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html)
* interface.
*
* ```js
* import { serialize } from "@thi.ng/hiccup";
*
* const foo = (ctx, a, b) => ["div#" + a, ctx.foo, b];
*
* serialize([foo, "id", "body"], { ctx: { foo: { class: "black" } } })
* // <div id="id" class="black">body</div>
* ```
*
* Functions located in other positions are called ONLY with the global context
* arg and can return any (serializable) value (i.e. new trees, strings,
* numbers, iterables or any type with a suitable `.toString()`, `.toHiccup()`
* or `.deref()` implementation).
*
* hiccup & hdom control attributes (i.e. attrib names prefixed with `__`) will
* be omitted from the output. The only control attrib supported by this package
* is `__serialize`. If set to `false`, the entire tree branch below (and
* including) the element with that attrib will be excluded from the output.
*
* **See {@link SerializeOpts} for further available options.**
*
* Single or multiline comments can be included using the special `COMMENT` tag
* (`"__COMMENT__"`) (always WITHOUT attributes!).
*
* ```js
* import { COMMENT } from "@thi.ng/hiccup";
*
* [COMMENT, "Hello world"]
* // serializes to:
* // <!-- Hello world -->
*
* [COMMENT, "Hello", "world"]
* // <!--
* // Hello
* // world
* // -->
* ```
*
* Currently, the only processing / DTD instructions supported are:
*
* - `?xml`
* - `!DOCTYTPE`
* - `!ELEMENT`
* - `!ENTITY`
* - `!ATTLIST`
*
* These are used as follows (attribs are only allowed for `?xml`, all others
* only accept a body string which is taken as is):
*
* ```js
* serialize(["?xml", { version: "1.0", standalone: "yes" }])
* // <?xml version="1.0" standalone="yes"?>
*
* ["!DOCTYPE", "html"] // (also available as DOCTYPE_HTML)
* // <!DOCTYPE html>
* ```
*
* @param tree - hiccup elements / component tree
* @param opts - options
*/
export declare const serialize: (tree: any, opts?: Partial<SerializeOpts>, path?: number[]) => string;
//# sourceMappingURL=serialize.d.ts.map