From 39c6aa65f319058938ba74e99e898b9c156f2b90 Mon Sep 17 00:00:00 2001 From: rjgotten Date: Thu, 26 Feb 2015 13:32:28 +0100 Subject: [PATCH] Make @import (plugin) environment-dependant Shifts some logic around and extends some of the management classes in such a way that plugins loaded via an `@import (plugin) "..."` declaration are only loaded in environments that have support for loading plugins. (i.e. Node.js) --- lib/less-node/plugin-loader.js | 22 ++++++++++++++ lib/less/environment/abstract-file-manager.js | 5 +++- lib/less/import-manager.js | 30 ++++++++++--------- lib/less/plugin-manager.js | 12 ++++++++ 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/lib/less-node/plugin-loader.js b/lib/less-node/plugin-loader.js index 29b28376..48b60781 100644 --- a/lib/less-node/plugin-loader.js +++ b/lib/less-node/plugin-loader.js @@ -5,6 +5,28 @@ var path = require("path"); var PluginLoader = function(less) { this.less = less; }; +PluginLoader.prototype.tryImportPlugin = function(resolvedFileName) { + var plugin; + try { + plugin = require(resolvedFileName); + if (plugin) { + // support plugins being a function + // so that the plugin can be more usable programmatically + if (typeof plugin === "function") { + plugin = new plugin(); + } + if (plugin.minVersion) { + if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + console.log("plugin " + name + " requires version " + this.versionToString(plugin.minVersion)); + return null; + } + } + return plugin; + } + } catch(e) {} + + return null; +}; PluginLoader.prototype.tryLoadPlugin = function(name, argument) { var plugin = this.tryRequirePlugin(name); if (plugin) { diff --git a/lib/less/environment/abstract-file-manager.js b/lib/less/environment/abstract-file-manager.js index 96b93283..9a04462d 100644 --- a/lib/less/environment/abstract-file-manager.js +++ b/lib/less/environment/abstract-file-manager.js @@ -15,9 +15,12 @@ abstractFileManager.prototype.getPath = function (filename) { } return filename.slice(0, j + 1); }; +abstractFileManager.prototype.tryAppendExtension = function(path, ext) { + return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext; +} abstractFileManager.prototype.tryAppendLessExtension = function(path) { - return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + '.less'; + return this.tryAppendExtension(path, '.less'); }; abstractFileManager.prototype.supportsSync = function() { diff --git a/lib/less/import-manager.js b/lib/less/import-manager.js index eac052e1..8f67210d 100644 --- a/lib/less/import-manager.js +++ b/lib/less/import-manager.js @@ -64,7 +64,21 @@ module.exports = function(environment) { return; } - if (tryAppendLessExtension && !importOptions.plugin) { + if (importOptions.plugin) { + path = fileManager.tryAppendExtension(path, '.js'); + var resolvedFilename = !fileManager.isPathAbsolute(path) + ? fileManager.join(currentFileInfo.currentDirectory, path) + : path; + try { + this.context.pluginManager.importPlugin(resolvedFilename); + fileParsedFunc(null, "", resolvedFilename); + } catch(e) { + fileParsedFunc(e, "", resolvedFilename); + } + return; + } + + if (tryAppendLessExtension) { path = fileManager.tryAppendLessExtension(path); } @@ -101,19 +115,7 @@ module.exports = function(environment) { newFileInfo.reference = true; } - if (importOptions.plugin) { - try { - var plugin = require(resolvedFilename); - - if ( -1 === newEnv.pluginManager.installedPlugins.indexOf( plugin )) { - newEnv.pluginManager.addPlugin(plugin); - } - fileParsedFunc(null, "", resolvedFilename); - } catch(e) { - fileParsedFunc(e, "", resolvedFilename); - } - - } else if (importOptions.inline) { + if (importOptions.inline) { fileParsedFunc(null, contents, resolvedFilename); } else { new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { diff --git a/lib/less/plugin-manager.js b/lib/less/plugin-manager.js index 8f6df7c7..c6973e42 100644 --- a/lib/less/plugin-manager.js +++ b/lib/less/plugin-manager.js @@ -9,6 +9,18 @@ var PluginManager = function(less) { this.installedPlugins = []; this.fileManagers = []; }; +/** + * Attempts to load a plugin from a resolved file name + * @param {String} fileName + */ +PluginManager.prototype.importPlugin = function(fileName) { + var Loader = this.less.PluginLoader, + plugin = Loader && new Loader( this.less ).tryImportPlugin(fileName); + + if (plugin && (-1 === this.installedPlugins.indexOf(plugin))) { + this.addPlugin(plugin); + } +}; /** * Adds all the plugins in the array * @param {Array} plugins