allow lessc to load plugins. rename visitor directory to visitors to match others. Fix indexes in URL

This commit is contained in:
Luke Page
2014-09-09 21:20:04 +01:00
parent 1a78cd5901
commit e357dae7bc
19 changed files with 111 additions and 46 deletions

View File

@@ -5,7 +5,9 @@ var path = require('path'),
os = require('os'),
mkdirp;
var less = require('../lib/less-node');
var less = require('../lib/less-node'),
pluginManager = new less.PluginManager(less);
var args = process.argv.slice(1);
var options = {
depends: false,
@@ -251,9 +253,12 @@ args = args.filter(function (arg) {
}
break;
default:
require('../lib/less/lessc_helper').printUsage();
continueProcessing = false;
currentErrorcode = 1;
if (!pluginManager.interpretCommandLineArgument(arg, match[2])) {
// TODO more of an explanation
require('../lib/less/lessc_helper').printUsage();
continueProcessing = false;
currentErrorcode = 1;
}
break;
}
});
@@ -368,6 +373,7 @@ var parseLessFile = function (e, data) {
options.sourceMapFilename = options.sourceMap;
options.sourceMap = Boolean(options.sourceMap);
options.sourceMapRootpath = options.sourceMapRootpath || "";
options.plugins = pluginManager;
less.render(data, options)
.then(function(css) {

View File

@@ -1,17 +1,19 @@
var environment = require("./environment"),
createFromEnvironment = require("../less"),
less = createFromEnvironment(environment);
less = createFromEnvironment(environment),
lesscHelper = require('./lessc-helper');
// allow people to create less with their own environment
less.createFromEnvironment = createFromEnvironment;
less.lesscHelper = lesscHelper;
less.PluginManager = require("./node-plugin-manager");
less.formatError = function(ctx, options) {
options = options || {};
var message = "";
var extract = ctx.extract;
var error = [];
var stylize = options.color ? require('./lessc-helper').stylize : function (str) { return str; };
var stylize = options.color ? lesscHelper.stylize : function (str) { return str; };
// only output a stack if it isn't a less error
if (ctx.stack && !ctx.type) { return stylize(ctx.stack, 'red'); }

View File

@@ -0,0 +1,29 @@
var PluginManager = require("../less/plugin-manager");
/**
* Node Plugin Manager
*/
var NodePluginManager = function(less) {
PluginManager.call(this, less);
};
NodePluginManager.prototype = new PluginManager();
NodePluginManager.prototype.interpretCommandLineArgument = function(name, argument) {
var plugin = this.tryRequirePlugin(name);
if (plugin) {
this.addPlugin(plugin);
return true;
}
return false;
};
NodePluginManager.prototype.tryRequirePlugin = function(name) {
try {
return require("less-plugin-"+name);
}
catch(e) {
}
try {
return require("../../../less-plugin-"+name);
}
catch(e) {
}
};
module.exports = NodePluginManager;

View File

@@ -6,7 +6,7 @@ module.exports = function(environment) {
functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {
if (!environment.supportsDataURI(this.env)) {
return new URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env);
return new URL(filePathNode || mimetypeNode, this.index, this.currentFileInfo).eval(this.env);
}
var mimetype = mimetypeNode.value;
@@ -60,7 +60,7 @@ module.exports = function(environment) {
console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB);
}
return new URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env);
return new URL(filePathNode || mimetypeNode, this.index, this.currentFileInfo).eval(this.env);
}
}
@@ -68,6 +68,6 @@ module.exports = function(environment) {
: encodeURIComponent(buf);
var uri = "\"data:" + mimetype + ',' + buf + fragment + "\"";
return new(URL)(new(Anonymous)(uri));
return new URL(new Anonymous(uri), this.index, this.currentFileInfo);
});
};

View File

@@ -1,8 +1,9 @@
var functionRegistry = require("./function-registry");
var functionCaller = function(name, env, currentFileInfo) {
var functionCaller = function(name, env, index, currentFileInfo) {
this.name = name.toLowerCase();
this.function = functionRegistry.get(this.name);
this.index = index;
this.env = env;
this.currentFileInfo = currentFileInfo;
};

View File

@@ -78,6 +78,6 @@ module.exports = function(environment) {
}
returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'";
return new(URL)(new(Anonymous)(returner));
return new URL(new Anonymous(returner), this.index, this.currentFileInfo);
});
};

View File

@@ -3,12 +3,19 @@ module.exports = function(environment) {
version: [2, 0, 0],
data: require('./data'),
tree: require('./tree'),
visitor: require('./visitor'),
visitors: require('./visitors'),
Parser: require('./parser/parser'),
functions: require('./functions')(environment),
contexts: require("./contexts"),
environment: environment,
render: require("./render")(environment)
render: require("./render")(environment),
// ParseTree: require('./parse-tree'), // TODO - move environment to constructor? make available to consumers
//SourceMapOutput: require('./source-map-output.js'), // TODO - move environment to constructor? make available to consumers
getImportManager: require('./imports'), // TODO: change to class? add static ways of replacing file-manager?
LessError: require('./less-error'),
transformTree: require('./transform-tree'),
utils: require('./utils'),
PluginManager: require('./plugin-manager')
};
return less;

View File

