77 * @typedef {import('hast').Comment } HastComment
88 * @typedef {HastParent['children'][number] } HastChild
99 * @typedef {HastChild|HastRoot } HastNode
10+ *
11+ * @callback AfterTransform
12+ * Function called when a DOM node is transformed into a hast node
13+ * @param {Node } domNode
14+ * The DOM node that was handled
15+ * @param {HastNode|undefined } hastNode
16+ * The corresponding hast node
17+ * @returns {void }
18+ *
19+ * @typedef Options
20+ * @property {AfterTransform } [afterTransform]
21+ *
22+ * @typedef Context
23+ * @property {AfterTransform } [afterTransform]
1024 */
1125
1226import { webNamespaces } from 'web-namespaces'
@@ -21,17 +35,29 @@ const DOCUMENT_FRAGMENT_NODE = 11
2135
2236/**
2337 * @param {Node } node
38+ * @param {Context } ctx
39+ * @returns {HastNode|undefined }
40+ */
41+ function transform ( node , ctx ) {
42+ const transformed = one ( node , ctx )
43+ if ( ctx . afterTransform ) ctx . afterTransform ( node , transformed )
44+ return transformed
45+ }
46+
47+ /**
48+ * @param {Node } node
49+ * @param {Context } ctx
2450 * @returns {HastNode|undefined }
2551 */
26- function transform ( node ) {
52+ function one ( node , ctx ) {
2753 switch ( node . nodeType ) {
2854 case ELEMENT_NODE :
2955 // @ts -expect-error TypeScript is wrong.
30- return element ( node )
56+ return element ( node , ctx )
3157 case DOCUMENT_NODE :
3258 case DOCUMENT_FRAGMENT_NODE :
3359 // @ts -expect-error TypeScript is wrong.
34- return root ( node )
60+ return root ( node , ctx )
3561 case TEXT_NODE :
3662 // @ts -expect-error TypeScript is wrong.
3763 return text ( node )
@@ -49,10 +75,11 @@ function transform(node) {
4975 * Transform a document.
5076 *
5177 * @param {Document|DocumentFragment } node
78+ * @param {Context } ctx
5279 * @returns {HastRoot }
5380 */
54- function root ( node ) {
55- return { type : 'root' , children : all ( node ) }
81+ function root ( node , ctx ) {
82+ return { type : 'root' , children : all ( node , ctx ) }
5683}
5784
5885/**
@@ -89,9 +116,10 @@ function comment(node) {
89116 * Transform an element.
90117 *
91118 * @param {Element } node
119+ * @param {Context } ctx
92120 * @returns {HastElement }
93121 */
94- function element ( node ) {
122+ function element ( node , ctx ) {
95123 const space = node . namespaceURI
96124 const fn = space === webNamespaces . svg ? s : h
97125 const tagName =
@@ -109,23 +137,24 @@ function element(node) {
109137 props [ attributes [ index ] ] = node . getAttribute ( attributes [ index ] ) || ''
110138 }
111139
112- return fn ( tagName , props , all ( content ) )
140+ return fn ( tagName , props , all ( content , ctx ) )
113141}
114142
115143/**
116144 * Transform an element.
117145 *
118146 * @param {Document|DocumentFragment|Element } node
147+ * @param {Context } ctx
119148 * @returns {Array.<HastChild> }
120149 */
121- function all ( node ) {
150+ function all ( node , ctx ) {
122151 const nodes = node . childNodes
123152 /** @type {Array.<HastChild> } */
124153 const children = [ ]
125154 let index = - 1
126155
127156 while ( ++ index < nodes . length ) {
128- const child = transform ( nodes [ index ] )
157+ const child = transform ( nodes [ index ] , ctx )
129158
130159 if ( child !== undefined ) {
131160 // @ts -expect-error Assume no document inside document.
@@ -138,8 +167,9 @@ function all(node) {
138167
139168/**
140169 * @param {Node } node
170+ * @param {Options } [options]
141171 * @returns {HastNode }
142172 */
143- export function fromDom ( node ) {
144- return transform ( node || { } ) || { type : 'root' , children : [ ] }
173+ export function fromDom ( node , options = { } ) {
174+ return transform ( node || { } , options ) || { type : 'root' , children : [ ] }
145175}
0 commit comments