@@ -7,24 +7,24 @@ var toParse5 = require('hast-util-to-parse5');
7
7
var voids = require ( 'html-void-elements' ) ;
8
8
var ns = require ( 'web-namespaces' ) ;
9
9
var zwitch = require ( 'zwitch' ) ;
10
+ var xtend = require ( 'xtend' ) ;
10
11
11
12
module . exports = wrap ;
12
13
13
14
var IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE' ;
14
15
var CHARACTER_TOKEN = 'CHARACTER_TOKEN' ;
15
16
var START_TAG_TOKEN = 'START_TAG_TOKEN' ;
16
17
var END_TAG_TOKEN = 'END_TAG_TOKEN' ;
17
- var HIBERNATION_TOKEN = 'HIBERNATION_TOKEN' ;
18
18
var COMMENT_TOKEN = 'COMMENT_TOKEN' ;
19
19
var DOCTYPE_TOKEN = 'DOCTYPE_TOKEN' ;
20
- var DOCUMENT = 'document' ;
21
- var FRAGMENT = 'fragment' ;
22
20
23
21
function wrap ( tree , file ) {
24
- var parser = new Parser ( { locationInfo : true } ) ;
22
+ var parser = new Parser ( { sourceCodeLocationInfo : true , scriptingEnabled : false } ) ;
25
23
var one = zwitch ( 'type' ) ;
26
- var mode = inferMode ( tree ) ;
24
+ var tokenizer ;
27
25
var preprocessor ;
26
+ var posTracker ;
27
+ var locationTracker ;
28
28
var result ;
29
29
30
30
one . handlers . root = root ;
@@ -35,7 +35,7 @@ function wrap(tree, file) {
35
35
one . handlers . raw = raw ;
36
36
one . unknown = unknown ;
37
37
38
- result = fromParse5 ( mode === FRAGMENT ? fragment ( ) : document ( ) , file ) ;
38
+ result = fromParse5 ( documentMode ( tree ) ? document ( ) : fragment ( ) , file ) ;
39
39
40
40
/* Unpack if possible and when not given a `root`. */
41
41
if ( tree . type !== 'root' && result . children . length === 1 ) {
@@ -77,7 +77,10 @@ function wrap(tree, file) {
77
77
parser . _resetInsertionMode ( ) ;
78
78
parser . _findFormInFragmentContext ( ) ;
79
79
80
- preprocessor = parser . tokenizer . preprocessor ;
80
+ tokenizer = parser . tokenizer ;
81
+ preprocessor = tokenizer . preprocessor ;
82
+ locationTracker = tokenizer . __mixins [ 0 ] ;
83
+ posTracker = locationTracker . posTracker ;
81
84
82
85
one ( tree ) ;
83
86
@@ -90,6 +93,10 @@ function wrap(tree, file) {
90
93
var doc = parser . treeAdapter . createDocument ( ) ;
91
94
92
95
parser . _bootstrap ( doc , null ) ;
96
+ tokenizer = parser . tokenizer ;
97
+ preprocessor = tokenizer . preprocessor ;
98
+ locationTracker = tokenizer . __mixins [ 0 ] ;
99
+ posTracker = locationTracker . posTracker ;
93
100
94
101
one ( tree ) ;
95
102
@@ -100,7 +107,7 @@ function wrap(tree, file) {
100
107
var length = 0 ;
101
108
var index = - 1 ;
102
109
103
- /* istanbul ignore else - invalid nodes, see wooorm /rehype-raw#7. */
110
+ /* istanbul ignore else - invalid nodes, see rehypejs /rehype-raw#7. */
104
111
if ( nodes ) {
105
112
length = nodes . length ;
106
113
}
@@ -127,145 +134,136 @@ function wrap(tree, file) {
127
134
}
128
135
129
136
function text ( node ) {
130
- var start = pos . start ( node ) ;
131
137
parser . _processToken ( {
132
138
type : CHARACTER_TOKEN ,
133
139
chars : node . value ,
134
- location : {
135
- line : start . line ,
136
- col : start . column ,
137
- startOffset : start . offset ,
138
- endOffset : pos . end ( node ) . offset
139
- }
140
+ location : createParse5Location ( node )
140
141
} ) ;
141
142
}
142
143
143
144
function doctype ( node ) {
144
145
var p5 = toParse5 ( node ) ;
146
+
145
147
parser . _processToken ( {
146
148
type : DOCTYPE_TOKEN ,
147
149
name : p5 . name ,
148
150
forceQuirks : false ,
149
151
publicId : p5 . publicId ,
150
- systemId : p5 . systemId
152
+ systemId : p5 . systemId ,
153
+ location : createParse5Location ( node )
151
154
} ) ;
152
155
}
153
156
154
157
function comment ( node ) {
155
- var start = pos . start ( node ) ;
156
158
parser . _processToken ( {
157
159
type : COMMENT_TOKEN ,
158
160
data : node . value ,
159
- location : {
160
- line : start . line ,
161
- col : start . column ,
162
- startOffset : start . offset ,
163
- endOffset : pos . end ( node ) . offset
164
- }
161
+ location : createParse5Location ( node )
165
162
} ) ;
166
163
}
167
164
168
165
function raw ( node ) {
169
- var start = pos . start ( node ) . offset ;
166
+ var start = pos . start ( node ) ;
167
+ var token ;
170
168
169
+ // Reset preprocessor:
170
+ // https://github.com/inikulin/parse5/blob/0491902/packages/parse5/lib/tokenizer/preprocessor.js
171
171
preprocessor . html = null ;
172
+ preprocessor . endOfChunkHit = false ;
173
+ preprocessor . lastChunkWritten = false ;
172
174
preprocessor . lastCharPos = - 1 ;
173
175
preprocessor . pos = - 1 ;
174
176
175
- if ( start !== null ) {
176
- preprocessor . __locTracker . droppedBufferSize = start ;
177
- }
178
-
179
- parser . tokenizer . write ( node . value ) ;
180
-
181
- run ( parser ) ;
182
- }
183
- }
184
-
185
- function run ( p ) {
186
- var tokenizer = p . tokenizer ;
187
- var token ;
188
-
189
- while ( ! p . stopped ) {
190
- p . _setupTokenizerCDATAMode ( ) ;
191
-
192
- token = tokenizer . getNextToken ( ) ;
193
-
194
- if ( token . type === HIBERNATION_TOKEN ) {
195
- token = tokenizer . currentCharacterToken || tokenizer . currentToken ;
196
-
197
- if ( token ) {
198
- p . _processInputToken ( token ) ;
199
- }
200
-
201
- tokenizer . currentToken = null ;
202
- tokenizer . currentCharacterToken = null ;
203
-
204
- break ;
177
+ // Reset preprocessor mixin:
178
+ // https://github.com/inikulin/parse5/blob/0491902/packages/parse5/lib/extensions/position-tracking/preprocessor-mixin.js
179
+ posTracker . droppedBufferSize = 0 ;
180
+ posTracker . line = start . line ;
181
+ posTracker . col = 1 ;
182
+ posTracker . offset = 0 ;
183
+ posTracker . lineStartPos = - start . column + 1 ;
184
+ posTracker . droppedBufferSize = start . offset ;
185
+
186
+ // Reset location tracker:
187
+ // https://github.com/inikulin/parse5/blob/0491902/packages/parse5/lib/extensions/location-info/tokenizer-mixin.js
188
+ locationTracker . currentAttrLocation = null ;
189
+ locationTracker . ctLoc = createParse5Location ( node ) ;
190
+
191
+ // See the code for `parse` and `parseFragment`:
192
+ // https://github.com/inikulin/parse5/blob/0491902/packages/parse5/lib/parser/index.js#L371
193
+ tokenizer . write ( node . value ) ;
194
+ parser . _runParsingLoop ( null ) ;
195
+
196
+ // Process final characters if they’re still there after hibernating.
197
+ // Similar to:
198
+ // https://github.com/inikulin/parse5/blob/3bfa7d9/packages/parse5/lib/extensions/location-info/tokenizer-mixin.js#L95
199
+ token = tokenizer . currentCharacterToken ;
200
+
201
+ if ( token ) {
202
+ token . location . endLine = posTracker . line ;
203
+ token . location . endCol = posTracker . col + 1 ;
204
+ token . location . endOffset = posTracker . offset + 1 ;
205
+ parser . _processToken ( token ) ;
205
206
}
206
207
207
- p . _processInputToken ( token ) ;
208
+ // Reset tokenizer:
209
+ // https://github.com/inikulin/parse5/blob/8b0048e/packages/parse5/lib/tokenizer/index.js#L215
210
+ tokenizer . currentToken = null ;
211
+ tokenizer . currentCharacterToken = null ;
212
+ tokenizer . currentAttr = null ;
208
213
}
209
214
}
210
215
211
216
function startTag ( node ) {
212
- var start = pos . start ( node ) ;
213
- var end = pos . end ( node ) ;
217
+ var location = createParse5Location ( node ) ;
218
+
219
+ location . startTag = xtend ( location ) ;
214
220
215
221
return {
216
222
type : START_TAG_TOKEN ,
217
223
tagName : node . tagName ,
218
224
selfClosing : false ,
219
225
attrs : attributes ( node ) ,
220
- location : {
221
- line : start . line ,
222
- col : start . column ,
223
- startOffset : start . offset ,
224
- endOffset : end . offset ,
225
- attrs : { } ,
226
- startTag : {
227
- line : start . line ,
228
- col : start . column ,
229
- startOffset : start . offset ,
230
- endOffset : end . offset
231
- }
232
- }
226
+ location : location
233
227
} ;
234
228
}
235
229
236
230
function attributes ( node ) {
237
- return toParse5 ( {
238
- type : 'element' ,
239
- properties : node . properties
240
- } ) . attrs ;
231
+ return toParse5 ( { type : 'element' , properties : node . properties } ) . attrs ;
241
232
}
242
233
243
234
function endTag ( node ) {
244
- var end = pos . end ( node ) ;
235
+ var location = createParse5Location ( node ) ;
236
+
237
+ location . endTag = xtend ( location ) ;
245
238
246
239
return {
247
240
type : END_TAG_TOKEN ,
248
241
tagName : node . tagName ,
249
242
attrs : [ ] ,
250
- location : {
251
- line : end . line ,
252
- col : end . column ,
253
- startOffset : end . offset ,
254
- endOffset : end . offset
255
- }
243
+ location : location
256
244
} ;
257
245
}
258
246
259
247
function unknown ( node ) {
260
248
throw new Error ( 'Cannot compile `' + node . type + '` node' ) ;
261
249
}
262
250
263
- function inferMode ( node ) {
251
+ function documentMode ( node ) {
264
252
var head = node . type === 'root' ? node . children [ 0 ] : node ;
265
253
266
- if ( head && ( head . type === 'doctype' || head . tagName === 'html' ) ) {
267
- return DOCUMENT ;
268
- }
254
+ return head && ( head . type === 'doctype' || head . tagName === 'html' ) ;
255
+ }
269
256
270
- return FRAGMENT ;
257
+ function createParse5Location ( node ) {
258
+ var start = pos . start ( node ) ;
259
+ var end = pos . end ( node ) ;
260
+
261
+ return {
262
+ startLine : start . line ,
263
+ startCol : start . column ,
264
+ startOffset : start . offset ,
265
+ endLine : end . line ,
266
+ endCol : end . column ,
267
+ endOffset : end . offset
268
+ } ;
271
269
}
0 commit comments