[Pkg-javascript-commits] [less.js] 142/285: Pull out the file manager aspect of the environment so new file managers can be added dynamically

Jonas Smedegaard dr at jones.dk
Mon Oct 26 23:23:48 UTC 2015


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag v2.0.0
in repository less.js.

commit 7a6b1e278b5a81ae6ca984e2d04c6146464162b0
Author: Luke Page <luke.a.page at gmail.com>
Date:   Sat Oct 4 17:46:30 2014 +0100

    Pull out the file manager aspect of the environment so new file managers can be added dynamically
---
 bin/lessc                                     |   1 -
 lib/less-browser/browser-import.js            | 137 +++++++++++++++++
 lib/less-browser/environment.js               | 203 +------------------------
 lib/less-browser/index.js                     |  44 +++---
 lib/less-node/environment.js                  | 204 --------------------------
 lib/less-node/file-import.js                  |  79 ++++++++++
 lib/less-node/index.js                        |   7 +-
 lib/less-node/url-import.js                   |  52 +++++++
 lib/less/contexts.js                          |   3 +-
 lib/less/environment/abstract-file-manager.js | 111 ++++++++++++++
 lib/less/environment/api.js                   |  23 +++
 lib/less/environment/environment.js           |  36 +++++
 lib/less/functions/data-uri.js                |  37 ++---
 lib/less/imports.js                           |  92 ++++++------
 lib/less/index.js                             |  12 +-
 lib/less/parser/parser.js                     |   1 -
 lib/less/source-map-builder.js                |   4 +-
 lib/less/tree/import.js                       |   1 -
 18 files changed, 551 insertions(+), 496 deletions(-)

diff --git a/bin/lessc b/bin/lessc
index c170d00..afb75c3 100755
--- a/bin/lessc
+++ b/bin/lessc
@@ -281,7 +281,6 @@ if (options.sourceMap) {
         // make the sourcemap filename point to the sourcemap relative to the css file output directory
         sourceMapOptions.sourceMapFilename = path.join(
             path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename));
-        console.log(sourceMapOptions.sourceMapFile);
     }
 }
 
