From f68337e45077bdf1066fc81a8fd8e352c3dfa9b7 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Sat, 16 Feb 2013 22:11:01 +0000 Subject: [PATCH] change data-uri to look at the file relative to the root or current less file. Fixes #1186 --- lib/less/env.js | 4 ++++ lib/less/functions.js | 29 +++++++++++++++++++---------- lib/less/parser.js | 2 +- lib/less/tree/call.js | 5 +++-- lib/less/tree/url.js | 2 +- test/browser/css/urls.css | 8 ++++---- test/browser/less/urls.less | 8 ++++---- test/less/urls.less | 8 ++++---- 8 files changed, 40 insertions(+), 26 deletions(-) diff --git a/lib/less/env.js b/lib/less/env.js index 70a56192..afc747d6 100644 --- a/lib/less/env.js +++ b/lib/less/env.js @@ -59,6 +59,10 @@ return this.strictMaths === false ? true : (this.parensStack && this.parensStack.length); }; + tree.evalEnv.prototype.isPathRelative = function (path) { + return !/^(?:[a-z-]+:|\/)/.test(path); + }; + //todo - do the same for the toCSS env //tree.toCSSEnv = function (options) { //}; diff --git a/lib/less/functions.js b/lib/less/functions.js index 62f564f9..ab6fca60 100644 --- a/lib/less/functions.js +++ b/lib/less/functions.js @@ -373,17 +373,26 @@ tree.functions = { return values.value[index]; }, - "data-uri": function(mimetype, path) { + "data-uri": function(mimetype, filePath) { if (typeof window !== 'undefined') { - return new less.tree.URL(path || mimetype, this.rootpath).eval(this.env); + return new less.tree.URL(filePath || mimetype, this.rootpath).eval(this.env); } mimetype = mimetype.value; - path = (path && path.value); + filePath = (filePath && filePath.value); - var fs = require('fs'); - var useBase64 = false; + var fs = require("fs"), + path = require("path"), + useBase64 = false; + + if (arguments.length < 2) { + filePath = mimetype; + } + + if (this.relativePath && this.env.isPathRelative(filePath)) { + filePath = path.join(this.relativePath, filePath); + } // detect the mimetype if not given if (arguments.length < 2) { @@ -394,8 +403,7 @@ tree.functions = { mime = tree._mime; } - path = mimetype; - mimetype = mime.lookup(path); + mimetype = mime.lookup(filePath); // use base 64 unless it's an ASCII or UTF-8 format var charset = mime.charsets.lookup(mimetype); @@ -406,12 +414,12 @@ tree.functions = { useBase64 = /;base64$/.test(mimetype) } - var buf = fs.readFileSync(path); + var buf = fs.readFileSync(filePath); buf = useBase64 ? buf.toString('base64') : encodeURIComponent(buf); - var uri = "'data:"+mimetype+','+buf+"'"; + var uri = "'data:" + mimetype + ',' + buf + "'"; return new(tree.URL)(new(tree.Anonymous)(uri)); } }; @@ -489,9 +497,10 @@ function clamp(val) { return Math.min(1, Math.max(0, val)); } -tree.functionCall = function(env, rootpath) { +tree.functionCall = function(env, rootpath, relativePath) { this.env = env; this.rootpath = rootpath; + this.relativePath = relativePath; }; tree.functionCall.prototype = tree.functions; diff --git a/lib/less/parser.js b/lib/less/parser.js index 0642f351..b854f06e 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -630,7 +630,7 @@ less.Parser = function Parser(env) { return; } - if (name) { return new(tree.Call)(name, args, index, env.filename, env.rootpath) } + if (name) { return new(tree.Call)(name, args, index, env.filename, env.rootpath, env.rootpath || env.paths[0]); } }, arguments: function () { var args = [], arg; diff --git a/lib/less/tree/call.js b/lib/less/tree/call.js index 249f5048..0805f919 100644 --- a/lib/less/tree/call.js +++ b/lib/less/tree/call.js @@ -3,12 +3,13 @@ // // A function call node. // -tree.Call = function (name, args, index, filename, rootpath) { +tree.Call = function (name, args, index, filename, rootpath, relativePath) { this.name = name; this.args = args; this.index = index; this.filename = filename; this.rootpath = rootpath; + this.relativePath = relativePath; }; tree.Call.prototype = { // @@ -31,7 +32,7 @@ tree.Call.prototype = { if (nameLC in tree.functions) { // 1. try { - func = new tree.functionCall(env, this.rootpath); + func = new tree.functionCall(env, this.rootpath, this.relativePath); result = func[nameLC].apply(func, args); if (result != null) { return result; diff --git a/lib/less/tree/url.js b/lib/less/tree/url.js index 80c70ad8..e0ee7d42 100644 --- a/lib/less/tree/url.js +++ b/lib/less/tree/url.js @@ -12,7 +12,7 @@ tree.URL.prototype = { var val = this.value.eval(ctx), rootpath; // Add the base path if the URL is relative - if (this.rootpath && typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) { + if (this.rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { rootpath = this.rootpath; if (!val.quote) { rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); diff --git a/test/browser/css/urls.css b/test/browser/css/urls.css index fe1a1415..39c22b1a 100644 --- a/test/browser/css/urls.css +++ b/test/browser/css/urls.css @@ -35,12 +35,12 @@ url: url('http://localhost:8081/browser/less/Trebuchet'); } #data-uri { - uri: url('http://localhost:8081/browser/less/test/data/image.jpg'); + uri: url('http://localhost:8081/browser/less/../../data/image.jpg'); } #data-uri-guess { - uri: url('http://localhost:8081/browser/less/test/data/image.jpg'); + uri: url('http://localhost:8081/browser/less/../../data/image.jpg'); } #data-uri-ascii { - uri-1: url('http://localhost:8081/browser/less/test/data/page.html'); - uri-2: url('http://localhost:8081/browser/less/test/data/page.html'); + uri-1: url('http://localhost:8081/browser/less/../../data/page.html'); + uri-2: url('http://localhost:8081/browser/less/../../data/page.html'); } diff --git a/test/browser/less/urls.less b/test/browser/less/urls.less index 81c06fdc..d4a4d8d1 100644 --- a/test/browser/less/urls.less +++ b/test/browser/less/urls.less @@ -32,14 +32,14 @@ url: url(@a); } #data-uri { - uri: data-uri('image/jpeg;base64', 'test/data/image.jpg'); + uri: data-uri('image/jpeg;base64', '../../data/image.jpg'); } #data-uri-guess { - uri: data-uri('test/data/image.jpg'); + uri: data-uri('../../data/image.jpg'); } #data-uri-ascii { - uri-1: data-uri('text/html', 'test/data/page.html'); - uri-2: data-uri('test/data/page.html'); + uri-1: data-uri('text/html', '../../data/page.html'); + uri-2: data-uri('../../data/page.html'); } diff --git a/test/less/urls.less b/test/less/urls.less index 9e7947cd..d7afeeca 100644 --- a/test/less/urls.less +++ b/test/less/urls.less @@ -35,14 +35,14 @@ @import "import/import-and-relative-paths-test"; #data-uri { - uri: data-uri('image/jpeg;base64', 'test/data/image.jpg'); + uri: data-uri('image/jpeg;base64', '../data/image.jpg'); } #data-uri-guess { - uri: data-uri('test/data/image.jpg'); + uri: data-uri('../data/image.jpg'); } #data-uri-ascii { - uri-1: data-uri('text/html', 'test/data/page.html'); - uri-2: data-uri('test/data/page.html'); + uri-1: data-uri('text/html', '../data/page.html'); + uri-2: data-uri('../data/page.html'); }