Skip to content

Commit 71e0908

Browse files
sontekmichael-ciniawsky
authored andcommitted
fix: match parens recursively on URLs to not fix embeded calls (#192)
1 parent b48121e commit 71e0908

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

fixUrls.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,35 @@ module.exports = function (css) {
2929
var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");
3030

3131
// convert each url(...)
32-
var fixedCss = css.replace(/url *\( *(.+?) *\)/g, function(fullMatch, origUrl) {
32+
/*
33+
This regular expression is just a way to recursively match brackets within
34+
a string.
35+
36+
/url\s*\( = Match on the word "url" with any whitespace after it and then a parens
37+
( = Start a capturing group
38+
(?: = Start a non-capturing group
39+
[^)(] = Match anything that isn't a parentheses
40+
| = OR
41+
\( = Match a start parentheses
42+
(?: = Start another non-capturing groups
43+
[^)(]+ = Match anything that isn't a parentheses
44+
| = OR
45+
\( = Match a start parentheses
46+
[^)(]* = Match anything that isn't a parentheses
47+
\) = Match a end parentheses
48+
) = End Group
49+
*\) = Match anything and then a close parens
50+
) = Close non-capturing group
51+
* = Match anything
52+
) = Close capturing group
53+
\) = Match a close parens
54+
55+
/gi = Get all matches, not the first. Be case insensitive.
56+
*/
57+
var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
3358
// strip quotes (if they exist)
3459
var unquotedOrigUrl = origUrl
60+
.trim()
3561
.replace(/^"(.*)"$/, function(o, $1){ return $1; })
3662
.replace(/^'(.*)'$/, function(o, $1){ return $1; });
3763

test/fixUrlsTest.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe("fix urls tests", function() {
2222
var resultCss = fixUrls(origCss, specialUrl || defaultUrl);
2323
expectedCss = expectedCss || origCss;
2424

25-
assert.equal(resultCss, expectedCss);
25+
assert.equal(expectedCss, resultCss);
2626
};
2727

2828
// no change
@@ -100,11 +100,18 @@ describe("fix urls tests", function() {
100100
// relative urls
101101
it("Relative url", function() {
102102
assertUrl(
103-
"body { background-image:url(bg.jpg); }",
103+
"body { background-image:url (bg.jpg); }",
104104
"body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }"
105105
);
106106
});
107107

108+
it("Relative url case sensitivity", function() {
109+
assertUrl(
110+
"body { background-image:URL (bg.jpg); }",
111+
"body { background-image:url(\"https://x.y.z/a/bg.jpg\"); }"
112+
);
113+
});
114+
108115
it("Relative url with path", function() {
109116
assertUrl(
110117
"body { background-image:url(c/d/bg.jpg); }",
@@ -180,4 +187,12 @@ describe("fix urls tests", function() {
180187
"http://x.y.z"
181188
);
182189
});
190+
191+
it("Doesn't break inline SVG", function() {
192+
const svg = "url('data:image/svg+xml;charset=utf-8,<svg><feFlood flood-color=\"rgba(0,0,0,0.5)\" /></svg>')";
193+
194+
assertUrl(
195+
"body: { background: " + svg + " }"
196+
);
197+
});
183198
});

0 commit comments

Comments
 (0)