Skip to content

Keep empty values in the middle and at the start of list.comma() - #2134

Merged
ai merged 1 commit into
postcss:mainfrom
MahinAnowar:fix/list-comma-empty-values
Aug 14, 2026
Merged

Keep empty values in the middle and at the start of list.comma()#2134
ai merged 1 commit into
postcss:mainfrom
MahinAnowar:fix/list-comma-empty-values

Conversation

@MahinAnowar

Copy link
Copy Markdown
Contributor

list.split() only pushed an item when it had collected some text, so an empty value was dropped unless it happened to be the last one:

list.comma(',,')    // ['']            expected ['', '', '']
list.comma(', b')   // ['b']           expected ['', 'b']
list.comma('a,, b') // ['a', 'b']      expected ['a', '', 'b']
list.comma('a, b,') // ['a', 'b', '']  already correct

Whitespace hides it. 'a, ,b' collects ' ' between the commas, which is not empty, so it survives and is then trimmed to ''. The result ends up depending on the spacing rather than on the number of commas:

list.comma('a,,b')  // ['a', 'b']
list.comma('a, ,b') // ['a', '', 'b']

Rule#selectors reads through list.comma, so this loses a selector:

let rule = postcss.parse('a,,b{}').first
rule.selectors        // ['a', 'b']
rule.selectors = rule.selectors
rule.toString()       // 'a,b{}'

This is the same thing #2129 fixed for '', just in the other positions — that PR made the empty value survive when it is the whole string, and the trailing empty was already handled by last. The first and middle ones were still being dropped.

The change

One condition. last already marks the separator as significant — comma() passes it and space() does not — so it is the right thing to check here too:

 if (split) {
-  if (current !== '') array.push(current.trim())
+  if (last || current !== '') array.push(current.trim())

space() is unchanged, so runs of whitespace still collapse rather than producing empty items. I added a test pinning that down as well, since it is the behaviour this condition protects.

Tests

Four cases in test/list.test.ts and two in test/rule.test.ts, covering the leading and middle positions and the spacing inconsistency. All six fail on main and pass with the change. Full suite is 693 passing; the 686 that existed before are untouched, so nothing was relying on the empty values being dropped.

pnpm test:lint and pnpm test:types are clean.

split() only pushed an item at a separator when it had collected some
text, so an empty value was dropped unless it happened to be the last
one. list.comma(',,') returned [''] instead of ['', '', ''].

Whitespace hid the inconsistency: 'a, ,b' collects ' ', which is not
empty, so it survives and is then trimmed to ''. That makes the result
depend on the spacing rather than the number of commas:

    list.comma('a,,b')  // ['a', 'b']
    list.comma('a, ,b') // ['a', '', 'b']

Rule#selectors reads through list.comma, so 'a,,b' reported two
selectors and assigning them back rewrote the rule as 'a,b'.

The `last` flag already marks the separator as significant, which is
what comma() passes and space() does not, so it is the right condition
here too. Runs of whitespace still collapse for space().
@ai
ai merged commit 27c8be3 into postcss:main Aug 14, 2026
10 checks passed
@ai

ai commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks. I hope it would not break something

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

Successfully merging this pull request may close these issues.

2 participants