diff --git a/lib/index.js b/lib/index.js index 625ee6e..0761e0f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -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' @@ -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) diff --git a/readme.md b/readme.md index ba487b4..eb05134 100644 --- a/readme.md +++ b/readme.md @@ -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 diff --git a/test/index.js b/test/index.js index cb00e96..23adafc 100644 --- a/test/index.js +++ b/test/index.js @@ -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'), '