| 'use strict'; |
| |
| const sourceMapGenerator_js = require('source-map-js/lib/source-map-generator.js'); |
| |
| const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']); |
| |
| function generateSourceMap(handlers) { |
| const map = new sourceMapGenerator_js.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; |
| } |
| |
| exports.generateSourceMap = generateSourceMap; |