From: banderson Date: Thu, 23 May 2013 06:34:20 +0000 (-0600) Subject: rebase relative urls in inlined imports X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=43798d91c886fcedf5926fd4a8858e13cbceb27f;p=clean-css.git rebase relative urls in inlined imports --- diff --git a/lib/clean.js b/lib/clean.js index 1b897557..e0cd5b62 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -361,6 +361,7 @@ var CleanCSS = { var cursor = 0; options.relativeTo = options.relativeTo || options.root; + options._baseRelativeTo = options._baseRelativeTo || options.relativeTo; options.visited = options.visited || []; var inlinedFile = function() { @@ -383,9 +384,12 @@ var CleanCSS = { options.visited.push(fullPath); var importedData = fs.readFileSync(fullPath, 'utf8'); + var importRelativeTo = path.dirname(fullPath); + importedData = CleanCSS._rebaseRelativeURLs(importedData, importRelativeTo, options._baseRelativeTo); return CleanCSS._inlineImports(importedData, { root: options.root, - relativeTo: path.dirname(fullPath), + relativeTo: importRelativeTo, + _baseRelativeTo: options.baseRelativeTo, visited: options.visited }); } else { @@ -412,6 +416,34 @@ var CleanCSS = { data; }, + _rebaseRelativeURLs: function(data, fromBase, toBase) { + var tempData = []; + var nextStart = 0; + var nextEnd = 0; + var cursor = 0; + + for (; nextEnd < data.length; ) { + nextStart = data.indexOf('url(', nextEnd); + if (nextStart == -1) + break; + nextEnd = data.indexOf(')', nextStart + 4); + if (nextEnd == -1) + break; + + tempData.push(data.substring(cursor, nextStart)); + var url = data.substring(nextStart + 4, nextEnd).replace(/['"]/g, ''); + if (url[0] != '/' && url.substring(url.length - 4) != '.css') { + url = path.relative(toBase, path.join(fromBase, url)).replace(/\\/g, '/'); + } + tempData.push('url(' + url + ')'); + cursor = nextEnd + 1; + } + + return tempData.length > 0 ? + tempData.join('') + data.substring(cursor, data.length) : + data; + }, + // Strip special comments (/*! ... */) by replacing them by __CSSCOMMENT__ marker // for further restoring. Plain comments are removed. It's done by scanning datq using // String#indexOf scanning instead of regexps to speed up the process. diff --git a/test/data/partials/extra/down.gif b/test/data/partials/extra/down.gif new file mode 100755 index 00000000..9bd94475 Binary files /dev/null and b/test/data/partials/extra/down.gif differ diff --git a/test/data/partials/four.css b/test/data/partials/four.css new file mode 100644 index 00000000..581c1ef9 --- /dev/null +++ b/test/data/partials/four.css @@ -0,0 +1 @@ +.four {background-image: url(/partials/extra/down.gif);} diff --git a/test/data/partials/three.css b/test/data/partials/three.css new file mode 100644 index 00000000..d2d40066 --- /dev/null +++ b/test/data/partials/three.css @@ -0,0 +1 @@ +.three {background-image: url(extra/down.gif);} diff --git a/test/unit-test.js b/test/unit-test.js index bda5be71..99611cb2 100644 --- a/test/unit-test.js +++ b/test/unit-test.js @@ -808,6 +808,14 @@ title']", 'of multi-level, circular dependency file': [ "@import url(test/data/partials/two.css);", ".one{color:red}.three{color:#0f0}.four{color:#00f}.two{color:#fff}" + ], + 'of a file with a relative resource path': [ + "@import url(test/data/partials/three.css);", + ".three{background-image:url(test/data/partials/extra/down.gif)}", + ], + 'of a file with an absolute resource path': [ + "@import url(test/data/partials/four.css);", + ".four{background-image:url(/partials/extra/down.gif)}", ] }), '@import with absolute paths': cssContext({