diff --git a/lib/less-browser/browser-import.js b/lib/less-browser/browser-import.js
new file mode 100644
index 0000000..5a5ec3f
--- /dev/null
+++ b/lib/less-browser/browser-import.js
@@ -0,0 +1,137 @@
+/*global window, XMLHttpRequest */
+
+module.exports = function(options, isFileProtocol, log, logLevel) {
+
+var PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
+    AbstractFileManager = require("../less/environment/abstract-file-manager.js");
+
+var fileCache = {};
+
+//TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
+//        isFileProtocol is global
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) {
+        return new XMLHttpRequest();
+    } else {
+        try {
+            /*global ActiveXObject */
+            return new ActiveXObject("Microsoft.XMLHTTP");
+        } catch (e) {
+            log("browser doesn't support AJAX.", logLevel.errors);
+            return null;
+        }
+    }
+};
+
+var BrowserImport = function() {
+};
+
+BrowserImport.prototype = new AbstractFileManager();
+
+BrowserImport.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() {
+    return true;
+};
+BrowserImport.prototype.join = function (url, baseUrl) {
+    // diff between two paths to create a relative path
+
+    var urlParts = this.extractUrlParts(url),
+        baseUrlParts = this.extractUrlParts(baseUrl),
+        i, max, urlDirectories, baseUrlDirectories, diff = "";
+    if (urlParts.hostPart !== baseUrlParts.hostPart) {
+        return "";
+    }
+    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
+    for(i = 0; i < max; i++) {
+        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
+    }
+    baseUrlDirectories = baseUrlParts.directories.slice(i);
+    urlDirectories = urlParts.directories.slice(i);
+    for(i = 0; i < baseUrlDirectories.length-1; i++) {
+        diff += "../";
+    }
+    for(i = 0; i < urlDirectories.length-1; i++) {
+        diff += urlDirectories[i] + "/";
+    }
+    return diff;
+};
+BrowserImport.prototype.doXHR = function doXHR(url, type, callback, errback) {
+
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? options.fileAsync : options.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    log("XHR: Getting '" + url + "'", logLevel.debug);
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+
+    if (isFileProtocol && !options.fileAsync) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+};
+BrowserImport.prototype.supports = function(filename, currentDirectory, options, environment) {
+    return true;
+};
+
+BrowserImport.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment) {
+    return new PromiseConstructor(function(fullfill, reject) {
+        if (currentDirectory && !this.isPathAbsolute(filename)) {
+            filename = currentDirectory + filename;
+        }
+
+        options = options || {};
+
+        // sheet may be set to the stylesheet for the initial load or a collection of properties including
+        // some env variables for imports
+        var hrefParts = this.extractUrlParts(filename, window.location.href);
+        var href      = hrefParts.url;
+
+        if (options.useFileCache && fileCache[href]) {
+            try {
+                var lessText = fileCache[href];
+                fullfill({ content: lessText, filename: href, webInfo: { lastModified: new Date() }});
+            } catch (e) {
+                reject({filename: href, message: "Error loading file " + href + " error was " + e.message});
+            }
+            return;
+        }
+
+        this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
+            // per file cache
+            fileCache[href] = data;
+
+            // Use remote copy (re-parse)
+            fullfill({ content: data, filename: href, webInfo: { lastModified: lastModified }});
+        }, function doXHRError(status, url) {
+            reject({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", filename: href });
+        });
+    }.bind(this));
+};
+
+
+return new BrowserImport();
+};
diff --git a/lib/less-browser/environment.js b/lib/less-browser/environment.js
index 5f65bd4..6adc7d6 100644
--- a/lib/less-browser/environment.js
+++ b/lib/less-browser/environment.js
@@ -1,206 +1,5 @@
-/*global window, XMLHttpRequest */
-
-module.exports = function(options, isFileProtocol, log, logLevel) {
-
-var fileCache = {};
-
-//TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
-//        isFileProtocol is global
-
-function getXMLHttpRequest() {
-    if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) {
-        return new XMLHttpRequest();
-    } else {
-        try {
-            /*global ActiveXObject */
-            return new ActiveXObject("Microsoft.XMLHTTP");
-        } catch (e) {
-            log("browser doesn't support AJAX.", logLevel.errors);
-            return null;
-        }
-    }
-}
-
-return {
-    // make generic but overriddable
+module.exports = {
     warn: function warn(msg) {
         console.warn(msg);
-    },
-    // make generic but overriddable
-    getPath: function getPath(filename) {
-        var j = filename.lastIndexOf('/');
-        if (j < 0) {
-            j = filename.lastIndexOf('\\');
-        }
-        if (j < 0) {
-            return "";
-        }
-        return filename.slice(0, j + 1);
-    },
-    // make generic but overriddable
-    isPathAbsolute: function isPathAbsolute(filename) {
-        return /^(?:[a-z-]+:|\/|\\)/i.test(filename);
-    },
-    alwaysMakePathsAbsolute: function alwaysMakePathsAbsolute() {
-        return true;
-    },
-    supportsDataURI: function() {
-        return false;
-    },
-    pathDiff: function pathDiff(url, baseUrl) {
-        // diff between two paths to create a relative path
-
-        var urlParts = this.extractUrlParts(url),
-            baseUrlParts = this.extractUrlParts(baseUrl),
-            i, max, urlDirectories, baseUrlDirectories, diff = "";
-        if (urlParts.hostPart !== baseUrlParts.hostPart) {
-            return "";
-        }
-        max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
-        for(i = 0; i < max; i++) {
-            if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
-        }
-        baseUrlDirectories = baseUrlParts.directories.slice(i);
-        urlDirectories = urlParts.directories.slice(i);
-        for(i = 0; i < baseUrlDirectories.length-1; i++) {
-            diff += "../";
-        }
-        for(i = 0; i < urlDirectories.length-1; i++) {
-            diff += urlDirectories[i] + "/";
-        }
-        return diff;
-    },
-    join: function join(basePath, laterPath) {
-        if (!basePath) {
-            return laterPath;
-        }
-        return this.extractUrlParts(laterPath, basePath).path;
-    },
-    // helper function, not part of API
-    extractUrlParts: function extractUrlParts(url, baseUrl) {
-        // urlParts[1] = protocol&hostname || /
-        // urlParts[2] = / if path relative to host base
-        // urlParts[3] = directories
-        // urlParts[4] = filename
-        // urlParts[5] = parameters
-
-        var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
-            urlParts = url.match(urlPartsRegex),
-            returner = {}, directories = [], i, baseUrlParts;
-
-        if (!urlParts) {
-            throw new Error("Could not parse sheet href - '"+url+"'");
-        }
-
-        // Stylesheets in IE don't always return the full path
-        if (!urlParts[1] || urlParts[2]) {
-            baseUrlParts = baseUrl.match(urlPartsRegex);
-            if (!baseUrlParts) {
-                throw new Error("Could not parse page url - '"+baseUrl+"'");
-            }
-            urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
-            if (!urlParts[2]) {
-                urlParts[3] = baseUrlParts[3] + urlParts[3];
-            }
-        }
-
-        if (urlParts[3]) {
-            directories = 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;
-                }
-            }
-
-            for(i = 0; i < directories.length; i++) {
-                if (directories[i] === ".." && i > 0) {
-                    directories.splice(i-1, 2);
-                    i -= 2;
-                }
-            }
-        }
-
-        returner.hostPart = urlParts[1];
-        returner.directories = directories;
-        returner.path = urlParts[1] + directories.join("/");
-        returner.fileUrl = returner.path + (urlParts[4] || "");
-        returner.url = returner.fileUrl + (urlParts[5] || "");
-        return returner;
-    },
-    doXHR: function doXHR(url, type, callback, errback) {
-
-        var xhr = getXMLHttpRequest();
-        var async = isFileProtocol ? options.fileAsync : options.async;
-
-        if (typeof(xhr.overrideMimeType) === 'function') {
-            xhr.overrideMimeType('text/css');
-        }
-        log("XHR: Getting '" + url + "'", logLevel.debug);
-        xhr.open('GET', url, async);
-        xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
-        xhr.send(null);
-
-        function handleResponse(xhr, callback, errback) {
-            if (xhr.status >= 200 && xhr.status < 300) {
-                callback(xhr.responseText,
-                    xhr.getResponseHeader("Last-Modified"));
-            } else if (typeof(errback) === 'function') {
-                errback(xhr.status, url);
-            }
-        }
-
-        if (isFileProtocol && !options.fileAsync) {
-            if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
-                callback(xhr.responseText);
-            } else {
-                errback(xhr.status, url);
-            }
-        } else if (async) {
-            xhr.onreadystatechange = function () {
-                if (xhr.readyState == 4) {
-                    handleResponse(xhr, callback, errback);
-                }
-            };
-        } else {
-            handleResponse(xhr, callback, errback);
-        }
-    },
-    loadFile: function loadFile(filename, currentDirectory, options, callback) {
-        if (currentDirectory && !this.isPathAbsolute(filename)) {
-            filename = currentDirectory + filename;
-        }
-
-        options = options || {};
-
-        // sheet may be set to the stylesheet for the initial load or a collection of properties including
-        // some env variables for imports
-        var hrefParts = this.extractUrlParts(filename, window.location.href);
-        var href      = hrefParts.url;
-
-        if (options.useFileCache && fileCache[href]) {
-            try {
-                var lessText = fileCache[href];
-                callback(null, lessText, href, { lastModified: new Date() });
-            } catch (e) {
-                callback(e, null, href);
-            }
-            return;
-        }
-
-        this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
-            // per file cache
-            fileCache[href] = data;
-
-            // Use remote copy (re-parse)
-            callback(null, data, href, { lastModified: lastModified });
-        }, function doXHRError(status, url) {
-            callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href);
-        });
-
     }
 };
