@@ -253,19 +253,31 @@ export function parse(
253
253
}
254
254
}
255
255
256
+ // dedent pug/jade templates
257
+ let templateColumnOffset = 0
258
+ if (
259
+ descriptor . template &&
260
+ ( descriptor . template . lang === 'pug' || descriptor . template . lang === 'jade' )
261
+ ) {
262
+ ; [ descriptor . template . content , templateColumnOffset ] = dedent (
263
+ descriptor . template . content
264
+ )
265
+ }
266
+
256
267
if ( sourceMap ) {
257
- const genMap = ( block : SFCBlock | null ) => {
268
+ const genMap = ( block : SFCBlock | null , columnOffset = 0 ) => {
258
269
if ( block && ! block . src ) {
259
270
block . map = generateSourceMap (
260
271
filename ,
261
272
source ,
262
273
block . content ,
263
274
sourceRoot ,
264
- ! pad || block . type === 'template' ? block . loc . start . line - 1 : 0
275
+ ! pad || block . type === 'template' ? block . loc . start . line - 1 : 0 ,
276
+ columnOffset
265
277
)
266
278
}
267
279
}
268
- genMap ( descriptor . template )
280
+ genMap ( descriptor . template , templateColumnOffset )
269
281
genMap ( descriptor . script )
270
282
descriptor . styles . forEach ( genMap )
271
283
descriptor . customBlocks . forEach ( genMap )
@@ -369,7 +381,8 @@ function generateSourceMap(
369
381
source : string ,
370
382
generated : string ,
371
383
sourceRoot : string ,
372
- lineOffset : number
384
+ lineOffset : number ,
385
+ columnOffset : number
373
386
) : RawSourceMap {
374
387
const map = new SourceMapGenerator ( {
375
388
file : filename . replace ( / \\ / g, '/' ) ,
@@ -386,7 +399,7 @@ function generateSourceMap(
386
399
source : filename ,
387
400
original : {
388
401
line : originalLine ,
389
- column : i
402
+ column : i + columnOffset
390
403
} ,
391
404
generated : {
392
405
line : generatedLine ,
@@ -466,3 +479,31 @@ export function hmrShouldReload(
466
479
467
480
return false
468
481
}
482
+
483
+ /**
484
+ * Dedent a string.
485
+ *
486
+ * This removes any whitespace that is common to all lines in the string from
487
+ * each line in the string.
488
+ */
489
+ function dedent ( s : string ) : [ string , number ] {
490
+ const lines = s . split ( '\n' )
491
+ const minIndent = lines . reduce ( function ( minIndent , line ) {
492
+ if ( line . trim ( ) === '' ) {
493
+ return minIndent
494
+ }
495
+ const indent = line . match ( / ^ \s * / ) ?. [ 0 ] ?. length || 0
496
+ return Math . min ( indent , minIndent )
497
+ } , Infinity )
498
+ if ( minIndent === 0 ) {
499
+ return [ s , minIndent ]
500
+ }
501
+ return [
502
+ lines
503
+ . map ( function ( line ) {
504
+ return line . slice ( minIndent )
505
+ } )
506
+ . join ( '\n' ) ,
507
+ minIndent
508
+ ]
509
+ }
0 commit comments