Skip to content

Commit d83cd7f

Browse files
fix: unit parsing (TrySound#58)
1 parent 13ab2c7 commit d83cd7f

File tree

2 files changed

+216
-47
lines changed

2 files changed

+216
-47
lines changed

lib/unit.js

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,117 @@ var dot = ".".charCodeAt(0);
44
var exp = "e".charCodeAt(0);
55
var EXP = "E".charCodeAt(0);
66

7+
// Check if three code points would start a number
8+
// https://www.w3.org/TR/css-syntax-3/#starts-with-a-number
9+
function likeNumber(value) {
10+
var code = value.charCodeAt(0);
11+
var nextCode;
12+
13+
if (code === plus || code === minus) {
14+
nextCode = value.charCodeAt(1);
15+
16+
if (nextCode >= 48 && nextCode <= 57) {
17+
return true;
18+
}
19+
20+
var nextNextCode = value.charCodeAt(2);
21+
22+
if (nextCode === dot && nextNextCode >= 48 && nextNextCode <= 57) {
23+
return true;
24+
}
25+
26+
return false;
27+
}
28+
29+
if (code === dot) {
30+
nextCode = value.charCodeAt(1);
31+
32+
if (nextCode >= 48 && nextCode <= 57) {
33+
return true;
34+
}
35+
36+
return false;
37+
}
38+
39+
if (code >= 48 && code <= 57) {
40+
return true;
41+
}
42+
43+
return false;
44+
}
45+
46+
// Consume a number
47+
// https://www.w3.org/TR/css-syntax-3/#consume-number
748
module.exports = function(value) {
849
var pos = 0;
950
var length = value.length;
10-
var dotted = false;
11-
var sciPos = -1;
12-
var containsNumber = false;
1351
var code;
52+
var nextCode;
53+
var nextNextCode;
54+
55+
if (length === 0 || !likeNumber(value)) {
56+
return false;
57+
}
58+
59+
code = value.charCodeAt(pos);
60+
61+
if (code === plus || code === minus) {
62+
pos++;
63+
}
1464

1565
while (pos < length) {
1666
code = value.charCodeAt(pos);
1767

18-
if (code >= 48 && code <= 57) {
19-
containsNumber = true;
20-
} else if (code === exp || code === EXP) {
21-
if (sciPos > -1 || pos === 0) {
22-
break;
23-
}
24-
sciPos = pos;
68+
if (code < 48 || code > 57) {
69+
break;
70+
}
2571

26-
var nextCode = value.charCodeAt(pos + 1);
72+
pos += 1;
73+
}
2774

28-
if (
29-
nextCode === plus ||
30-
nextCode === minus ||
31-
(nextCode >= 48 && nextCode <= 57)
32-
) {
33-
if (nextCode === plus || nextCode === minus) {
34-
var nextNextCode = value.charCodeAt(pos + 2);
75+
code = value.charCodeAt(pos);
76+
nextCode = value.charCodeAt(pos + 1);
3577

36-
if (nextNextCode < 48 || nextNextCode > 57) {
37-
break;
38-
}
78+
if (code === dot && nextCode >= 48 && nextCode <= 57) {
79+
pos += 2;
3980

40-
pos += 1;
41-
}
81+
while (pos < length) {
82+
code = value.charCodeAt(pos);
4283

43-
pos += 1;
44-
} else {
84+
if (code < 48 || code > 57) {
4585
break;
4686
}
47-
} else if (code === dot) {
48-
if (dotted) {
49-
break;
50-
}
51-
dotted = true;
52-
} else if (code === plus || code === minus) {
53-
if (pos !== 0) {
54-
break;
55-
}
56-
} else {
57-
break;
58-
}
5987

60-
pos += 1;
88+
pos += 1;
89+
}
6190
}
6291

63-
if (sciPos + 1 === pos) pos--;
92+
code = value.charCodeAt(pos);
93+
nextCode = value.charCodeAt(pos + 1);
94+
nextNextCode = value.charCodeAt(pos + 2);
95+
96+
if (
97+
(code === exp || code === EXP) &&
98+
((nextCode >= 48 && nextCode <= 57) ||
99+
((nextCode === plus || nextCode === minus) &&
100+
nextNextCode >= 48 &&
101+
nextNextCode <= 57))
102+
) {
103+
pos += nextCode === plus || nextCode === minus ? 3 : 2;
104+
105+
while (pos < length) {
106+
code = value.charCodeAt(pos);
64107

65-
return containsNumber
66-
? {
67-
number: value.slice(0, pos),
68-
unit: value.slice(pos)
108+
if (code < 48 || code > 57) {
109+
break;
69110
}
70-
: false;
111+
112+
pos += 1;
113+
}
114+
}
115+
116+
return {
117+
number: value.slice(0, pos),
118+
unit: value.slice(pos)
119+
};
71120
};

test/unit.js

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ var tests = [
1212
},
1313
{
1414
fixture: "2.",
15-
expected: { number: "2.", unit: "" }
15+
expected: { number: "2", unit: "." }
1616
},
1717
{
1818
fixture: "+2.",
19-
expected: { number: "+2.", unit: "" }
19+
expected: { number: "+2", unit: "." }
2020
},
2121
{
2222
fixture: "-2.",
23-
expected: { number: "-2.", unit: "" }
23+
expected: { number: "-2", unit: "." }
2424
},
2525
{
2626
fixture: "+-2.",
@@ -149,6 +149,126 @@ var tests = [
149149
{
150150
fixture: "-100.1e-1e-1px",
151151
expected: { number: "-100.1e-1", unit: "e-1px" }
152+
},
153+
{
154+
fixture: ".5px",
155+
expected: { number: ".5", unit: "px" }
156+
},
157+
{
158+
fixture: "+.5px",
159+
expected: { number: "+.5", unit: "px" }
160+
},
161+
{
162+
fixture: "-.5px",
163+
expected: { number: "-.5", unit: "px" }
164+
},
165+
{
166+
fixture: ".5e1px",
167+
expected: { number: ".5e1", unit: "px" }
168+
},
169+
{
170+
fixture: "-.5e1px",
171+
expected: { number: "-.5e1", unit: "px" }
172+
},
173+
{
174+
fixture: "+.5e1px",
175+
expected: { number: "+.5e1", unit: "px" }
176+
},
177+
{
178+
fixture: ".5e1e1px",
179+
expected: { number: ".5e1", unit: "e1px" }
180+
},
181+
{
182+
fixture: ".5.5px",
183+
expected: { number: ".5", unit: ".5px" }
184+
},
185+
{
186+
fixture: "1e",
187+
expected: { number: "1", unit: "e" }
188+
},
189+
{
190+
fixture: "1e1",
191+
expected: { number: "1e1", unit: "" }
192+
},
193+
{
194+
fixture: "1ee",
195+
expected: { number: "1", unit: "ee" }
196+
},
197+
{
198+
fixture: "1e+",
199+
expected: { number: "1", unit: "e+" }
200+
},
201+
{
202+
fixture: "1e-",
203+
expected: { number: "1", unit: "e-" }
204+
},
205+
{
206+
fixture: "1e+1",
207+
expected: { number: "1e+1", unit: "" }
208+
},
209+
{
210+
fixture: "1e++1",
211+
expected: { number: "1", unit: "e++1" }
212+
},
213+
{
214+
fixture: "1e--1",
215+
expected: { number: "1", unit: "e--1" }
216+
},
217+
{
218+
fixture: "+10",
219+
expected: { number: "+10", unit: "" }
220+
},
221+
{
222+
fixture: "-10",
223+
expected: { number: "-10", unit: "" }
224+
},
225+
{
226+
fixture: ".2px",
227+
expected: { number: ".2", unit: "px" }
228+
},
229+
{
230+
fixture: "-.2px",
231+
expected: { number: "-.2", unit: "px" }
232+
},
233+
{
234+
fixture: "+.2px",
235+
expected: { number: "+.2", unit: "px" }
236+
},
237+
{
238+
fixture: ".a",
239+
expected: false
240+
},
241+
{
242+
fixture: ".",
243+
expected: false
244+
},
245+
{
246+
fixture: "+",
247+
expected: false
248+
},
249+
{
250+
fixture: "-",
251+
expected: false
252+
},
253+
{
254+
fixture: "-a",
255+
expected: false
256+
},
257+
{
258+
fixture: "+a",
259+
expected: false
260+
},
261+
{
262+
fixture: "+.a",
263+
expected: false
264+
},
265+
{
266+
fixture: "-.a",
267+
expected: false
268+
},
269+
{
270+
fixture: "",
271+
expected: false
152272
}
153273
];
154274

0 commit comments

Comments
 (0)