Skip to content

Commit

Permalink
Pushing WIP of changes to file manager to track changes
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-dean committed Jun 8, 2017
1 parent ff5760e commit 9fd1ef5
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 110 deletions.
5 changes: 4 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

module.exports = function (grunt) {


grunt.option('stack', true)

// Report the elapsed execution time of tasks.
require('time-grunt')(grunt);

Expand Down Expand Up @@ -438,7 +441,7 @@ module.exports = function (grunt) {
'uglify:dist'
]);

// Release Rhino Version
// Release Rhino Version (UNSUPPORTED)
grunt.registerTask('rhino', [
'browserify:rhino',
'concat:rhino',
Expand Down
8 changes: 1 addition & 7 deletions lib/less-browser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@ module.exports = function(window, options) {
var typePattern = /^text\/(x-)?less$/;

function clone(obj) {
var cloned = {};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
cloned[prop] = obj[prop];
}
}
return cloned;
return JSON.parse(JSON.stringify(obj || {}));
}

// only really needed for phantom
Expand Down
126 changes: 87 additions & 39 deletions lib/less-node/file-manager.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
var path = require('path'),
fs = require('./fs'),
PromiseConstructor,
PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
AbstractFileManager = require("../less/environment/abstract-file-manager.js");

try {
PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
} catch (e) {
}

var FileManager = function() {
this.files = {};
};

FileManager.prototype = new AbstractFileManager();
Expand All @@ -20,46 +16,85 @@ FileManager.prototype.supportsSync = function(filename, currentDirectory, option
return true;
};

FileManager.prototype.loadFile = function(filename, currentDirectory, options, environment, callback) {
FileManager.prototype.loadFile = function(filename, currentDirectory, options, environment) {

// TODO refactor so isn't cut and paste between loadFileSync
var fullFilename,
data,
isAbsoluteFilename = this.isPathAbsolute(filename),
filenamesTried = [];
filenamesTried = [],
self = this,
prefix = filename.slice(0, 1),
explicit = prefix === "." || prefix === "/";

options = options || {};

if (options.syncImport || !PromiseConstructor) {
data = this.loadFileSync(filename, currentDirectory, options, environment, 'utf-8');
callback(data.error, data);
return;
}
var paths = isAbsoluteFilename ? [''] : [currentDirectory];

var paths = isAbsoluteFilename ? [""] : [currentDirectory];
if (options.paths) { paths.push.apply(paths, options.paths); }

// Search node_modules
if (!explicit) { paths.push.apply(paths, this.modulePaths); }

if (!isAbsoluteFilename && paths.indexOf('.') === -1) { paths.push('.'); }

var prefixes = options.prefixes || [''];
var fileParts = this.extractUrlParts(filename);

// promise is guaranteed to be asyncronous
// which helps as it allows the file handle
// to be closed before it continues with the next file
return new PromiseConstructor(function(fulfill, reject) {
if (options.syncImport) {
data = this.loadFileSync(filename, currentDirectory, options, environment, 'utf-8');
if (data.error) {
reject(data.error);
}
else {
fulfill(data);
}
return;
}
(function tryPathIndex(i) {
if (i < paths.length) {
fullFilename = filename;
if (paths[i]) {
fullFilename = path.join(paths[i], fullFilename);
}
fs.stat(fullFilename, function (err) {
if (err) {
filenamesTried.push(fullFilename);
tryPathIndex(i + 1);
} else {
fs.readFile(fullFilename, 'utf-8', function(e, data) {
if (e) { reject(e); return; }
(function tryPrefix(j) {
if (j < prefixes.length) {

fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename;

if (paths[i]) {
fullFilename = path.join(paths[i], fullFilename);
}
if (paths[i].indexOf('node_modules') > -1) {
try {
fullFilename = require.resolve(fullFilename);
}
catch (e) {}
}
else {
fullFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename;
}

if (self.files[fullFilename]) {
fulfill({ contents: self.files[fullFilename], filename: fullFilename});
}
else {

fs.readFile(fullFilename, 'utf-8', function(e, data) {
if (e) {
filenamesTried.push(fullFilename);
return tryPrefix(j + 1);
}
self.files[fullFilename] = data;
fulfill({ contents: data, filename: fullFilename});
});
}

fulfill({ contents: data, filename: fullFilename});
});
}
});
else {
tryPathIndex(i + 1);
}
})(0);
} else {
reject({ type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(",") });
}
Expand All @@ -79,26 +114,39 @@ FileManager.prototype.loadFileSync = function(filename, currentDirectory, option
paths.push('.');
}

var err, result;
var prefixes = options.prefixes || [''];
var fileParts = this.extractUrlParts(filename);

var err, result, breakAll = false;
for (var i = 0; i < paths.length; i++) {
try {
fullFilename = filename;
if (paths[i]) {
fullFilename = path.join(paths[i], fullFilename);
for (var j = 0; j < prefixes.length; j++) {
try {
fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename;
if (paths[i]) {
fullFilename = path.join(paths[i], fullFilename);
}
filenamesTried.push(fullFilename);
fs.statSync(fullFilename);
breakAll = true;
break;
} catch (e) {
fullFilename = null;
}
filenamesTried.push(fullFilename);
fs.statSync(fullFilename);
break;
} catch (e) {
fullFilename = null;
}
if (breakAll) { break; }
}

if (!fullFilename) {
err = { type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(",") };
result = { error: err };
} else {
data = fs.readFileSync(fullFilename, encoding);
if (this.files[fullFilename]) {
data = this.files[fullFilename];
}
else {
data = fs.readFileSync(fullFilename, encoding);
this.files[fullFilename] = data;
}
result = { contents: data, filename: fullFilename};
}

Expand Down
6 changes: 5 additions & 1 deletion lib/less-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ var environment = require("./environment"),
UrlFileManager = require("./url-file-manager"),
createFromEnvironment = require("../less"),
less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]),
lesscHelper = require('./lessc-helper');
lesscHelper = require('./lessc-helper'),
path = require('path');

// allow people to create less with their own environment
less.createFromEnvironment = createFromEnvironment;
Expand All @@ -13,6 +14,9 @@ less.fs = require("./fs");
less.FileManager = FileManager;
less.UrlFileManager = UrlFileManager;
less.options = require('../less/default-options');
less.options.paths = [
path.join(process.cwd(), "node_modules")
];

// provide image-size functionality
require('./image-size')(less.environment);
Expand Down
41 changes: 24 additions & 17 deletions lib/less-node/plugin-loader.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
var path = require("path"),
PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
AbstractPluginLoader = require("../less/environment/abstract-plugin-loader.js");

/**
* Node Plugin Loader
*/
var PluginLoader = function(less) {
this.less = less;
this.require = require;
this.requireRelative = function(prefix) {
this.require = function(prefix) {
prefix = path.dirname(prefix);
return function(id) {
var str = id.substr(0, 2);
Expand All @@ -23,24 +23,31 @@ var PluginLoader = function(less) {

PluginLoader.prototype = new AbstractPluginLoader();

PluginLoader.prototype.tryLoadPlugin = function(name, basePath, callback) {
PluginLoader.prototype.loadPlugin = function(filename, basePath, context, environment, fileManager) {
var self = this;
var prefix = name.slice(0, 1);
var explicit = prefix === "." || prefix === "/" || name.slice(-3).toLowerCase() === ".js";
if (explicit) {
this.tryLoadFromEnvironment(name, basePath, explicit, callback);
}
else {
this.tryLoadFromEnvironment('less-plugin-' + name, basePath, explicit, function(err, data) {
if (!err) {
callback(null, data);
}
else {
self.tryLoadFromEnvironment(name, basePath, explicit, callback);
}
});
var prefixes, prefix = filename.slice(0, 1);
var explicit = prefix === "." || prefix === "/" || filename.slice(-3).toLowerCase() === ".js";
if (!explicit) {
context.prefixes = ['less-plugin-', ''];
}

return fileManager.loadFile(filename, basePath, context, environment);
// return new PromiseConstructor(function(fulfill, reject) {
// fileManager.loadFile(filename, basePath, context, environment).then(
// function(data) {
// try {
// self.require = self.requireRelative(filename);
// fulfill(data);
// }
// catch (e) {
// reject(e);
// }
// }
// ).catch(function(err) {
// reject(err);
// });
// });

};

PluginLoader.prototype.tryLoadFromEnvironment = function(name, basePath, explicit, callback) {
Expand Down
25 changes: 12 additions & 13 deletions lib/less/environment/abstract-file-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba

var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
urlParts = url.match(urlPartsRegex),
returner = {}, directories = [], i, baseUrlParts;
returner = {}, rawDirectories = [], directories = [], i, d, baseUrlParts;

if (!urlParts) {
throw new Error("Could not parse sheet href - '" + url + "'");
Expand All @@ -95,26 +95,25 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
}

if (urlParts[3]) {
directories = urlParts[3].replace(/\\/g, "/").split("/");
rawDirectories = urlParts[3].replace(/\\/g, "/").split("/");

// extract out . before .. so .. doesn't absorb a non-directory
for (i = 0; i < directories.length; i++) {
if (directories[i] === ".") {
directories.splice(i, 1);
i -= 1;
}
}
// collapse '..' and skip '.'
for (d = 0, i = 0; i < rawDirectories.length; i++) {

for (i = 0; i < directories.length; i++) {
if (directories[i] === ".." && i > 0) {
directories.splice(i - 1, 2);
i -= 2;
if (rawDirectories[i] === ".." && d > 0) {
d -= 1;
}
else if (rawDirectories[i] !== ".") {
directories[d] = rawDirectories[i];
d++;
}

}
}

returner.hostPart = urlParts[1];
returner.directories = directories;
returner.rawPath = (urlParts[1] || "") + rawDirectories.join("/");
returner.path = (urlParts[1] || "") + directories.join("/");
returner.filename = urlParts[4];
returner.fileUrl = returner.path + (urlParts[4] || "");
Expand Down
Loading

0 comments on commit 9fd1ef5

Please sign in to comment.