Commit 615097b4 by Nick Schonning

Merge pull request #200 from arian/source-maps

Initial support for the new source map feature of libsass
parents ce2df81d aa10b5e9
...@@ -191,9 +191,17 @@ void MakeFileCallback(uv_work_t* req) { ...@@ -191,9 +191,17 @@ void MakeFileCallback(uv_work_t* req) {
if (ctx->error_status == 0) { if (ctx->error_status == 0) {
// if no error, do callback(null, result) // if no error, do callback(null, result)
const unsigned argc = 1; Handle<Value> source_map;
if (ctx->options.source_comments == SASS_SOURCE_COMMENTS_MAP) {
source_map = String::New(ctx->source_map_string);
} else {
source_map = Null();
}
const unsigned argc = 2;
Local<Value> argv[argc] = { Local<Value> argv[argc] = {
NanNewLocal(String::New(ctx->output_string)) NanNewLocal(String::New(ctx->output_string)),
NanNewLocal(source_map)
}; };
ctx_w->callback->Call(argc, argv); ctx_w->callback->Call(argc, argv);
...@@ -222,6 +230,7 @@ NAN_METHOD(RenderFile) { ...@@ -222,6 +230,7 @@ NAN_METHOD(RenderFile) {
Local<Function> callback = Local<Function>::Cast(args[1]); Local<Function> callback = Local<Function>::Cast(args[1]);
Local<Function> errorCallback = Local<Function>::Cast(args[2]); Local<Function> errorCallback = Local<Function>::Cast(args[2]);
String::AsciiValue bstr(args[3]); String::AsciiValue bstr(args[3]);
String::AsciiValue cstr(args[6]);
filename = new char[strlen(*astr)+1]; filename = new char[strlen(*astr)+1];
strcpy(filename, *astr); strcpy(filename, *astr);
...@@ -232,6 +241,10 @@ NAN_METHOD(RenderFile) { ...@@ -232,6 +241,10 @@ NAN_METHOD(RenderFile) {
ctx->options.output_style = args[4]->Int32Value(); ctx->options.output_style = args[4]->Int32Value();
ctx->options.image_path = new char[0]; ctx->options.image_path = new char[0];
ctx->options.source_comments = args[5]->Int32Value(); ctx->options.source_comments = args[5]->Int32Value();
if (ctx->options.source_comments == SASS_SOURCE_COMMENTS_MAP) {
ctx->source_map_file = new char[strlen(*cstr)+1];
strcpy(ctx->source_map_file, *cstr);
}
ctx_w->ctx = ctx; ctx_w->ctx = ctx;
ctx_w->callback = new NanCallback(callback); ctx_w->callback = new NanCallback(callback);
ctx_w->errorCallback = new NanCallback(errorCallback); ctx_w->errorCallback = new NanCallback(errorCallback);
......
...@@ -14,6 +14,9 @@ var optimist = require('optimist') ...@@ -14,6 +14,9 @@ var optimist = require('optimist')
describe: 'Include debug info in output (none|normal|map)', describe: 'Include debug info in output (none|normal|map)',
'default': 'none' 'default': 'none'
}) })
.options('source-map', {
describe: 'Emit source map'
})
.options('include-path', { .options('include-path', {
describe: 'Path to look for @import-ed files', describe: 'Path to look for @import-ed files',
'default': cwd 'default': cwd
...@@ -99,6 +102,16 @@ exports = module.exports = function(args) { ...@@ -99,6 +102,16 @@ exports = module.exports = function(args) {
options.sourceComments = options.sourceComments[0]; options.sourceComments = options.sourceComments[0];
} }
// set source map file and set sourceComments to 'map'
if (argv['source-map']) {
options.sourceComments = 'map';
if (argv['source-map'] === true) {
options.sourceMap = outFile + '.map';
} else {
options.sourceMap = path.resolve(cwd, argv['source-map']);
}
}
if (argv.w) { if (argv.w) {
var watchDir = argv.w; var watchDir = argv.w;
......
...@@ -9,7 +9,15 @@ function render(options, emitter) { ...@@ -9,7 +9,15 @@ function render(options, emitter) {
includePaths: options.includePaths, includePaths: options.includePaths,
outputStyle: options.outputStyle, outputStyle: options.outputStyle,
sourceComments: options.sourceComments, sourceComments: options.sourceComments,
success: function(css) { sourceMap: options.sourceMap,
success: function(css, sourceMap) {
var todo = 1;
var done = function() {
if (--todo <= 0) {
emitter.emit('done');
}
};
emitter.emit('warn', chalk.green('Rendering Complete, saving .css file...')); emitter.emit('warn', chalk.green('Rendering Complete, saving .css file...'));
...@@ -17,8 +25,19 @@ function render(options, emitter) { ...@@ -17,8 +25,19 @@ function render(options, emitter) {
if (err) { return emitter.emit('error', chalk.red('Error: ' + err)); } if (err) { return emitter.emit('error', chalk.red('Error: ' + err)); }
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.outFile)); emitter.emit('warn', chalk.green('Wrote CSS to ' + options.outFile));
emitter.emit('write', err, options.outFile, css); emitter.emit('write', err, options.outFile, css);
done();
}); });
if (options.sourceMap) {
todo++;
fs.writeFile(options.sourceMap, sourceMap, function(err) {
if (err) {return emitter.emit('error', chalk.red('Error' + err)); }
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, sourceMap);
done();
});
}
if (options.stdout) { if (options.stdout) {
emitter.emit('log', css); emitter.emit('log', css);
} }
......
...@@ -68,9 +68,8 @@ exports.render = function(options) { ...@@ -68,9 +68,8 @@ exports.render = function(options) {
options.error = options.error || function(){}; options.error = options.error || function(){};
if (options.file !== undefined && options.file !== null) { if (options.file !== undefined && options.file !== null) {
return binding.renderFile(options.file, options.success, options.error, newOptions.paths.join(path.delimiter), newOptions.style, newOptions.comments); return binding.renderFile(options.file, options.success, options.error, newOptions.paths.join(path.delimiter), newOptions.style, newOptions.comments, options.sourceMap);
} }
//Assume data is present if file is not. binding/libsass will tell the user otherwise! //Assume data is present if file is not. binding/libsass will tell the user otherwise!
return binding.render(options.data, options.success, options.error, newOptions.paths.join(path.delimiter), newOptions.style); return binding.render(options.data, options.success, options.error, newOptions.paths.join(path.delimiter), newOptions.style);
}; };
......
...@@ -103,4 +103,41 @@ describe('cli', function() { ...@@ -103,4 +103,41 @@ describe('cli', function() {
}); });
}); });
it('should compile with the --source-map option', function(done){
var emitter = cli([path.join(__dirname, 'sample.scss'), '--source-map']);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
assert.equal(file, path.join(__dirname, '../sample.css.map'));
fs.exists(file, function(exists) {
assert(exists);
});
});
emitter.on('done', function() {
fs.unlink(path.join(__dirname, '../sample.css.map'), function() {
fs.unlink(path.join(__dirname, '../sample.css'), function() {
done();
});
});
});
});
it('should compile with the --source-map option with specific filename', function(done){
var emitter = cli([path.join(__dirname, 'sample.scss'), '--source-map', path.join(__dirname, '../sample.map')]);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
assert.equal(file, path.join(__dirname, '../sample.map'));
fs.exists(file, function(exists) {
assert(exists);
});
});
emitter.on('done', function() {
fs.unlink(path.join(__dirname, '../sample.map'), function() {
fs.unlink(path.join(__dirname, '../sample.css'), function() {
done();
});
});
});
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment