Skip to content

Commit 5c85840

Browse files
committed
Better matching and escpaing
1 parent 459ddea commit 5c85840

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

lib/parseValues.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ function endSpacingMatch(match) {
2323
}
2424

2525
function unescapeString(content) {
26-
return content.replace(/\\./g, function(escaped) {
27-
return escaped.substr(1);
26+
return content.replace(/\\([a-fA-F0-9]{4}|.)/g, function(escaped) {
27+
if(escaped.length > 2) {
28+
return String.fromCharCode(parseInt(escaped.substr(1), 16));
29+
} else {
30+
return escaped.substr(1);
31+
}
2832
});
2933
}
3034

@@ -87,6 +91,7 @@ function nestedItemEndMatch(match, spacing, remaining) {
8791
this.value.after = spacing;
8892
}
8993
this.root = this.stack.pop();
94+
this.value = this.root.nodes[this.root.nodes.length - 1];
9095
}
9196
}
9297

@@ -125,7 +130,7 @@ var parser = new Parser({
125130
"url\\((\\s*)(\"(?:[^\\\\\"]|\\\\.)*\")(\\s*)\\)": urlMatch,
126131
"url\\((\\s*)('(?:[^\\\\']|\\\\.)*')(\\s*)\\)": urlMatch,
127132
"url\\((\\s*)((?:[^\\\\)'\"]|\\\\.)*)(\\s*)\\)": urlMatch,
128-
"(\\w+)\\((\\s*)": nestedItemMatch,
133+
"([\\w\-]+)\\((\\s*)": nestedItemMatch,
129134
"(\\s*)(\\))": nestedItemEndMatch,
130135
",(\\s*)": commaMatch,
131136
"\\s+$": endSpacingMatch,

lib/stringifyValues.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,27 @@
22

33
var stringify;
44

5+
function escape(str, stringType) {
6+
return str.replace(/["'\\\x80-\uFFFF]/g, function(match) {
7+
switch(match) {
8+
case "\"":
9+
if(stringType === "\"") {
10+
return "\\\"";
11+
}
12+
return match;
13+
case "'":
14+
if(stringType === "'") {
15+
return "\\'";
16+
}
17+
return match;
18+
case "\\":
19+
return "\\\\";
20+
default:
21+
return "\\" + (0x10000 + match.charCodeAt(0)).toString(16).substr(1);
22+
}
23+
});
24+
}
25+
526
function stringifyWithoutBeforeAfter(tree) {
627
switch(tree.type) {
728
case "values":
@@ -19,9 +40,9 @@ function stringifyWithoutBeforeAfter(tree) {
1940
case "string":
2041
switch(tree.stringType) {
2142
case "'":
22-
return "'" + tree.value.replace(/'/g, "\\'") + "'";
43+
return "'" + escape(tree.value, "'") + "'";
2344
case "\"":
24-
return "\"" + tree.value.replace(/"/g, "\\\"") + "\"";
45+
return "\"" + escape(tree.value, "\"") + "\"";
2546
}
2647
/* istanbul ignore next */
2748
throw new Error("Invalid stringType");

test/test-cases-values.js

+23
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,28 @@ module.exports = {
123123
], before: " ", after: "\t" }
124124
]
125125
}
126+
],
127+
"escaped unicode": [
128+
"'\\f0e3\\\\\\'\"'",
129+
singleValue([
130+
{ type: "string", stringType: "'", value: "\uf0e3\\'\"" }
131+
])
132+
],
133+
"escaped unicode 2": [
134+
"\"\\f0e3\\\\'\\\"\"",
135+
singleValue([
136+
{ type: "string", stringType: "\"", value: "\uf0e3\\'\"" }
137+
])
138+
],
139+
"nested-item-with append": [
140+
"linear-gradient(45deg) 25%",
141+
singleValue([
142+
{ type: "nested-item", name: "linear-gradient", nodes: [
143+
{ type: "value", nodes: [
144+
{ type: "item", name: "45deg"}
145+
]}
146+
], after: " " },
147+
{ type: "item", name: "25%" }
148+
])
126149
]
127150
};

0 commit comments

Comments
 (0)