New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hast-util-to-dom

Package Overview
Dependencies
Maintainers
2
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hast-util-to-dom - npm Package Compare versions

Comparing version 3.1.0 to 3.1.1

1

index.d.ts
export {toDom} from './lib/index.js'
export type AfterTransform = import('./lib/index.js').AfterTransform
export type Options = import('./lib/index.js').Options
/**
* @typedef {import('./lib/index.js').AfterTransform} AfterTransform
* @typedef {import('./lib/index.js').Options} Options

@@ -3,0 +4,0 @@ */

66

lib/index.d.ts
/**
* Transform a hast tree to a DOM tree
*
* @param {HastNode} node
* @param {Options} [options]
* @returns {Node}
* @param {HastNode} tree
* Tree to transform.
* @param {Options | null | undefined} [options]
* Configuration (optional).
* @returns {XMLDocument | DocumentFragment | Text | DocumentType | Comment | Element}
* Equivalent DOM node.
*/
export function toDom(node: HastNode, options?: Options | undefined): Node
export type HastParent = import('hast').Parent
export function toDom(
tree: HastNode,
options?: Options | null | undefined
): XMLDocument | DocumentFragment | Text | DocumentType | Comment | Element
export type HastRoot = import('hast').Root

@@ -15,32 +20,53 @@ export type HastDoctype = import('hast').DocType

