Skip to content

Add support for afterTransform hook #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 26, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
30 changes: 27 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,30 @@
* @typedef {HastParent['children'][number]} HastChild
* @typedef {HastChild|HastRoot} HastNode
*
* @callback AfterTransform
* Function called when a hast node is transformed into a DOM node
* @param {HastNode} hastNode
* The hast node that was handled
* @param {Node} domNode
* The corresponding DOM node
* @returns {void}
*
* @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 {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
*
* @typedef Context
* @property {Document} doc
* @property {boolean} [fragment=false]
* @property {string} [namespace]
* @property {string} [impliedNamespace]
* @property {AfterTransform} [afterTransform]
*/

import {webNamespaces} from 'web-namespaces'
Expand All @@ -30,6 +44,16 @@ import {find, html, svg} from 'property-information'
* @param {Context} ctx
*/
function transform(node, ctx) {
const transformed = one(node, ctx)
if (ctx.afterTransform) ctx.afterTransform(node, transformed)
return transformed
}

/**
* @param {HastNode} node
* @param {Context} ctx
*/
function one(node, ctx) {
switch (node.type) {
case 'root':
return root(node, ctx)
Expand Down
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ Document interface to use (default: `globalThis.document`).

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

###### `options.afterTransform`

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.

## 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