From 7acf7938b173533cf30f622d3d3bfce1735d7071 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sun, 2 Nov 2014 15:57:17 +0000 Subject: [PATCH] Adds source file tracking to source maps. --- lib/clean.js | 2 +- lib/imports/inliner.js | 2 + lib/selectors/tokenizer.js | 11 +- lib/utils/source-maps.js | 3 +- test/selectors/tokenizer-source-maps-test.js | 179 +++++++++++-------- 5 files changed, 119 insertions(+), 78 deletions(-) diff --git a/lib/clean.js b/lib/clean.js index a7693c05..f3f4b930 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -86,7 +86,7 @@ function runMinifier(callback, self) { function minifyWithDebug(self, data) { var startedAt = process.hrtime(); - self.stats.originalSize = data.length; + self.stats.originalSize = data.replace(/__ESCAPED_SOURCE_CLEAN_CSS\(.+\)__/g, '').length; data = minify.call(self, data); diff --git a/lib/imports/inliner.js b/lib/imports/inliner.js index ec2b67ab..0a641658 100644 --- a/lib/imports/inliner.js +++ b/lib/imports/inliner.js @@ -249,6 +249,7 @@ module.exports = function Inliner(context, options) { res.on('end', function() { var importedData = chunks.join(''); importedData = UrlRewriter.process(importedData, { toBase: importedUrl }); + importedData = '__ESCAPED_SOURCE_CLEAN_CSS(' + url + ')__' + importedData; if (mediaQuery.length > 0) importedData = '@media ' + mediaQuery + '{' + importedData + '}'; @@ -300,6 +301,7 @@ module.exports = function Inliner(context, options) { fromBase: importRelativeTo, toBase: options._baseRelativeTo }); + importedData = '__ESCAPED_SOURCE_CLEAN_CSS(' + path.relative(options.root, fullPath) + ')__' + importedData; if (mediaQuery.length > 0) importedData = '@media ' + mediaQuery + '{' + importedData + '}'; diff --git a/lib/selectors/tokenizer.js b/lib/selectors/tokenizer.js index 568fbb85..48e48d3a 100644 --- a/lib/selectors/tokenizer.js +++ b/lib/selectors/tokenizer.js @@ -26,7 +26,8 @@ Tokenizer.prototype.toTokens = function (data) { addMetadata: this.addMetadata, addSourceMap: this.addSourceMap, line: 1, - column: 1 + column: 1, + source: undefined }; return tokenize(context); @@ -152,7 +153,13 @@ function tokenize(context) { } else if (what == 'escape') { nextEnd = chunk.indexOf('__', nextSpecial + 1); var escaped = chunk.substring(context.cursor, nextEnd + 2); - tokenized.push({ kind: 'text', value: escaped }); + var isSourceMarker = escaped.indexOf('__ESCAPED_SOURCE_CLEAN_CSS') > -1; + + if (isSourceMarker) { + context.source = escaped.substring(escaped.indexOf('(') + 1, escaped.indexOf(')')); + } else { + tokenized.push({ kind: 'text', value: escaped }); + } if (addSourceMap) SourceMaps.track(escaped, context); diff --git a/lib/utils/source-maps.js b/lib/utils/source-maps.js index 1413c7a6..70b4cd8e 100644 --- a/lib/utils/source-maps.js +++ b/lib/utils/source-maps.js @@ -2,7 +2,8 @@ var SourceMaps = { saveAndTrack: function (data, context, hasSuffix) { var metadata = { line: context.line, - column: context.column + column: context.column, + source: context.source }; this.track(data, context); diff --git a/test/selectors/tokenizer-source-maps-test.js b/test/selectors/tokenizer-source-maps-test.js index 6a36d362..84868311 100644 --- a/test/selectors/tokenizer-source-maps-test.js +++ b/test/selectors/tokenizer-source-maps-test.js @@ -32,7 +32,7 @@ vows.describe('source-maps/analyzer') 'a{}', [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], body: [] }] ], @@ -41,8 +41,8 @@ vows.describe('source-maps/analyzer') [{ kind: 'selector', value: [ - { value: 'a', metadata: { line: 1, column: 1 } }, - { value: 'div', metadata: { line: 1, column: 3 } } + { value: 'a', metadata: { line: 1, column: 1, source: undefined } }, + { value: 'div', metadata: { line: 1, column: 3, source: undefined } } ], body: [] }] @@ -52,8 +52,8 @@ vows.describe('source-maps/analyzer') [{ kind: 'selector', value: [ - { value: ' a', metadata: { line: 1, column: 2 } }, - { value: '\n\ndiv', metadata: { line: 3, column: 1 } } + { value: ' a', metadata: { line: 1, column: 2, source: undefined } }, + { value: '\n\ndiv', metadata: { line: 3, column: 1, source: undefined } } ], body: [] }] @@ -63,9 +63,9 @@ vows.describe('source-maps/analyzer') [{ kind: 'selector', value: [ - { value: 'a', metadata: { line: 1, column: 1 } }, - { value: 'div', metadata: { line: 1, column: 3 } }, - { value: 'p', metadata: { line: 1, column: 7 } } + { value: 'a', metadata: { line: 1, column: 1, source: undefined } }, + { value: 'div', metadata: { line: 1, column: 3, source: undefined } }, + { value: 'p', metadata: { line: 1, column: 7, source: undefined } } ], body: [] }] @@ -75,9 +75,9 @@ vows.describe('source-maps/analyzer') [{ kind: 'selector', value: [ - { value: ' a', metadata: { line: 1, column: 2 } }, - { value: '\n\ndiv\na', metadata: { line: 3, column: 1 } }, - { value: '\n p', metadata: { line: 5, column: 2 } } + { value: ' a', metadata: { line: 1, column: 2, source: undefined } }, + { value: '\n\ndiv\na', metadata: { line: 3, column: 1, source: undefined } }, + { value: '\n p', metadata: { line: 5, column: 2, source: undefined } } ], body: [] }] @@ -87,12 +87,12 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], body: [] }, { kind: 'selector', - value: [{ value: 'div', metadata: { line: 1, column: 4 } }], + value: [{ value: 'div', metadata: { line: 1, column: 4, source: undefined } }], body: [] } ] @@ -102,17 +102,17 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a ', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a ', metadata: { line: 1, column: 1, source: undefined } }], body: [] }, { kind: 'selector', - value: [{ value: '\n\ndiv', metadata: { line: 3, column: 1 } }], + value: [{ value: '\n\ndiv', metadata: { line: 3, column: 1, source: undefined } }], body: [] }, { kind: 'selector', - value: [{ value: '\n \n p', metadata: { line: 5, column: 3 } }], + value: [{ value: '\n \n p', metadata: { line: 5, column: 3, source: undefined } }], body: [] } ] @@ -125,18 +125,18 @@ vows.describe('source-maps/analyzer') 'a{color:red}', [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 3 } }] + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }] }] ], 'double': [ 'a{color:red;border:none}', [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], body: [ - { value: 'color:red', metadata: { line: 1, column: 3 } }, - { value: 'border:none', metadata: { line: 1, column: 13 } } + { value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }, + { value: 'border:none', metadata: { line: 1, column: 13, source: undefined } } ] }] ], @@ -144,11 +144,11 @@ vows.describe('source-maps/analyzer') 'a{color:red;\nborder:\nnone;\n\n display:block}', [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], body: [ - { value: 'color:red', metadata: { line: 1, column: 3 } }, - { value: 'border:none', metadata: { line: 2, column: 1 } }, - { value: 'display:block', metadata: { line: 5, column: 3 } } + { value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }, + { value: 'border:none', metadata: { line: 2, column: 1, source: undefined } }, + { value: 'display:block', metadata: { line: 5, column: 3, source: undefined } } ] }] ], @@ -157,13 +157,13 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 3 } }] + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }] }, { kind: 'selector', - value: [{ value: 'div', metadata: { line: 1, column: 13 } }], - body: [{ value: 'color:blue', metadata: { line: 1, column: 17 } }] + value: [{ value: 'div', metadata: { line: 1, column: 13, source: undefined } }], + body: [{ value: 'color:blue', metadata: { line: 1, column: 17, source: undefined } }] } ] ], @@ -172,13 +172,13 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 3 } }] + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }] }, { kind: 'selector', - value: [{ value: '\n div', metadata: { line: 2, column: 2 } }], - body: [{ value: 'color:blue', metadata: { line: 2, column: 6 } }] + value: [{ value: '\n div', metadata: { line: 2, column: 2, source: undefined } }], + body: [{ value: 'color:blue', metadata: { line: 2, column: 6, source: undefined } }] } ] ], @@ -187,13 +187,13 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 3 } }] + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 3, source: undefined } }] }, { kind: 'selector', - value: [{ value: '\n div', metadata: { line: 3, column: 2 } }], - body: [{ value: 'color:blue', metadata: { line: 3, column: 6 } }] + value: [{ value: '\n div', metadata: { line: 3, column: 2, source: undefined } }], + body: [{ value: 'color:blue', metadata: { line: 3, column: 6, source: undefined } }] } ] ] @@ -206,18 +206,18 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 1 } }], + value: [{ value: 'a', metadata: { line: 1, column: 1, source: undefined } }], body: [] }, { kind: 'at-rule', value: '@import \n"test.css";', - metadata: { line: 1, column: 4 } + metadata: { line: 1, column: 4, source: undefined } }, { kind: 'selector', - value: [{ value: '\n\na', metadata: { line: 4, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 4, column: 3 } }] + value: [{ value: '\n\na', metadata: { line: 4, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 4, column: 3, source: undefined } }] } ] ], @@ -227,12 +227,12 @@ vows.describe('source-maps/analyzer') { kind: 'at-rule', value: '@charset "utf-8";', - metadata: { line: 1, column: 1 } + metadata: { line: 1, column: 1, source: undefined } }, { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 19 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 21 } }] + value: [{ value: 'a', metadata: { line: 1, column: 19, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 21, source: undefined } }] } ] ] @@ -246,12 +246,12 @@ vows.describe('source-maps/analyzer') { kind: 'block', value: '@media (min-width:980px)', - metadata: { line: 1, column: 1 }, + metadata: { line: 1, column: 1, source: undefined }, isFlatBlock: false, body: [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 26 } }], - body: [{ value: 'color:red', metadata: { line: 1, column: 28 } }] + value: [{ value: 'a', metadata: { line: 1, column: 26, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 1, column: 28, source: undefined } }] }] } ] @@ -262,17 +262,17 @@ vows.describe('source-maps/analyzer') { kind: 'block', value: '@media (\nmin-width:980px)', - metadata: { line: 1, column: 1 }, + metadata: { line: 1, column: 1, source: undefined }, isFlatBlock: false, body: [ { kind: 'selector', - value: [{ value: '\na', metadata: { line: 3, column: 1 } }], - body: [{ value: 'color:red', metadata: { line: 4, column: 1 } }] + value: [{ value: '\na', metadata: { line: 3, column: 1, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 4, column: 1, source: undefined } }] }, { kind: 'selector', - value: [{ value: 'p', metadata: { line: 5, column: 5 } }], + value: [{ value: 'p', metadata: { line: 5, column: 5, source: undefined } }], body: [] } ] @@ -285,18 +285,18 @@ vows.describe('source-maps/analyzer') { kind: 'block', value: '@font-face', - metadata: { line: 1, column: 1 }, + metadata: { line: 1, column: 1, source: undefined }, isFlatBlock: true, body: [ - { value: 'font-family:"Font"', metadata: { line: 1, column: 12 } }, - { value: 'src:url("font.ttf")', metadata: { line: 2, column: 1 } }, - { value: 'font-weight:normal', metadata: { line: 3, column: 1 } }, - { value: 'font-style:normal', metadata: { line: 3, column: 21 } } + { value: 'font-family:"Font"', metadata: { line: 1, column: 12, source: undefined } }, + { value: 'src:url("font.ttf")', metadata: { line: 2, column: 1, source: undefined } }, + { value: 'font-weight:normal', metadata: { line: 3, column: 1, source: undefined } }, + { value: 'font-style:normal', metadata: { line: 3, column: 21, source: undefined } } ] }, { kind: 'selector', - value: [{ value: 'a', metadata: { line: 3, column: 40 } }], + value: [{ value: 'a', metadata: { line: 3, column: 40, source: undefined } }], body: [] } ] @@ -314,7 +314,7 @@ vows.describe('source-maps/analyzer') }, { kind: 'selector', - value: [{ value: 'a', metadata: { line: 1, column: 6 } }], + value: [{ value: 'a', metadata: { line: 1, column: 6, source: undefined } }], body: [] } ] @@ -328,7 +328,7 @@ vows.describe('source-maps/analyzer') }, { kind: 'selector', - value: [{ value: 'a', metadata: { line: 3, column: 6 } }], + value: [{ value: 'a', metadata: { line: 3, column: 6, source: undefined } }], body: [] } ] @@ -338,10 +338,10 @@ vows.describe('source-maps/analyzer') [{ kind: 'selector', value: [ - { value: 'div[data-type=__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__]', metadata: { line: 1, column: 1 } }, - { value: 'div[data-id=__ESCAPED_FREE_TEXT_CLEAN_CSS1(0,7)__]', metadata: { line: 2, column: 6 } } + { value: 'div[data-type=__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__]', metadata: { line: 1, column: 1, source: undefined } }, + { value: 'div[data-id=__ESCAPED_FREE_TEXT_CLEAN_CSS1(0,7)__]', metadata: { line: 2, column: 6, source: undefined } } ], - body: [{ value: 'color:red', metadata: { line: 2, column: 27 } }] + body: [{ value: 'color:red', metadata: { line: 2, column: 27, source: undefined } }] }] ], 'in properties': [ @@ -349,19 +349,19 @@ vows.describe('source-maps/analyzer') [ { kind: 'selector', - value: [{ value: 'div', metadata: { line: 1, column: 1 } }], + value: [{ value: 'div', metadata: { line: 1, column: 1, source: undefined } }], body: [ - { value: '__ESCAPED_COMMENT_CLEAN_CSS0(2,5)__', metadata: { line: 1, column: 5 }}, - { value: 'background:url(__ESCAPED_URL_CLEAN_CSS0(0,20)__)', metadata: { line: 3, column: 6 } }, - { value: 'color:blue', metadata: { line: 3, column: 43 } } + { value: '__ESCAPED_COMMENT_CLEAN_CSS0(2,5)__', metadata: { line: 1, column: 5, source: undefined }}, + { value: 'background:url(__ESCAPED_URL_CLEAN_CSS0(0,20)__)', metadata: { line: 3, column: 6, source: undefined } }, + { value: 'color:blue', metadata: { line: 3, column: 43, source: undefined } } ] }, { kind: 'selector', - value: [{ value: 'a', metadata: { line: 3, column: 54 } }], + value: [{ value: 'a', metadata: { line: 3, column: 54, source: undefined } }], body: [ - { value: 'font-family:__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__', metadata: { line: 3, column: 56 } }, - { value: 'color:red', metadata: { line: 4, column: 5 } } + { value: 'font-family:__ESCAPED_FREE_TEXT_CLEAN_CSS0(1,3)__', metadata: { line: 3, column: 56, source: undefined } }, + { value: 'color:red', metadata: { line: 4, column: 5, source: undefined } } ] } ] @@ -372,11 +372,11 @@ vows.describe('source-maps/analyzer') { kind: 'at-rule', value: '@charset __ESCAPED_FREE_TEXT_CLEAN_CSS0(1, 5)__;', - metadata: { line: 1, column: 1 } + metadata: { line: 1, column: 1, source: undefined } }, { kind: 'selector', - value: [{ value: 'div', metadata: { line: 2, column: 8 } }], + value: [{ value: 'div', metadata: { line: 2, column: 8, source: undefined } }], body: [] } ] @@ -387,16 +387,47 @@ vows.describe('source-maps/analyzer') { kind: 'block', value: '@media (__ESCAPED_COMMENT_CLEAN_CSS0(2, 1)__min-width:980px)', - metadata: { line: 1, column: 1 }, + metadata: { line: 1, column: 1, source: undefined }, isFlatBlock: false, body: [{ kind: 'selector', - value: [{ value: 'a', metadata: { line: 3, column: 19 } }], - body: [{ value: 'color:red', metadata: { line: 3, column: 21 } }] + value: [{ value: 'a', metadata: { line: 3, column: 19, source: undefined } }], + body: [{ value: 'color:red', metadata: { line: 3, column: 21, source: undefined } }] }] } ] ] }) ) + .addBatch( + sourceMapContext('sources', { + 'one': [ + '__ESCAPED_SOURCE_CLEAN_CSS(one.css)__a{}', + [{ + kind: 'selector', + value: [{ value: 'a', metadata: { line: 1, column: 1, source: 'one.css' } }], + body: [] + }] + ], + 'two': [ + '__ESCAPED_SOURCE_CLEAN_CSS(one.css)__a{}\n__ESCAPED_SOURCE_CLEAN_CSS(two.css)__a{color:red}', + [ + { + kind: 'selector', + value: [ + { value: 'a', metadata: { line: 1, column: 1, source: 'one.css' } } + ], + body: [] + }, + { + kind: 'selector', + value: [ + { value: 'a', metadata: { line: 2, column: 1, source: 'two.css' } } + ], + body: [{ value: 'color:red', metadata: { line: 2, column: 3, source: 'two.css' } }] + } + ] + ] + }) + ) .export(module); -- 2.34.1