-
-};
diff --git a/lib/less-browser/index.js b/lib/less-browser/index.js
index 59d68bb..8736884 100644
--- a/lib/less-browser/index.js
+++ b/lib/less-browser/index.js
@@ -29,9 +29,10 @@ function log(str, level) {
 
 var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol),
     options = window.less || {},
-    environment = require("./environment")(options, isFileProtocol, log, logLevel);
+    environment = require("./environment"),
+    browserImport = require("./browser-import")(options, isFileProtocol, log, logLevel);
 
-window.less = less = require('../less')(environment);
+window.less = less = require('../less')(environment, [browserImport]);
 
 less.env = options.env || (location.hostname == '127.0.0.1' ||
                         location.hostname == '0.0.0.0'   ||
@@ -41,6 +42,10 @@ less.env = options.env || (location.hostname == '127.0.0.1' ||
                         isFileProtocol                   ? 'development'
                                                          : 'production');
 
+if (!options.hasOwnProperty('disableDataURIs')) {
+    options.disableDataURIs = true;
+}
+
 // The amount of logging in the javascript console.
 // 3 - Debug, information and errors
 // 2 - Information and errors
@@ -377,7 +382,12 @@ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
         instanceOptions.useFileCache = true;
     }
 
-    less.environment.loadFile(sheet.href, null, instanceOptions, function loadInitialFileCallback(e, data, path, webInfo) {
+    browserImport.loadFile(sheet.href, null, instanceOptions, environment)
+    .then(function loadInitialFileCallback(loadedFile) {
+
+       var data = loadedFile.contents,
+           path = loadedFile.filename,
+           webInfo = loadedFile.webInfo;
 
         var newFileInfo = {
             currentDirectory: less.environment.getPath(path),
@@ -408,18 +418,18 @@ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
         //TODO add tests around how this behaves when reloading
         removeError(path);
 
-        if (data) {
-            instanceOptions.rootFileInfo = newFileInfo;
-            less.render(data, instanceOptions)
-                .then(function(result) {
-                    callback(null, result.css, data, sheet, webInfo, path);
-                },
-                function(e) {
-                    callback(e, null, null, sheet);
-                });
-        } else {
-            callback(e, null, null, sheet, webInfo, path);
-        }
+        instanceOptions.rootFileInfo = newFileInfo;
+        less.render(data, instanceOptions)
+            .then(function(result) {
+                callback(null, result.css, data, sheet, webInfo, path);
+            },
+            function(e) {
+                e.href = path;
+                callback(e);
+            });
+    },
+    function(e) {
+        callback(e);
     });
 }
 
@@ -435,7 +445,7 @@ function initRunningMode(){
             if (less.watchMode) {
                 loadStyleSheets(function (e, css, _, sheet, env) {
                     if (e) {
-                        error(e, sheet.href);
+                        error(e, e.href || sheet.href);
                     } else if (css) {
                         css = postProcessCSS(css);
                         createCSS(css, sheet, env.lastModified);
@@ -498,7 +508,7 @@ less.refresh = function (reload, modifyVars) {
 
     loadStyleSheets(function (e, css, _, sheet, webInfo) {
         if (e) {
-            return error(e, sheet.href);
+            return error(e, e.href || sheet.href);
         }
         if (webInfo.local) {
             log("loading " + sheet.href + " from cache.", logLevel.info);
diff --git a/lib/less-node/environment.js b/lib/less-node/environment.js
index f4abb06..63b564b 100644
--- a/lib/less-node/environment.js
+++ b/lib/less-node/environment.js
@@ -1,9 +1,3 @@
-var path = require('path'),
-    url = require('url'),
-    request,
-    fs = require('./fs'),
-    isUrlRe = /^(?:https?:)?\/\//i;
-
 module.exports = {
     warn: function(msg) {
         console.warn(msg);
@@ -11,211 +5,13 @@ module.exports = {
     encodeBase64: function encodeBase64(str) {
         return new Buffer(str).toString('base64');
     },
-    supportsDataURI: function() {
-        return true;
-    },
     mimeLookup: function (filename) {
         return require('mime').lookup(filename);
     },
     charsetLookup: function (mime) {
         return require('mime').charsets.lookup(mime);
     },
-    readFileSync: function (filename) {
-        return require("fs").readFileSync(filename);
-    },
-    getPath: function (filename) {
-        var j = filename.lastIndexOf('/');
-        if (j < 0) {
-            j = filename.lastIndexOf('\\');
-        }
-        if (j < 0) {
-            return "";
-        }
-        return filename.slice(0, j + 1);
-    },
-    isPathAbsolute: function(filename) {
-        return (/^(?:[a-z-]+:|\/|\\)/i).test(filename);
-    },
-    getAbsolutePath: function getAbsolutePath(filename) {
-        return require('path').resolve(filename);
-    },
     getSourceMapGenerator: function getSourceMapGenerator() {
         return require("source-map").SourceMapGenerator;
-    },
-    alwaysMakePathsAbsolute: function alwaysMakePathsAbsolute() {
-        return false;
-    },
-    join: function join(basePath, laterPath) {
-        if (!basePath) {
-            return laterPath;
-        }
-        return basePath + laterPath;
-    },
-    pathDiff: function pathDiff(url, baseUrl) {
-        // diff between two paths to create a relative path
-
-        var urlParts = this.extractUrlParts(url),
-            baseUrlParts = this.extractUrlParts(baseUrl),
-            i, max, urlDirectories, baseUrlDirectories, diff = "";
-        if (urlParts.hostPart !== baseUrlParts.hostPart) {
-            return "";
-        }
-        max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
-        for(i = 0; i < max; i++) {
-            if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
-        }
-        baseUrlDirectories = baseUrlParts.directories.slice(i);
-        urlDirectories = urlParts.directories.slice(i);
-        for(i = 0; i < baseUrlDirectories.length-1; i++) {
-            diff += "../";
-        }
-        for(i = 0; i < urlDirectories.length-1; i++) {
-            diff += urlDirectories[i] + "/";
-        }
-        return diff;
-    },
-    // helper function, not part of API
-    extractUrlParts: function extractUrlParts(url, baseUrl) {
-        // urlParts[1] = protocol&hostname || /
-        // urlParts[2] = / if path relative to host base
-        // urlParts[3] = directories
-        // urlParts[4] = filename
-        // urlParts[5] = parameters
-
-        var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
-            urlParts = url.match(urlPartsRegex),
-            returner = {}, directories = [], i, baseUrlParts;
-
-        if (!urlParts) {
-            throw new Error("Could not parse sheet href - '"+url+"'");
-        }
-
-        // Stylesheets in IE don't always return the full path
-        if (baseUrl && (!urlParts[1] || urlParts[2])) {
-            baseUrlParts = baseUrl.match(urlPartsRegex);
-            if (!baseUrlParts) {
-                throw new Error("Could not parse page url - '"+baseUrl+"'");
-            }
-            urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
-            if (!urlParts[2]) {
-                urlParts[3] = baseUrlParts[3] + urlParts[3];
-            }
-        }
-
-        if (urlParts[3]) {
-            directories = 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;
-                }
-            }
-
-            for(i = 0; i < directories.length; i++) {
-                if (directories[i] === ".." && i > 0) {
-                    directories.splice(i-1, 2);
-                    i -= 2;
-                }
-            }
-        }
-
-        returner.hostPart = urlParts[1];
-        returner.directories = directories;
-        returner.path = urlParts[1] + directories.join("/");
-        returner.fileUrl = returner.path + (urlParts[4] || "");
-        returner.url = returner.fileUrl + (urlParts[5] || "");
-        return returner;
-    },
-    // consider if we really want this in the environment or whether all or some of this should be moved to (for node) built in import manager plugins?
-    loadFile: function(filename, currentDirectory, options, callback) {
-        var fullFilename,
-            data,
-            isUrl = isUrlRe.test( filename );
-
-        options = options || {};
-
-        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),
-                urlObj = url.parse(urlStr);
-
-            if (!urlObj.protocol) {
-                urlObj.protocol = "http";
-                urlStr = urlObj.format();
-            }
-
-            request.get({uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) {
-                if (error) {
-                    callback({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n  "+ error +"\n" });
-                }
-                if (res && res.statusCode === 404) {
-                    callback({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
-                    return;
-                }
-                if (!body) {
-                    this.warn('Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"');
-                }
-                fullFilename = urlStr;
-                callback(null, body, fullFilename);
-            });
-        } else {
-
-            var paths = [currentDirectory];
-            if (options.paths) paths.push.apply(paths, options.paths);
-            if (paths.indexOf('.') === -1) paths.push('.');
-
-            if (options.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;
-                }
-
-                data = fs.readFileSync(fullFilename, 'utf-8');
-                callback(null, data, fullFilename);
-            } 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); }
-
-                                    // do processing in the next tick to allow
-                                    // file handling to dispose
-                                    process.nextTick(function() {
-                                        callback(null, data, fullFilename);
-                                    });
-                                });
-                            }
-                        });
-                    } else {
-                        callback({ type: 'File', message: "'" + filename + "' wasn't found" });
-                    }
-                }(0));
-            }
-        }
     }
 };
diff --git a/lib/less-node/file-import.js b/lib/less-node/file-import.js
new file mode 100644
index 0000000..84734b7
--- /dev/null
+++ b/lib/less-node/file-import.js
@@ -0,0 +1,79 @@
+var path = require('path'),
+    fs = require('./fs'),
+    PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
+    AbstractFileManager = require("../less/environment/abstract-file-manager.js");
+
+var FileImport = function() {
+};
+
+FileImport.prototype = new AbstractFileManager();
+
+FileImport.prototype.supports = function(filename, currentDirectory, options, environment) {
+    return true;
+};
+FileImport.prototype.supportsSync = function(filename, currentDirectory, options, environment) {
+    return true;
+};
+
+FileImport.prototype.loadFile = function(filename, currentDirectory, options, environment) {
+    return new PromiseConstructor(function(fullfill, reject) {
+        var fullFilename,
+            data;
+
+        options = options || {};
+
+        var paths = [currentDirectory];
+        if (options.paths) paths.push.apply(paths, options.paths);
+        if (paths.indexOf('.') === -1) paths.push('.');
+
+        if (options.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) {
+                reject({ type: 'File', message: "'" + filename + "' wasn't found" });
+                return;
+            }
+
+            data = fs.readFileSync(fullFilename, 'utf-8');
+            fullfill({ contents: data, filename: fullFilename});
+        } 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) { reject(e); return; }
+
+                                // do processing in the next tick to allow
+                                // file handling to dispose
+                                process.nextTick(function() {
+                                    fullfill({ contents: data, filename: fullFilename});
+                                });
+                            });
+                        }
+                    });
+                } else {
+                    reject({ type: 'File', message: "'" + filename + "' wasn't found" });
+                }
+            }(0));
+        }
+    });
+};
+
+FileImport.prototype.loadFileSync = function(filename, currentDirectory, options, environment) {
+    filename = path.join(currentDirectory, filename);
+    return { contents: fs.readFileSync(filename), filename: filename };
+};
+
+module.exports = new FileImport();
diff --git a/lib/less-node/index.js b/lib/less-node/index.js
index 63f2ded..8392690 100644
--- a/lib/less-node/index.js
+++ b/lib/less-node/index.js
@@ -1,6 +1,8 @@
 var environment = require("./environment"),
