Skip to content

Commit

Permalink
Fix a bug: css urls are incorrectly stripped of commas (#14476)
Browse files Browse the repository at this point in the history
Co-authored-by: fisker Cheung <lionkay@gmail.com>
  • Loading branch information
seiyab and fisker committed Mar 29, 2023
1 parent 281072b commit 9500403
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 15 deletions.
19 changes: 19 additions & 0 deletions changelog_unreleased/css/14476.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#### Fix url contains comma (#14476 by @seiyab)

<!-- prettier-ignore -->
```css
/* Input */
@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
}

/* Prettier stable */
@font-face {
src: url(RobotoFlex-VariableFont_GRADXTRAYOPQYTASYTDEYTFIYTLCYTUCopszslntwdthwght.ttf);
}

/* Prettier main */
@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
}
```
18 changes: 4 additions & 14 deletions src/language-css/parse/parse-value.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import PostcssValuesParser from "postcss-values-parser/lib/parser.js";
import getFunctionArgumentsText from "../utils/get-function-arguments-text.js";
import getValueRoot from "../utils/get-value-root.js";
import hasSCSSInterpolation from "../utils/has-scss-interpolation.js";
import hasStringOrFunction from "../utils/has-string-or-function.js";
import isSCSSVariable from "../utils/is-scss-variable.js";
import stringifyNode from "../utils/stringify-node.js";
import parseSelector from "./parse-selector.js";
import { addTypePrefix } from "./utils.js";

const getHighestAncestor = (node) => {
while (node.parent) {
node = node.parent;
}
return node;
};

function parseValueNode(valueNode, options) {
const { nodes } = valueNode;
let parenGroup = {
Expand Down Expand Up @@ -48,7 +42,7 @@ function parseValueNode(valueNode, options) {
if (node.type === "func" && node.value === "selector") {
node.group.groups = [
parseSelector(
getHighestAncestor(valueNode).text.slice(
getValueRoot(valueNode).text.slice(
node.group.open.sourceIndex + 1,
node.group.close.sourceIndex
)
Expand Down Expand Up @@ -76,10 +70,7 @@ function parseValueNode(valueNode, options) {
(!hasStringOrFunction(groupList) &&
!isSCSSVariable(groupList[0], options))
) {
const stringifiedContent = stringifyNode({
groups: node.group.groups,
});
node.group.groups = [stringifiedContent.trim()];
node.group.groups = [getFunctionArgumentsText(node)];
}
}
if (node.type === "paren" && node.value === "(") {
Expand Down Expand Up @@ -162,7 +153,6 @@ function parseNestedValue(node, options) {
}
}
}
delete node.parent;
}
return node;
}
Expand Down
13 changes: 13 additions & 0 deletions src/language-css/utils/get-function-arguments-text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import getValueRoot from "./get-value-root.js";

/**
* @param {*} node
* @returns {string}
*/
function getFunctionArgumentsText(node) {
return getValueRoot(node)
.text.slice(node.group.open.sourceIndex + 1, node.group.close.sourceIndex)
.trim();
}

export default getFunctionArgumentsText;
9 changes: 9 additions & 0 deletions src/language-css/utils/get-value-root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const getValueRoot = (node) => {
while (node.parent) {
node = node.parent;
}

return node;
};

export default getValueRoot;
6 changes: 5 additions & 1 deletion src/language-css/utils/has-string-or-function.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
function hasStringOrFunction(groupList) {
return groupList.some(
(group) => group.type === "string" || group.type === "func"
(group) =>
group.type === "string" ||
(group.type === "func" &&
// workaround false-positive func
!group.value.endsWith("\\"))
);
}

Expand Down
52 changes: 52 additions & 0 deletions tests/format/css/url/__snapshots__/jsfmt.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,63 @@ div {
background: -fb-url(/images/bg.png);
}
@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
src: url(foo.ttf?query=foo,bar,);
src: url(foo.woff2?foo=rgb\\(255,255,0\\));
}
a {
content: url(https://example.com/\\)\\).jpg);
content: url(https://example.com/\\(\\(.jpg);
content: url(https://example.com/\\ \\ .jpg);
content: url( https://example.com/\\)\\).jpg );
content: url( https://example.com/\\(\\(.jpg );
content: url( https://example.com/\\ \\ .jpg );
background:
no-repeat url(https://example.com/\\)\\).jpg),
no-repeat url(https://example.com/\\(\\(.jpg),
no-repeat url(https://example.com/\\ \\ .jpg),
no-repeat url( https://example.com/\\)\\).jpg ),
no-repeat url( https://example.com/\\(\\(.jpg ),
no-repeat url( https://example.com/\\ \\ .jpg ),
no-repeat url(foo.ttf?query=foo,bar,),
no-repeat url(foo.woff2?foo=rgb\\(255,255,0\\))
no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
;
}
=====================================output=====================================
div {
background: url(/images/bg.png);
background: -fb-url(/images/bg.png);
}
@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
src: url(foo.ttf?query=foo,bar,);
src: url(foo.woff2?foo=rgb\\(255,255,0\\));
}
a {
content: url(https://example.com/\\)\\).jpg);
content: url(https://example.com/\\(\\(.jpg);
content: url(https://example.com/\\ \\ .jpg);
content: url( https://example.com/\\)\\).jpg );
content: url( https://example.com/\\(\\(.jpg );
content: url(https://example.com/\\ \\ .jpg);
background: no-repeat url(https://example.com/\\)\\).jpg),
no-repeat url(https://example.com/\\(\\(.jpg),
no-repeat url(https://example.com/\\ \\ .jpg),
no-repeat url( https://example.com/\\)\\).jpg ),
no-repeat url( https://example.com/\\(\\(.jpg ),
no-repeat url( https://example.com/\\ \\ .jpg ),
no-repeat url(foo.ttf?query=foo,bar,),
no-repeat url(foo.woff2?foo=rgb\\(255,255,0\\))
no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
}
================================================================================
`;
27 changes: 27 additions & 0 deletions tests/format/css/url/url.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,30 @@ div {
background: url(/images/bg.png);
background: -fb-url(/images/bg.png);
}

@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
src: url(foo.ttf?query=foo,bar,);
src: url(foo.woff2?foo=rgb\(255,255,0\));
}

a {
content: url(https://example.com/\)\).jpg);
content: url(https://example.com/\(\(.jpg);
content: url(https://example.com/\ \ .jpg);
content: url( https://example.com/\)\).jpg );
content: url( https://example.com/\(\(.jpg );
content: url( https://example.com/\ \ .jpg );

background:
no-repeat url(https://example.com/\)\).jpg),
no-repeat url(https://example.com/\(\(.jpg),
no-repeat url(https://example.com/\ \ .jpg),
no-repeat url( https://example.com/\)\).jpg ),
no-repeat url( https://example.com/\(\(.jpg ),
no-repeat url( https://example.com/\ \ .jpg ),
no-repeat url(foo.ttf?query=foo,bar,),
no-repeat url(foo.woff2?foo=rgb\(255,255,0\))
no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
;
}

0 comments on commit 9500403

Please sign in to comment.