diff --git a/fixUrls.js b/fixUrls.js index 148384d..d215ae8 100644 --- a/fixUrls.js +++ b/fixUrls.js @@ -29,9 +29,35 @@ module.exports = function (css) { var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/"); // convert each url(...) - var fixedCss = css.replace(/url *\( *(.+?) *\)/g, function(fullMatch, origUrl) { + /* + This regular expression is just a way to recursively match brackets within + a string. + + /url\s*\( = Match on the word "url" with any whitespace after it and then a parens + ( = Start a capturing group + (?: = Start a non-capturing group + [^)(] = Match anything that isn't a parentheses + | = OR + \( = Match a start parentheses + (?: = Start another non-capturing groups + [^)(]+ = Match anything that isn't a parentheses + | = OR + \( = Match a start parentheses + [^)(]* = Match anything that isn't a parentheses + \) = Match a end parentheses + ) = End Group + *\) = Match anything and then a close parens + ) = Close non-capturing group + * = Match anything + ) = Close capturing group + \) = Match a close parens + + /gi = Get all matches, not the first. Be case insensitive. + */ + var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) { // strip quotes (if they exist) var unquotedOrigUrl = origUrl + .trim() .replace(/^"(.*)"$/, function(o, $1){ return $1; }) .replace(/^'(.*)'$/, function(o, $1){ return $1; }); diff --git a/test/fixUrlsTest.js b/test/fixUrlsTest.js index d41da4c..f8fa7fb 100644 --- a/test/fixUrlsTest.js +++ b/test/fixUrlsTest.js @@ -22,7 +22,7 @@ describe("fix urls tests", function() { var resultCss = fixUrls(origCss, specialUrl || defaultUrl); expectedCss = expectedCss || origCss; - assert.equal(resultCss, expectedCss); + assert.equal(expectedCss, resultCss); }; // no change @@ -100,11 +100,18 @@ describe("fix urls tests", function() { // relative urls it("Relative url", function() { assertUrl( - "body { background-image:url(bg.jpg); }", + "body { background-image:url (bg.jpg); }", "body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }" ); }); + it("Relative url case sensitivity", function() { + assertUrl( + "body { background-image:URL (bg.jpg); }", + "body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }" + ); + }); + it("Relative url with path", function() { assertUrl( "body { background-image:url(c/d/bg.jpg); }", @@ -180,4 +187,12 @@ describe("fix urls tests", function() { "http://x.y.z" ); }); + + it("Doesn't break inline SVG", function() { + const svg = "url('data:image/svg+xml;charset=utf-8,')"; + + assertUrl( + "body: { background: " + svg + " }" + ); + }); });