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