export type HastComment = import('hast').Comment
export type HastChild = HastParent['children'][number]
export type HastChild = import('hast').Content
export type HastNode = HastChild | HastRoot
/**
* Function called when a hast node is transformed into a DOM node
* callback called when each node is transformed.
*/
export type AfterTransform = (hastNode: HastNode, domNode: Node) => void
/**
* Configuration.
*/
export type Options = {
/**
* Whether a DOM fragment should be returned
* Callback called when each node is transformed.
*/
fragment?: boolean | undefined
afterTransform?: AfterTransform | null | undefined
/**
* Document interface to use (default: `globalThis.document`)
* Document interface to use (default: `globalThis.document`).
*/
document?: Document | undefined
document?: Document | null | undefined
/**
* `namespace` to use to create elements
* Whether to return a DOM fragment (`true`) or a whole document (`false`).
*/
namespace?: string | undefined
fragment?: boolean | null | undefined
/**
* Callback invoked after each node transformation
* Namespace to use to create elements.
*/
afterTransform?: AfterTransform | undefined
namespace?: string | null | undefined
}
export type Context = {
/**
* Info passed around about the current state.
*/
export type State = {
/**
* Document interface to use.
*/
doc: Document
fragment?: boolean | undefined
namespace?: string | undefined
impliedNamespace?: string | undefined
afterTransform?: AfterTransform | undefined
/**
* Whether a fragment (`true`) or whole document (`false`) is built.
*/
fragment: boolean
/**
* Namespace to use.
*/
namespace: string | undefined
/**
* To do.
*/
impliedNamespace: string | undefined
/**
* Callback called after each hast node is transformed.
*/
afterTransform: AfterTransform | undefined
}
/**
* @typedef {import('hast').Parent} HastParent
* @typedef {import('hast').Root} HastRoot

@@ -8,43 +7,81 @@ * @typedef {import('hast').DocType} HastDoctype

* @typedef {import('hast').Comment} HastComment
* @typedef {HastParent['children'][number]} HastChild
* @typedef {HastChild|HastRoot} HastNode
* @typedef {import('hast').Content} HastChild
*/
/**
* @typedef {HastChild | HastRoot} HastNode
*
* @callback AfterTransform
* Function called when a hast node is transformed into a DOM node
* Callback called when each node is transformed.
* @param {HastNode} hastNode
* The hast node that was handled
* hast node that was handled.
* @param {Node} domNode
* The corresponding DOM node
* Corresponding DOM node.
* @returns {void}
* Nothing.
*
* @typedef Options
* @property {boolean} [fragment=false]
* Whether a DOM fragment should be returned
* @property {Document} [document]
* Document interface to use (default: `globalThis.document`)
* @property {string} [namespace]
* `namespace` to use to create elements
* @property {AfterTransform} [afterTransform]
* Callback invoked after each node transformation
* Configuration.
* @property {AfterTransform | null | undefined} [afterTransform]
* Callback called when each node is transformed.
* @property {Document | null | undefined} [document]
* Document interface to use (default: `globalThis.document`).
* @property {boolean | null | undefined} [fragment=false]
* Whether to return a DOM fragment (`true`) or a whole document (`false`).
* @property {string | null | undefined} [namespace]
* Namespace to use to create elements.
*
* @typedef Context
* @typedef State
* Info passed around about the current state.
* @property {Document} doc
* @property {boolean} [fragment=false]
* @property {string} [namespace]
* @property {string} [impliedNamespace]
* @property {AfterTransform} [afterTransform]
* Document interface to use.
* @property {boolean} fragment
* Whether a fragment (`true`) or whole document (`false`) is built.
* @property {string | undefined} namespace
* Namespace to use.
* @property {string | undefined} impliedNamespace
* To do.
* @property {AfterTransform | undefined} afterTransform
* Callback called after each hast node is transformed.
*/
/* eslint-env browser */
import {webNamespaces} from 'web-namespaces'
import {find, html, svg} from 'property-information'
/* eslint-env browser */
const own = {}.hasOwnProperty
/**
* Transform a hast tree to a DOM tree
*
* @param {HastNode} tree
* Tree to transform.
* @param {Options | null | undefined} [options]
* Configuration (optional).
* @returns {XMLDocument | DocumentFragment | Text | DocumentType | Comment | Element}
* Equivalent DOM node.
*/
export function toDom(tree, options) {
const config = options || {}
return transform(tree, {
doc: config.document || document,
fragment: config.fragment || false,
namespace: config.namespace || undefined,
impliedNamespace: undefined,
afterTransform: config.afterTransform || undefined
})
}
/**
* @param {HastNode} node
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {XMLDocument | DocumentFragment | Text | DocumentType | Comment | Element}
* Equivalent DOM node.
*/
function transform(node, ctx) {
const transformed = one(node, ctx)
if (ctx.afterTransform) ctx.afterTransform(node, transformed)
function transform(node, state) {
const transformed = one(node, state)
if (state.afterTransform) state.afterTransform(node, transformed)
return transformed

@@ -54,19 +91,33 @@ }

/**
* Transform any hast node.
*
* @param {HastNode} node
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {XMLDocument | DocumentFragment | Text | DocumentType | Comment | Element}
* Equivalent DOM node.
*/
function one(node, ctx) {
function one(node, state) {
switch (node.type) {
case 'root':
return root(node, ctx)
case 'text':
return text(node, ctx)
case 'element':
return element(node, ctx)
case 'doctype':
return doctype(node, ctx)
case 'comment':
return comment(node, ctx)
default:
return element(node, ctx)
case 'root': {
return root(node, state)
}
case 'text': {
return text(node, state)
}
case 'doctype': {
return doctype(node, state)
}
case 'comment': {
return comment(node, state)
}
default: {
// Important: unknown nodes are passed to `element`.
return element(node, state)
}
}

@@ -79,12 +130,14 @@ }

* @param {HastRoot} node
* @param {Context} ctx
* @returns {XMLDocument|DocumentFragment|HTMLHtmlElement}
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {XMLDocument | DocumentFragment | HTMLHtmlElement}
* Equivalent DOM node.
*/
function root(node, ctx) {
const {doc, fragment, namespace: ctxNamespace} = ctx
const {children = []} = node
let namespace = ctxNamespace
function root(node, state) {
const children = node.children || []
let rootIsDocument = children.length === 0
let index = -1
/** @type {string | undefined} */
let foundNamespace

@@ -95,32 +148,38 @@ while (++index < children.length) {

if (child.type === 'element' && child.tagName === 'html') {
const {properties = {}} = child
// If we have a root HTML node, we don’t need to render as a fragment.
rootIsDocument = true
// Take namespace of the first child.
if (ctxNamespace === undefined) {
namespace = String(properties.xmlns || '') || webNamespaces.html
}
// Take namespace.
foundNamespace =
String((child.properties && child.properties.xmlns) || '') ||
webNamespaces.html
break
}
}
// The root node will be a Document, DocumentFragment, or HTMLElement.
/** @type {XMLDocument|DocumentFragment|HTMLHtmlElement} */
const namespace = state.namespace || foundNamespace
// The root node will be `Document`, `DocumentFragment`, or `HTMLElement`.
/** @type {XMLDocument | DocumentFragment | HTMLHtmlElement} */
let result
if (rootIsDocument) {
result = doc.implementation.createDocument(namespace || null, '', null)
} else if (fragment) {
result = doc.createDocumentFragment()
result = state.doc.implementation.createDocument(
namespace || null,
'',
null
)
} else if (state.fragment) {
result = state.doc.createDocumentFragment()
} else {
result = doc.createElement('html')
result = state.doc.createElement('html')
}
return appendAll(result, children, {
...ctx,
fragment,
appendAll(result, children, {
...state,
namespace,
impliedNamespace: namespace
})
return result
}

@@ -132,7 +191,10 @@

* @param {HastDoctype} _
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {DocumentType}
* DOM document type.
*/
function doctype(_, {doc}) {
return doc.implementation.createDocumentType('html', '', '')
function doctype(_, state) {
return state.doc.implementation.createDocumentType('html', '', '')
}

@@ -144,7 +206,10 @@

* @param {HastText} node
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {Text}
* DOM text.
*/
function text(node, {doc}) {
return doc.createTextNode(node.value)
function text(node, state) {
return state.doc.createTextNode(node.value)
}

@@ -156,7 +221,10 @@

* @param {HastComment} node
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {Comment}
* DOM comment.
*/
function comment(node, {doc}) {
return doc.createComment(node.value)
function comment(node, state) {
return state.doc.createComment(node.value)
}

@@ -168,18 +236,20 @@

* @param {HastElement} node
* @param {Context} ctx
* Node to transform.
* @param {State} state
* Info passed around about the current state.
* @returns {Element}
* DOM element.
*/
// eslint-disable-next-line complexity
function element(node, ctx) {
const {namespace, doc} = ctx
let impliedNamespace = ctx.impliedNamespace || namespace
const {
tagName = impliedNamespace === webNamespaces.svg ? 'g' : 'div',
properties = {},
children = []
} = node
function element(node, state) {
let impliedNamespace = state.impliedNamespace || state.namespace
// Important: unknown nodes are passed to `element`.
const tagName =
node.tagName || (impliedNamespace === webNamespaces.svg ? 'g' : 'div')
const properties = node.properties || {}
const children = node.children || []
// Switch automatically from HTML to SVG on `<svg>`.
if (
(impliedNamespace === null ||
impliedNamespace === undefined ||
(impliedNamespace === undefined ||
impliedNamespace === webNamespaces.html) &&

@@ -193,56 +263,50 @@ tagName === 'svg'

const result =
impliedNamespace === null || impliedNamespace === undefined
? doc.createElement(tagName)
: doc.createElementNS(impliedNamespace, tagName)
const result = impliedNamespace
? state.doc.createElementNS(impliedNamespace, tagName)
: state.doc.createElement(tagName)
// Add HTML attributes.
const props = Object.keys(properties)
const {length} = props
/** @type {string} */
let key
for (let i = 0; i < length; i += 1) {
const key = props[i]
for (key in properties) {
if (own.call(properties, key)) {
const info = find(schema, key)
let value = properties[key]
const {
attribute,
property,
// `mustUseAttribute`,
mustUseProperty,
boolean,
booleanish,
overloadedBoolean,
// `number`,
// `defined`,
commaSeparated
// `spaceSeparated`,
// `commaOrSpaceSeparated`,
} = find(schema, key)
if (Array.isArray(value)) {
value = value.join(info.commaSeparated ? ', ' : ' ')
}
let value = properties[key]
if (info.mustUseProperty) {
// @ts-expect-error: fine.
result[info.property] = value
}
if (Array.isArray(value)) {
value = value.join(commaSeparated ? ', ' : ' ')
}
if (mustUseProperty) {
// @ts-expect-error: fine.
result[property] = value
}
if (boolean || (overloadedBoolean && typeof value === 'boolean')) {
if (value) {
result.setAttribute(attribute, '')
} else {
result.removeAttribute(attribute)
if (
info.boolean ||
(info.overloadedBoolean && typeof value === 'boolean')
) {
if (value) {
result.setAttribute(info.attribute, '')
} else {
result.removeAttribute(info.attribute)
}
} else if (info.booleanish) {
result.setAttribute(info.attribute, String(value))
} else if (value === true) {
result.setAttribute(info.attribute, '')
} else if (value || value === 0 || value === '') {
result.setAttribute(info.attribute, String(value))
}
} else if (booleanish) {
result.setAttribute(attribute, String(value))
} else if (value === true) {
result.setAttribute(attribute, '')
} else if (value || value === 0 || value === '') {
result.setAttribute(attribute, String(value))
}
}
return appendAll(result, children, {...ctx, impliedNamespace})
const currentImpliedNamespace = state.impliedNamespace
state.impliedNamespace = impliedNamespace
appendAll(result, children, state)
state.impliedNamespace = currentImpliedNamespace
return result
}

@@ -253,9 +317,12 @@

*
* @template {Node} N
* @param {N} node
* @param {Array.<HastChild>} children
* @param {Context} ctx
* @returns {N}
* @param {Node} node
* DOM node to append to.
* @param {Array<HastChild>} children
* hast children.
* @param {State} state
* Info passed around about the current state.
* @returns {void}
* Nothing.
*/
function appendAll(node, children, ctx) {
function appendAll(node, children, state) {
let index = -1

@@ -265,18 +332,4 @@

// eslint-disable-next-line unicorn/prefer-dom-node-append
node.appendChild(transform(children[index], ctx))
node.appendChild(transform(children[index], state))
}
return node
}
/**
* Transform a hast tree to a DOM tree
*
* @param {HastNode} node
* @param {Options} [options]
* @returns {Node}
*/
export function toDom(node, options = {}) {
const {document: doc = document, ...rest} = options
return transform(node, {doc, ...rest})
}
{
"name": "hast-util-to-dom",
"version": "3.1.0",
"version": "3.1.1",
"description": "hast utility to transform to the DOM",

@@ -41,26 +41,22 @@ "license": "ISC",

"devDependencies": {
"@types/glob": "^7.0.0",
"@types/jsdom": "^16.0.0",
"@types/tape": "^4.0.0",
"@types/jsdom": "^20.0.0",
"@types/node": "^18.0.0",
"@types/w3c-xmlserializer": "^2.0.0",
"c8": "^7.0.0",
"glob": "^7.0.0",
"hastscript": "^7.0.0",
"jsdom": "^19.0.0",
"jsdom": "^20.0.0",
"prettier": "^2.0.0",
"remark-cli": "^10.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"w3c-xmlserializer": "^3.0.0",
"xo": "^0.47.0"
"w3c-xmlserializer": "^4.0.0",
"xo": "^0.53.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{lib/**,test/**,}*.d.ts\" && tsc && type-coverage",
"build": "tsc --build --clean && tsc --build && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test/index.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
"test-api": "node --conditions development test/index.js",
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"

@@ -77,3 +73,13 @@ },

"xo": {
"prettier": true
"prettier": true,
"overrides": [
{
"files": [
"test/**/*.js"
],
"rules": {
"no-await-in-loop": 0
}
}
]
},

@@ -80,0 +86,0 @@ "remarkConfig": {

@@ -11,11 +11,46 @@ # hast-util-to-dom

[**hast**][hast] utility to transform to a DOM tree.
[hast][] utility to transform to a [DOM][] tree.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`toDom(tree[, options])`](#todomtree-options)
* [`AfterTransform`](#aftertransform)
* [`Options`](#options)
* [Syntax tree](#syntax-tree)
* [Types](#types)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a utility that creates a DOM tree (defaulting to the actual DOM
but also supporting things like [`jsdom`][jsdom]) from a [hast][] (HTML) syntax
tree.
## When should I use this?
You can use this project when you want to turn hast into a DOM in browsers,
either to use it directly on a page, or to enable the use of DOM APIs (such as
`querySelector` to find things or `innerHTML` to serialize stuff).
The hast utility [`hast-util-from-dom`][hast-util-from-dom] does the inverse of
this utility.
It turns DOM trees into hast.
The rehype plugin [`rehype-dom-stringify`][rehype-dom-stringify] wraps this
utility to serialize as HTML with DOM APIs.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
This package is [ESM only][esm].
In Node.js (version 14.14+ or 16.0+), install with [npm][]:
[npm][]:
```sh

@@ -25,75 +60,106 @@ npm install hast-util-to-dom

## Use
In Deno with [`esm.sh`][esmsh]:
This utility is intended for browser use!
```js
import {toDom} from 'hast-util-to-dom';
const el = toDom({
type: 'element',
tagName: 'h1',
properties: {},
children: [{type: 'text', value: 'World!'}]
});
console.log(el);
import {toDom} from 'https://esm.sh/hast-util-to-dom@3'
```
This will create a DOM node like this:
In browsers with [`esm.sh`][esmsh]:
```html
<h1>World!</h1>
<script type="module">
import {toDom} from 'https://esm.sh/hast-util-to-dom@3?bundle'
</script>
```
If you want a string of HTML, you have a few options:
## Use
```js
// Outer HTML, eg. if you want an entire fragment
console.log(el.outerHTML);
// "<h1>World</h1>"
Say our page `example.html` looks as follows:
// Inner HTML, eg. if you have a wrapping element you don't need
console.log(el.innerHTML);
// "World"
```html
<!doctype html>
<title>Example</title>
<body>
<script type="module">
import {h} from 'https://esm.sh/hastscript?bundle'
import {toDom} from 'https://esm.sh/hast-util-to-dom?bundle'
// Full serialization, eg. when you want the whole document
console.log(new XMLSerializer().serializeToString(el));
// "<div xmlns="http://www.w3.org/1999/xhtml">World</div>"
const tree = h('main', [
h('h1', 'Hi'),
h('p', [h('em', 'Hello'), ', world!'])
])
document.body.append(toDom(tree))
</script>
```
Due to the nature of various browser implementations, you may notice
cross-browser differences in the serialized output, especially with respect to
whitespace or self-closing tags.
Buddy, that’s the web!
Now running `open example.html` shows the `main`, `h1`, and `p` elements on the
page.
## API
This package exports the following identifiers: `toDom`.
This package exports the identifier [`toDom`][to-dom].
There is no default export.
### `toDom(node[, options])`
### `toDom(tree[, options])`
Transform a [**hast**][hast] [*tree*][tree] to a DOM tree.
Turn a hast tree into a DOM tree.
##### `options`
###### Parameters
###### `options.fragment`
* `tree` ([`HastNode`][hast-node])
— tree to transform
* `options` ([`Options`][options], optional)
— configuration
Whether a DOM fragment should be returned (default: `false`).
###### Returns
###### `options.document`
DOM node ([`DomNode`][dom-node]).
Document interface to use (default: `globalThis.document`).
### `AfterTransform`
###### `options.namespace`
Callback called when each node is transformed (TypeScript type).
`namespace` to use to create [*elements*][element].
###### Parameters
###### `options.afterTransform`
* `hastNode` ([`HastNode`][hast-node])
— hast node that was handled
* `domNode` ([`DomNode`][dom-node])
— corresponding DOM node
Function called when a hast node is transformed into a DOM node (`Function?`).
Given the hast node that was handled as the first parameter and the
corresponding DOM node as the second parameter.
###### Returns
Nothing.
### `Options`
Configuration (TypeScript type).
###### Fields
* `afterTransform` ([`AfterTransform`][aftertransform], optional)
— callback called when each node is transformed
* `document` (`Document`, default: `globalThis.document`)
— document interface to use.
* `fragment` (`boolean`, default: `false`)
— whether to return a DOM fragment (`true`) or a whole document (`false`)
* `namespace` (`string`, default: depends)
— namespace to use to create elements
## Syntax tree
The syntax tree is [hast][].
## Types
This package is fully typed with [TypeScript][].
It exports the additional types `AfterTransform` and `Options`.
## Compatibility
Projects maintained by the unified collective are compatible with all maintained
versions of Node.js.
As of now, that is Node.js 14.14+ and 16.0+.
Our projects sometimes work with older versions, but this is not guaranteed.
## Security

@@ -103,3 +169,3 @@

[cross-site scripting (XSS)][xss] attack if the hast tree is unsafe.
Use [`hast-util-santize`][sanitize] to make the hast tree safe.
Use [`hast-util-santize`][hast-util-sanitize] to make the hast tree safe.

@@ -109,12 +175,12 @@ ## Related

* [`hast-util-sanitize`](https://github.com/syntax-tree/hast-util-sanitize)
— Sanitize hast nodes
— sanitize hast nodes
* [`hast-util-to-html`](https://github.com/syntax-tree/hast-util-to-html)
— Create an HTML string
— serialize as HTML
* [`hast-util-from-dom`](https://github.com/syntax-tree/hast-util-from-dom)
— Create a hast tree from a DOM tree
— create a hast tree from a DOM tree
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
ways to get started.
See [`support.md`][support] for ways to get help.

@@ -160,2 +226,8 @@

[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[license]: license

@@ -165,16 +237,32 @@

[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[health]: https://github.com/syntax-tree/.github
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[support]: https://github.com/syntax-tree/.github/blob/main/support.md
[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[hast-util-sanitize]: https://github.com/syntax-tree/hast-util-sanitize
[hast-util-from-dom]: https://github.com/syntax-tree/hast-util-from-dom
[jsdom]: https://github.com/jsdom/jsdom
[rehype-dom-stringify]: https://github.com/rehypejs/rehype-dom/tree/main/packages/rehype-dom-stringify
[hast]: https://github.com/syntax-tree/hast
[element]: https://github.com/syntax-tree/hast#element
[hast-node]: https://github.com/syntax-tree/hast#nodes
[tree]: https://github.com/syntax-tree/unist#tree
[dom]: https://developer.mozilla.org/docs/Web/API/Document_Object_Model
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[dom-node]: https://developer.mozilla.org/docs/Web/API/Node
[sanitize]: https://github.com/syntax-tree/hast-util-sanitize
[to-dom]: #todomtree-options
[aftertransform]: #aftertransform
[options]: #options
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