From: Jakub Pawlowicz Date: Mon, 9 Jan 2017 09:44:51 +0000 (+0100) Subject: See #791 - normalizes stored paths. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=909460778f78b7ece96fd2e040cec70b035331e4;p=clean-css.git See #791 - normalizes stored paths. Stores all paths internally as normalized to *nix format but still outputs Windows friendly paths if needed. `source-map` does it internally so there's no need to transform paths in source maps. --- diff --git a/lib/reader/normalize-path.js b/lib/reader/normalize-path.js new file mode 100644 index 00000000..a9eca38c --- /dev/null +++ b/lib/reader/normalize-path.js @@ -0,0 +1,8 @@ +var UNIX_SEPARATOR = '/'; +var WINDOWS_SEPARATOR_PATTERN = /\\/g; + +function normalizePath(path) { + return path.replace(WINDOWS_SEPARATOR_PATTERN, UNIX_SEPARATOR); +} + +module.exports = normalizePath; diff --git a/lib/reader/read-sources.js b/lib/reader/read-sources.js index 1ccbdb29..82c34ec1 100644 --- a/lib/reader/read-sources.js +++ b/lib/reader/read-sources.js @@ -6,6 +6,7 @@ var extractImportUrlAndMedia = require('./extract-import-url-and-media'); var isAllowedResource = require('./is-allowed-resource'); var loadOriginalSources = require('./load-original-sources'); var loadRemoteResource = require('./load-remote-resource'); +var normalizePath = require('./normalize-path'); var rebase = require('./rebase'); var rebaseLocalMap = require('./rebase-local-map'); var rebaseRemoteMap = require('./rebase-remote-map'); @@ -57,7 +58,9 @@ function fromString(input, context, callback) { function fromArray(input, context, callback) { var inputAsImports = input.reduce(function (accumulator, uri) { - accumulator.push(restoreAsRelativeImport(uri)); + var normalizedUri = isRemoteResource(uri) ? uri : normalizePath(uri); + + accumulator.push(restoreAsRelativeImport(normalizedUri)); return accumulator; }, []); @@ -66,17 +69,20 @@ function fromArray(input, context, callback) { function fromHash(input, context, callback) { var uri; + var normalizedUri; var source; var inputAsImports = []; for (uri in input) { source = input[uri]; - inputAsImports.push(restoreAsRelativeImport(uri)); + normalizedUri = isRemoteResource(uri) ? uri : normalizePath(uri); + + inputAsImports.push(restoreAsRelativeImport(normalizedUri)); - context.sourcesContent[uri] = source.styles; + context.sourcesContent[normalizedUri] = source.styles; if (source.sourceMap) { - trackSourceMap(source.sourceMap, uri, context); + trackSourceMap(source.sourceMap, normalizedUri, context); } } @@ -274,7 +280,8 @@ function inlineLocalStylesheet(uri, mediaQuery, metadata, inlinerContext) { var importedStyles; var importedTokens; var isAllowed = isAllowedResource(uri, false, inlinerContext.inline); - var isLoaded = relativeToCurrentPath in inlinerContext.externalContext.sourcesContent; + var normalizedPath = normalizePath(relativeToCurrentPath); + var isLoaded = normalizedPath in inlinerContext.externalContext.sourcesContent; if (inlinerContext.inlinedStylesheets.indexOf(absoluteUri) > -1) { inlinerContext.warnings.push('Ignoring local @import of "' + uri + '" as it has already been imported.'); @@ -289,14 +296,14 @@ function inlineLocalStylesheet(uri, mediaQuery, metadata, inlinerContext) { inlinerContext.outputTokens = inlinerContext.outputTokens.concat(inlinerContext.sourceTokens.slice(0, 1)); } else { importedStyles = isLoaded ? - inlinerContext.externalContext.sourcesContent[relativeToCurrentPath] : + inlinerContext.externalContext.sourcesContent[normalizedPath] : fs.readFileSync(absoluteUri, 'utf-8'); inlinerContext.inlinedStylesheets.push(absoluteUri); inlinerContext.inline = inlinerContext.externalContext.options.inline; - inlinerContext.externalContext.source = relativeToCurrentPath; - inlinerContext.externalContext.sourcesContent[relativeToCurrentPath] = importedStyles; + inlinerContext.externalContext.source = normalizedPath; + inlinerContext.externalContext.sourcesContent[normalizedPath] = importedStyles; inlinerContext.externalContext.stats.originalSize += importedStyles.length; importedTokens = fromStyles(importedStyles, inlinerContext.externalContext, inlinerContext, function (tokens) { return tokens; }); diff --git a/lib/writer/source-maps.js b/lib/writer/source-maps.js index c7374b2f..54a0090b 100644 --- a/lib/writer/source-maps.js +++ b/lib/writer/source-maps.js @@ -4,7 +4,10 @@ var all = require('./helpers').all; var isRemoteResource = require('../utils/is-remote-resource'); var isWindows = process.platform == 'win32'; + +var NIX_SEPARATOR_PATTERN = /\//g; var UNKNOWN_SOURCE = '$stdin'; +var WINDOWS_SEPARATOR = '\\'; function store(element, serializeContext) { var fromString = typeof element == 'string'; @@ -40,7 +43,7 @@ function trackMapping(mapping, serializeContext) { var storedSource = source || UNKNOWN_SOURCE; if (isWindows && source && !isRemoteResource(source)) { - source = source.replace(/\\/g, '/'); + storedSource = source.replace(NIX_SEPARATOR_PATTERN, WINDOWS_SEPARATOR); } serializeContext.outputMap.addMapping({ diff --git a/test/module-test.js b/test/module-test.js index b15e548b..f31e34f9 100644 --- a/test/module-test.js +++ b/test/module-test.js @@ -664,6 +664,24 @@ vows.describe('module tests').addBatch({ assert.equal(minified.styles, '.one{background-color:red}.test{color:#000}'); } }, + 'with mixed-style paths': { + 'topic': function () { + new CleanCSS({ level: 1, inline: 'all' }).minify({ + 'main.css': { + styles: '@import url(test/fixtures/partials/one.css);\n@import url(http://127.0.0.1/test.css);' + }, + 'test\\fixtures\\partials\\one.css': { + styles: '.one { background-color:#f00; }' + }, + 'http://127.0.0.1/test.css': { + styles: '.test { color: #000 }' + } + }, this.callback); + }, + 'gives right output without reading resources': function (minified) { + assert.equal(minified.styles, '.one{background-color:red}.test{color:#000}'); + } + }, 'with @import and rules after': { 'topic': function () { return new CleanCSS().minify(sourcesAsHash(['./test/fixtures/partials/two.css', './test/fixtures/partials-absolute/base.css'])); diff --git a/test/source-map-test.js b/test/source-map-test.js index 0ae3c806..5ef05fe5 100644 --- a/test/source-map-test.js +++ b/test/source-map-test.js @@ -1410,9 +1410,9 @@ vows.describe('source-map') }, 'has embedded sources': function (minified) { assert.deepEqual(JSON.parse(minified.sourceMap.toString()).sources, [ - 'test/fixtures/source-maps/some.css', - 'test/fixtures/source-maps/nested/once.css', - 'test/fixtures/source-maps/styles.css' + path.join('test', 'fixtures', 'source-maps', 'some.css'), + path.join('test', 'fixtures', 'source-maps', 'nested', 'once.css'), + path.join('test', 'fixtures', 'source-maps', 'styles.css') ]); }, 'has embedded sources content': function (minified) { @@ -1438,9 +1438,9 @@ vows.describe('source-map') }, 'has embedded sources': function (minified) { assert.deepEqual(JSON.parse(minified.sourceMap.toString()).sources, [ - 'test/fixtures/source-maps/some.css', - 'test/fixtures/source-maps/nested/once.css', - 'test/fixtures/source-maps/styles.css' + path.join('test', 'fixtures', 'source-maps', 'some.css'), + path.join('test', 'fixtures', 'source-maps', 'nested', 'once.css'), + path.join('test', 'fixtures', 'source-maps', 'styles.css') ]); }, 'has embedded sources content': function (minified) {