Skip to content

SCSS: Support parameterized pseudo-classes in selectors#4093

Open
dweep-js wants to merge 1 commit into
PrismJS:v2from
dweep-js:fix-scss-pseudo-class-parens
Open

SCSS: Support parameterized pseudo-classes in selectors#4093
dweep-js wants to merge 1 commit into
PrismJS:v2from
dweep-js:fix-scss-pseudo-class-parens

Conversation

@dweep-js

@dweep-js dweep-js commented Jul 5, 2026

Copy link
Copy Markdown

Fixes #3740

Problem

SCSS selectors containing a parameterized pseudo-class were not
highlighted as selectors:

foo :foo() bar {

}

:foo() broke the match entirely — only bar was left as an
unmatched token, while foo :foo() fell out of the selector token.
The equivalent selector without parens (foo :foo bar {}) worked fine.

Root cause

Prism.languages.scss.selector.pattern explicitly excludes ( and )
from the character class that makes up a selector:

[^@;{}()\s]

This exclusion exists on purpose: the same pattern is reused (via
atrule's $rest: 'scss') to tokenize the inside of at-rules like
@mixin and @include, and parens there belong to the argument list,
not to a selector. A naive fix — just deleting () from the exclusion
class, as originally suggested in the issue — makes the selector
pattern swallow at-rule argument lists too, which breaks highlighting
of code like:

@mixin prefix($property, $value, $prefixes) {
}

(prefix should tokenize as a function; with the naive fix it gets
absorbed into a spurious selector token instead, as flagged by
@Golmote in the issue thread.)

Fix

Instead of opening up () unconditionally, this adds one new,
narrowly-scoped alternative to the selector pattern: a balanced
parenthesized group, but only when it directly follows a
pseudo-class name (:name(...) or ::name(...)):

:{1,2}[-\w]+\((?:[^()]|\([^()]*\))*\)

This matches :foo(), :nth-child(2n+1), :not(.active), etc., while
leaving the existing exclusion of bare (/) intact everywhere else —
so @mixin/@include argument lists (which are never preceded by a
colon) are unaffected.

Testing

Added a new case to tests/languages/scss/selector_feature.test:

foo :foo() bar {}

Verified the fix two ways:

  1. Regression-proof: temporarily reverted just the scss.js
    change (git stash push -- src/languages/scss.js) while keeping
    the new test case, and confirmed selector_feature fails against
    the old pattern — foo :foo() bar {} tokenizes as
    property/punctuation/function/punctuation/punctuation/
    selector("bar ") instead of one clean selector token. This
    reproduces the exact bug from the issue.
  2. Restored the fix and confirmed all tests pass again
    (npm run test:languages -- --language=scss, 15 passing).
  3. Manually re-checked Golmote's @mixin prefix($property, $value, $prefixes) {} counter-example against the new pattern to confirm
    prefix still tokenizes correctly as a function and is not
    swallowed into a selector — the specific regression that sank
    the original one-line workaround in the issue thread.

Scope

One-line regex change in src/languages/scss.js, plus one new test
case appended to the existing selector_feature.test (no existing
cases modified).

Fixes PrismJS#3740. Selectors like `:foo()` were not being highlighted
because the selector pattern excluded all parentheses. This adds
a constrained alternative that only allows balanced parens when
they directly follow a pseudo-class (`:name(...)` or `::name(...)`),
which fixes the reported case without regressing the @mixin/@include
argument-list case Golmote flagged in the original workaround.
@netlify

netlify Bot commented Jul 5, 2026

Copy link
Copy Markdown

Deploy Preview for dev-prismjs-com ready!

Name Link
🔨 Latest commit c08bb7a
🔍 Latest deploy log https://app.netlify.com/projects/dev-prismjs-com/deploys/6a49fd62c1c6ab00084ab789
😎 Deploy Preview https://deploy-preview-4093--dev-prismjs-com.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

No JS Changes

Generated by 🚫 dangerJS against c08bb7a

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.

Parameterized pseudo-classes break selector highlighting in SCSS

1 participant