Commit 69a45603 by Jakob Heuser

Adding a backwards compatible node-style callback

This is node-style callbacks for #676. This allows us to release
the new callback style without introducing backwards incompatible
changes (or making changes to the binary from 2.0.1). If a node style
callback is provided, it will be used. For now, this stacks with
the original `options.success` and `options.error`, although it can
be trivially changed to an xor.

To highlight the new interface, a separate `describe` was added to the
tests which identifies the `{options}, cb` interface and tests it
independently.
parent 92456685
......@@ -54,9 +54,8 @@ Compiling versions 0.9.4 and above on Windows machines requires [Visual Studio 2
var sass = require('node-sass');
sass.render({
file: scss_filename,
success: callback
[, options..]
});
}, function(err, result) { /*...*/ });
// OR
var result = sass.renderSync({
data: scss_content
......@@ -66,7 +65,7 @@ var result = sass.renderSync({
### Options
The API for using node-sass has changed, so that now there is only one variable - an options hash. Some of these options are optional, and in some circumstances some are mandatory.
The API for using node-sass has changed, so that now there is only one options hash. In the options hash, some items are optional, others may be mandatory depending on circumstances.
#### file
`file` is a `String` of the path to an `scss` file for [libsass] to render. One of this or `data` options are required, for both render and renderSync.
......@@ -140,6 +139,26 @@ You must define this option as well as `outFile` in order to generate a source m
#### sourceMapContents
`sourceMapContents` is a `Boolean` flag to determine whether to include `contents` in maps.
### The `render` Callback (starting from v2.1)
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.
#### The Error Object
* `message` - The error message.
* `line` - The line number of error.
* `column` - The column number of error.
* `status` - 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`.
#### The Result Object
* `css` - The compiled CSS. Write this to a file, or serve it out as needed.
* `map` - The source map
* `stats` - 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
* `start` - Date.now() before the compilation
* `end` - Date.now() after the compilation
* `duration` - *end* - *start*
* `includedFiles` - Absolute paths to all related scss files in no particular order.
### Examples
```javascript
......@@ -176,6 +195,10 @@ sass.render({
},
includePaths: [ 'lib/', 'mod/' ],
outputStyle: 'compressed'
}, function(error, result) {
// starting v2.1 the node-style callback has error (Object) and result (Object)
// the objects are identical to those provided for the error and success keys
// in the options object
});
// OR
var result = sass.renderSync({
......
......@@ -127,7 +127,7 @@ function getSourceMap(options) {
* @param {Object} options
* @api private
*/
function getOptions(options) {
function getOptions(options, cb) {
options = options || {};
options.comments = options.source_comments || options.sourceComments || false;
options.data = options.data || null;
......@@ -150,21 +150,30 @@ function getOptions(options) {
var success = options.success;
options.error = function(err) {
var payload = util._extend(new Error(), JSON.parse(err));
if (cb) {
cb.call(options.context, payload, null);
}
if (error) {
error.call(options.context, util._extend(new Error(), JSON.parse(err)));
error.call(options.context, payload);
}
};
options.success = function() {
var result = options.result;
var stats = endStats(result.stats);
if (success) {
success.call(options.context, {
var payload = {
css: result.css,
map: result.map,
stats: stats
});
};
if (cb) {
cb.call(options.context, null, payload);
}
if (success) {
success.call(options.context, payload);
}
};
......@@ -194,8 +203,8 @@ var binding = require(getBinding());
* @api public
*/
module.exports.render = function(options) {
options = getOptions(options);
module.exports.render = function(options, cb) {
options = getOptions(options, cb);
var importer = options.importer;
......@@ -243,7 +252,6 @@ module.exports.renderSync = function(options) {
if(status) {
result.stats = endStats(result.stats);
return result;
}
......
......@@ -411,6 +411,28 @@ describe('api', function() {
});
});
describe('.render(options, cb)', function() {
it('should compile sass to css with file', function(done) {
var expected = 'div {\n color: yellow; }';
sass.render({
data: 'div {color: yellow;}'
}, function(err, result) {
assert.equal(result.css.trim(), expected);
done();
});
});
it('should throw error status 1 for bad input', function(done) {
sass.render({
data: '#navbar width 80%;'
}, function(err) {
assert(err.message);
assert.equal(err.status, 1);
done();
});
});
});
describe('.renderSync(options)', function() {
it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
......
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