web 3d图形渲染器
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.

133 lines
2.9 KiB

  1. /**
  2. * Module dependencies.
  3. */
  4. var SourceMap = require('source-map').SourceMapGenerator;
  5. var SourceMapConsumer = require('source-map').SourceMapConsumer;
  6. var sourceMapResolve = require('source-map-resolve');
  7. var fs = require('fs');
  8. var path = require('path');
  9. /**
  10. * Expose `mixin()`.
  11. */
  12. module.exports = mixin;
  13. /**
  14. * Ensure Windows-style paths are formatted properly
  15. */
  16. const makeFriendlyPath = function(aPath) {
  17. return path.sep === "\\" ? aPath.replace(/\\/g, "/").replace(/^[a-z]:\/?/i, "/") : aPath;
  18. }
  19. /**
  20. * Mixin source map support into `compiler`.
  21. *
  22. * @param {Compiler} compiler
  23. * @api public
  24. */
  25. function mixin(compiler) {
  26. compiler._comment = compiler.comment;
  27. compiler.map = new SourceMap();
  28. compiler.position = { line: 1, column: 1 };
  29. compiler.files = {};
  30. for (var k in exports) compiler[k] = exports[k];
  31. }
  32. /**
  33. * Update position.
  34. *
  35. * @param {String} str
  36. * @api private
  37. */
  38. exports.updatePosition = function(str) {
  39. var lines = str.match(/\n/g);
  40. if (lines) this.position.line += lines.length;
  41. var i = str.lastIndexOf('\n');
  42. this.position.column = ~i ? str.length - i : this.position.column + str.length;
  43. };
  44. /**
  45. * Emit `str`.
  46. *
  47. * @param {String} str
  48. * @param {Object} [pos]
  49. * @return {String}
  50. * @api private
  51. */
  52. exports.emit = function(str, pos) {
  53. if (pos) {
  54. var sourceFile = makeFriendlyPath(pos.source || 'source.css');
  55. this.map.addMapping({
  56. source: sourceFile,
  57. generated: {
  58. line: this.position.line,
  59. column: Math.max(this.position.column - 1, 0)
  60. },
  61. original: {
  62. line: pos.start.line,
  63. column: pos.start.column - 1
  64. }
  65. });
  66. this.addFile(sourceFile, pos);
  67. }
  68. this.updatePosition(str);
  69. return str;
  70. };
  71. /**
  72. * Adds a file to the source map output if it has not already been added
  73. * @param {String} file
  74. * @param {Object} pos
  75. */
  76. exports.addFile = function(file, pos) {
  77. if (typeof pos.content !== 'string') return;
  78. if (Object.prototype.hasOwnProperty.call(this.files, file)) return;
  79. this.files[file] = pos.content;
  80. };
  81. /**
  82. * Applies any original source maps to the output and embeds the source file
  83. * contents in the source map.
  84. */
  85. exports.applySourceMaps = function() {
  86. Object.keys(this.files).forEach(function(file) {
  87. var content = this.files[file];
  88. this.map.setSourceContent(file, content);
  89. if (this.options.inputSourcemaps !== false) {
  90. var originalMap = sourceMapResolve.resolveSync(
  91. content, file, fs.readFileSync);
  92. if (originalMap) {
  93. var map = new SourceMapConsumer(originalMap.map);
  94. var relativeTo = originalMap.sourcesRelativeTo;
  95. this.map.applySourceMap(map, file, makeFriendlyPath(path.dirname(relativeTo)));
  96. }
  97. }
  98. }, this);
  99. };
  100. /**
  101. * Process comments, drops sourceMap comments.
  102. * @param {Object} node
  103. */
  104. exports.comment = function(node) {
  105. if (/^# sourceMappingURL=/.test(node.comment))
  106. return this.emit('', node.position);
  107. else
  108. return this._comment(node);
  109. };