Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect parsing of calc operations without spaces in parentheses #86

Open
nex3 opened this issue Oct 12, 2022 · 5 comments
Open

Incorrect parsing of calc operations without spaces in parentheses #86

nex3 opened this issue Oct 12, 2022 · 5 comments

Comments

@nex3
Copy link
Contributor

nex3 commented Oct 12, 2022

When a multiplication operation exists within parentheses in a calc() expression and it doesn't have spaces around the * (which it probably won't if the CSS has been minified), postcss-value-parser parses the * as though it's part of a word token with any adjacent numbers. Here's the simplest reproduction:

var pvp = require("postcss-value-parser")

pvp('calc((1*1))')

(Live on RunKit)

This returns two nested function nodes which ultimately contain a single word node with value: "1*1". Since 1*1 parses correctly at the root of the calc() expression, I'm guessing that the parser is forgetting that it's in a calc() context upon descending into the parentheses... although it seems like even outside that context 1*1 should parse as separate tokens, according to the CSS tokenizer algorithms.

@romainmenke
Copy link

We have just released a new tokenizer which should not have this issue : https://www.npmjs.com/package/@csstools/css-tokenizer

example : https://runkit.com/romainmenke/calc-1-1-with-css-tokenizer

@Goodwine
Copy link

FWIW I don't think the issue is that there are no spaces. I think the issue here is that calc() and otherFunction() are treated differenlty. Parenthesis inside calc() are considered to be a nameless function so it's parsed differently than calc().

@nex3
Copy link
Contributor Author

nex3 commented Apr 14, 2023

Most browsers now support calc-style syntax in min(), max(), clamp(), trigonometric functions, and so on. This is likely to continue to become a bigger and bigger problem as time goes by.

@Goodwine
Copy link

Adding a bit more info. The division operator / is parsed in calc(a/b) to be:
[word: 'a', word: '/', word: 'b']. This is fine.

But in calc((a/b)) the same behavior happens where () is a nameless function treated differently than calc, so it becomes [word: 'a', div: '/', word: 'b'] (if it had been a multiplcation like it would have returned a single word 'a*b' as originally reported.

Just pointing it out because / is treated different than *,-,+

@nex3
Copy link
Contributor Author

nex3 commented Dec 6, 2023

I've just found a new instance of this: calc((-1*var(--a))) parses the inner function as -1*var. This reproduces on the latest release.

@TrySound Can you clarify whether this package is still being maintained? I note that there are no commits or releases in the past two years.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants