| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 | 'use strict';var fs = require('fs');var path = require('path');var define = require('define-property');var utils = require('./utils');/** * Expose `mixin()`. * This code is based on `source-maps-support.js` in reworkcss/css * https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js * Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> */module.exports = mixin;/** * Mixin source map support into `compiler`. * * @param {Object} `compiler` * @api public */function mixin(compiler) {  define(compiler, '_comment', compiler.comment);  compiler.map = new utils.SourceMap.SourceMapGenerator();  compiler.position = { line: 1, column: 1 };  compiler.content = {};  compiler.files = {};  for (var key in exports) {    define(compiler, key, exports[key]);  }}/** * Update position. * * @param {String} str */exports.updatePosition = function(str) {  var lines = str.match(/\n/g);  if (lines) this.position.line += lines.length;  var i = str.lastIndexOf('\n');  this.position.column = ~i ? str.length - i : this.position.column + str.length;};/** * Emit `str` with `position`. * * @param {String} str * @param {Object} [pos] * @return {String} */exports.emit = function(str, node) {  var position = node.position || {};  var source = position.source;  if (source) {    if (position.filepath) {      source = utils.unixify(position.filepath);    }    this.map.addMapping({      source: source,      generated: {        line: this.position.line,        column: Math.max(this.position.column - 1, 0)      },      original: {        line: position.start.line,        column: position.start.column - 1      }    });    if (position.content) {      this.addContent(source, position);    }    if (position.filepath) {      this.addFile(source, position);    }    this.updatePosition(str);    this.output += str;  }  return str;};/** * Adds a file to the source map output if it has not already been added * @param {String} `file` * @param {Object} `pos` */exports.addFile = function(file, position) {  if (typeof position.content !== 'string') return;  if (Object.prototype.hasOwnProperty.call(this.files, file)) return;  this.files[file] = position.content;};/** * Adds a content source to the source map output if it has not already been added * @param {String} `source` * @param {Object} `position` */exports.addContent = function(source, position) {  if (typeof position.content !== 'string') return;  if (Object.prototype.hasOwnProperty.call(this.content, source)) return;  this.map.setSourceContent(source, position.content);};/** * Applies any original source maps to the output and embeds the source file * contents in the source map. */exports.applySourceMaps = function() {  Object.keys(this.files).forEach(function(file) {    var content = this.files[file];    this.map.setSourceContent(file, content);    if (this.options.inputSourcemaps === true) {      var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync);      if (originalMap) {        var map = new utils.SourceMap.SourceMapConsumer(originalMap.map);        var relativeTo = originalMap.sourcesRelativeTo;        this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo)));      }    }  }, this);};/** * Process comments, drops sourceMap comments. * @param {Object} node */exports.comment = function(node) {  if (/^# sourceMappingURL=/.test(node.comment)) {    return this.emit('', node.position);  }  return this._comment(node);};
 |