mirror of
https://github.com/less/less.js.git
synced 2026-04-09 03:00:20 -04:00
start abstracting out the file loader
This commit is contained in:
103
lib/less/environments/node.js
Normal file
103
lib/less/environments/node.js
Normal file
@@ -0,0 +1,103 @@
|
||||
var path = require('path'),
|
||||
url = require('url'),
|
||||
request,
|
||||
fs = require('fs'),
|
||||
isUrlRe = /^(?:https?:)?\/\//i;
|
||||
|
||||
module.exports = {
|
||||
warn: function(env, msg) {
|
||||
console.warn(msg);
|
||||
},
|
||||
getPath: function (env, filename) {
|
||||
var j = filename.lastIndexOf('/');
|
||||
if (j < 0) {
|
||||
j = filename.lastIndexOf('\\');
|
||||
}
|
||||
if (j < 0) {
|
||||
return "";
|
||||
}
|
||||
return filename.slice(0, j + 1);
|
||||
},
|
||||
isPathAbsolute: function(env, filename) {
|
||||
return /^(?:[a-z-]+:|\/|\\)/.test(filename);
|
||||
},
|
||||
loadFile: function(env, filename, currentDirectory, callback) {
|
||||
var fullFilename,
|
||||
data,
|
||||
isUrl = isUrlRe.test( filename );
|
||||
|
||||
if (isUrl || isUrlRe.test(currentDirectory)) {
|
||||
if (request === undefined) {
|
||||
try { request = require('request'); }
|
||||
catch(e) { request = null; }
|
||||
}
|
||||
if (!request) {
|
||||
callback({ type: 'File', message: "optional dependency 'request' required to import over http(s)\n" });
|
||||
return;
|
||||
}
|
||||
|
||||
var urlStr = isUrl ? filename : url.resolve(currentDirectory, filename);
|
||||
|
||||
request.get({uri: urlStr, strictSSL: !env.insecure }, function (error, res, body) {
|
||||
if (res.statusCode === 404) {
|
||||
callback({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
|
||||
return;
|
||||
}
|
||||
if (!body) {
|
||||
this.warn( env, 'Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"');
|
||||
}
|
||||
if (error) {
|
||||
callback({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n "+ error +"\n" });
|
||||
}
|
||||
fullFilename = urlStr;
|
||||
callback(null, body, fullFilename);
|
||||
});
|
||||
} else {
|
||||
|
||||
var paths = [currentDirectory].concat(env.paths);
|
||||
paths.push('.');
|
||||
|
||||
if (env.syncImport) {
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
try {
|
||||
fullFilename = path.join(paths[i], filename);
|
||||
fs.statSync(fullFilename);
|
||||
break;
|
||||
} catch (e) {
|
||||
fullFilename = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fullFilename) {
|
||||
callback({ type: 'File', message: "'" + filename + "' wasn't found" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
data = fs.readFileSync(fullFilename, 'utf-8');
|
||||
callback(null, data, fullFilename);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
} else {
|
||||
(function tryPathIndex(i) {
|
||||
if (i < paths.length) {
|
||||
fullFilename = path.join(paths[i], filename);
|
||||
fs.stat(fullFilename, function (err) {
|
||||
if (err) {
|
||||
tryPathIndex(i + 1);
|
||||
} else {
|
||||
fs.readFile(fullFilename, 'utf-8', function(e, data) {
|
||||
if (e) { callback(e); }
|
||||
callback(null, data, fullFilename);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback({ type: 'File', message: "'" + filename + "' wasn't found" });
|
||||
}
|
||||
}(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,8 +1,3 @@
|
||||
var path = require('path'),
|
||||
url = require('url'),
|
||||
request,
|
||||
fs = require('fs');
|
||||
|
||||
var less = {
|
||||
version: [1, 6, 3],
|
||||
Parser: require('./parser').Parser,
|
||||
@@ -123,20 +118,21 @@ require('./tree/negative');
|
||||
require('./tree/extend');
|
||||
require('./tree/ruleset-call');
|
||||
|
||||
less.Parser.environment = require("./environments/node");
|
||||
|
||||
var isUrlRe = /^(?:https?:)?\/\//i;
|
||||
|
||||
less.Parser.fileLoader = function (file, currentFileInfo, callback, env) {
|
||||
var pathname, dirname, data,
|
||||
newFileInfo = {
|
||||
less.Parser.fileLoader = function (filename, currentFileInfo, callback, env) {
|
||||
var newFileInfo = {
|
||||
relativeUrls: env.relativeUrls,
|
||||
entryPath: currentFileInfo.entryPath,
|
||||
rootpath: currentFileInfo.rootpath,
|
||||
rootFilename: currentFileInfo.rootFilename
|
||||
};
|
||||
|
||||
function handleDataAndCallCallback(data) {
|
||||
var j = file.lastIndexOf('/');
|
||||
|
||||
function handleDataAndCallCallback(e, data, resolvedFilename) {
|
||||
if (e) {
|
||||
callback(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass on an updated rootpath if path of imported file is relative and file
|
||||
// is in a (sub|sup) directory
|
||||
@@ -146,92 +142,17 @@ less.Parser.fileLoader = function (file, currentFileInfo, callback, env) {
|
||||
// then rootpath should become 'less/module/nav/'
|
||||
// - If path of imported file is '../mixins.less' and rootpath is 'less/',
|
||||
// then rootpath should become 'less/../'
|
||||
if(newFileInfo.relativeUrls && !/^(?:[a-z-]+:|\/)/.test(file) && j != -1) {
|
||||
var relativeSubDirectory = file.slice(0, j+1);
|
||||
newFileInfo.rootpath = newFileInfo.rootpath + relativeSubDirectory; // append (sub|sup) directory path of imported file
|
||||
var originalRelativePath = less.Parser.environment.getPath(env, filename);
|
||||
if(newFileInfo.relativeUrls && !less.Parser.environment.isPathAbsolute(env, filename) && originalRelativePath) {
|
||||
newFileInfo.rootpath = newFileInfo.rootpath + originalRelativePath; // append (sub|sup) directory path of imported file
|
||||
}
|
||||
newFileInfo.currentDirectory = pathname.replace(/[^\\\/]*$/, "");
|
||||
newFileInfo.filename = pathname;
|
||||
newFileInfo.currentDirectory = less.Parser.environment.getPath(env, resolvedFilename);
|
||||
newFileInfo.filename = resolvedFilename;
|
||||
|
||||
callback(null, data, pathname, newFileInfo);
|
||||
callback(null, data, resolvedFilename, newFileInfo); //TODO adjust callback
|
||||
}
|
||||
|
||||
var isUrl = isUrlRe.test( file );
|
||||
if (isUrl || isUrlRe.test(currentFileInfo.currentDirectory)) {
|
||||
if (request === undefined) {
|
||||
try { request = require('request'); }
|
||||
catch(e) { request = null; }
|
||||
}
|
||||
if (!request) {
|
||||
callback({ type: 'File', message: "optional dependency 'request' required to import over http(s)\n" });
|
||||
return;
|
||||
}
|
||||
|
||||
var urlStr = isUrl ? file : url.resolve(currentFileInfo.currentDirectory, file),
|
||||
urlObj = url.parse(urlStr);
|
||||
|
||||
request.get({uri: urlStr, strictSSL: !env.insecure }, function (error, res, body) {
|
||||
if (res.statusCode === 404) {
|
||||
callback({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
|
||||
return;
|
||||
}
|
||||
if (!body) {
|
||||
console.error( 'Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"' );
|
||||
}
|
||||
if (error) {
|
||||
callback({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n "+ error +"\n" });
|
||||
}
|
||||
pathname = urlStr;
|
||||
dirname = urlObj.protocol +'//'+ urlObj.host + urlObj.pathname.replace(/[^\/]*$/, '');
|
||||
handleDataAndCallCallback(body);
|
||||
});
|
||||
} else {
|
||||
|
||||
var paths = [currentFileInfo.currentDirectory].concat(env.paths);
|
||||
paths.push('.');
|
||||
|
||||
if (env.syncImport) {
|
||||
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) {
|
||||
callback({ type: 'File', message: "'" + file + "' wasn't found" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
data = fs.readFileSync(pathname, 'utf-8');
|
||||
handleDataAndCallCallback(data);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
}
|
||||
} else {
|
||||
(function tryPathIndex(i) {
|
||||
if (i < paths.length) {
|
||||
pathname = path.join(paths[i], file);
|
||||
fs.stat(pathname, function (err) {
|
||||
if (err) {
|
||||
tryPathIndex(i + 1);
|
||||
} else {
|
||||
fs.readFile(pathname, 'utf-8', function(e, data) {
|
||||
if (e) { callback(e); }
|
||||
handleDataAndCallCallback(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback({ type: 'File', message: "'" + file + "' wasn't found" });
|
||||
}
|
||||
}(0));
|
||||
}
|
||||
}
|
||||
less.Parser.environment.loadFile(env, filename, currentFileInfo.currentDirectory, handleDataAndCallCallback);
|
||||
};
|
||||
|
||||
require('./env');
|
||||
@@ -244,4 +165,4 @@ require('./join-selector-visitor.js');
|
||||
require('./to-css-visitor.js');
|
||||
require('./source-map-output.js');
|
||||
|
||||
for (var k in less) { if (less.hasOwnProperty(k)) { exports[k] = less[k]; }}
|
||||
module.exports = less;
|
||||
Reference in New Issue
Block a user