diff --git a/lib/ValuesParser.js b/lib/ValuesParser.js
index 82d9e5a..5f65d6f 100644
--- a/lib/ValuesParser.js
+++ b/lib/ValuesParser.js
@@ -148,6 +148,8 @@ module.exports = class ValuesParser extends Parser {
if (Punctuation.chars.includes(type)) {
Punctuation.fromTokens(tokens, this);
+ } else if (type === 'word' && Operator.compact.test(value)) {
+ Operator.fromTokens(tokens, this);
} else if (Func.test(tokens)) {
Func.fromTokens(tokens, this);
} else if (this.options.interpolation && Interpolation.test(tokens, this)) {
diff --git a/lib/nodes/Operator.js b/lib/nodes/Operator.js
index 2fac9af..aed491c 100644
--- a/lib/nodes/Operator.js
+++ b/lib/nodes/Operator.js
@@ -14,6 +14,7 @@ const Node = require('./Node');
const operators = ['+', '-', '/', '*', '%', '=', '<=', '>=', '<', '>'];
const operRegex = new RegExp(`([/|*}])`);
+const compactRegex = /^\*\b/;
class Operator extends Node {
constructor(options) {
@@ -33,6 +34,10 @@ class Operator extends Node {
return operRegex;
}
+ static get compact() {
+ return compactRegex;
+ }
+
static tokenize(tokens, parser) {
const [first, ...rest] = tokens;
const [, value, startLine, , endLine, endChar] = first;
diff --git a/test/fixtures/func.js b/test/fixtures/func.js
index c58e3bf..7b4f6ea 100644
--- a/test/fixtures/func.js
+++ b/test/fixtures/func.js
@@ -29,6 +29,7 @@ module.exports = {
'lCH(40% 68.8 34.5 / 50%)',
'hwb(90deg 0% 0% / 0.5)',
'calc(-0.5 * var(foo))',
+ 'calc(var(--foo)*var(--bar))',
'calc(1px + -2vw - 4px)',
'calc(((768px - 100vw) / 2) - 15px)',
'bar(baz(black, 10%), 10%)',
diff --git a/test/snapshots/func.test.js.md b/test/snapshots/func.test.js.md
index 4591cb5..b91d405 100644
--- a/test/snapshots/func.test.js.md
+++ b/test/snapshots/func.test.js.md
@@ -5114,3 +5114,988 @@ Generated by [AVA](https://avajs.dev).
[Symbol(isClean)]: false,
},
]
+
+## calc(-0.5*var(foo))
+
+> Snapshot 1
+
+ 'calc(-0.5*var(foo))'
+
+> Snapshot 2
+
+ 'calc(-0.5*var(foo))'
+
+> Snapshot 3
+
+ [
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'calc',
+ nodes: [
+ Numeric {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '-0.5*var(foo)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'numeric',
+ unit: '',
+ value: '-0.5',
+ [Symbol(isClean)]: false,
+ },
+ Operator {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '-0.5*var(foo)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'operator',
+ value: '*',
+ [Symbol(isClean)]: false,
+ },
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: false,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: 'foo',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: 'foo',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(foo)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 9,
+ line: 1,
+ offset: 8,
+ },
+ input: Input {
+ css: '-0.5*var(foo)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(-0.5*var(foo))',
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 19,
+ line: 1,
+ offset: 18,
+ },
+ input: Input {
+ css: 'calc(-0.5*var(foo))',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ]
+
+## calc(var(--foo))
+
+> Snapshot 1
+
+ 'calc(var(--foo))'
+
+> Snapshot 2
+
+ 'calc(var(--foo))'
+
+> Snapshot 3
+
+ [
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'calc',
+ nodes: [
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--foo',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--foo',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--foo)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 4,
+ line: 1,
+ offset: 3,
+ },
+ input: Input {
+ css: 'var(--foo)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(var(--foo))',
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15,
+ },
+ input: Input {
+ css: 'calc(var(--foo))',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ]
+
+## calc(var(--foo) * var(--bar))
+
+> Snapshot 1
+
+ 'calc(var(--foo) * var(--bar))'
+
+> Snapshot 2
+
+ 'calc(var(--foo) * var(--bar))'
+
+> Snapshot 3
+
+ [
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'calc',
+ nodes: [
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--foo',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--foo',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--foo)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 4,
+ line: 1,
+ offset: 3,
+ },
+ input: Input {
+ css: 'var(--foo) * var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ Operator {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: ' ',
+ },
+ source: {
+ end: {
+ column: 12,
+ line: 1,
+ offset: 11,
+ },
+ input: Input {
+ css: 'var(--foo) * var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 12,
+ line: 1,
+ offset: 11,
+ },
+ },
+ type: 'operator',
+ value: '*',
+ [Symbol(isClean)]: false,
+ },
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--bar',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--bar',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--bar)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: ' ',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 17,
+ line: 1,
+ offset: 16,
+ },
+ input: Input {
+ css: 'var(--foo) * var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 14,
+ line: 1,
+ offset: 13,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(var(--foo) * var(--bar))',
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 29,
+ line: 1,
+ offset: 28,
+ },
+ input: Input {
+ css: 'calc(var(--foo) * var(--bar))',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ]
+
+## calc(var(--foo)* var(--bar))
+
+> Snapshot 1
+
+ 'calc(var(--foo)* var(--bar))'
+
+> Snapshot 2
+
+ 'calc(var(--foo)* var(--bar))'
+
+> Snapshot 3
+
+ [
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'calc',
+ nodes: [
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--foo',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--foo',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--foo)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 4,
+ line: 1,
+ offset: 3,
+ },
+ input: Input {
+ css: 'var(--foo)* var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ Operator {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ input: Input {
+ css: 'var(--foo)* var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ },
+ type: 'operator',
+ value: '*',
+ [Symbol(isClean)]: false,
+ },
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--bar',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--bar',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--bar)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: ' ',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15,
+ },
+ input: Input {
+ css: 'var(--foo)* var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 13,
+ line: 1,
+ offset: 12,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(var(--foo)* var(--bar))',
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 28,
+ line: 1,
+ offset: 27,
+ },
+ input: Input {
+ css: 'calc(var(--foo)* var(--bar))',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ]
+
+## calc(var(--foo)*var(--bar))
+
+> Snapshot 1
+
+ 'calc(var(--foo)*var(--bar))'
+
+> Snapshot 2
+
+ 'calc(var(--foo)*var(--bar))'
+
+> Snapshot 3
+
+ [
+ Func {
+ isColor: false,
+ isVar: false,
+ name: 'calc',
+ nodes: [
+ Func {
+ isColor: false,
+ isVar: true,
+ name: 'var',
+ nodes: [
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: '--foo',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--foo',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(--foo)',
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 4,
+ line: 1,
+ offset: 3,
+ },
+ input: Input {
+ css: 'var(--foo)*var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ Operator {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ input: Input {
+ css: 'var(--foo)*var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10,
+ },
+ },
+ type: 'operator',
+ value: '*var',
+ [Symbol(isClean)]: false,
+ },
+ Punctuation {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 15,
+ line: 1,
+ offset: 14,
+ },
+ input: Input {
+ css: 'var(--foo)*var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 15,
+ line: 1,
+ offset: 14,
+ },
+ },
+ type: 'punctuation',
+ value: '(',
+ [Symbol(isClean)]: false,
+ },
+ Word {
+ isColor: false,
+ isHex: false,
+ isUrl: false,
+ isVariable: true,
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ input: Input {
+ css: 'var(--foo)*var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'word',
+ value: '--bar',
+ [Symbol(isClean)]: false,
+ },
+ Punctuation {
+ parent: [Circular],
+ raws: {
+ after: '',
+ before: '',
+ },
+ source: {
+ end: {
+ column: 15,
+ line: 1,
+ offset: 14,
+ },
+ input: Input {
+ css: 'var(--foo)*var(--bar)',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 15,
+ line: 1,
+ offset: 14,
+ },
+ },
+ type: 'punctuation',
+ value: ')',
+ [Symbol(isClean)]: false,
+ },
+ ],
+ params: '(var(--foo)*var(--bar))',
+ raws: {
+ after: '',
+ before: '',
+ semicolon: false,
+ },
+ source: {
+ end: {
+ column: 27,
+ line: 1,
+ offset: 26,
+ },
+ input: Input {
+ css: 'calc(var(--foo)*var(--bar))',
+ hasBOM: false,
+ id: '',
+ [Symbol(fromOffset cache)]: [
+ 0,
+ ],
+ },
+ start: {
+ column: 1,
+ line: 1,
+ offset: 0,
+ },
+ },
+ type: 'func',
+ [Symbol(isClean)]: false,
+ },
+ ]
diff --git a/test/snapshots/func.test.js.snap b/test/snapshots/func.test.js.snap
index 610dc5c..ebb0c45 100644
Binary files a/test/snapshots/func.test.js.snap and b/test/snapshots/func.test.js.snap differ