Skip to content

Commit d6c3d91

Browse files
committed
feat: Add support for interpolations
1 parent d383e7f commit d6c3d91

File tree

4 files changed

+174
-27
lines changed

4 files changed

+174
-27
lines changed

lib/parse.js

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,6 @@ var openInterpolation = "{".charCodeAt(0);
1414
var closeInterpolation = "}".charCodeAt(0);
1515
var isUnicodeRange = /^[a-f0-9?-]+$/i;
1616

17-
function isOpenInterpolation(code, value, pos, interpolation) {
18-
return (
19-
interpolation !== null &&
20-
interpolation.charCodeAt(0) === code &&
21-
value.charCodeAt(pos + 1) === openInterpolation
22-
);
23-
}
24-
25-
function isCloseInterpolation(code) {
26-
return code === closeInterpolation;
27-
}
28-
2917
module.exports = function(input, options) {
3018
var tokens = [];
3119
var value = input;
@@ -70,7 +58,7 @@ module.exports = function(input, options) {
7058

7159
prev = tokens[tokens.length - 1];
7260
if (
73-
(code === closeParentheses || isCloseInterpolation(code)) &&
61+
(code === closeParentheses || code === closeInterpolation) &&
7462
balanced
7563
) {
7664
after = token;
@@ -177,18 +165,15 @@ module.exports = function(input, options) {
177165
code = value.charCodeAt(pos);
178166

179167
// Open parentheses
180-
} else if (
181-
openParentheses === code ||
182-
isOpenInterpolation(code, value, pos, interpolationPrefix)
183-
) {
168+
} else if (openParentheses === code || openInterpolation === code) {
184169
var isFunction = openParentheses === code;
185170
// Whitespaces after open parentheses
186-
next = isFunction ? pos : pos + 1;
171+
next = pos;
187172
do {
188173
next += 1;
189174
code = value.charCodeAt(next);
190175
} while (code <= 32);
191-
parenthesesOpenPos = isFunction ? pos : pos + 1;
176+
parenthesesOpenPos = pos;
192177
token = {
193178
type: isFunction ? "function" : "interpolation",
194179
sourceIndex: pos - name.length,
@@ -261,7 +246,7 @@ module.exports = function(input, options) {
261246

262247
// Close parentheses
263248
} else if (
264-
(code === closeParentheses || isCloseInterpolation(code)) &&
249+
(code === closeParentheses || code === closeInterpolation) &&
265250
balanced
266251
) {
267252
pos += 1;
@@ -293,24 +278,22 @@ module.exports = function(input, options) {
293278
code === colon ||
294279
code === slash ||
295280
code === openParentheses ||
296-
isOpenInterpolation(code, value, pos, interpolationPrefix) ||
281+
code === openInterpolation ||
282+
(interpolationPrefix && code === interpolationPrefix.charCodeAt(0)) ||
297283
(code === star &&
298284
parent &&
299285
parent.type === "function" &&
300286
parent.value === "calc") ||
301287
(code === slash &&
302288
parent.type === "function" &&
303289
parent.value === "calc") ||
304-
((code === closeParentheses || isCloseInterpolation(code)) &&
290+
((code === closeParentheses || code === closeInterpolation) &&
305291
balanced)
306292
)
307293
);
308294
token = value.slice(pos, next);
309295

310-
if (
311-
openParentheses === code ||
312-
isOpenInterpolation(code, value, pos, interpolationPrefix)
313-
) {
296+
if (openParentheses === code || openInterpolation === code) {
314297
name = token;
315298
} else if (
316299
(uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) &&

test/index.js

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test("ValueParser", function(tp) {
2121
});
2222

2323
tp.test("walk", function(t) {
24-
t.plan(5);
24+
t.plan(7);
2525
var result;
2626

2727
result = [];
@@ -117,6 +117,92 @@ test("ValueParser", function(tp) {
117117

118118
result = [];
119119

120+
parser("fn( ) --#{fn2( fn3())}", { interpolationPrefix: "#" }).walk(
121+
function(node) {
122+
if (node.type === "interpolation") {
123+
result.push(node);
124+
}
125+
}
126+
);
127+
128+
t.deepEqual(
129+
result,
130+
[
131+
{
132+
type: "interpolation",
133+
sourceIndex: 8,
134+
value: "#",
135+
before: "",
136+
after: "",
137+
nodes: [
138+
{
139+
type: "function",
140+
sourceIndex: 10,
141+
value: "fn2",
142+
before: " ",
143+
after: "",
144+
nodes: [
145+
{
146+
type: "function",
147+
sourceIndex: 15,
148+
value: "fn3",
149+
before: "",
150+
after: "",
151+
nodes: []
152+
}
153+
]
154+
}
155+
]
156+
}
157+
],
158+
"should process all interpolations with word"
159+
);
160+
161+
result = [];
162+
163+
parser("fn( ) /#{fn2( fn3())}", { interpolationPrefix: "#" }).walk(function(
164+
node
165+
) {
166+
if (node.type === "interpolation") {
167+
result.push(node);
168+
}
169+
});
170+
171+
t.deepEqual(
172+
result,
173+
[
174+
{
175+
type: "interpolation",
176+
sourceIndex: 7,
177+
value: "#",
178+
before: "",
179+
after: "",
180+
nodes: [
181+
{
182+
type: "function",
183+
sourceIndex: 9,
184+
value: "fn2",
185+
before: " ",
186+
after: "",
187+
nodes: [
188+
{
189+
type: "function",
190+
sourceIndex: 14,
191+
value: "fn3",
192+
before: "",
193+
after: "",
194+
nodes: []
195+
}
196+
]
197+
}
198+
]
199+
}
200+
],
201+
"should process all interpolations with divider (/)"
202+
);
203+
204+
result = [];
205+
120206
parser("fn( ) fn2( fn3())").walk(function(node) {
121207
if (node.type === "function") {
122208
result.push(node);

test/parse.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,70 @@ var tests = [
115115
}
116116
]
117117
},
118+
{
119+
message: "should process interpolation with word",
120+
fixture: "--#{name()}",
121+
options: {
122+
interpolationPrefix: "#"
123+
},
124+
expected: [
125+
{
126+
type: "word",
127+
sourceIndex: 0,
128+
value: "--"
129+
},
130+
{
131+
type: "interpolation",
132+
sourceIndex: 2,
133+
value: "#",
134+
before: "",
135+
after: "",
136+
nodes: [
137+
{
138+
type: "function",
139+
sourceIndex: 4,
140+
value: "name",
141+
before: "",
142+
after: "",
143+
nodes: []
144+
}
145+
]
146+
}
147+
]
148+
},
149+
{
150+
message: "should process interpolation with divider (/)",
151+
fixture: "/#{name()}",
152+
options: {
153+
interpolationPrefix: "#"
154+
},
155+
expected: [
156+
{
157+
type: "div",
158+
sourceIndex: 0,
159+
value: "/",
160+
before: "",
161+
after: ""
162+
},
163+
{
164+
type: "interpolation",
165+
sourceIndex: 1,
166+
value: "#",
167+
before: "",
168+
after: "",
169+
nodes: [
170+
{
171+
type: "function",
172+
sourceIndex: 3,
173+
value: "name",
174+
before: "",
175+
after: "",
176+
nodes: []
177+
}
178+
]
179+
}
180+
]
181+
},
118182
{
119183
message: "should process nested functions",
120184
fixture: "((()))",

test/stringify.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ var tests = [
6161
interpolationPrefix: "#"
6262
}
6363
},
64+
{
65+
message: "Should correctly process interpolation with word",
66+
fixture: "-#{url(\n)}",
67+
options: {
68+
interpolationPrefix: "#"
69+
}
70+
},
71+
{
72+
message: "Should correctly process interpolation with divider (/)",
73+
fixture: "/#{url(\n)}",
74+
options: {
75+
interpolationPrefix: "#"
76+
}
77+
},
6478
{
6579
message: "Should correctly process empty url with newline (LF)",
6680
fixture: "url(\n\n\n)"

0 commit comments

Comments
 (0)