asynchronous import functionality! All tests passing.
This commit is contained in:
parent
ef97105ce3
commit
3253afad27
47
lib/less.js
47
lib/less.js
@ -1,10 +1,13 @@
|
|||||||
var path = require('path');
|
var path = require('path'),
|
||||||
|
fs = require('fs');
|
||||||
|
|
||||||
require.paths.unshift(__dirname);
|
require.paths.unshift(__dirname);
|
||||||
|
|
||||||
var less = {
|
var less = {
|
||||||
version: [2, 0, 0],
|
version: [2, 0, 0],
|
||||||
parser: require('less/parser').parser,
|
Parser: require('less/parser').Parser,
|
||||||
|
import: require('less/parser').import,
|
||||||
|
importer: require('less/parser').importer,
|
||||||
tree: require('less/tree')
|
tree: require('less/tree')
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -17,6 +20,46 @@ var less = {
|
|||||||
require(path.join('less', 'tree', n));
|
require(path.join('less', 'tree', n));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
less.Parser.importer = function (file, paths, callback) {
|
||||||
|
var pathname;
|
||||||
|
|
||||||
|
paths.unshift('.');
|
||||||
|
|
||||||
|
for (var i = 0; i < paths.length; i++) {
|
||||||
|
try {
|
||||||
|
pathname = path.join(paths[i], file);
|
||||||
|
fs.statSync(pathname);
|
||||||
|
break;
|
||||||
|
} catch (e) {
|
||||||
|
pathname = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
fs.stat(pathname, function (e, stats) {
|
||||||
|
if (e) process.stdio.writeError(e);
|
||||||
|
|
||||||
|
fs.open(pathname, process.O_RDONLY, stats.mode, function (e, fd) {
|
||||||
|
if (e) process.stdio.writeError(e);
|
||||||
|
|
||||||
|
fs.read(fd, stats.size, 0, "utf8", function (e, data) {
|
||||||
|
if (e) process.stdio.writeError(e);
|
||||||
|
|
||||||
|
new(less.Parser)({
|
||||||
|
paths: [path.dirname(pathname)]
|
||||||
|
}).parse(data, function (e, root) {
|
||||||
|
if (e) process.stdio.writeError(e);
|
||||||
|
callback(root);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
process.stdio.writeError("file '" + file + "' wasn't found.\n");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
require('less/functions');
|
require('less/functions');
|
||||||
require('ext/array');
|
require('ext/array');
|
||||||
|
|
||||||
|
@ -18,36 +18,36 @@ if (typeof(require) !== 'undefined') { var tree = require('less/tree') }
|
|||||||
// and when `this.eval` is called (during code-gen), we pass the
|
// and when `this.eval` is called (during code-gen), we pass the
|
||||||
// imported rules to the callback [1b].
|
// imported rules to the callback [1b].
|
||||||
//
|
//
|
||||||
// 2. The current file finishes parsing, and is evaluated before the import.
|
// 2. The current file finishes parsing before the import.
|
||||||
// In this case, the rules aren't available yet, so we save
|
// In this case, the rules aren't available yet, so we save
|
||||||
// the callback in `this.callback` [2b], which will be called when
|
// the callback in `this.callback` [2b], which will be called when
|
||||||
// the importer is done [2a].
|
// the importer is done [2a].
|
||||||
//
|
//
|
||||||
tree.Import = function Import(path, importer) {
|
tree.Import = function Import(path, import) {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
// The '.less' extension is optional
|
// The '.less' extension is optional
|
||||||
if (path instanceof tree.Quoted) {
|
if (path instanceof tree.Quoted) {
|
||||||
this.path = /\.le?ss$/.test(path.content) ? path.content : path.content + '.less';
|
this.path = /\.(le?|c)ss$/.test(path.content) ? path.content : path.content + '.less';
|
||||||
} else {
|
} else {
|
||||||
this.path = path.value;
|
this.path = path.value.content || path.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
importer(this.path, function (rules) {
|
import.push(this.path, function (root) {
|
||||||
if (this.callback) {
|
that.root = root; // 1a.
|
||||||
this.callback(rules); // 2a.
|
|
||||||
} else {
|
|
||||||
that.rules = rules; // 1a.
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
tree.Import.prototype = {
|
tree.Import.prototype = {
|
||||||
toCSS: function () { return "" },
|
toCSS: function () { return "" },
|
||||||
eval: function (callback) {
|
eval: function () {
|
||||||
if (this.rules) {
|
for (var i = 0; i < this.root.rules.length; i++) {
|
||||||
callback(this.rules); // 1b.
|
if (this.root.rules[i] instanceof tree.Import) {
|
||||||
} else {
|
Array.prototype
|
||||||
this.callback = callback; // 2b.
|
.splice
|
||||||
|
.apply(this.root.rules,
|
||||||
|
[i, 1].concat(this.root.rules[i].eval()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return this.root.rules;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,15 @@ tree.Ruleset.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { context = [], env = { frames: [] } }
|
} else {
|
||||||
|
context = [], env = { frames: [] }
|
||||||
|
for (var i = 0; i < this.rules.length; i++) {
|
||||||
|
if (this.rules[i] instanceof tree.Import) {
|
||||||
|
Array.prototype.splice
|
||||||
|
.apply(this.rules, [i, 1].concat(this.rules[i].eval(env)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// push the current ruleset to the frames stack
|
// push the current ruleset to the frames stack
|
||||||
env.frames.unshift(this);
|
env.frames.unshift(this);
|
||||||
|
8
test/css/import.css
vendored
8
test/css/import.css
vendored
@ -1,5 +1,9 @@
|
|||||||
#css { color: yellow; }
|
#css {
|
||||||
#import { color: red; }
|
color: yellow;
|
||||||
|
}
|
||||||
|
#import {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
.mixin {
|
.mixin {
|
||||||
height: 10px;
|
height: 10px;
|
||||||
color: red;
|
color: red;
|
||||||
|
2
test/less/import.less
vendored
2
test/less/import.less
vendored
@ -1,5 +1,5 @@
|
|||||||
@import url("import/import-test-a.less");
|
@import url("import/import-test-a.less");
|
||||||
@import url("import/import-test-a.less");
|
//@import url("import/import-test-a.less");
|
||||||
|
|
||||||
#import-test {
|
#import-test {
|
||||||
.mixin;
|
.mixin;
|
||||||
|
Loading…
Reference in New Issue
Block a user