Skip to content

Commit

Permalink
Adding a backwards compatible node-style callback
Browse files Browse the repository at this point in the history
This is node-style callbacks for sass#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.
  • Loading branch information
thecodedrift committed Feb 20, 2015
1 parent 8c3bd77 commit 50fb92f
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 30 deletions.
63 changes: 42 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 are only two variables - an options hash and an optional callback beginning in v2.1. 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.
Expand All @@ -82,11 +81,11 @@ The callback function is passed a results object, containing the following keys:
* `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.
* `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.

#### error
`error` is a `Function` to be called upon occurrence of an error when rendering the scss to css. This option is optional, and only applies to the render function.
Expand Down Expand Up @@ -140,26 +139,33 @@ 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 callbacks with the signature of `function(err, result)`. In error conditions, the `err` 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
var sass = require('node-sass');
sass.render({
file: '/path/to/myFile.scss',
data: 'body{background:blue; a{color:black;}}',
success: function(result) {
// result is an object: v2 change
console.log(result.css);
console.log(result.stats);
console.log(result.map)
},
error: function(error) { // starting v2.1 error is an Error-typed object
// error is an object: v2 change
console.log(error.message);
console.log(error.status); // changed from code to status in v2.1
console.log(error.line);
console.log(error.column); // new in v2
},
importer: function(url, prev, done) {
// url is the path in import as is, which libsass encountered.
// prev is the previously resolved path.
Expand All @@ -176,6 +182,21 @@ sass.render({
},
includePaths: [ 'lib/', 'mod/' ],
outputStyle: 'compressed'
}, function(error, result) {
if (error) {
// starting v2.1 error is an Error-typed object
// error is an object: v2 change
console.log(error.message);
console.log(error.status); // changed from code to status in v2.1
console.log(error.line);
console.log(error.column); // new in v2
}
else if (result) {
// result is an object: v2 change
console.log(result.css);
console.log(result.stats);
console.log(result.map)
}
});
// OR
var result = sass.renderSync({
Expand Down
22 changes: 13 additions & 9 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -150,21 +150,25 @@ 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 (cb) {
cb.call(options.context, null, result);
}
if (success) {
success.call(options.context, {
css: result.css,
map: result.map,
stats: stats
});
success.call(options.context, result);
}
};

Expand Down Expand Up @@ -194,8 +198,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;

Expand Down
22 changes: 22 additions & 0 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,28 @@ describe('api', function() {
});
});

describe('.render(options, cb)', function() {
it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
sass.render({
file: fixture('simple/index.scss')
}, function(err, result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
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('.render(importer)', function() {
var src = read(fixture('include-files/index.scss'), 'utf8');

Expand Down

0 comments on commit 50fb92f

Please sign in to comment.