Projekt

Obecné

Profil

Stáhnout (3.52 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict';
2
3
var fs = require('fs');
4
var path = require('path');
5
var define = require('define-property');
6
var utils = require('./utils');
7
8
/**
9
 * Expose `mixin()`.
10
 * This code is based on `source-maps-support.js` in reworkcss/css
11
 * https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js
12
 * Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
13
 */
14
15
module.exports = mixin;
16
17
/**
18
 * Mixin source map support into `compiler`.
19
 *
20
 * @param {Object} `compiler`
21
 * @api public
22
 */
23
24
function mixin(compiler) {
25
  define(compiler, '_comment', compiler.comment);
26
  compiler.map = new utils.SourceMap.SourceMapGenerator();
27
  compiler.position = { line: 1, column: 1 };
28
  compiler.content = {};
29
  compiler.files = {};
30
31
  for (var key in exports) {
32
    define(compiler, key, exports[key]);
33
  }
34
}
35
36
/**
37
 * Update position.
38
 *
39
 * @param {String} str
40
 */
41
42
exports.updatePosition = function(str) {
43
  var lines = str.match(/\n/g);
44
  if (lines) this.position.line += lines.length;
45
  var i = str.lastIndexOf('\n');
46
  this.position.column = ~i ? str.length - i : this.position.column + str.length;
47
};
48
49
/**
50
 * Emit `str` with `position`.
51
 *
52
 * @param {String} str
53
 * @param {Object} [pos]
54
 * @return {String}
55
 */
56
57
exports.emit = function(str, node) {
58
  var position = node.position || {};
59
  var source = position.source;
60
  if (source) {
61
    if (position.filepath) {
62
      source = utils.unixify(position.filepath);
63
    }
64
65
    this.map.addMapping({
66
      source: source,
67
      generated: {
68
        line: this.position.line,
69
        column: Math.max(this.position.column - 1, 0)
70
      },
71
      original: {
72
        line: position.start.line,
73
        column: position.start.column - 1
74
      }
75
    });
76
77
    if (position.content) {
78
      this.addContent(source, position);
79
    }
80
    if (position.filepath) {
81
      this.addFile(source, position);
82
    }
83
84
    this.updatePosition(str);
85
    this.output += str;
86
  }
87
  return str;
88
};
89
90
/**
91
 * Adds a file to the source map output if it has not already been added
92
 * @param {String} `file`
93
 * @param {Object} `pos`
94
 */
95
96
exports.addFile = function(file, position) {
97
  if (typeof position.content !== 'string') return;
98
  if (Object.prototype.hasOwnProperty.call(this.files, file)) return;
99
  this.files[file] = position.content;
100
};
101
102
/**
103
 * Adds a content source to the source map output if it has not already been added
104
 * @param {String} `source`
105
 * @param {Object} `position`
106
 */
107
108
exports.addContent = function(source, position) {
109
  if (typeof position.content !== 'string') return;
110
  if (Object.prototype.hasOwnProperty.call(this.content, source)) return;
111
  this.map.setSourceContent(source, position.content);
112
};
113
114
/**
115
 * Applies any original source maps to the output and embeds the source file
116
 * contents in the source map.
117
 */
118
119
exports.applySourceMaps = function() {
120
  Object.keys(this.files).forEach(function(file) {
121
    var content = this.files[file];
122
    this.map.setSourceContent(file, content);
123
124
    if (this.options.inputSourcemaps === true) {
125
      var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync);
126
      if (originalMap) {
127
        var map = new utils.SourceMap.SourceMapConsumer(originalMap.map);
128
        var relativeTo = originalMap.sourcesRelativeTo;
129
        this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo)));
130
      }
131
    }
132
  }, this);
133
};
134
135
/**
136
 * Process comments, drops sourceMap comments.
137
 * @param {Object} node
138
 */
139
140
exports.comment = function(node) {
141
  if (/^# sourceMappingURL=/.test(node.comment)) {
142
    return this.emit('', node.position);
143
  }
144
  return this._comment(node);
145
};