Commit 65619ba4 by Adeel

API: Returns result as `Buffer`s not string.

* CSS and Map is casted as Buffer from binding.
Advantages:
  * Buffers are super fast.
  * User can write them to file as is.
  * User can forward to response stream as is.
  * User can strigify it as is:
    * `result.css.toString()`
    * `result.map.toString()` or
      `JSON.stringify(result.map)`
* Updates tests and CLI usage accordingly.
* Updates README to reflect the changes.

Issue URL: #711.
PR URL: #729.
parent b04137d0
...@@ -157,21 +157,21 @@ Default: `false` ...@@ -157,21 +157,21 @@ Default: `false`
node-sass supports standard node style asynchronous callbacks with the signature of `function(err, result)`. In error conditions, the `error` argument is populated with the error object. In success conditions, the `result` object is populated with an object describing the result of the render call. node-sass supports standard node style asynchronous callbacks with the signature of `function(err, result)`. In error conditions, the `error` argument is populated with the error object. In success conditions, the `result` object is populated with an object describing the result of the render call.
### Error Object ### Error Object
* `message` - The error message. * `message` (String) - The error message.
* `line` - The line number of error. * `line` (Number) - The line number of error.
* `column` - The column number of error. * `column` (Number) - The column number of error.
* `status` - The status code. * `status` (Number) - The status code.
* `file` - The filename of error. In case `file` option was not set (in favour of `data`), this will reflect the value `stdin`. * `file` (String) - The filename of error. In case `file` option was not set (in favour of `data`), this will reflect the value `stdin`.
### Result Object ### Result Object
* `css` - The compiled CSS. Write this to a file, or serve it out as needed. * `css` (Buffer) - The compiled CSS. Write this to a file, or serve it out as needed.
* `map` - The source map * `map` (Buffer) - The source map
* `stats` - An object containing information about the compile. It contains the following keys: * `stats` (Object) - An object containing information about the compile. It contains the following keys:
* `entry` - The path to the scss file, or `data` if the source was not a file * `entry` (String) - The path to the scss file, or `data` if the source was not a file
* `start` - Date.now() before the compilation * `start` (Number) - Date.now() before the compilation
* `end` - Date.now() after the compilation * `end` (Number) - Date.now() after the compilation
* `duration` - *end* - *start* * `duration` (Number) - *end* - *start*
* `includedFiles` - Absolute paths to all related scss files in no particular order. * `includedFiles` (Array) - Absolute paths to all related scss files in no particular order.
### Examples ### Examples
...@@ -205,9 +205,9 @@ sass.render({ ...@@ -205,9 +205,9 @@ sass.render({
console.log(error.line); console.log(error.line);
} }
else { else {
console.log(result.css); console.log(result.css.toString());
console.log(result.stats); console.log(result.stats);
console.log(result.map); console.log(result.map.toString()); // or console.log(JSON.stringify(result.map));
} }
}); });
// OR // OR
......
...@@ -42,10 +42,10 @@ module.exports = function(options, emitter) { ...@@ -42,10 +42,10 @@ module.exports = function(options, emitter) {
}; };
if (!options.dest || options.stdin) { if (!options.dest || options.stdin) {
emitter.emit('log', result.css); emitter.emit('log', result.css.toString());
if (options.sourceMap) { if (options.sourceMap) {
emitter.emit('log', result.map); emitter.emit('log', result.map.toString());
} }
return done(); return done();
...@@ -58,13 +58,13 @@ module.exports = function(options, emitter) { ...@@ -58,13 +58,13 @@ module.exports = function(options, emitter) {
return emitter.emit('error', chalk.red(err)); return emitter.emit('error', chalk.red(err));
} }
fs.writeFile(options.dest, result.css, function(err) { fs.writeFile(options.dest, result.css.toString(), function(err) {
if (err) { if (err) {
return emitter.emit('error', chalk.red(err)); return emitter.emit('error', chalk.red(err));
} }
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.dest)); emitter.emit('warn', chalk.green('Wrote CSS to ' + options.dest));
emitter.emit('write', err, options.dest, result.css); emitter.emit('write', err, options.dest, result.css.toString());
done(); done();
}); });
}); });
...@@ -78,12 +78,12 @@ module.exports = function(options, emitter) { ...@@ -78,12 +78,12 @@ module.exports = function(options, emitter) {
} }
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap)); emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, result.sourceMap); emitter.emit('write-source-map', err, options.sourceMap, result.map);
done(); done();
}); });
} }
emitter.emit('render', result.css); emitter.emit('render', result.css.toString());
}; };
var error = function(error) { var error = function(error) {
......
...@@ -146,7 +146,7 @@ void extract_options(Local<Object> options, void* cptr, sass_context_wrapper* ct ...@@ -146,7 +146,7 @@ void extract_options(Local<Object> options, void* cptr, sass_context_wrapper* ct
sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w)); sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w));
} }
if(!is_file) { if (!is_file) {
sass_option_set_input_path(sass_options, create_string(options->Get(NanNew("file")))); sass_option_set_input_path(sass_options, create_string(options->Get(NanNew("file"))));
} }
...@@ -177,34 +177,22 @@ void get_stats(sass_context_wrapper* ctx_w, Sass_Context* ctx) { ...@@ -177,34 +177,22 @@ void get_stats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr); NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr);
} }
void get_source_map(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanScope();
Handle<Value> source_map;
if (sass_context_get_error_status(ctx)) {
return;
}
if (sass_context_get_source_map_string(ctx)) {
source_map = NanNew<String>(sass_context_get_source_map_string(ctx));
}
else {
source_map = NanNew<String>("{}");
}
NanNew(ctx_w->result)->Set(NanNew("map"), source_map);
}
int get_result(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) { int get_result(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
NanScope(); NanScope();
int status = sass_context_get_error_status(ctx); int status = sass_context_get_error_status(ctx);
if (status == 0) { if (status == 0) {
NanNew(ctx_w->result)->Set(NanNew("css"), NanNew<String>(sass_context_get_output_string(ctx))); const char* css = sass_context_get_output_string(ctx);
const char* map = sass_context_get_source_map_string(ctx);
NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, strlen(css)));
get_stats(ctx_w, ctx); get_stats(ctx_w, ctx);
get_source_map(ctx_w, ctx);
if (map) {
NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, strlen(map)));
}
} }
else if (is_sync) { else if (is_sync) {
NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx))); NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx)));
...@@ -233,7 +221,7 @@ void make_callback(uv_work_t* req) { ...@@ -233,7 +221,7 @@ void make_callback(uv_work_t* req) {
// if no error, do callback(null, result) // if no error, do callback(null, result)
ctx_w->success_callback->Call(0, 0); ctx_w->success_callback->Call(0, 0);
} }
else if(ctx_w->error_callback) { else if (ctx_w->error_callback) {
// if error, do callback(error) // if error, do callback(error)
const char* err = sass_context_get_error_json(ctx); const char* err = sass_context_get_error_json(ctx);
Local<Value> argv[] = { Local<Value> argv[] = {
......
...@@ -14,7 +14,7 @@ describe('api', function() { ...@@ -14,7 +14,7 @@ describe('api', function() {
sass.render({ sass.render({
file: fixture('simple/index.scss') file: fixture('simple/index.scss')
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
}); });
...@@ -59,7 +59,7 @@ describe('api', function() { ...@@ -59,7 +59,7 @@ describe('api', function() {
sass.render({ sass.render({
data: src data: src
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
}); });
...@@ -72,7 +72,7 @@ describe('api', function() { ...@@ -72,7 +72,7 @@ describe('api', function() {
data: src, data: src,
indentedSyntax: true indentedSyntax: true
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
}); });
...@@ -98,7 +98,7 @@ describe('api', function() { ...@@ -98,7 +98,7 @@ describe('api', function() {
fixture('include-path/lib') fixture('include-path/lib')
] ]
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
}); });
...@@ -132,7 +132,7 @@ describe('api', function() { ...@@ -132,7 +132,7 @@ describe('api', function() {
data: src, data: src,
precision: 10 precision: 10
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
}); });
...@@ -167,7 +167,7 @@ describe('api', function() { ...@@ -167,7 +167,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -182,7 +182,7 @@ describe('api', function() { ...@@ -182,7 +182,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -197,7 +197,7 @@ describe('api', function() { ...@@ -197,7 +197,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -212,7 +212,7 @@ describe('api', function() { ...@@ -212,7 +212,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -226,7 +226,7 @@ describe('api', function() { ...@@ -226,7 +226,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
}); });
...@@ -240,7 +240,7 @@ describe('api', function() { ...@@ -240,7 +240,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
}); });
...@@ -254,7 +254,7 @@ describe('api', function() { ...@@ -254,7 +254,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
}); });
...@@ -268,7 +268,7 @@ describe('api', function() { ...@@ -268,7 +268,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
}); });
...@@ -282,7 +282,7 @@ describe('api', function() { ...@@ -282,7 +282,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -296,7 +296,7 @@ describe('api', function() { ...@@ -296,7 +296,7 @@ describe('api', function() {
}); });
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -310,7 +310,7 @@ describe('api', function() { ...@@ -310,7 +310,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -324,7 +324,7 @@ describe('api', function() { ...@@ -324,7 +324,7 @@ describe('api', function() {
}; };
} }
}, function(error, result) { }, function(error, result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
}); });
...@@ -382,7 +382,7 @@ describe('api', function() { ...@@ -382,7 +382,7 @@ describe('api', function() {
var expected = read(fixture('simple/expected.css'), 'utf8').trim(); var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({ file: fixture('simple/index.scss') }); var result = sass.renderSync({ file: fixture('simple/index.scss') });
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
...@@ -424,19 +424,19 @@ describe('api', function() { ...@@ -424,19 +424,19 @@ describe('api', function() {
var expected = read(fixture('simple/expected.css'), 'utf8').trim(); var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({ data: src }); var result = sass.renderSync({ data: src });
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
it('should compile sass to css using indented syntax', function(done) { it('should compile sass to css using indented syntax', function(done) {
var src = read(fixture('indent/index.sass'), 'utf8'); var src = read(fixture('indent/index.sass'), 'utf8');
var expected = read(fixture('indent/expected.css'), 'utf8').trim(); var expected = read(fixture('indent/expected.css'), 'utf8').trim();
var css = sass.renderSync({ var result = sass.renderSync({
data: src, data: src,
indentedSyntax: true indentedSyntax: true
}).css.trim(); });
assert.equal(css, expected.replace(/\r\n/g, '\n')); assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
done(); done();
}); });
...@@ -463,7 +463,7 @@ describe('api', function() { ...@@ -463,7 +463,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
...@@ -478,7 +478,7 @@ describe('api', function() { ...@@ -478,7 +478,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
...@@ -492,7 +492,7 @@ describe('api', function() { ...@@ -492,7 +492,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
...@@ -506,7 +506,7 @@ describe('api', function() { ...@@ -506,7 +506,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), ''); assert.equal(result.css.toString().trim(), '');
done(); done();
}); });
...@@ -520,7 +520,7 @@ describe('api', function() { ...@@ -520,7 +520,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
...@@ -534,7 +534,7 @@ describe('api', function() { ...@@ -534,7 +534,7 @@ describe('api', function() {
} }
}); });
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done(); done();
}); });
......
...@@ -42,7 +42,7 @@ describe('spec', function() { ...@@ -42,7 +42,7 @@ describe('spec', function() {
includePaths: t.paths includePaths: t.paths
}, function(error, result) { }, function(error, result) {
assert(!error); assert(!error);
assert.equal(util.normalize(result.css), expected); assert.equal(util.normalize(result.css.toString()), expected);
done(); 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