22
33var information = require ( 'property-information' ) ;
44var camelcase = require ( 'camelcase' ) ;
5- var vfileLocation = require ( 'vfile-location' ) ;
65var h = require ( 'hastscript' ) ;
6+ var xtend = require ( 'xtend' ) ;
7+ var count = require ( 'ccount' ) ;
78
89module . exports = wrapper ;
910
@@ -32,7 +33,6 @@ function wrapper(ast, options) {
3233
3334 return transform ( ast , {
3435 file : file ,
35- toPosition : file ? vfileLocation ( file ) . toPosition : null ,
3636 verbose : settings . verbose ,
3737 location : false
3838 } ) ;
@@ -43,20 +43,20 @@ function transform(ast, config) {
4343 var fn = own . call ( map , ast . nodeName ) ? map [ ast . nodeName ] : element ;
4444 var children ;
4545 var node ;
46- var position ;
46+ var pos ;
4747
4848 if ( ast . childNodes ) {
4949 children = nodes ( ast . childNodes , config ) ;
5050 }
5151
5252 node = fn ( ast , children , config ) ;
5353
54- if ( ast . __location && config . toPosition ) {
55- config . location = true ;
56- position = location ( ast . __location , ast , node , config ) ;
54+ if ( ast . sourceCodeLocation && config . file ) {
55+ pos = location ( node , ast . sourceCodeLocation , config . verbose ) ;
5756
58- if ( position ) {
59- node . position = position ;
57+ if ( pos ) {
58+ config . location = true ;
59+ node . position = pos ;
6060 }
6161 }
6262
@@ -79,25 +79,18 @@ function nodes(children, config) {
7979/* Transform a document.
8080 * Stores `ast.quirksMode` in `node.data.quirksMode`. */
8181function root ( ast , children , config ) {
82- var quirks = ast . mode === 'quirks' || ast . mode === 'limited-quirks' ;
83- var node = { type : 'root' , children : children } ;
84- var position ;
85-
86- node . data = { quirksMode : quirks } ;
82+ var node = { type : 'root' , children : children , data : { } } ;
83+ var doc ;
8784
88- if ( ast . __location ) {
89- if ( config . toPosition ) {
90- config . location = true ;
91- position = ast . __location ;
92- }
93- } else if ( config . file && config . location ) {
94- position = { startOffset : 0 , endOffset : String ( config . file ) . length } ;
95- }
85+ node . data . quirksMode = ast . mode === 'quirks' || ast . mode === 'limited-quirks' ;
9686
97- position = position && location ( position , ast , node , config ) ;
87+ if ( config . file && config . location ) {
88+ doc = String ( config . file ) ;
9889
99- if ( position ) {
100- node . position = position ;
90+ node . position = {
91+ start : { line : 1 , column : 1 , offset : 0 } ,
92+ end : { line : count ( doc , '\n' ) + 1 , column : doc . length - doc . lastIndexOf ( '\n' ) , offset : doc . length }
93+ } ;
10194 }
10295
10396 return node ;
@@ -131,7 +124,9 @@ function element(ast, children, config) {
131124 var index = - 1 ;
132125 var attr ;
133126 var node ;
134- var fragment ;
127+ var pos ;
128+ var start ;
129+ var end ;
135130
136131 while ( ++ index < length ) {
137132 attr = values [ index ] ;
@@ -141,74 +136,65 @@ function element(ast, children, config) {
141136 node = h ( ast . tagName , props , children ) ;
142137
143138 if ( ast . nodeName === 'template' && 'content' in ast ) {
144- fragment = ast . content ;
145-
146- if ( ast . __location ) {
147- fragment . __location = {
148- startOffset : ast . __location . startTag . endOffset ,
149- endOffset : ast . __location . endTag . startOffset
150- } ;
151- }
139+ pos = ast . sourceCodeLocation ;
140+ start = pos && pos . startTag && position ( pos . startTag ) . end ;
141+ end = pos && pos . endTag && position ( pos . endTag ) . start ;
152142
153143 node . content = transform ( ast . content , config ) ;
144+
145+ if ( ( start || end ) && config . file ) {
146+ node . content . position = { start : start , end : end } ;
147+ }
154148 }
155149
156150 return node ;
157151}
158152
159153/* Create clean positional information. */
160- function loc ( toPosition , dirty ) {
161- return {
162- start : toPosition ( dirty . startOffset ) ,
163- end : toPosition ( dirty . endOffset )
164- } ;
165- }
166-
167- /* Create clean positional information. */
168- function location ( info , ast , node , config ) {
169- var start = info . startOffset ;
170- var end = info . endOffset ;
171- var values = info . attrs || { } ;
172- var propPositions = { } ;
154+ function location ( node , location , verbose ) {
155+ var pos = position ( location ) ;
156+ var reference ;
157+ var values ;
158+ var props ;
173159 var prop ;
174160 var name ;
175- var reference ;
176-
177- for ( prop in values ) {
178- name = ( information ( prop ) || { } ) . propertyName || camelcase ( prop ) ;
179- propPositions [ name ] = loc ( config . toPosition , values [ prop ] ) ;
180- }
181161
182- /* Upstream: https://github.com/inikulin/parse5/issues/109 */
183- if ( node . type === 'element' && ! info . endTag ) {
162+ if ( node . type === 'element' ) {
184163 reference = node . children [ node . children . length - 1 ] ;
185164
186- /* Unclosed with children: */
187- if ( reference && reference . position ) {
188- if ( reference . position . end ) {
189- end = reference . position . end . offset ;
190- } else {
191- end = null ;
192- }
165+ /* Unclosed with children (upstream: https://github.com/inikulin/parse5/issues/109) */
166+ if ( ! location . endTag && reference && reference . position && reference . position . end ) {
167+ pos . end = xtend ( reference . position . end ) ;
193168 }
194- }
195169
196- if ( config . verbose && node . type === 'element' ) {
197- node . data = {
198- position : {
199- opening : loc ( config . toPosition , info . startTag ) ,
200- closing : info . endTag ? loc ( config . toPosition , info . endTag ) : null ,
201- properties : propPositions
170+ if ( verbose ) {
171+ values = location . attrs ;
172+ props = { } ;
173+
174+ for ( prop in values ) {
175+ name = ( information ( prop ) || { } ) . propertyName || camelcase ( prop ) ;
176+ props [ name ] = position ( values [ prop ] ) ;
202177 }
203- } ;
178+
179+ node . data = {
180+ position : {
181+ opening : position ( location . startTag ) ,
182+ closing : location . endTag ? position ( location . endTag ) : null ,
183+ properties : props
184+ }
185+ } ;
186+ }
204187 }
205188
206- start = typeof start === 'number' ? config . toPosition ( start ) : null ;
207- end = typeof end === 'number' ? config . toPosition ( end ) : null ;
189+ return pos ;
190+ }
208191
209- if ( ! start && ! end ) {
210- return undefined ;
211- }
192+ function position ( loc ) {
193+ var start = point ( { line : loc . startLine , column : loc . startCol , offset : loc . startOffset } ) ;
194+ var end = point ( { line : loc . endLine , column : loc . endCol , offset : loc . endOffset } ) ;
195+ return start || end ? { start : start , end : end } : null ;
196+ }
212197
213- return { start : start , end : end } ;
198+ function point ( point ) {
199+ return point . line && point . column ? point : null ;
214200}
0 commit comments