@@ -1,6 +1,6 @@
var LessError = require('../less-error'),
tree = require("../tree"),
visitor = require("../visitor"),
visitors = require("../visitors"),
getParserInput = require("./parser-input"),
utils = require("../utils");
@@ -170,7 +170,7 @@ var Parser = function Parser(env, imports) {
};
if (env.processImports !== false) {
new visitor.ImportVisitor(imports, finish)
new visitors.ImportVisitor(imports, finish)
.run(root);
} else {
return finish();
@@ -381,7 +381,7 @@ var Parser = function Parser(env, imports) {
// to be enclosed within a string, so it can't be parsed as an Expression.
//
url: function () {
var value;
var value, index = parserInput.i;
if (parserInput.currentChar() !== 'u' || !parserInput.$re(/^url\(/)) {
return;
@@ -396,8 +396,8 @@ var Parser = function Parser(env, imports) {
expectChar(')');
return new(tree.URL)((value.value != null || value instanceof tree.Variable)
? value : new(tree.Anonymous)(value), env.currentFileInfo);
return new(tree.URL)((value.value != null || value instanceof tree.Variable) ?
value : new(tree.Anonymous)(value), index, env.currentFileInfo);
},
//

View File

@@ -0,0 +1,17 @@
/**
* Plugin Manager
*/
var PluginManager = function(less) {
this.less = less;
this.visitors = [];
};
PluginManager.prototype.addPlugin = function(plugin) {
plugin.install(this.less, this);
};
PluginManager.prototype.addVisitor = function(visitor) {
this.visitors.push(visitor);
};
PluginManager.prototype.getVisitors = function() {
return this.visitors;
};
module.exports = PluginManager;

View File

@@ -1,5 +1,5 @@
var contexts = require("./contexts"),
visitor = require("./visitor"),
visitor = require("./visitors"),
tree = require("./tree");
module.exports = function(root, options) {
@@ -44,14 +44,16 @@ module.exports = function(root, options) {
], i;
if (options.plugins) {
for(i =0; i < options.plugins.length; i++) {
if (options.plugins[i].isPreEvalVisitor) {
preEvalVisitors.push(options.plugins[i]);
var pluginVisitors = options.plugins.getVisitors();
for(i =0; i < pluginVisitors.length; i++) {
var pluginVisitor = pluginVisitors[i];
if (pluginVisitor.isPreEvalVisitor) {
preEvalVisitors.push(pluginVisitor);
} else {
if (options.plugins[i].isPreVisitor) {
visitors.splice(0, 0, options.plugins[i]);
if (pluginVisitor.isPreVisitor) {
visitors.splice(0, 0, pluginVisitor);
} else {
visitors.push(options.plugins[i]);
visitors.push(pluginVisitor);
}
}
}

View File

@@ -31,7 +31,7 @@ Call.prototype.accept = function (visitor) {
//
Call.prototype.eval = function (env) {
var args = this.args.map(function (a) { return a.eval(env); }),
result, funcCaller = new FunctionCaller(this.name, env, this.currentFileInfo);
result, funcCaller = new FunctionCaller(this.name, env, this.index, this.currentFileInfo);
if (funcCaller.isValid()) { // 1.
try {

View File

@@ -1,8 +1,9 @@
var Node = require("./node");
var URL = function (val, currentFileInfo, isEvald) {
var URL = function (val, index, currentFileInfo, isEvald) {
this.value = val;
this.currentFileInfo = currentFileInfo;
this.index = index;
this.isEvald = isEvald;
};
URL.prototype = new Node();
@@ -45,6 +46,6 @@ URL.prototype.eval = function (ctx) {
}
}
return new(URL)(val, this.currentFileInfo, true);
return new URL(val, this.index, this.currentFileInfo, true);
};
module.exports = URL;

View File

@@ -1,9 +0,0 @@
var visitors = {
Visitor: require("./visitor"),
ImportVisitor: require('./import-visitor.js'),
ExtendVisitor: require('./extend-visitor.js'),
JoinSelectorVisitor: require('./join-selector-visitor.js'),
ToCSSVisitor: require('./to-css-visitor.js')
};
module.exports = visitors;

View File

@@ -1,5 +1,5 @@
var tree = require("../tree/index.js"),
Visitor = require("./visitor.js");
var tree = require("../tree"),
Visitor = require("./visitor");
/*jshint loopfunc:true */

View File

@@ -1,5 +1,5 @@
var contexts = require("../contexts.js"),
Visitor = require("./visitor.js");
var contexts = require("../contexts"),
Visitor = require("./visitor");
var ImportVisitor = function(importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) {
this._visitor = new Visitor(this);

View File

@@ -0,0 +1,9 @@
var visitors = {
Visitor: require("./visitor"),
ImportVisitor: require('./import-visitor'),
ExtendVisitor: require('./extend-visitor'),
JoinSelectorVisitor: require('./join-selector-visitor'),
ToCSSVisitor: require('./to-css-visitor')
};
module.exports = visitors;

View File

@@ -1,4 +1,4 @@
var Visitor = require("./visitor.js");
var Visitor = require("./visitor");
var JoinSelectorVisitor = function() {
this.contexts = [[]];

View File

@@ -1,5 +1,5 @@
var tree = require("../tree/index.js"),
Visitor = require("./visitor.js");
var tree = require("../tree"),
Visitor = require("./visitor");
var ToCSSVisitor = function(env) {
this._visitor = new Visitor(this);

View File

@@ -1,4 +1,4 @@
var tree = require("../tree/index.js");
var tree = require("../tree");
var _visitArgs = { visitDeeper: true },
_hasIndexed = false;