Skip to content

Commit 1d1c8e7

Browse files
committed
fixes #29; calc with leading operator within parens
1 parent 2a2e99e commit 1d1c8e7

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

lib/number.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class NumberNode extends Node {
1111
}
1212

1313
toString () {
14-
// console.log('node >', 'toString:', this.value);
15-
1614
return [
1715
this.raws.before,
1816
String(this.value),

lib/parser.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ module.exports = class Parser {
146146
if (!this.options.loose) {
147147
if (this.position > 0) {
148148
if (this.current.type === 'func' && this.current.value === 'calc') {
149-
if (this.prevToken[0] !== 'space') {
149+
// allow operators to be proceeded by spaces and opening parens
150+
if (this.prevToken[0] !== 'space' && this.prevToken[0] !== '(') {
150151
this.error('Syntax Error', this.currToken);
151152
}
152153
// valid: calc(1 - +2)
@@ -155,8 +156,10 @@ module.exports = class Parser {
155156
this.error('Syntax Error', this.currToken);
156157
}
157158
// valid: calc(1 - +2)
159+
// valid: calc(-0.5 + 2)
158160
// invalid: calc(1 -2)
159-
else if (this.nextToken[0] === 'word' && this.current.last.type !== 'operator') {
161+
else if (this.nextToken[0] === 'word' && this.current.last.type !== 'operator' &&
162+
this.current.last.value !== '(') {
160163
this.error('Syntax Error', this.currToken);
161164
}
162165
}

test/function.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ describe('Parser → Function', () => {
3535
{ type: 'word', value: 'baz' }
3636
]
3737
},
38+
// not ready yet - #30
39+
// {
40+
// it: 'should loosely parse url function with sub func',
41+
// test: 'url(var(foo))',
42+
// loose: true,
43+
// expected: [
44+
// { type: 'func', value: 'url' },
45+
// { type: 'paren', value: '(' },
46+
// { type: 'paren', value: ')' }
47+
// ]
48+
// },
3849
{
3950
it: 'should parse url function',
4051
test: 'url( /gfx/img/bg.jpg )',
@@ -70,6 +81,21 @@ describe('Parser → Function', () => {
7081
{ type: 'paren', value: ')' }
7182
]
7283
},
84+
{
85+
it: 'should parse calc function with number and var #29',
86+
test: 'calc(-0.5 * var(foo))',
87+
expected: [
88+
{ type: 'func', value: 'calc' },
89+
{ type: 'paren', value: '(' },
90+
{ type: 'number', value: '-0.5', unit: '' },
91+
{ type: 'operator', value: '*' },
92+
{ type: 'func', value: 'var' },
93+
{ type: 'paren', value: '(' },
94+
{ type: 'word', value: 'foo' },
95+
{ type: 'paren', value: ')' },
96+
{ type: 'paren', value: ')' }
97+
]
98+
},
7399
{
74100
it: 'should parse calc function with nutty numbers',
75101
test: 'calc(1px + -2vw - 4px)',
@@ -140,7 +166,7 @@ describe('Parser → Function', () => {
140166

141167
fixtures.forEach((fixture) => {
142168
it(fixture.it, () => {
143-
let ast = new Parser(fixture.test).parse(),
169+
let ast = new Parser(fixture.test, { loose: fixture.loose }).parse(),
144170
index = 0;
145171

146172
ast.first.walk((node) => {

test/number.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ describe('Parser → Number', () => {
1111
test: '.23rem',
1212
expected: { value: '.23', unit: 'rem', length: 1 }
1313
},
14+
{
15+
test: '0.5',
16+
expected: { value: '0.5', unit: '', length: 1 }
17+
},
18+
{
19+
test: '-0.5',
20+
expected: { value: '-0.5', unit: '', length: 1 }
21+
},
22+
{
23+
test: '-0.5 * 1',
24+
expected: { value: '1', unit: '', length: 3 }
25+
},
1426
{
1527
test: '.2.3rem',
1628
expected: { value: '.2', unit: '.3rem', length: 1 }

0 commit comments

Comments
 (0)