Permalink
Browse files

Interim commit while changing stuff

  • Loading branch information...
1 parent d0f1372 commit eff389ca0a67ceead6501a80dc83bc2520ed791f @download13 committed May 4, 2012
Showing with 188 additions and 7 deletions.
  1. +30 −0 lib/minify-closure.js
  2. +6 −1 lib/source-build.js
  3. +4 −1 lib/source-package.js
  4. +132 −0 lib/sourcemap.js
  5. +13 −3 lib/write.js
  6. +1 −0 package.json
  7. +2 −2 resources/source-package.mustache
View
@@ -0,0 +1,30 @@
+var path = require('path');
+var fs = require('fs');
+var child_process = require('child_process');
+
+var supportpath = path.resolve(__dirname, '../support/');
+var jarpath = path.join(supportpath, 'closure.jar');
+var mappath = '_tmp_map'; // Should probably make use of that generateTempFile function
+var cmd = 'java -jar "' + jarpath + '" --compilation_level SIMPLE_OPTIMIZATIONS --create_source_map ' + mappath;
+
+// This needs some error handling and general cleanup
+function minify(source, cb) {
+ var child = child_process.exec(cmd);
+ var minified = '';
+
+ child.stdout.setEncoding('utf8');
+ child.stdout.on('data', function(data) {
+ minified += data;
+ });
+
+ child.on('exit', function() {
+ fs.readFile(mappath, 'utf8', function(err, mapdata) {
+ fs.unlink(mappath);
+ cb(null, minified, mapdata);
+ });
+ });
+
+ child.stdin.end(source);
+}
+
+exports.minify = minify;
View
@@ -32,7 +32,7 @@
var async = require('async')
, fs = require('fs')
- , minify = require('./minify')
+ , minify = require('./minify-closure')
, template = require('./template')
, argsParse = require('./args-parse')
, BuildParseError = require('./errors').BuildParseError
@@ -46,11 +46,16 @@ var async = require('async')
init: function (options) {
this.options = options
this.packages = []
+
+ this.sourcesMap = {};
+
return this
}
, addPackage: function (srcPackage) { // add a SourcePackage object for each package
this.packages.push(srcPackage)
+ srcPackage.asString()
+ this.sourcesMap[srcPackage.filename] = srcPackage.fileContents;
}
, asString: function (options, callback) {
@@ -81,6 +81,7 @@ var fs = require('fs')
// utility to read multiple files in order and append them
, loadFilesAsString: function (root, files, callback) {
+ var self = this;
if (!Array.isArray(files)) files = [ files ]
if (!files.length || (files.length == 1 && files[0] == 'noop')) return callback()
@@ -90,8 +91,10 @@ var fs = require('fs')
files
, function (file, callback) {
file = path.join(root, file).replace(/(\.js)?$/, '.js')
- fs.readFile(file, 'utf-8', function (err) {
+ fs.readFile(file, 'utf-8', function (err, contents) {
if (err) return callback(new FilesystemError(err))
+ self.filename = file;
+ self.fileContents = contents;
callback.apply(null, arguments)
})
}
View
@@ -0,0 +1,132 @@
+function SourceMap(data) {
+ data = JSON.parse(data);
+ this.sources = data.sources;
+ this.names = data.names;
+ this.version = data.version;
+ this.sourceRoot = data.sourceRoot;
+ this.file = data.file;
+
+ this.groups = data.mappings.split(';').map(function(group) {
+ return group.split(',').map(function(segment) {
+ segment = decodeVLQStr(segment);
+ var r = {};
+ for(var i = 0; i < segment.length; i++) {
+ r['field' + (i + 1)] = segment[i];
+ }
+ return r;
+ });
+ });
+}
+SourceMap.prototype = {
+ translate: function(offsetMap) {
+ var sources = this.sources = Object.keys(offsetMap);
+ var groups = this.groups;
+
+ for(var k = 0; k < groups.length; k++) {
+ var segments = groups[k];
+ for(var i = 0; i < segments.length; i++) {
+ var segment = segments[i];
+ var enderline = segment.field3;
+
+ for(var j = 0; j < sources.length; j++) {
+ var current = offsetMap[sources[j]];
+ var next = offsetMap[sources[j + 1]] || Infinity; // It had better match...
+
+ if(enderline >= current && enderline <= next) {
+ segment.field3 -= current;
+ segment.field2 = j;
+ }
+ }
+ }
+ }
+ },
+ serialize: function() {
+ var mappings = this.groups.map(function(group) {
+ return group.map(function(segment) {
+ var r = [];
+ var len = Object.keys(segment).length;
+ for(var i = 0; i < len; i++) {
+ r.push(segment['field' + (i + 1)]);
+ }
+ return encodeVLQArr(r);
+ }).join(',');
+ }).join(';');
+
+ return JSON.stringify({
+ version: this.version,
+ file: this.file,
+ sourceRoot: this.sourceRoot,
+ sources: this.sources,
+ names: this.names,
+ mappings: mappings
+ });
+ }
+}
+
+
+var iToB = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
+var bToI = {};
+iToB.forEach(function(v, i) {
+ bToI[v] = i;
+});
+
+function encodeVLQArr(values) {
+ return values.map(function(v) {
+ return encodeVLQ(v);
+ }).join('');
+}
+function encodeVLQ(aValue) {
+ var encoded = '';
+ var vlq = toVLQSigned(aValue);
+ var sign = aValue < 0 ? 1 : 0;
+
+ do {
+ var digit = vlq & 31; // Mask to first 5 bits
+ vlq >>>= 5; // Remove the first 5 bits
+ if(vlq > 0) {
+ digit |= 32; // Set sixth bit
+ }
+ encoded += iToB[digit];
+ } while(vlq > 0);
+
+ return encoded;
+}
+function toVLQSigned(aValue) {
+ return aValue < 0 ? ((-aValue) << 1) | 1 : (aValue << 1);
+}
+
+function decodeVLQStr(str) {
+ var r = [];
+ while(str.length > 0) {
+ var t = decodeVLQ(str);
+ r.push(t.value);
+ str = t.rest;
+ }
+ return r;
+}
+function decodeVLQ(aStr) {
+ var i = 0;
+ var result = 0;
+ var shift = 0;
+ var continuation;
+
+ do {
+ if(i >= aStr.length) {
+ throw new Error('Expected more digits in base 64 VLQ value.');
+ }
+
+ var digit = bToI[aStr[i++]];
+ continuation = digit >>> 5;
+ digit &= 31;
+ result |= digit << shift;
+ shift += 5;
+ } while(continuation);
+
+ return {value: fromVLQSigned(result), rest: aStr.slice(i)};
+}
+function fromVLQSigned(aValue) {
+ var shifted = aValue >>> 1;
+ return (aValue & 1) ? -shifted : shifted;
+}
+
+module.exports = SourceMap;
View
@@ -35,8 +35,18 @@ var fs = require('fs')
, util = require('./util')
, FilesystemError = require('./errors').FilesystemError
- , writeFile = function (file, callback, err, data) {
+ , writeFile = function (file, sourcesMap, callback, err, data, mapdata) {
if (err) return callback(err) // wrapped in source-build.js
+
+ var diff = require('diff');
+ var offsetMap = {}; // TODO: Where do I get this again?
+ for(var filename in sourcesMap) {
+ // TODO: mess around with diff to figure out how to apply it to this
+ }
+ var sm = new require('source-map')(mapdata);
+ sm.translate(offsetMap);
+ mapdata = sm.serialize();
+
fs.writeFile(file, data, 'utf-8', function (err) {
if (err) return callback(new FilesystemError(err))
callback.apply(null, arguments)
@@ -45,12 +55,12 @@ var fs = require('fs')
, writePlainFile = function (options, sourceBuild, out, callback) {
var filename = util.getOutputFilenameFromOptions(options)
- sourceBuild.asString({ type: 'plain' }, writeFile.bind(null, filename, callback))
+ sourceBuild.asString({ type: 'plain' }, writeFile.bind(null, filename, sourceBuild.sourcesMap, callback))
}
, writeMinifiedFile = function (options, sourceBuild, out, callback) {
var filename = util.getOutputFilenameFromOptions(options).replace(/(\.min)?\.js/, '.min.js')
- sourceBuild.asString({ type: 'minified' }, writeFile.bind(null, filename, callback))
+ sourceBuild.asString({ type: 'minified' }, writeFile.bind(null, filename, sourceBuild.sourcesMap, callback))
}
, write = function (options, sourceBuild, out, callback) {
View
@@ -23,6 +23,7 @@
, "colors-tmpl": ">= 0.0.3"
, "xregexp": ">= 1.5.3"
, "errno": ">= 0.0.1"
+ , "diff": ">= 1.0.3"
}
, "directories": {
"lib": "./lib"
@@ -4,14 +4,14 @@
var module = { exports: {} }, exports = module.exports;
{{#mainSource}}
-{{{indented}}}{{/mainSource}}
+{{{raw}}}{{/mainSource}}
provide("{{packageName}}", module.exports);
{{#options.sandbox}}
window["{{packageName}}"] = module.exports;
{{/options.sandbox}}{{#enderSource}}
-{{{indented}}}
+{{{raw}}}
{{/enderSource}}
{{^enderSource}}
$.ender(module.exports);

0 comments on commit eff389c

Please sign in to comment.