+    fileImport = require("./file-import.js"),
+    urlImport = require("./url-import.js"),
     createFromEnvironment = require("../less"),
-    less = createFromEnvironment(environment),
+    less = createFromEnvironment(environment, [fileImport, urlImport]),
     lesscHelper = require('./lessc-helper');
 
 // allow people to create less with their own environment
@@ -8,7 +10,8 @@ less.createFromEnvironment = createFromEnvironment;
 less.lesscHelper = lesscHelper;
 less.PluginManager = require("./node-plugin-manager");
 less.fs = require("./fs");
-less.environment = environment;
+less.fileImport = require("./file-import.js");
+less.urlImport = require("./url-import.js");
 less.formatError = function(ctx, options) {
     options = options || {};
 
diff --git a/lib/less-node/url-import.js b/lib/less-node/url-import.js
new file mode 100644
index 0000000..7d5aa46
--- /dev/null
+++ b/lib/less-node/url-import.js
@@ -0,0 +1,52 @@
+var isUrlRe = /^(?:https?:)?\/\//i,
+    url = require('url'),
+    request,
+    PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
+    AbstractFileManager = require("../less/environment/abstract-file-manager.js");
+
+var UrlImport = function() {
+};
+
+UrlImport.prototype = new AbstractFileManager();
+
+UrlImport.prototype.supports = function(filename, currentDirectory, options, environment) {
+    return isUrlRe.test( filename ) || isUrlRe.test(currentDirectory);
+};
+
+UrlImport.prototype.loadFile = function(filename, currentDirectory, options, environment) {
+    return new PromiseConstructor(function(fullfill, reject) {
+        if (request === undefined) {
+            try { request = require('request'); }
+            catch(e) { request = null; }
+        }
+        if (!request) {
+            reject({ type: 'File', message: "optional dependency 'request' required to import over http(s)\n" });
+            return;
+        }
+
+        var urlStr = isUrlRe.test( filename ) ? filename : url.resolve(currentDirectory, filename),
+            urlObj = url.parse(urlStr);
+
+        if (!urlObj.protocol) {
+            urlObj.protocol = "http";
+            urlStr = urlObj.format();
+        }
+
+        request.get({uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) {
+            if (error) {
+                reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n  "+ error +"\n" });
+                return;
+            }
+            if (res && res.statusCode === 404) {
+                reject({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
+                return;
+            }
+            if (!body) {
+                environment.warn('Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"');
+            }
+            fullfill({ contents: body, filename: urlStr });
+        });
+    });
+};
+
+module.exports = new UrlImport();
diff --git a/lib/less/contexts.js b/lib/less/contexts.js
index 467cfe6..b486535 100644
--- a/lib/less/contexts.js
+++ b/lib/less/contexts.js
@@ -49,7 +49,8 @@ var evalCopyProperties = [
     'sourceMap',      // whether to output a source map
     'importMultiple', // whether we are currently importing multiple copies
     'urlArgs',        // whether to add args into url tokens
-    'javascriptEnabled'// option - whether JavaScript is enabled. if undefined, defaults to true
+    'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true
+    'disableDataURIs' // option - disable data URIs (they will be converted to URL())
     ];
 
 contexts.evalEnv = function(options, frames) {
diff --git a/lib/less/environment/abstract-file-manager.js b/lib/less/environment/abstract-file-manager.js
new file mode 100644
index 0000000..1ca31b2
--- /dev/null
+++ b/lib/less/environment/abstract-file-manager.js
@@ -0,0 +1,111 @@
+var abstractFileManager = function() {
+};
+
+abstractFileManager.prototype.getPath = function (filename) {
+    var j = filename.lastIndexOf('/');
+    if (j < 0) {
+        j = filename.lastIndexOf('\\');
+    }
+    if (j < 0) {
+        return "";
+    }
+    return filename.slice(0, j + 1);
+};
+
+abstractFileManager.prototype.supportsSync = function() {
+    return false;
+};
+
+abstractFileManager.prototype.alwaysMakePathsAbsolute = function() {
+    return false;
+};
+
+abstractFileManager.prototype.isPathAbsolute = function(filename) {
+    return (/^(?:[a-z-]+:|\/|\\)/i).test(filename);
+};
+
+abstractFileManager.prototype.join = function(basePath, laterPath) {
+    if (!basePath) {
+        return laterPath;
+    }
+    return basePath + laterPath;
+};
+abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
+    // diff between two paths to create a relative path
+
+    var urlParts = this.extractUrlParts(url),
+        baseUrlParts = this.extractUrlParts(baseUrl),
+        i, max, urlDirectories, baseUrlDirectories, diff = "";
+    if (urlParts.hostPart !== baseUrlParts.hostPart) {
+        return "";
+    }
+    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
+    for(i = 0; i < max; i++) {
+        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
+    }
+    baseUrlDirectories = baseUrlParts.directories.slice(i);
+    urlDirectories = urlParts.directories.slice(i);
+    for(i = 0; i < baseUrlDirectories.length-1; i++) {
+        diff += "../";
+    }
+    for(i = 0; i < urlDirectories.length-1; i++) {
+        diff += urlDirectories[i] + "/";
+    }
+    return diff;
+};
+// helper function, not part of API
+abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, baseUrl) {
+    // urlParts[1] = protocol&hostname || /
+    // urlParts[2] = / if path relative to host base
+    // urlParts[3] = directories
+    // urlParts[4] = filename
+    // urlParts[5] = parameters
+
+    var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
+        urlParts = url.match(urlPartsRegex),
+        returner = {}, directories = [], i, baseUrlParts;
+
+    if (!urlParts) {
+        throw new Error("Could not parse sheet href - '" + url + "'");
+    }
+
+    // Stylesheets in IE don't always return the full path
+    if (!urlParts[1] || urlParts[2]) {
+        baseUrlParts = baseUrl.match(urlPartsRegex);
+        if (!baseUrlParts) {
+            throw new Error("Could not parse page url - '"+baseUrl+"'");
+        }
+        urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
+        if (!urlParts[2]) {
+            urlParts[3] = baseUrlParts[3] + urlParts[3];
+        }
+    }
+
+    if (urlParts[3]) {
+        directories = 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;
+            }
+        }
+
+        for(i = 0; i < directories.length; i++) {
+            if (directories[i] === ".." && i > 0) {
+                directories.splice(i-1, 2);
+                i -= 2;
+            }
+        }
+    }
+
+    returner.hostPart = urlParts[1];
+    returner.directories = directories;
+    returner.path = urlParts[1] + directories.join("/");
+    returner.fileUrl = returner.path + (urlParts[4] || "");
+    returner.url = returner.fileUrl + (urlParts[5] || "");
+    return returner;
+};
+
+module.exports = abstractFileManager;
diff --git a/lib/less/environment/api.js b/lib/less/environment/api.js
index 90a71fc..bd72a50 100644
--- a/lib/less/environment/api.js
+++ b/lib/less/environment/api.js
@@ -6,6 +6,29 @@ module.exports = {
     warn: function(msg) {
     },
     /**
+     * Converts a string to a base 64 string
+     * @param str
+     */
+    encodeBase64: function(str) {
+    },
+    /**
+     * Lookup the mime-type of a filename
+     * @param filename
+     */
+    mimeLookup: function (filename) {
+    },
+    /**
+     * Look up the charset of a mime type
+     * @param mime
+     */
+    charsetLookup: function (mime) {
+    },
+    /**
+     *
+     */
+    getSourceMapGenerator: function getSourceMapGenerator() {
+    },
+    /**
       * gets the path from the filename, e.g. "http://wwe.files.com/ha/ha.less" would return
       * "http://wwe.files.com/ha/"
       * If the filename is a file e.g. "file.less" it should return the empty string ""
diff --git a/lib/less/environment/environment.js b/lib/less/environment/environment.js
new file mode 100644
index 0000000..454bcaa
--- /dev/null
+++ b/lib/less/environment/environment.js
@@ -0,0 +1,36 @@
+var environment = function(externalEnvironment, fileManagers) {
+    this.fileManagers = fileManagers || [];
+    var functions = ["warn", "encodeBase64", "mimeLookup", "charsetLookup", "getSourceMapGenerator"],
+        emptyFunc = function() {};
+
+    for(var i = 0; i < functions.length; i++) {
+        var propName = functions[i],
+            environmentFunc = externalEnvironment[propName];
+        if (environmentFunc) {
+            this[propName] = environmentFunc.bind(externalEnvironment);
+        } else {
+            this[propName] = emptyFunc;
+            this.warn("missing function in environment - " + propName);
+        }
+    }
+};
+
+environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
+    for(var i = this.fileManagers.length - 1; i >= 0 ; i--) {
+        var fileManager = this.fileManagers[i];
+        if (fileManager[isSync ? "supports" : "supportsSync"](filename, currentDirectory, options, environment)) {
+            return fileManager;
+        }
+    }
+    return null;
+};
+
+environment.prototype.addFileManager = function (fileManager) {
+    this.fileManagers.push(fileManager);
+};
+
+environment.prototype.clearFileManagers = function () {
+    this.fileManagers = [];
+};
+
+module.exports = environment;
diff --git a/lib/less/functions/data-uri.js b/lib/less/functions/data-uri.js
index 8a4ee5e..76d44c1 100644
--- a/lib/less/functions/data-uri.js
+++ b/lib/less/functions/data-uri.js
@@ -1,17 +1,22 @@
 module.exports = function(environment) {
     var Anonymous = require("../tree/anonymous"),
         URL = require("../tree/url"),
-        functionRegistry = require("./function-registry");
+        functionRegistry = require("./function-registry"),
+        fallback = function(functionContext, node) {
+            return new URL(node, functionContext.index, functionContext.currentFileInfo).eval(functionContext.env);
+        };
 
     functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {
 
-        if (!environment.supportsDataURI()) {
-            return new URL(filePathNode || mimetypeNode, this.index, this.currentFileInfo).eval(this.env);
-        }
-
         var mimetype = mimetypeNode.value;
         var filePath = (filePathNode && filePathNode.value);
 
+        var fileManager = environment.getFileManager(filePath, this.env.currentFileInfo, this.env, environment, true);
+
+        if (!fileManager) {
+            return fallback(this, filePathNode || mimetypeNode);
+        }
+
         var useBase64 = false;
 
         if (arguments.length < 2) {
@@ -25,13 +30,8 @@ module.exports = function(environment) {
             filePath = filePath.slice(0, fragmentStart);
         }
 
-        if (this.env.isPathRelative(filePath)) {
-            if (this.currentFileInfo.relativeUrls) {
-                filePath = environment.join(this.currentFileInfo.currentDirectory, filePath);
-            } else {
-                filePath = environment.join(this.currentFileInfo.entryPath, filePath);
-            }
-        }
+        var currentDirectory = this.currentFileInfo.relativeUrls ?
+            this.currentFileInfo.currentDirectory : this.currentFileInfo.entryPath;
 
         // detect the mimetype if not given
         if (arguments.length < 2) {
@@ -47,7 +47,12 @@ module.exports = function(environment) {
             useBase64 = /;base64$/.test(mimetype);
         }
 
-        var buf = environment.readFileSync(filePath);
+        var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.env, environment);
+        if (!fileSync.contents) {
+            environment.warn("Skipped data-uri embedding because file not found");
+            return fallback(this, filePathNode || mimetypeNode);
+        }
+        var buf = fileSync.contents;
 
         // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded
         // and the --ieCompat flag is enabled, return a normal url() instead.
@@ -56,11 +61,9 @@ module.exports = function(environment) {
         if (fileSizeInKB >= DATA_URI_MAX_KB) {
 
             if (this.env.ieCompat !== false) {
-                if (!this.env.silent) {
-                    console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB);
-                }
+                environment.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.index, this.currentFileInfo).eval(this.env);
+                return fallback(this, filePathNode || mimetypeNode);
             }
         }
 
diff --git a/lib/less/imports.js b/lib/less/imports.js
index e426c6d..a8299c5 100644
--- a/lib/less/imports.js
+++ b/lib/less/imports.js
@@ -24,11 +24,6 @@ module.exports = function(environment) {
         this.queue = [];        // Files which haven't been imported yet
         this.files = [];        // Holds the imported parse trees.
     };
-    ImportManager.prototype.getAbsolutePath = function(filename) {
-        // proxy needed for "DebugInfo"
-        // I hope one day we can remove this function
-        return environment.getAbsolutePath(filename);
-    };
     ImportManager.prototype.push = function (path, currentFileInfo, importOptions, callback) {
         var parserImports = this;
         this.queue.push(path);
@@ -52,46 +47,55 @@ module.exports = function(environment) {
             rootFilename: currentFileInfo.rootFilename
         };
 
-        environment.loadFile(path, currentFileInfo.currentDirectory, this.env, function loadFileCallback(e, contents, resolvedFilename) {
-            if (e) {
-                fileParsedFunc(e);
-                return;
-            }
-
-            // Pass on an updated rootpath if path of imported file is relative and file
-            // is in a (sub|sup) directory
-            //
-            // Examples:
-            // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
-            //   then rootpath should become 'less/module/nav/'
-            // - If path of imported file is '../mixins.less' and rootpath is 'less/',
-            //   then rootpath should become 'less/../'
-            newFileInfo.currentDirectory = environment.getPath(resolvedFilename);
-            if(newFileInfo.relativeUrls) {
-                newFileInfo.rootpath = environment.join((parserImports.env.rootpath || ""), environment.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
-                if (!environment.isPathAbsolute(newFileInfo.rootpath) && environment.alwaysMakePathsAbsolute()) {
-                    newFileInfo.rootpath = environment.join(newFileInfo.entryPath, newFileInfo.rootpath);
+        var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.env, environment);
+
+        if (!fileManager) {
+            fileParsedFunc({ message: "Could not find a file-manager for " + path });
+            return;
+        }
+
+        fileManager.loadFile(path, currentFileInfo.currentDirectory, this.env, environment)
+            .then(function loadFileCallback(loadedFile) {
+                var resolvedFilename = loadedFile.filename,
+                    contents = loadedFile.contents;
+
+                // Pass on an updated rootpath if path of imported file is relative and file
+                // is in a (sub|sup) directory
+                //
+                // Examples:
+                // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
+                //   then rootpath should become 'less/module/nav/'
+                // - If path of imported file is '../mixins.less' and rootpath is 'less/',
+                //   then rootpath should become 'less/../'
+                newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
+                if(newFileInfo.relativeUrls) {
+                    newFileInfo.rootpath = fileManager.join((parserImports.env.rootpath || ""), environment.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
+                    if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
+                        newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
+                    }
+                }
+                newFileInfo.filename = resolvedFilename;
+
+                var newEnv = new contexts.parseEnv(parserImports.env);
+
+                newEnv.processImports = false;
+                parserImports.contents[resolvedFilename] = contents;
+
+                if (currentFileInfo.reference || importOptions.reference) {
+                    newFileInfo.reference = true;
+                }
+
+                if (importOptions.inline) {
+                    fileParsedFunc(null, contents, resolvedFilename);
+                } else {
+                    new Parser(newEnv, parserImports, newFileInfo).parse(contents, function (e, root) {
+                        fileParsedFunc(e, root, resolvedFilename);
+                    });
                 }
-            }
-            newFileInfo.filename = resolvedFilename;
-
-            var newEnv = new contexts.parseEnv(parserImports.env);
-
-            newEnv.processImports = false;
-            parserImports.contents[resolvedFilename] = contents;
-
-            if (currentFileInfo.reference || importOptions.reference) {
-                newFileInfo.reference = true;
-            }
-
-            if (importOptions.inline) {
-                fileParsedFunc(null, contents, resolvedFilename);
-            } else {
-                new Parser(newEnv, parserImports, newFileInfo).parse(contents, function (e, root) {
-                    fileParsedFunc(e, root, resolvedFilename);
-                });
-            }
-        });
+            },
+            function(error) {
+                fileParsedFunc(error);
+            });
     };
     return ImportManager;
 };
diff --git a/lib/less/index.js b/lib/less/index.js
index 5b1f5ce..e520b2c 100644
--- a/lib/less/index.js
+++ b/lib/less/index.js
@@ -1,17 +1,19 @@
-module.exports = function(environment) {
-    var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager;
+module.exports = function(environment, fileManagers) {
+    var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
 
     var less = {
         version: [2, 0, 0],
         data: require('./data'),
         tree: require('./tree'),
+        Environment: (Environment = require("./environment/environment")),
+        AbstractFileManager: require("./environment/abstract-file-manager"),
+        environment: (environment = new Environment(environment, fileManagers)),
         visitors: require('./visitors'),
         Parser: require('./parser/parser'),
         functions: require('./functions')(environment),
         contexts: require("./contexts"),
-        environment: environment,
-        SourceMapOutput: (SourceMapOutput = require('./source-map-output.js')(environment)),
-        SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder.js')(SourceMapOutput)),
+        SourceMapOutput: (SourceMapOutput = require('./source-map-output')(environment)),
+        SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder')(SourceMapOutput)),
         ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)),
         ImportManager: (ImportManager = require('./imports')(environment)),
         render: require("./render")(environment, ParseTree, ImportManager),
diff --git a/lib/less/parser/parser.js b/lib/less/parser/parser.js
index 85792d3..43a6ba1 100644
--- a/lib/less/parser/parser.js
+++ b/lib/less/parser/parser.js
@@ -73,7 +73,6 @@ var Parser = function Parser(env, imports, fileInfo) {
 
     function getDebugInfo(index) {
         var filename = fileInfo.filename;
-        filename = imports.getAbsolutePath(filename);
 
         return {
             lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,
diff --git a/lib/less/source-map-builder.js b/lib/less/source-map-builder.js
index 3cd382f..f212d11 100644
--- a/lib/less/source-map-builder.js
+++ b/lib/less/source-map-builder.js
@@ -23,7 +23,9 @@ module.exports = function (SourceMapOutput) {
         var css = sourceMapOutput.toCSS(options);
         this.sourceMap = sourceMapOutput.sourceMap;
         this.sourceMapURL = sourceMapOutput.sourceMapURL;
-        this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
+        if (this.options.sourceMapInputFilename) {
+            this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
+        }
         return css;
     };
 
diff --git a/lib/less/tree/import.js b/lib/less/tree/import.js
index e0ac6d8..9171990 100644
--- a/lib/less/tree/import.js
+++ b/lib/less/tree/import.js
@@ -111,7 +111,6 @@ Import.prototype.eval = function (env) {
     }
 
     if (this.options.inline) {
-        //todo needs to reference css file not import
         var contents = new(Anonymous)(this.root, 0, {filename: this.importedFilename}, true, true);
         return this.features ? new(Media)([contents], this.features.value) : [contents];
     } else if (this.css) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/less.js.git



More information about the Pkg-javascript-commits mailing list