sourceMap.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use strict';
  2. var SourceMapGenerator = require('source-map').SourceMapGenerator;
  3. var trackNodes = {
  4. Atrule: true,
  5. Selector: true,
  6. Declaration: true
  7. };
  8. module.exports = function generateSourceMap(handlers) {
  9. var map = new SourceMapGenerator();
  10. var line = 1;
  11. var column = 0;
  12. var generated = {
  13. line: 1,
  14. column: 0
  15. };
  16. var original = {
  17. line: 0, // should be zero to add first mapping
  18. column: 0
  19. };
  20. var sourceMappingActive = false;
  21. var activatedGenerated = {
  22. line: 1,
  23. column: 0
  24. };
  25. var activatedMapping = {
  26. generated: activatedGenerated
  27. };
  28. var handlersNode = handlers.node;
  29. handlers.node = function(node) {
  30. if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
  31. var nodeLine = node.loc.start.line;
  32. var nodeColumn = node.loc.start.column - 1;
  33. if (original.line !== nodeLine ||
  34. original.column !== nodeColumn) {
  35. original.line = nodeLine;
  36. original.column = nodeColumn;
  37. generated.line = line;
  38. generated.column = column;
  39. if (sourceMappingActive) {
  40. sourceMappingActive = false;
  41. if (generated.line !== activatedGenerated.line ||
  42. generated.column !== activatedGenerated.column) {
  43. map.addMapping(activatedMapping);
  44. }
  45. }
  46. sourceMappingActive = true;
  47. map.addMapping({
  48. source: node.loc.source,
  49. original: original,
  50. generated: generated
  51. });
  52. }
  53. }
  54. handlersNode.call(this, node);
  55. if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
  56. activatedGenerated.line = line;
  57. activatedGenerated.column = column;
  58. }
  59. };
  60. var handlersChunk = handlers.chunk;
  61. handlers.chunk = function(chunk) {
  62. for (var i = 0; i < chunk.length; i++) {
  63. if (chunk.charCodeAt(i) === 10) { // \n
  64. line++;
  65. column = 0;
  66. } else {
  67. column++;
  68. }
  69. }
  70. handlersChunk(chunk);
  71. };
  72. var handlersResult = handlers.result;
  73. handlers.result = function() {
  74. if (sourceMappingActive) {
  75. map.addMapping(activatedMapping);
  76. }
  77. return {
  78. css: handlersResult(),
  79. map: map
  80. };
  81. };
  82. return handlers;
  83. };