fix(core): keep function values intact when splitting css shorthands - #11364
Merged
Merged
Conversation
The whitespace and comma splitters guarded parenthesized arguments with a negative lookahead that only understands a single paren level, so a value holding a nested function - a box-shadow colored with color-mix(in srgb, var(--x) 35%, transparent), or a comma separated list of such shadows - was split inside the function and failed to parse. A depth-counting scan handles any nesting, but without a JIT it is several times slower than the native regex engine, so values a regex already splits correctly keep taking one: no parenthesis at all takes a plain split, a single level keeps the previous lookahead, and only nested values - previously broken, so nothing regresses - take the scan. (node 24, ns/op) jit old/new jitless old/new no parens 117 / 100 262 / 290 single paren level 141 / 177 301 / 438 nested (was broken) 232 / 130 447 / 1621 Splitting also no longer emits empty parts for consecutive whitespace, which used to inject a bogus zero length into a shadow and shift every value after it.
parseBorderColorPositioning only recognized values starting with rgb or hsl, treating anything else as a list to split on every space and comma - which shredded other function colors (color-mix, oklch, hwb) and any per-side list containing a function. The sides are now separated on top-level spaces and commas only, so a single function color reaches all four sides whatever its name, and per-side lists can hold function colors. The prefix special case is gone.
|
View your CI Pipeline Execution ↗ for commit 8007ee0
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
commit: |
4 of 5 tasks
NathanWalker
approved these changes
Aug 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
What is the current behavior?
CSS values holding nested functions fall apart during parsing:
css-utils.tsguard parenthesized arguments with a negative lookahead (/\s(?![^(]*\))/) that only understands a single paren level. A shadow likebox-shadow: 0 0 10px color-mix(in srgb, var(--x) 35%, transparent)— or a comma-separated list of such shadows — gets split inside the function and the parse fails.border-coloronly special-cases values starting withrgb/hsl; any other function color (color-mix(),oklch(),hwb()) or a per-side list containing a function gets shredded on every space and comma — even thoughColoritself parses all of these.1px 1px 2px black) injects an empty part that becomes a bogus zero length, silently shifting every value after it (blur becomes 0, spread takes the blur).Apps currently patch
@nativescript/coredist output to work around both.What is the new behavior?
A depth-counting scanner splits on top-level separators only, so any nesting depth parses correctly.
Since a per-character scan is several times slower than the native regex engine when there's no JIT (iOS), the splitters are tiered: values with no parenthesis take a plain native split, a single paren level keeps the previous (provably correct there) lookahead regex, and only nested values — previously broken, so nothing regresses — take the scan.
border-colorsplits sides on top-level spaces/commas, soborder-color: color-mix(in srgb, red 50%, blue)applies to all four sides, andborder-color: red rgb(1, 2, 3) blue oklch(0.5 0.1 20)assigns per side. Thergb/hslprefix special case is gone. Legacy comma-separated values still parse.Empty parts from consecutive whitespace are dropped, fixing the shifted-shadow bug.
20 new unit tests across
css-utils.spec.ts(new),css-shadow.spec.ts, andstyle-properties.spec.ts(new).