Skip to content

Parse error: [attr i] flag + pseudo-class followed by quoted attribute selector #175

Description

@sjorsverhoef

Summary

Parsing fails when a compound selector contains an attribute selector with the case-insensitive i flag and a pseudo-class, followed by a combinator and another quoted attribute selector. The quotes of the second attribute selector appear to get corrupted during selector normalization (they show up as commas in the error message).

Reproduced on nwsapi 2.2.23 (via jsdom 22.1.0) and 2.2.27 (latest).

Minimal reproduction

const { JSDOM } = require('jsdom');
const dom = new JSDOM('<div><p class="a">t</p><p class="b" id="t"></p></div>');
const el = dom.window.document.getElementById('t');

el.matches("[class*='a' i]:not(:empty) + [class*='b']");
// SyntaxError: '[class*='a' i]:not(:empty)+[class*,,,b,,' is not a valid selector

Note the mangled quotes (,,,b,,) in the error message.

Variants tested

Selector Result
[class*='a' i]:not(:empty) + [class*='b'] ❌ FAIL
[class*="a" i]:not(:empty) + [class*="b"] ❌ FAIL (double quotes too)
[class*='a' i]:not(.x) + [class*='b'] ❌ FAIL (any pseudo-class)
[class*='a' i]:empty + [class*='b'] ❌ FAIL
[class*='a' i]:not(:empty) ✅ OK (no trailing attribute selector)
[class*='a' i]:not(:empty) + b ✅ OK (unquoted second selector)
[class*='a' i] + [class*='b' i] ✅ OK (no pseudo-class)
[class*='a']:not(:empty) + [class*='b'] ✅ OK (no i flag)

So all three ingredients are required to trigger it: the i flag, a pseudo-class on the same compound, and a following quoted attribute selector.

All failing selectors are valid per CSS Selectors Level 4 and match correctly in browsers.

Environment

  • nwsapi 2.2.23 and 2.2.27
  • Node.js 24.5.0
  • Encountered in the wild via jsdom → @testing-library/user-event (pointer-events check calls matches() against all stylesheet rules, so any such selector in a stylesheet breaks unrelated tests)

Possibly related: #159 (quote/escape handling introduced in 2.2.23), #60, #89 — but this repro fails on 2.2.27 as well.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions