Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
* @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 {(node: HastNode, transformed: Node) => void} [afterTransform] Callback invoked after each node transformation
*
* @typedef Context
* @property {Document} doc
* @property {boolean} [fragment=false]
* @property {string} [namespace]
* @property {string} [impliedNamespace]
* @property {Options['afterTransform']} [afterTransform]
*/

import {webNamespaces} from 'web-namespaces'
Expand All @@ -30,19 +32,28 @@ import {find, html, svg} from 'property-information'
* @param {Context} ctx
*/
function transform(node, ctx) {
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)
const transformed = transformer(node)
if (ctx.afterTransform) ctx.afterTransform(node, transformed)
return transformed

/**
* @param {HastNode} node
*/
function transformer(node) {
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)
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ Document interface to use (default: `globalThis.document`).

`namespace` to use to create [*elements*][element].

###### `options.afterTransform(node, transformed)`

Callback invoked after each node transformation (`Function`).

## Security

Use of `hast-util-to-dom` can open you up to a
Expand Down
19 changes: 19 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,25 @@ test('hast-util-to-dom', (t) => {
'encodes data properties when string'
)

t.deepEqual(
(() => {
/** @type {Array<[HastNode, string]>} */
const calls = []
toDom(h('html', [h('title', 'Hi')]), {
afterTransform: (node, transformed) => {
calls.push([node, serializeNodeToHtmlString(transformed)])
}
})
return calls
})(),
[
[{type: 'text', value: 'Hi'}, 'Hi'],
[h('title', 'Hi'), '<title>Hi</title>'],
[h('html', [h('title', 'Hi')]), '<html><title>Hi</title></html>']
],
'should invoke afterTransform'
)

t.end()
})

Expand Down