1
1
/**
2
- * @typedef {import('vfile').VFile } VFile
3
- * @typedef {import('property-information').Schema } Schema
4
- * @typedef {import('unist').Position } Position
5
- * @typedef {import('unist').Point } Point
6
2
* @typedef {import('hast').Element } Element
3
+ * @typedef {import('hast').Nodes } Nodes
7
4
* @typedef {import('hast').Root } Root
8
5
* @typedef {import('hast').RootContent } RootContent
9
- * @typedef { import('hast').Nodes } Nodes
6
+ *
10
7
* @typedef {import('parse5').DefaultTreeAdapterMap } DefaultTreeAdapterMap
11
8
* @typedef {import('parse5').Token.ElementLocation } P5ElementLocation
12
9
* @typedef {import('parse5').Token.Location } P5Location
10
+ *
11
+ * @typedef {import('property-information').Schema } Schema
12
+ *
13
+ * @typedef {import('unist').Point } Point
14
+ * @typedef {import('unist').Position } Position
15
+ *
16
+ * @typedef {import('vfile').VFile } VFile
13
17
*/
14
18
15
19
/**
21
25
* @typedef {DefaultTreeAdapterMap['element'] } P5Element
22
26
* @typedef {DefaultTreeAdapterMap['node'] } P5Node
23
27
* @typedef {DefaultTreeAdapterMap['template'] } P5Template
24
- *
25
- * @typedef {'html' | 'svg' } Space
26
- * Namespace.
27
- *
28
+ */
29
+
30
+ /**
28
31
* @typedef Options
29
32
* Configuration.
30
33
* @property {Space | null | undefined } [space='html']
31
- * Which space the document is in.
34
+ * Which space the document is in (default: `'html'`) .
32
35
*
33
36
* When an `<svg>` element is found in the HTML space, this package already
34
37
* automatically switches to and from the SVG space when entering and exiting
35
38
* it.
36
39
* @property {VFile | null | undefined } [file]
37
- * File used to add positional info to nodes.
40
+ * File used to add positional info to nodes (optional) .
38
41
*
39
42
* If given, the file should represent the original HTML source.
40
43
* @property {boolean } [verbose=false]
41
44
* Whether to add extra positional info about starting tags, closing tags,
42
- * and attributes to elements.
45
+ * and attributes to elements (default: `false`) .
43
46
*
44
47
* > 👉 **Note**: only used when `file` is given.
45
48
*
49
+ * @typedef {'html' | 'svg' } Space
50
+ * Namespace.
51
+ *
46
52
* @typedef State
47
53
* Info passed around about the current state.
48
- * @property {Schema } schema
49
- * Current schema.
50
54
* @property {VFile | undefined } file
51
55
* Corresponding file.
52
- * @property {boolean | undefined } verbose
53
- * Add extra positional info.
54
56
* @property {boolean } location
55
57
* Whether location info was found.
58
+ * @property {Schema } schema
59
+ * Current schema.
60
+ * @property {boolean | undefined } verbose
61
+ * Add extra positional info.
56
62
*/
57
63
64
+ import { ok as assert } from 'devlop'
58
65
import { h , s } from 'hastscript'
59
- import { html , svg , find } from 'property-information'
66
+ import { find , html , svg } from 'property-information'
60
67
import { location } from 'vfile-location'
61
68
import { webNamespaces } from 'web-namespaces'
62
69
@@ -71,7 +78,7 @@ const proto = Object.prototype
71
78
* @param {P5Node } tree
72
79
* `parse5` tree to transform.
73
80
* @param {Options | VFile | null | undefined } [options]
74
- * Configuration.
81
+ * Configuration (optional) .
75
82
* @returns {Nodes }
76
83
* hast tree.
77
84
*/
@@ -92,10 +99,10 @@ export function fromParse5(tree, options) {
92
99
93
100
return one (
94
101
{
95
- schema : settings . space === 'svg' ? svg : html ,
96
102
file,
97
- verbose : settings . verbose ,
98
- location : false
103
+ location : false ,
104
+ schema : settings . space === 'svg' ? svg : html ,
105
+ verbose : settings . verbose
99
106
} ,
100
107
tree
101
108
)
@@ -142,7 +149,9 @@ function one(state, node) {
142
149
const loc = location ( doc )
143
150
const start = loc . toPoint ( 0 )
144
151
const end = loc . toPoint ( doc . length )
145
- // @ts -expect-error: always defined as we give valid input.
152
+ // Always defined as we give valid input.
153
+ assert ( start , 'expected `start`' )
154
+ assert ( end , 'expected `end`' )
146
155
result . position = { start, end}
147
156
}
148
157
@@ -185,14 +194,15 @@ function one(state, node) {
185
194
function all ( state , nodes ) {
186
195
let index = - 1
187
196
/** @type {Array<RootContent> } */
188
- const result = [ ]
197
+ const results = [ ]
189
198
190
199
while ( ++ index < nodes . length ) {
191
- // @ts -expect-error Assume no roots in `nodes`.
192
- result [ index ] = one ( state , nodes [ index ] )
200
+ // Assume no roots in `nodes`.
201
+ const result = /** @type {RootContent } */ ( one ( state , nodes [ index ] ) )
202
+ results . push ( result )
193
203
}
194
204
195
- return result
205
+ return results
196
206
}
197
207
198
208
/**
@@ -236,9 +246,8 @@ function element(state, node) {
236
246
const startTag = pos && pos . startTag && position ( pos . startTag )
237
247
const endTag = pos && pos . endTag && position ( pos . endTag )
238
248
239
- /** @type {Root } */
240
- // @ts -expect-error Types are wrong.
241
- const content = one ( state , reference . content )
249
+ // Root in, root out.
250
+ const content = /** @type {Root } */ ( one ( state , reference . content ) )
242
251
243
252
if ( startTag && endTag && state . file ) {
244
253
content . position = { start : startTag . end , end : endTag . start }
@@ -261,7 +270,7 @@ function element(state, node) {
261
270
* p5 node.
262
271
* @param {Nodes } to
263
272
* hast node.
264
- * @returns {void }
273
+ * @returns {undefined }
265
274
* Nothing.
266
275
*/
267
276
function patch ( state , from , to ) {
@@ -321,14 +330,15 @@ function createLocation(state, node, location) {
321
330
}
322
331
}
323
332
324
- node . data = {
325
- position : {
326
- // @ts -expect-error: assume not `undefined`.
327
- opening : position ( location . startTag ) ,
328
- closing : location . endTag ? position ( location . endTag ) : null ,
329
- properties : props
330
- }
331
- }
333
+ assert ( location . startTag , 'a start tag should exist' )
334
+ const opening = position ( location . startTag )
335
+ const closing = location . endTag ? position ( location . endTag ) : undefined
336
+ /** @type {Record<string, unknown> } */
337
+ const data = { opening}
338
+ if ( closing ) data . closing = closing
339
+ data . properties = props
340
+
341
+ node . data = { position : data }
332
342
}
333
343
}
334
344
@@ -354,7 +364,9 @@ function position(loc) {
354
364
column : loc . endCol ,
355
365
offset : loc . endOffset
356
366
} )
357
- // @ts -expect-error `undefined` is fine.
367
+
368
+ // @ts -expect-error: we do use `undefined` for points if one or the other
369
+ // exists.
358
370
return start || end ? { start, end} : undefined
359
371
}
360
372
0 commit comments