1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | 'use strict';
|
11 |
|
12 | var through = require('through2'),
|
13 | gutil = require('gulp-util'),
|
14 | extend = require('xtend'),
|
15 | BufferStreams = require('bufferstreams'),
|
16 | espower = require('espower'),
|
17 | espowerSource = require('espower-source'),
|
18 | esprima = require('esprima'),
|
19 | escodegen = require('escodegen'),
|
20 | applySourceMap = require('vinyl-sourcemaps-apply'),
|
21 | transfer = require('multi-stage-sourcemap').transfer,
|
22 | convert = require('convert-source-map');
|
23 |
|
24 | function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
|
25 | if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
|
26 | outgoingSourceMap = JSON.parse(outgoingSourceMap);
|
27 | }
|
28 | if (!incomingSourceMap) {
|
29 | return outgoingSourceMap;
|
30 | }
|
31 | return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
|
32 | }
|
33 |
|
34 | function transform (file, encoding, opt) {
|
35 | var inMap = file.sourceMap;
|
36 | var escodegenOptions = {};
|
37 | var jsCode = file.contents.toString(encoding);
|
38 |
|
39 |
|
40 | var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: file.relative});
|
41 |
|
42 | var espowerOptions = extend(espower.defaultOptions(), opt, {
|
43 | destructive: true,
|
44 | path: file.path
|
45 | });
|
46 | if (inMap) {
|
47 | espowerOptions.sourceMap = inMap;
|
48 | escodegenOptions = extend(escodegenOptions, {
|
49 | file: file.relative,
|
50 | sourceMap: true,
|
51 |
|
52 |
|
53 | sourceMapWithCode: true
|
54 | });
|
55 | }
|
56 | var modifiedAst = espower(jsAst, espowerOptions);
|
57 | var escodegenOutput = escodegen.generate(modifiedAst, escodegenOptions);
|
58 | if (inMap) {
|
59 | file.contents = new Buffer(escodegenOutput.code);
|
60 | var outMap = convert.fromJSON(escodegenOutput.map.toString());
|
61 | outMap.setProperty('sources', inMap.sources);
|
62 | outMap.setProperty('sourcesContent', inMap.sourcesContent);
|
63 |
|
64 | var reMap;
|
65 | if (inMap.mappings === '') {
|
66 | applySourceMap(file, outMap.toJSON());
|
67 | reMap = convert.fromObject(file.sourceMap);
|
68 | } else {
|
69 | reMap = convert.fromObject(mergeSourceMap(inMap, outMap.toJSON()));
|
70 | }
|
71 | reMap.setProperty('sources', inMap.sources);
|
72 | reMap.setProperty('sourcesContent', inMap.sourcesContent);
|
73 |
|
74 |
|
75 |
|
76 | file.sourceMap = reMap.toObject();
|
77 | } else {
|
78 | file.contents = new Buffer(escodegenOutput);
|
79 | }
|
80 | }
|
81 |
|
82 | module.exports = function (opt) {
|
83 | return through.obj(function (file, encoding, callback) {
|
84 | encoding = encoding || 'utf8';
|
85 | if (file.isNull()) {
|
86 | this.push(file);
|
87 | } else if (file.isBuffer()) {
|
88 | try {
|
89 | transform(file, encoding, opt);
|
90 | this.push(file);
|
91 | } catch (err) {
|
92 | return callback(new gutil.PluginError('gulp-espoewr', err, {showStack: true}));
|
93 | }
|
94 | } else if (file.isStream()) {
|
95 | file.contents = file.contents.pipe(new BufferStreams(function(err, buf, cb) {
|
96 | if(err) {
|
97 | cb(new gutil.PluginError('gulp-espower', err, {showStack: true}));
|
98 | } else {
|
99 | cb(null, new Buffer(espowerSource(buf.toString(encoding), file.path, opt)));
|
100 | }
|
101 | }));
|
102 | this.push(file);
|
103 | }
|
104 | callback();
|
105 | });
|
106 | };
|