From 70ab173d26bbe260fb4e932e0aec5583666424b3 Mon Sep 17 00:00:00 2001 From: GoalSmashers Date: Sat, 1 Feb 2014 07:30:24 +0000 Subject: [PATCH] Fixes #218 - gets rid of @import statements appearing after CSS content. See www.w3.org/TR/CSS21/cascade.html#at-import for details. --- History.md | 1 + lib/imports/inliner.js | 21 ++++++++++++++++++++- test/unit-test.js | 16 ++++++++++++---- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/History.md b/History.md index 20c49f46..0c6e632d 100644 --- a/History.md +++ b/History.md @@ -13,6 +13,7 @@ * Fixed issue [#186](https://github.com/GoalSmashers/clean-css/issues/186) - strip unit from 0rem. * Fixed issue [#207](https://github.com/GoalSmashers/clean-css/issues/207) - bug in parsing protocol `@import`s. * Fixed issue [#213](https://github.com/GoalSmashers/clean-css/issues/213) - faster rgb to hex transforms. +* Fixed issue [#218](https://github.com/GoalSmashers/clean-css/issues/218) - `@import` statements cleanup. [2.0.7 / 2014-01-16](https://github.com/GoalSmashers/clean-css/compare/v2.0.6...v2.0.7) ================== diff --git a/lib/imports/inliner.js b/lib/imports/inliner.js index 29d309c5..2b9d5f0d 100644 --- a/lib/imports/inliner.js +++ b/lib/imports/inliner.js @@ -34,6 +34,7 @@ module.exports = function Inliner(context, options) { var nextEnd = 0; var cursor = 0; var isComment = commentScanner(data); + var afterContent = contentScanner(data); options.relativeTo = options.relativeTo || options.root; options._baseRelativeTo = options._baseRelativeTo || options.relativeTo; @@ -59,7 +60,9 @@ module.exports = function Inliner(context, options) { shared.done.push(data.substring(cursor, nextStart)); shared.left.unshift([data.substring(nextEnd + 1), options]); - return inline(data, nextStart, nextEnd, options); + return afterContent(nextStart) ? + processNext(options) : + inline(data, nextStart, nextEnd, options); } // no @import matched in current data @@ -125,6 +128,22 @@ module.exports = function Inliner(context, options) { return scanner; }; + var contentScanner = function(data) { + var isComment = commentScanner(data); + var firstContentIdx = -1; + while (true) { + firstContentIdx = data.indexOf('{', firstContentIdx + 1); + if (firstContentIdx == -1 || !isComment(firstContentIdx)) + break; + } + + return function(idx) { + return firstContentIdx > -1 ? + idx > firstContentIdx : + false; + }; + }; + var inline = function(data, nextStart, nextEnd, options) { var importDeclaration = data .substring(data.indexOf(' ', nextStart) + 1, nextEnd) diff --git a/test/unit-test.js b/test/unit-test.js index 1a56bf89..6f3bb301 100644 --- a/test/unit-test.js +++ b/test/unit-test.js @@ -1082,8 +1082,8 @@ title']{display:block}", '' ], 'of more files': [ - "@import url(test/data/partials/one.css);\n\na{display:block}\n\n@import url(test/data/partials/extra/three.css);", - ".one{color:red}a{display:block}.three{color:#0f0}" + "@import url(test/data/partials/one.css);\n\n@import url(test/data/partials/extra/three.css);\n\na{display:block}", + ".one{color:red}.three{color:#0f0}a{display:block}" ], 'of more files with media': [ "@import url(test/data/partials/one.css) screen;@import url(test/data/partials/extra/three.css) tv;", @@ -1128,6 +1128,14 @@ title']{display:block}", 'of a file (with media) with a comment': [ '@import url(test/data/partials/comment.css) screen and (device-height: 600px);', '@media screen and (device-height:600px){a{display:block}}' + ], + 'after standard content': [ + "a{display:block}@import url(test/data/partials/one.css);body{margin:0}", + "a{display:block}body{margin:0}" + ], + 'after quoted content': [ + "/*a{display:block}*/@import url(test/data/partials/one.css);", + ".one{color:red}" ] }, { root: process.cwd() }), '@import with absolute paths': cssContext({ @@ -1144,8 +1152,8 @@ title']{display:block}", ".one{color:red}" ], 'of two files with mixed paths': [ - "@import url(/partials/one.css);a{display:block}@import url(partials/extra/three.css);", - ".one{color:red}a{display:block}.three{color:#0f0}" + "@import url(/partials/one.css);@import url(partials/extra/three.css);a{display:block}", + ".one{color:red}.three{color:#0f0}a{display:block}" ], 'of a multi-level, circular dependency file': [ "@import url(/partials/two.css);", -- 2.34.1