11/**
2+ * @typedef {import('property-information').Schema } Schema
3+ * @typedef {import('hast').Content } Content
24 * @typedef {import('hast').Element } Element
35 * @typedef {import('hast').Root } Root
4- * @typedef {import('hast').Text } Text
5- * @typedef {import('hast').Root|import('hast').Content } Node
6+ */
7+
8+ /**
9+ * @typedef {Root | Content } Node
610 *
711 * @callback CreateElementLike
12+ * Function that works somewhat like `React.createElement`.
813 * @param {string } name
14+ * Element name.
915 * @param {any } attributes
16+ * Properties.
1017 * @param {Array<any> } [children]
18+ * Children.
1119 * @returns {any }
20+ * Something.
1221 *
13- * @typedef Context
14- * @property {html|svg } schema
15- * @property {string|null } prefix
22+ * @typedef State
23+ * Info passed around.
24+ * @property {Schema } schema
25+ * Current schema.
26+ * @property {string | undefined } prefix
27+ * Prefix to use.
1628 * @property {number } key
29+ * Current key.
1730 * @property {boolean } react
31+ * Looks like React.
1832 * @property {boolean } vue
33+ * Looks like Vue.
1934 * @property {boolean } vdom
35+ * Looks like vdom.
2036 * @property {boolean } hyperscript
37+ * Looks like `hyperscript`.
2138 *
2239 * @typedef Options
23- * Configuration (optional) .
24- * @property {string| null } [prefix]
40+ * Configuration.
41+ * @property {string | null | undefined } [prefix]
2542 * Prefix to use as a prefix for keys passed in `props` to `h()`, this
2643 * behavior is turned off by passing `false` and turned on by passing a
2744 * `string`.
2845 * By default, `h-` is used as a prefix if the given `h` is detected as being
2946 * `virtual-dom/h` or `React.createElement`
30- * @property {'html'| 'svg' } [space]
47+ * @property {'html' | 'svg' | null | undefined } [space]
3148 * Whether `node` is in the `'html'` or `'svg'` space.
3249 * If an `<svg>` element is found when inside the HTML space, `toH`
3350 * automatically switches to the SVG space when entering the element, and
@@ -44,19 +61,19 @@ import {webNamespaces} from 'web-namespaces'
4461/** @type {(value: string, replacer: ((key: string, value: string) => void)) => void } */
4562const style = styleToObject
4663
47- const toReact = /** @type {Record<string, string> } */ ( hastToReact )
48-
4964const own = { } . hasOwnProperty
5065
5166/**
5267 * @template {CreateElementLike} H
68+ * Type of hyperscript function.
5369 * @param {H } h
5470 * HyperScript function.
5571 * @param {Node } tree
5672 * Tree to transform.
57- * @param {string| boolean| Options } [options]
73+ * @param {string | boolean | Options | null | undefined } [options]
5874 * Configuration (optional).
5975 * @returns {ReturnType<H> }
76+ * Return type of the hyperscript function.
6077 */
6178// eslint-disable-next-line complexity
6279export function toH ( h , tree , options ) {
@@ -106,12 +123,12 @@ export function toH(h, tree, options) {
106123 prefix === undefined || prefix === null
107124 ? r || v || vd
108125 ? 'h-'
109- : null
126+ : undefined
110127 : typeof prefix === 'string'
111128 ? prefix
112129 : prefix
113130 ? 'h-'
114- : null ,
131+ : undefined ,
115132 key : 0 ,
116133 react : r ,
117134 vue : v ,
@@ -124,12 +141,18 @@ export function toH(h, tree, options) {
124141 * Transform a hast node through a hyperscript interface to *anything*!
125142 *
126143 * @template {CreateElementLike} H
144+ * Type of hyperscript function.
127145 * @param {H } h
146+ * HyperScript function.
128147 * @param {Element } node
129- * @param {Context } ctx
148+ * Node to transform.
149+ * @param {State } state
150+ * Info passed around.
151+ * @returns {ReturnType<H> }
152+ * Return type of the hyperscript function.
130153 */
131- function transform ( h , node , ctx ) {
132- const parentSchema = ctx . schema
154+ function transform ( h , node , state ) {
155+ const parentSchema = state . schema
133156 let schema = parentSchema
134157 let name = node . tagName
135158 /** @type {Record<string, unknown> } */
@@ -142,42 +165,42 @@ function transform(h, node, ctx) {
142165
143166 if ( parentSchema . space === 'html' && name . toLowerCase ( ) === 'svg' ) {
144167 schema = svg
145- ctx . schema = schema
168+ state . schema = schema
146169 }
147170
148171 for ( key in node . properties ) {
149172 if ( node . properties && own . call ( node . properties , key ) ) {
150- addAttribute ( attributes , key , node . properties [ key ] , ctx , name )
173+ addAttribute ( attributes , key , node . properties [ key ] , state , name )
151174 }
152175 }
153176
154- if ( ctx . vdom ) {
177+ if ( state . vdom ) {
155178 if ( schema . space === 'html' ) {
156179 name = name . toUpperCase ( )
157180 } else if ( schema . space ) {
158181 attributes . namespace = webNamespaces [ schema . space ]
159182 }
160183 }
161184
162- if ( ctx . prefix ) {
163- ctx . key ++
164- attributes . key = ctx . prefix + ctx . key
185+ if ( state . prefix ) {
186+ state . key ++
187+ attributes . key = state . prefix + state . key
165188 }
166189
167190 if ( node . children ) {
168191 while ( ++ index < node . children . length ) {
169192 const value = node . children [ index ]
170193
171194 if ( value . type === 'element' ) {
172- nodes . push ( transform ( h , value , ctx ) )
195+ nodes . push ( transform ( h , value , state ) )
173196 } else if ( value . type === 'text' ) {
174197 nodes . push ( value . value )
175198 }
176199 }
177200 }
178201
179202 // Restore parent schema.
180- ctx . schema = parentSchema
203+ state . schema = parentSchema
181204
182205 // Ensure no React warnings are triggered for void elements having children
183206 // passed in.
@@ -187,16 +210,25 @@ function transform(h, node, ctx) {
187210}
188211
189212/**
213+ * Add an attribute to `props`.
214+ *
190215 * @param {Record<string, unknown> } props
216+ * Map.
191217 * @param {string } prop
218+ * Key.
192219 * @param {unknown } value
193- * @param {Context } ctx
220+ * Value.
221+ * @param {State } state
222+ * Info passed around.
194223 * @param {string } name
224+ * Element name.
225+ * @returns {void }
226+ * Nothing.
195227 */
196228// eslint-disable-next-line complexity, max-params
197- function addAttribute ( props , prop , value , ctx , name ) {
198- const info = find ( ctx . schema , prop )
199- /** @type {string| undefined } */
229+ function addAttribute ( props , prop , value , state , name ) {
230+ const info = find ( state . schema , prop )
231+ /** @type {string | undefined } */
200232 let subprop
201233
202234 // Ignore nullish and `NaN` values.
@@ -205,8 +237,8 @@ function addAttribute(props, prop, value, ctx, name) {
205237 value === undefined ||
206238 value === null ||
207239 ( typeof value === 'number' && Number . isNaN ( value ) ) ||
208- ( value === false && ( ctx . vue || ctx . vdom || ctx . hyperscript ) ) ||
209- ( ! value && info . boolean && ( ctx . vue || ctx . vdom || ctx . hyperscript ) )
240+ ( value === false && ( state . vue || state . vdom || state . hyperscript ) ) ||
241+ ( ! value && info . boolean && ( state . vue || state . vdom || state . hyperscript ) )
210242 ) {
211243 return
212244 }
@@ -218,28 +250,28 @@ function addAttribute(props, prop, value, ctx, name) {
218250 }
219251
220252 // Treat `true` and truthy known booleans.
221- if ( info . boolean && ctx . hyperscript ) {
253+ if ( info . boolean && state . hyperscript ) {
222254 value = ''
223255 }
224256
225257 // VDOM, Vue, and React accept `style` as object.
226258 if (
227259 info . property === 'style' &&
228260 typeof value === 'string' &&
229- ( ctx . react || ctx . vue || ctx . vdom )
261+ ( state . react || state . vue || state . vdom )
230262 ) {
231263 value = parseStyle ( value , name )
232264 }
233265
234266 // Vue 3 (used in our tests) doesn’t need this anymore.
235267 // Some major in the future we can drop Vue 2 support.
236268 /* c8 ignore next 2 */
237- if ( ctx . vue ) {
269+ if ( state . vue ) {
238270 if ( info . property !== 'style' ) subprop = 'attrs'
239271 } else if ( ! info . mustUseProperty ) {
240- if ( ctx . vdom ) {
272+ if ( state . vdom ) {
241273 if ( info . property !== 'style' ) subprop = 'attributes'
242- } else if ( ctx . hyperscript ) {
274+ } else if ( state . hyperscript ) {
243275 subprop = 'attrs'
244276 }
245277 }
@@ -248,8 +280,8 @@ function addAttribute(props, prop, value, ctx, name) {
248280 props [ subprop ] = Object . assign ( props [ subprop ] || { } , {
249281 [ info . attribute ] : value
250282 } )
251- } else if ( info . space && ctx . react ) {
252- props [ toReact [ info . property ] || info . property ] = value
283+ } else if ( info . space && state . react ) {
284+ props [ hastToReact [ info . property ] || info . property ] = value
253285 } else {
254286 props [ info . attribute ] = value
255287 }
@@ -259,7 +291,9 @@ function addAttribute(props, prop, value, ctx, name) {
259291 * Check if `h` is `react.createElement`.
260292 *
261293 * @param {CreateElementLike } h
294+ * HyperScript function.
262295 * @returns {boolean }
296+ * Looks like React.
263297 */
264298function react ( h ) {
265299 const node = /** @type {unknown } */ ( h ( 'div' , { } ) )
@@ -276,7 +310,9 @@ function react(h) {
276310 * Check if `h` is `hyperscript`.
277311 *
278312 * @param {CreateElementLike } h
313+ * HyperScript function.
279314 * @returns {boolean }
315+ * Looks like `hyperscript`.
280316 */
281317function hyperscript ( h ) {
282318 return 'context' in h && 'cleanup' in h
@@ -286,7 +322,9 @@ function hyperscript(h) {
286322 * Check if `h` is `virtual-dom/h`.
287323 *
288324 * @param {CreateElementLike } h
325+ * HyperScript function.
289326 * @returns {boolean }
327+ * Looks like `virtual-dom`
290328 */
291329function vdom ( h ) {
292330 const node = /** @type {unknown } */ ( h ( 'div' , { } ) )
@@ -298,7 +336,9 @@ function vdom(h) {
298336 * Check if `h` is Vue.
299337 *
300338 * @param {CreateElementLike } h
339+ * HyperScript function.
301340 * @returns {boolean }
341+ * Looks like Vue.
302342 */
303343function vue ( h ) {
304344 // Vue 3 (used in our tests) doesn’t need this anymore.
@@ -310,9 +350,14 @@ function vue(h) {
310350}
311351
312352/**
353+ * Parse a declaration into an object.
354+ *
313355 * @param {string } value
356+ * CSS declarations.
314357 * @param {string } tagName
358+ * Tag name.
315359 * @returns {Record<string, string> }
360+ * Properties.
316361 */
317362function parseStyle ( value , tagName ) {
318363 /** @type {Record<string, string> } */
0 commit comments