Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@thi.ng/hiccup

Package Overview
Dependencies
Maintainers
1
Versions
260
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@thi.ng/hiccup - npm Package Compare versions

Comparing version 4.3.3 to 5.0.0

2

api.d.ts

@@ -11,2 +11,4 @@ /** @internal */

export declare const CDATA = "!CDATA";
/** @internal */
export declare const DOCTYPE = "!DOCTYPE";
/**

@@ -13,0 +15,0 @@ * XML processing instruction in hiccup format.

4

api.js

@@ -15,2 +15,4 @@ /** @internal */

export const CDATA = "!CDATA";
/** @internal */
export const DOCTYPE = "!DOCTYPE";
/**

@@ -26,3 +28,3 @@ * XML processing instruction in hiccup format.

*/
export const DOCTYPE_HTML = ["!DOCTYPE", "html"];
export const DOCTYPE_HTML = [DOCTYPE, "html"];
/** @internal */

@@ -29,0 +31,0 @@ export const NO_SPANS = {

# Change Log
- **Last updated**: 2023-09-06T13:36:28Z
- **Last updated**: 2023-09-19T10:42:50Z
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)

@@ -12,2 +12,23 @@

# [5.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup@5.0.0) (2023-09-19)
#### 🛑 Breaking changes
- add SerializeOpts, update serialize() ([442d777](https://github.com/thi-ng/umbrella/commit/442d777))
- BREAKING CHANGE: update serialize() args, replace with options object
- only a breaking change for "advanced" use cases
- add SerializeOpts to simplify serialize() args
- add customizable entity escaping (via new opts)
- add/update tests
#### 🩹 Bug fixes
- update entity escapes in serialize() ([369d83e](https://github.com/thi-ng/umbrella/commit/369d83e))
- use [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/main/packages/strings) escapeEntitiesNum() for better XML/SVG compatibility
- add tests
#### ♻️ Refactoring
- minor updates ([94b3de6](https://github.com/thi-ng/umbrella/commit/94b3de6))
## [4.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hiccup@4.3.0) (2023-08-27)

@@ -14,0 +35,0 @@

@@ -8,6 +8,8 @@ import { deref } from "@thi.ng/api/deref";

v = deref(rules[r]);
isFunction(v) && (v = v(rules));
v != null && (css += `${r}:${v};`);
if (isFunction(v))
v = v(rules);
if (v != null)
css += `${r}:${v};`;
}
return css;
};

@@ -19,5 +19,6 @@ import { implementsFunction } from "@thi.ng/checks/implements-function";

const v = res[k];
implementsFunction(v, "deref") && (res[k] = v.deref());
if (implementsFunction(v, "deref"))
res[k] = v.deref();
}
return res;
};
{
"name": "@thi.ng/hiccup",
"version": "4.3.3",
"version": "5.0.0",
"description": "HTML/SVG/XML serialization of nested data structures, iterables & closures",

@@ -40,3 +40,3 @@ "type": "module",

"@thi.ng/errors": "^2.3.5",
"@thi.ng/strings": "^3.5.0"
"@thi.ng/strings": "^3.6.0"
},

@@ -131,3 +131,3 @@ "devDependencies": {

},
"gitHead": "b2ef5a1b8932d067af4ec2fc7da03d59d6868dc7\n"
"gitHead": "c22e8996cee284ebe8ea88582beb1ab5fc6ee503\n"
}

@@ -39,3 +39,2 @@ <!-- This file is generated - DO NOT EDIT! -->

- [serialize()](#serialize)
- [escape()](#escape)
- [Authors](#authors)

@@ -49,13 +48,14 @@ - [License](#license)

Inspired by [Hiccup](https://github.com/weavejester/hiccup) and
[Reagent](http://reagent-project.github.io/) for Clojure/ClojureScript.
[Reagent](http://reagent-project.github.io/) for Clojure/ClojureScript, this
package provides key infrastructure for a number of other related libraries.
Forget all the custom toy DSLs for templating and instead use the full
power of ES6 to directly define fully data-driven, purely functional and
easily *composable* components for static serialization to HTML &
friends.
Forget all the custom toy DSLs for templating and instead use the full power of
modern JavaScript to directly define fully data-driven, purely functional and
easily *composable* components for static serialization to HTML & friends.
This library is suitable for static website generation, server side rendering
This library is suitable for any SGML-style (HTML/XML/SVG/RSS/Atom etc.)
serialization, including static website/asset generation, server side rendering
etc. For interactive use cases, please see companion packages
[@thi.ng/rdom](https://github.com/thi-ng/umbrella/tree/develop/packages/rdom)
(or the older
(or the older, now unmaintained
[@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom))

@@ -66,14 +66,14 @@ and their various support packages.

- Only uses arrays, functions, ES6 iterables / iterators / generators
- Only uses JS arrays, plain objects, functions, ES6 iterables / iterators / generators
- Eager & lazy component composition using embedded functions / closures
- Support for self-closing tags (incl. validation), boolean attributes
- Arbitrary user context object injection for component functions
- Dynamic derived attribute value generation via function values
- Arbitrary user context object injection for embedded component functions
- Dynamically derived attribute value generation via function values
- CSS formatting of `style` attribute objects
- Optional HTML entity encoding
- Optional HTML/XML entity encoding
- Support for comments and XML/DTD processing instructions
- Branch-local behavior control attributes to control serialization
- Branch-local behavior control attributes to customize serialization
- Small (1.9KB minified) & fast
(*) Lazy composition here means that functions are only executed at
<sup>(*)</sup> Lazy composition here means that functions are only executed at
serialization time. Examples below...

@@ -92,20 +92,23 @@

Using only vanilla language features simplifies the development,
composability, reusability and testing of components. Furthermore, no
custom template parser is required and you're only restricted by the
expressiveness of the language / environment, not by your template
engine.
Using only vanilla language features simplifies the development, removes need
for extra tooling, improves composability, reusability, transformation and
testing of components. No custom template parser (a la JSX or Handlebars etc.)
is required and you're only restricted by the expressiveness of the language /
environment, not by your template engine.
Components can be defined as simple functions returning arrays or loaded
via JSON/JSONP.
Components can be defined as simple arrays and/or functions returning arrays or
can be dynamically generated or loaded via JSON...
### What is Hiccup?
For many years, [Hiccup](https://github.com/weavejester/hiccup) has been
the de-facto standard to encode HTML/XML datastructures in Clojure. This
library brings & extends this convention into ES6. A valid Hiccup tree
is any flat (though, usually nested) array of the following possible
structures. Any functions embedded in the tree are expected to return
values of the same structure. Please see [examples](#examples) &
[API](#api) further explanations...
For many years, [Hiccup](https://github.com/weavejester/hiccup) has been the
de-facto standard to encode HTML/XML datastructures in Clojure (and many years
before that, [the overall idea was introduced in Scheme by Oleg Kiselyov and
Kirill Lisovsky in
1999](https://web.archive.org/web/20011225105556/http://okmij.org/ftp/Scheme/xml.html)).
This library brings & extends this convention into ES6. A valid Hiccup tree is
any flat (though, usually nested) array of the following possible structures.
Any functions embedded in the tree are expected to return values of the same
structure. Please see [examples](#examples) & [API](#api) further
explanations...

@@ -134,2 +137,3 @@ ```ts

- [@thi.ng/hiccup-html](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-html) - 100+ type-checked HTML5 element functions for [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup) related infrastructure
- [@thi.ng/hiccup-html-parse](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-html-parse) - HTML parsing and transformation to nested JS arrays in hiccup format
- [@thi.ng/hiccup-markdown](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-markdown) - Markdown parser & serializer from/to Hiccup format

@@ -177,3 +181,3 @@ - [@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-svg) - SVG element functions for [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup) & related tooling

Package sizes (brotli'd, pre-treeshake): ESM: 2.09 KB
Package sizes (brotli'd, pre-treeshake): ESM: 2.14 KB

@@ -214,3 +218,3 @@ ## Dependencies

Tag names support
[Zencoding/Emmet](https://docs.emmet.io/abbreviations/syntax/#id-and-class)
[Emmet/Zencoding](https://docs.emmet.io/abbreviations/syntax/#id-and-class)
style ID & class attribute expansion:

@@ -256,10 +260,7 @@

If an attribute specifies a function as value, the function is called
with the entire attribute object as argument. This allows for the
dynamic generation of attribute values, based on existing ones. The
result MUST be a string.
If an attribute specifies a function as value, the function is called with the
entire attribute object as argument (incl. any `id` or `class` attribs derived
from an Emmet-style tag name). This allows for the dynamic generation of
attribute values, based on existing ones. The result MUST be a string.
**Function values for event attributes (any attrib name starting with
"on") WILL BE OMITTED from output.**
```ts

@@ -273,2 +274,5 @@ ["div#foo", { bar: (attribs) => attribs.id + "-bar" }]

Function values for event attributes (any attrib name starting with
"on") WILL BE OMITTED from output:
```ts

@@ -310,5 +314,7 @@ ["div#foo", { onclick: () => alert("foo") }, "click me!"]

Every component function will receive an arbitrary user defined context
object as first argument. This context object is passed to `serialize()`
and is then auto-injected for every component function call.
Every component function will receive an arbitrary user defined context object
as first argument. This context object can be passed to
[`serialize()`](https://docs.thi.ng/umbrella/hiccup/functions/serialize.html)
via its [options argument]() and is then passed as arg to every component function
call.

@@ -334,3 +340,4 @@ The context object should contain any global component configuration,

[section, "Hello world", "Easy theming"],
{ theme }
// pass context object via options
{ ctx: { theme } }
);

@@ -340,8 +347,8 @@ // <section class="bg-black moon-gray bt b--dark-gray mt3"><h1 class="white f3">Hello world</h1>Easy theming</section>

**Note:** Of course the context is ONLY auto-injected for lazily
embedded component functions (as shown above), i.e. if the functions are
wrapped in arrays and only called during serialization. If you call a
component function directly, you MUST pass the context (or `null`) as
first arg yourself. Likewise, if a component function doesn't make use
of the context you can either:
**Note:** Of course the context is ONLY auto-injected for lazily embedded
component functions (like the examples shown above), i.e. if the functions are
wrapped in arrays and only called during serialization. If you call such a
component function directly, you MUST pass the context (or `null`) as first arg
yourself. Likewise, if a component function doesn't make use of the context you
can use either:

@@ -377,4 +384,6 @@ ```ts

```ts
const fs = require("fs");
```ts tangle:export/readme-circles.js
import { serialize } from "@thi.ng/hiccup";
import { repeatedly } from "@thi.ng/transducers";
import { writeFileSync } from "fs";

@@ -384,3 +393,3 @@ // creates an unstyled SVG circle element

// context handling is described further below
const circle = (_, x, y, r) => ["circle", { cx: x | 0, cy: y | 0, r: r | 0 }];
const circle = (_, x, y, r) => ["circle", { cx: ~~x, cy: ~~y, r: ~~r }];

@@ -399,19 +408,16 @@ // note how this next component lazily composes `circle`.

// generator to produce iterable of `n` calls to `fn`
function* repeatedly(n, fn) {
while (n-- > 0) yield fn();
}
// generate 100 random circles and write serialized SVG to file
// `randomCircle` is wrapped
import { SVG_NS } from "@thi.ng/hiccup";
import { XML_SVG } from "@thi.ng/prefixes";
const doc = [
"svg", { xmlns: SVG_NS, width: 1000, height: 1000 },
"svg", { xmlns: XML_SVG, width: 1000, height: 1000 },
["g", { fill: "none", stroke: "red" },
repeatedly(100, randomCircle)]];
repeatedly(randomCircle, 100)]];
fs.writeFileSync("circles.svg", serialize(doc));
writeFileSync("export/circles.svg", serialize(doc));
```
Resulting example output:
```xml

@@ -431,3 +437,5 @@ <svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000">

```ts
```js tangle:export/readme-glossary.js
import { serialize } from "@thi.ng/hiccup";
// data

@@ -457,6 +465,9 @@ const glossary = {

// the 2nd arg `true` enforces HTML entity encoding (off by default)
serialize(widget, null, true);
// serialize with enforced HTML entity encoding (off by default)
console.log(serialize(widget, { escape: true }));
```
(Re)formatted output (generated HTML will always be dense, without intermittent
white space):
```html

@@ -480,3 +491,5 @@ <div class="widget">

```ts
```js tangle:export/readme-toc.js
import { serialize } from "@thi.ng/hiccup";
// stateful component to create hierarchically

@@ -511,8 +524,12 @@ // indexed & referencable section headlines:

serialize([
"div.toc",
TOC.map(([level, title]) => [section, level, title])
]);
console.log(
serialize([
"div.toc",
TOC.map(([level, title]) => [section, level, title])
])
);
```
Re-formatted HTML output:
```html

@@ -541,3 +558,3 @@ <div class="toc">

```ts
```js
const component = {

@@ -559,4 +576,4 @@ render: (ctx, title, ...body) => ["section", ["h1", title], ...body]

```ts
serialize(["div.container", ["div", {__skip: true}, "ignore me"]]);
```js
serialize(["div.container", ["div", { __skip: true }, "ignore me"]]);
// <div class="container"></div>

@@ -649,3 +666,3 @@ ```

```ts
["div", {style: {color: "red", background: "#000"}}]
["div", { style: { color: "red", background: "#000" } }]
// <div style="color:red;background:#000;"></div>

@@ -670,3 +687,3 @@ ```

serialize([foo, "id", "body"], { foo: { class: "black" }})
serialize([foo, "id", "body"], { foo: { class: "black" } })
// <div id="id" class="black">body</div>

@@ -683,11 +700,2 @@ ```

### escape()
Signature: `escape(str: string): string`
Helper function. Applies HTML entity replacement on given string. If
`serialize()` is called with `true` as 2nd argument, entity encoding is
done automatically ([list of entities
considered](https://github.com/thi-ng/umbrella/blob/develop/packages/hiccup/src/api.ts#L11)).
## Authors

@@ -694,0 +702,0 @@

@@ -0,2 +1,41 @@

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;
}
/**
* Recursively normalizes and serializes given tree as HTML/SVG/XML string.

@@ -18,3 +57,3 @@ * Expands any embedded component functions with their results.

*
* Tags can be defined in "Zencoding" convention, e.g.
* Tags can be defined in "Emmet" convention, e.g.
*

@@ -41,3 +80,3 @@ * ```js

* ```js
* ["div", {style: {color: "red", background: "#000"}}]
* ["div", { style: { color: "red", background: "#000" } }]
* // <div style="color:red;background:#000;"></div>

@@ -59,3 +98,3 @@ * ```

*
* If the `ctx` object it'll be passed to each embedded component fns.
* If the `ctx` option is given it'll be passed to each embedded component fns.
* Optionally call {@link derefContext} prior to {@link serialize} to auto-deref

@@ -69,3 +108,3 @@ * context keys with values implementing the

*
* serialize([foo, "id", "body"], { foo: { class: "black" } })
* serialize([foo, "id", "body"], { ctx: { foo: { class: "black" } } })
* // <div id="id" class="black">body</div>

@@ -79,21 +118,13 @@ * ```

*
* If the optional `span` flag is true (default: false), all text content will
* be wrapped in <span> elements (this is to ensure DOM compatibility with
* hdom). The only elements for spans are never created are listed in `NO_SPANS`
* in `api.ts`.
*
* If the optional `keys` flag is true (default: false), all elements will have
* an autogenerated `key` attribute injected. If `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)).
*
* 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 will be excluded
* from the output.
* 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!).
* (`"__COMMENT__"`) (always WITHOUT attributes!).
*
* ```
* ```js
* [COMMENT, "Hello world"]

@@ -103,6 +134,6 @@ * // <!-- Hello world -->

* [COMMENT, "Hello", "world"]
* <!--
* Hello
* world
* -->
* // <!--
* // Hello
* // world
* // -->
* ```

@@ -121,7 +152,7 @@ *

*
* ```
* ["?xml", { version: "1.0", standalone: "yes" }]
* ```js
* serialize(["?xml", { version: "1.0", standalone: "yes" }])
* // <?xml version="1.0" standalone="yes"?>
*
* ["!DOCTYPE", "html"]
* ["!DOCTYPE", "html"] // (also available as DOCTYPE_HTML)
* // <!DOCTYPE html>

@@ -131,8 +162,5 @@ * ```

* @param tree - hiccup elements / component tree
* @param ctx - arbitrary user context object
* @param escape - auto-escape entities
* @param span - use spans for text content
* @param keys - attach key attribs
* @param opts - options
*/
export declare const serialize: (tree: any, ctx?: any, escape?: boolean, span?: boolean, keys?: boolean, path?: number[]) => string;
export declare const serialize: (tree: any, opts?: Partial<SerializeOpts>, path?: number[]) => string;
//# sourceMappingURL=serialize.d.ts.map

@@ -9,3 +9,3 @@ import { deref, isDeref } from "@thi.ng/api/deref";

import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import { escapeEntities } from "@thi.ng/strings/entities";
import { escapeEntitiesNum } from "@thi.ng/strings/entities";
import { ATTRIB_JOIN_DELIMS, CDATA, COMMENT, NO_CLOSE_EMPTY, NO_SPANS, PROC_TAGS, VOID_TAGS, } from "./api.js";

@@ -32,3 +32,3 @@ import { css } from "./css.js";

*
* Tags can be defined in "Zencoding" convention, e.g.
* Tags can be defined in "Emmet" convention, e.g.
*

@@ -55,3 +55,3 @@ * ```js

* ```js
* ["div", {style: {color: "red", background: "#000"}}]
* ["div", { style: { color: "red", background: "#000" } }]
* // <div style="color:red;background:#000;"></div>

@@ -73,3 +73,3 @@ * ```

*
* If the `ctx` object it'll be passed to each embedded component fns.
* If the `ctx` option is given it'll be passed to each embedded component fns.
* Optionally call {@link derefContext} prior to {@link serialize} to auto-deref

@@ -83,3 +83,3 @@ * context keys with values implementing the

*
* serialize([foo, "id", "body"], { foo: { class: "black" } })
* serialize([foo, "id", "body"], { ctx: { foo: { class: "black" } } })
* // <div id="id" class="black">body</div>

@@ -93,21 +93,13 @@ * ```

*
* If the optional `span` flag is true (default: false), all text content will
* be wrapped in <span> elements (this is to ensure DOM compatibility with
* hdom). The only elements for spans are never created are listed in `NO_SPANS`
* in `api.ts`.
*
* If the optional `keys` flag is true (default: false), all elements will have
* an autogenerated `key` attribute injected. If `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)).
*
* 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 will be excluded
* from the output.
* 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!).
* (`"__COMMENT__"`) (always WITHOUT attributes!).
*
* ```
* ```js
* [COMMENT, "Hello world"]

@@ -117,6 +109,6 @@ * // <!-- Hello world -->

* [COMMENT, "Hello", "world"]
* <!--
* Hello
* world
* -->
* // <!--
* // Hello
* // world
* // -->
* ```

@@ -135,7 +127,7 @@ *

*
* ```
* ["?xml", { version: "1.0", standalone: "yes" }]
* ```js
* serialize(["?xml", { version: "1.0", standalone: "yes" }])
* // <?xml version="1.0" standalone="yes"?>
*
* ["!DOCTYPE", "html"]
* ["!DOCTYPE", "html"] // (also available as DOCTYPE_HTML)
* // <!DOCTYPE html>

@@ -145,24 +137,32 @@ * ```

* @param tree - hiccup elements / component tree
* @param ctx - arbitrary user context object
* @param escape - auto-escape entities
* @param span - use spans for text content
* @param keys - attach key attribs
* @param opts - options
*/
export const serialize = (tree, ctx, escape = false, span = false, keys = span, path = [0]) => _serialize(tree, ctx, escape, span, keys, path);
const _serialize = (tree, ctx, esc, span, keys, path) => tree == null
export const serialize = (tree, opts, path = [0]) => {
const $opts = {
escape: false,
escapeFn: escapeEntitiesNum,
span: false,
keys: false,
...opts,
};
if (opts?.keys == null && $opts.span)
$opts.keys = true;
return _serialize(tree, $opts, path);
};
const _serialize = (tree, opts, path) => tree == null
? ""
: Array.isArray(tree)
? serializeElement(tree, ctx, esc, span, keys, path)
? serializeElement(tree, opts, path)
: isFunction(tree)
? _serialize(tree(ctx), ctx, esc, span, keys, path)
? _serialize(tree(opts.ctx), opts, path)
: implementsFunction(tree, "toHiccup")
? _serialize(tree.toHiccup(ctx), ctx, esc, span, keys, path)
? _serialize(tree.toHiccup(opts.ctx), opts, path)
: isDeref(tree)
? _serialize(tree.deref(), ctx, esc, span, keys, path)
? _serialize(tree.deref(), opts, path)
: isNotStringAndIterable(tree)
? serializeIter(tree, ctx, esc, span, keys, path)
: ((tree = esc ? escapeEntities(String(tree)) : String(tree)), span)
? `<span${keys ? ` key="${path.join("-")}"` : ""}>${tree}</span>`
? serializeIter(tree, opts, path)
: ((tree = __escape(String(tree), opts)), opts.span)
? `<span${opts.keys ? ` key="${path.join("-")}"` : ""}>${tree}</span>`
: tree;
const serializeElement = (tree, ctx, esc, span, keys, path) => {
const serializeElement = (tree, opts, path) => {
let tag = tree[0];

@@ -172,5 +172,5 @@ return !tree.length

: isFunction(tag)
? _serialize(tag.apply(null, [ctx, ...tree.slice(1)]), ctx, esc, span, keys, path)
? _serialize(tag.apply(null, [opts.ctx, ...tree.slice(1)]), opts, path)
: implementsFunction(tag, "render")
? _serialize(tag.render.apply(null, [ctx, ...tree.slice(1)]), ctx, esc, span, keys, path)
? _serialize(tag.render.apply(null, [opts.ctx, ...tree.slice(1)]), opts, path)
: tag === COMMENT

@@ -181,8 +181,8 @@ ? serializeComment(tree)

: isString(tag)
? serializeTag(tree, ctx, esc, span, keys, path)
? serializeTag(tree, opts, path)
: isNotStringAndIterable(tree)
? serializeIter(tree, ctx, esc, span, keys, path)
? serializeIter(tree, opts, path)
: illegalArgs(`invalid tree node: ${tree}`);
};
const serializeTag = (tree, ctx, esc, span, keys, path) => {
const serializeTag = (tree, opts, path) => {
tree = normalize(tree);

@@ -192,12 +192,12 @@ const attribs = tree[1];

return "";
keys && attribs.key === undefined && (attribs.key = path.join("-"));
opts.keys && attribs.key === undefined && (attribs.key = path.join("-"));
const tag = tree[0];
const body = tree[2]
? serializeBody(tag, tree[2], ctx, esc, span, keys, path)
? serializeBody(tag, tree[2], opts, path)
: !VOID_TAGS[tag] && !NO_CLOSE_EMPTY[tag]
? `></${tag}>`
: PROC_TAGS[tag] || "/>";
return `<${tag}${serializeAttribs(attribs, esc)}${body}`;
return `<${tag}${serializeAttribs(attribs, opts)}${body}`;
};
const serializeAttribs = (attribs, esc) => {
const serializeAttribs = (attribs, opts) => {
let res = "";

@@ -207,3 +207,3 @@ for (let a in attribs) {

continue;
const v = serializeAttrib(attribs, a, deref(attribs[a]), esc);
const v = serializeAttrib(attribs, a, deref(attribs[a]), opts);
v != null && (res += v);

@@ -213,3 +213,3 @@ }

};
const serializeAttrib = (attribs, a, v, esc) => {
const serializeAttrib = (attribs, a, v, opts) => {
return v == null

@@ -224,6 +224,6 @@ ? null

: a === "data"
? serializeDataAttribs(v, esc)
: attribPair(a, v, esc);
? serializeDataAttribs(v, opts)
: attribPair(a, v, opts);
};
const attribPair = (a, v, esc) => {
const attribPair = (a, v, opts) => {
v =

@@ -237,5 +237,5 @@ a === "style" && isPlainObject(v)

: v.toString();
return v.length ? ` ${a}="${esc ? escapeEntities(v) : v}"` : null;
return v.length ? ` ${a}="${__escape(v, opts)}"` : null;
};
const serializeDataAttribs = (data, esc) => {
const serializeDataAttribs = (data, opts) => {
let res = "";

@@ -245,7 +245,7 @@ for (let id in data) {

isFunction(v) && (v = v(data));
v != null && (res += ` data-${id}="${esc ? escapeEntities(v) : v}"`);
v != null && (res += ` data-${id}="${__escape(v, opts)}"`);
}
return res;
};
const serializeBody = (tag, body, ctx, esc, span, keys, path) => {
const serializeBody = (tag, body, opts, path) => {
if (VOID_TAGS[tag]) {

@@ -256,5 +256,6 @@ illegalArgs(`No body allowed in tag: ${tag}`);

let res = proc ? " " : ">";
span = span && !proc && !NO_SPANS[tag];
if (opts.span && !proc && !NO_SPANS[tag])
opts = { ...opts, span: true };
for (let i = 0, n = body.length; i < n; i++) {
res += _serialize(body[i], ctx, esc, span, keys, [...path, i]);
res += _serialize(body[i], opts, [...path, i]);
}

@@ -270,3 +271,3 @@ return res + (proc || `</${tag}>`);

const serializeCData = (tree) => `<![CDATA[\n${tree.slice(1).join("\n")}\n]]>`;
const serializeIter = (iter, ctx, esc, span, keys, path) => {
const serializeIter = (iter, opts, path) => {
const res = [];

@@ -276,5 +277,6 @@ const p = path.slice(0, path.length - 1);

for (let i of iter) {
res.push(_serialize(i, ctx, esc, span, keys, [...p, k++]));
res.push(_serialize(i, opts, [...p, k++]));
}
return res.join("");
};
const __escape = (x, opts) => opts.escape ? opts.escapeFn(x) : x;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc