dat.gui/utils/closure.js
George Michael Brower b9adfd5b02 0.5
2011-11-07 13:29:37 -08:00

108 lines
2.8 KiB
JavaScript

/// # Google Closure Compiler Service #
/// https://github.com/weaver/scribbles/blob/master/node/google-closure/lib/closure.js
/// Compress javascript with Node.js using the Closure Compiler
/// Service.
var sys = require('sys');
exports.compile = compile;
// Use the Google Closure Compiler Service to compress Javascript
// code.
//
// + code - String of javascript to compress
// + next - Function callback that accepts.
//
// This method will POST the `code` to the compiler service. If an
// error occurs, `next()` will be called with an `Error` object as the
// first argument. Otherwise, the `next()` will be called with `null`
// as the first argument and a String of compressed javascript as the
// second argument.
//
// compile('... javascript ...', function(err, result) {
// if (err) throw err;
//
// ... do something with result ...
// });
//
// Returns nothing.
function compile(code, next) {
try {
var qs = require('querystring'),
http = require('http'),
host = 'closure-compiler.appspot.com',
body = qs.stringify({
js_code: code.toString('utf-8'),
compilation_level: 'SIMPLE_OPTIMIZATIONS',
output_format: 'json',
output_info: 'compiled_code'
}),
client = http.createClient(80, host).on('error', next),
req = client.request('POST', '/compile', {
'Host': host,
'Content-Length': body.length,
'Content-Type': 'application/x-www-form-urlencoded'
});
req.on('error', next).end(body);
req.on('response', function(res) {
if (res.statusCode != 200)
next(new Error('Unexpected HTTP response: ' + res.statusCode));
else
capture(res, 'utf-8', parseResponse);
});
function parseResponse(err, data) {
err ? next(err) : loadJSON(data, function(err, obj) {
var error;
if (err)
next(err);
else if ((error = obj.errors || obj.serverErrors || obj.warnings))
next(new Error('Failed to compile: ' + sys.inspect(error)));
else
next(null, obj.compiledCode);
});
}
} catch (err) {
next(err);
}
}
// Convert a Stream to a String.
//
// + input - Stream object
// + encoding - String input encoding
// + next - Function error/success callback
//
// Returns nothing.
function capture(input, encoding, next) {
var buffer = '';
input.on('data', function(chunk) {
buffer += chunk.toString(encoding);
});
input.on('end', function() {
next(null, buffer);
});
input.on('error', next);
}
// Convert JSON.load() to callback-style.
//
// + data - String value to load
// + next - Function error/success callback
//
// Returns nothing.
function loadJSON(data, next) {
var err, obj;
try {
obj = JSON.parse(data);
} catch (x) {
err = x;
}
next(err, obj);
}