fix: match parens recursively on URLs to not fix embeded calls (#192)

master
John Anderson 2017-03-16 16:22:26 -05:00 committed by Michael Ciniawsky
parent b48121e77c
commit 71e0908536
2 changed files with 44 additions and 3 deletions

View File

@ -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; });

View File

@ -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,<svg><feFlood flood-color=\"rgba(0,0,0,0.5)\" /></svg>')";
assertUrl(
"body: { background: " + svg + " }"
);
});
});