From bb5dcd9186816062e32cd5d8a74682f2af7a1062 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sat, 18 Apr 2015 01:11:28 +0100 Subject: [PATCH] Fixes #504 - keeping `url()` quotes. It's off by default. Kudos to @elcodedocle for inspiration. --- History.md | 1 + README.md | 1 + lib/clean.js | 2 +- lib/text/urls-processor.js | 9 +++++---- lib/utils/compatibility.js | 3 +++ test/integration-test.js | 6 ++++++ test/utils/compatibility-test.js | 3 +++ 7 files changed, 20 insertions(+), 5 deletions(-) diff --git a/History.md b/History.md index beae4a0f..9ca27ea3 100644 --- a/History.md +++ b/History.md @@ -16,6 +16,7 @@ * Fixed issue [#487](https://github.com/jakubpawlowicz/clean-css/issues/487) - source map paths under Windows. * Fixed issue [#490](https://github.com/jakubpawlowicz/clean-css/issues/490) - vendor prefixed multivalue `background`. * Fixed issue [#500](https://github.com/jakubpawlowicz/clean-css/issues/500) - merging duplicate adjacent properties. +* Fixed issue [#504](https://github.com/jakubpawlowicz/clean-css/issues/504) - keeping `url()` quotes. * Fixed issue [#507](https://github.com/jakubpawlowicz/clean-css/issues/507) - merging longhands into many shorthands. * Fixed issue [#508](https://github.com/jakubpawlowicz/clean-css/issues/508) - removing duplicate media queries. * Fixed issue [#521](https://github.com/jakubpawlowicz/clean-css/issues/521) - unit optimizations inside `calc()`. diff --git a/README.md b/README.md index 354d814f..4fddbc6c 100644 --- a/README.md +++ b/README.md @@ -311,6 +311,7 @@ with the following options available: * `'[+-]properties.backgroundSizeMerging'` - turn on / off background-size merging into shorthand * `'[+-]properties.merging'` - turn on / off property merging based on understandability * `'[+-]properties.spaceAfterClosingBrace'` - turn on / off removing space after closing brace - `url() no-repeat` into `url()no-repeat` +* `'[+-]properties.urlQuotes'` - turn on / off `url()` quoting * `'[+-]properties.zeroUnits'` - turn on / off units removal after a `0` value * `'[+-]selectors.adjacentSpace'` - turn on / off extra space before `nav` element * `'[+-]selectors.ie7Hack'` - turn on / off IE7 selector hack removal (`*+html...`) diff --git a/lib/clean.js b/lib/clean.js index d5fe4bd2..c6917b86 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -161,7 +161,7 @@ function minify(context, data) { var commentsProcessor = new CommentsProcessor(context, options.keepSpecialComments, options.keepBreaks, options.sourceMap); var expressionsProcessor = new ExpressionsProcessor(options.sourceMap); var freeTextProcessor = new FreeTextProcessor(options.sourceMap); - var urlsProcessor = new UrlsProcessor(context, options.sourceMap); + var urlsProcessor = new UrlsProcessor(context, options.sourceMap, options.compatibility.properties.urlQuotes); var urlRebase = new UrlRebase(context); var selectorsOptimizer = new SelectorsOptimizer(options, context); diff --git a/lib/text/urls-processor.js b/lib/text/urls-processor.js index eb924c55..3f913ff4 100644 --- a/lib/text/urls-processor.js +++ b/lib/text/urls-processor.js @@ -3,10 +3,11 @@ var UrlScanner = require('../utils/url-scanner'); var lineBreak = require('os').EOL; -function UrlsProcessor(context, saveWaypoints) { +function UrlsProcessor(context, saveWaypoints, keepUrlQuotes) { this.urls = new EscapeStore('URL'); this.context = context; this.saveWaypoints = saveWaypoints; + this.keepUrlQuotes = keepUrlQuotes; } // Strip urls by replacing them by a special @@ -33,7 +34,7 @@ UrlsProcessor.prototype.escape = function (data) { }); }; -function normalize(url) { +function normalize(url, keepUrlQuotes) { url = url .replace(/^url/gi, 'url') .replace(/\\?\n|\\?\r\n/g, '') @@ -41,7 +42,7 @@ function normalize(url) { .replace(/^url\((['"])? /, 'url($1') .replace(/ (['"])?\)$/, '$1)'); - if (!/url\(.*[\s\(\)].*\)/.test(url) && !/url\(['"]data:[^;]+;charset/.test(url)) + if (!keepUrlQuotes && !/url\(.*[\s\(\)].*\)/.test(url) && !/url\(['"]data:[^;]+;charset/.test(url)) url = url.replace(/["']/g, ''); return url; @@ -57,7 +58,7 @@ UrlsProcessor.prototype.restore = function (data) { break; tempData.push(data.substring(cursor, nextMatch.start)); - var url = normalize(this.urls.restore(nextMatch.match)); + var url = normalize(this.urls.restore(nextMatch.match), this.keepUrlQuotes); tempData.push(url); cursor = nextMatch.end; diff --git a/lib/utils/compatibility.js b/lib/utils/compatibility.js index 3d24301f..c5f6971c 100644 --- a/lib/utils/compatibility.js +++ b/lib/utils/compatibility.js @@ -11,6 +11,7 @@ var DEFAULTS = { ieSuffixHack: false, // \9 suffix hacks on IE merging: true, // merging properties into one spaceAfterClosingBrace: false, // 'url() no-repeat' to 'url()no-repeat' + urlQuotes: false, // whether to wrap content of `url()` into quotes or not zeroUnits: true // 0[unit] -> 0 }, selectors: { @@ -32,6 +33,7 @@ var DEFAULTS = { ieSuffixHack: true, merging: false, spaceAfterClosingBrace: true, + urlQuotes: false, zeroUnits: true }, selectors: { @@ -53,6 +55,7 @@ var DEFAULTS = { ieSuffixHack: true, merging: false, spaceAfterClosingBrace: true, + urlQuotes: false, zeroUnits: true }, selectors: { diff --git a/test/integration-test.js b/test/integration-test.js index ffe86894..84de7b21 100644 --- a/test/integration-test.js +++ b/test/integration-test.js @@ -983,6 +983,12 @@ path")}', 'urls whitespace in compatibility mode': cssContext({ 'keeps spaces as they are': '*{background:url(test.png) no-repeat}' }, { compatibility: 'ie8' }), + 'urls quotes in compatibility mode': cssContext({ + 'keeps quotes as they are': [ + 'div{background:url("test.png")}', + 'div{background:url("test.png")}' + ] + }, { compatibility: { properties: { urlQuotes: true } } }), 'urls rewriting - no root or target': cssContext({ 'no @import': [ 'a{background:url(test/fixtures/partials/extra/down.gif) no-repeat}', diff --git a/test/utils/compatibility-test.js b/test/utils/compatibility-test.js index b0c43bd0..cfca0ce7 100644 --- a/test/utils/compatibility-test.js +++ b/test/utils/compatibility-test.js @@ -16,6 +16,7 @@ vows.describe(Compatibility) assert.isFalse(options.properties.backgroundSizeMerging); assert.isTrue(options.properties.merging); assert.isFalse(options.properties.spaceAfterClosingBrace); + assert.isFalse(options.properties.urlQuotes); assert.isTrue(options.units.rem); assert.isTrue(options.colors.opacity); assert.deepEqual(options.selectors.special, /(\-moz\-|\-ms\-|\-o\-|\-webkit\-|:dir\([a-z-]*\)|:first(?![a-z-])|:fullscreen|:left|:read-only|:read-write|:right)/); @@ -61,6 +62,7 @@ vows.describe(Compatibility) assert.isFalse(options.properties.backgroundSizeMerging); assert.isFalse(options.properties.merging); assert.isTrue(options.properties.spaceAfterClosingBrace); + assert.isFalse(options.properties.urlQuotes); assert.isTrue(options.properties.zeroUnits); assert.isFalse(options.units.rem); assert.isFalse(options.colors.opacity); @@ -79,6 +81,7 @@ vows.describe(Compatibility) assert.isFalse(options.properties.backgroundSizeMerging); assert.isFalse(options.properties.merging); assert.isTrue(options.properties.spaceAfterClosingBrace); + assert.isFalse(options.properties.urlQuotes); assert.isTrue(options.properties.zeroUnits); assert.isFalse(options.units.rem); assert.isFalse(options.colors.opacity); -- 2.34.1