Skip to content

fix(core): keep function values intact when splitting css shorthands - #11364

Merged
NathanWalker merged 2 commits into
mainfrom
fix/css-function-value-splitting
Aug 26, 2026
Merged

NathanWalker merged 2 commits into
mainfrom
fix/css-function-value-splitting

Conversation

@edusperoni

Copy link
Copy Markdown
Contributor

PR Checklist

What is the current behavior?

CSS values holding nested functions fall apart during parsing:

  • The whitespace/comma splitters in css-utils.ts guard parenthesized arguments with a negative lookahead (/\s(?![^(]*\))/) that only understands a single paren level. A shadow like box-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-color only special-cases values starting with rgb/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 though Color itself parses all of these.
  • Consecutive whitespace in a shorthand (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/core dist 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.

    input class JIT old→new (ns/op) jitless old→new
    no parens 117 → 100 262 → 290
    single paren level 141 → 177 301 → 438
    nested (was broken) 232 → 130 447 → 1621
  • border-color splits sides on top-level spaces/commas, so border-color: color-mix(in srgb, red 50%, blue) applies to all four sides, and border-color: red rgb(1, 2, 3) blue oklch(0.5 0.1 20) assigns per side. The rgb/hsl prefix 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, and style-properties.spec.ts (new).

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.
@nx-cloud

nx-cloud Bot commented Aug 26, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 8007ee0

Command Status Duration Result
nx test apps-automated -c=android ✅ Succeeded 4m 15s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-08-26 18:35:00 UTC

@pkg-pr-new

pkg-pr-new Bot commented Aug 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nativescript/core@11364
npm i https://pkg.pr.new/@nativescript/vite@11364
npm i https://pkg.pr.new/@nativescript/webpack@11364

commit: 8007ee0

@NathanWalker
NathanWalker merged commit ac6e49e into main Aug 26, 2026
10 checks passed
@NathanWalker
NathanWalker deleted the fix/css-function-value-splitting branch August 26, 2026 18:57
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