You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.5 KiB
92 lines
2.5 KiB
import { SourceMapGenerator } from 'source-map-js/lib/source-map-generator.js'; |
|
|
|
const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']); |
|
|
|
export function generateSourceMap(handlers) { |
|
const map = new SourceMapGenerator(); |
|
const generated = { |
|
line: 1, |
|
column: 0 |
|
}; |
|
const original = { |
|
line: 0, // should be zero to add first mapping |
|
column: 0 |
|
}; |
|
const activatedGenerated = { |
|
line: 1, |
|
column: 0 |
|
}; |
|
const activatedMapping = { |
|
generated: activatedGenerated |
|
}; |
|
let line = 1; |
|
let column = 0; |
|
let sourceMappingActive = false; |
|
|
|
const origHandlersNode = handlers.node; |
|
handlers.node = function(node) { |
|
if (node.loc && node.loc.start && trackNodes.has(node.type)) { |
|
const nodeLine = node.loc.start.line; |
|
const nodeColumn = node.loc.start.column - 1; |
|
|
|
if (original.line !== nodeLine || |
|
original.column !== nodeColumn) { |
|
original.line = nodeLine; |
|
original.column = nodeColumn; |
|
|
|
generated.line = line; |
|
generated.column = column; |
|
|
|
if (sourceMappingActive) { |
|
sourceMappingActive = false; |
|
if (generated.line !== activatedGenerated.line || |
|
generated.column !== activatedGenerated.column) { |
|
map.addMapping(activatedMapping); |
|
} |
|
} |
|
|
|
sourceMappingActive = true; |
|
map.addMapping({ |
|
source: node.loc.source, |
|
original, |
|
generated |
|
}); |
|
} |
|
} |
|
|
|
origHandlersNode.call(this, node); |
|
|
|
if (sourceMappingActive && trackNodes.has(node.type)) { |
|
activatedGenerated.line = line; |
|
activatedGenerated.column = column; |
|
} |
|
}; |
|
|
|
const origHandlersEmit = handlers.emit; |
|
handlers.emit = function(value, type, auto) { |
|
for (let i = 0; i < value.length; i++) { |
|
if (value.charCodeAt(i) === 10) { // \n |
|
line++; |
|
column = 0; |
|
} else { |
|
column++; |
|
} |
|
} |
|
|
|
origHandlersEmit(value, type, auto); |
|
}; |
|
|
|
const origHandlersResult = handlers.result; |
|
handlers.result = function() { |
|
if (sourceMappingActive) { |
|
map.addMapping(activatedMapping); |
|
} |
|
|
|
return { |
|
css: origHandlersResult(), |
|
map |
|
}; |
|
}; |
|
|
|
return handlers; |
|
};
|
|
|