fix: implement nested selector parsing (#12587)

This commit is contained in:
Alex Rudenko 2024-06-14 18:52:57 +02:00 committed by GitHub
parent 80783fef5a
commit 3874300715
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 1 deletions

View File

@ -0,0 +1,50 @@
/**
* @license
* Copyright 2024 Google Inc.
* SPDX-License-Identifier: Apache-2.0
*/
import {describe, it} from 'node:test';
import expect from 'expect';
import {parsePSelectors} from './PSelectorParser.js';
describe('PSelectorParser', () => {
describe('parsePSelectors', () => {
it('parses nested selectors', () => {
const [updatedSelector, isPureCSS, hasPseudoClasses] =
parsePSelectors('& > div');
expect(updatedSelector).toEqual([[['&>div']]]);
expect(isPureCSS).toBeTruthy();
expect(hasPseudoClasses).toBeFalsy();
});
it('parses nested selectors with p-selector syntax', () => {
const [updatedSelector, isPureCSS, hasPseudoClasses] =
parsePSelectors('& > div >>> button');
expect(updatedSelector).toEqual([[['&>div'], '>>>', ['button']]]);
expect(isPureCSS).toBeFalsy();
expect(hasPseudoClasses).toBeFalsy();
});
it('parses selectors with pseudo classes', () => {
const [updatedSelector, isPureCSS, hasPseudoClasses] =
parsePSelectors('div:focus');
expect(updatedSelector).toEqual([[['div:focus']]]);
expect(isPureCSS).toBeTruthy();
expect(hasPseudoClasses).toBeTruthy();
});
it('parses nested selectors with pseudo classes and p-selector syntax', () => {
const [updatedSelector, isPureCSS, hasPseudoClasses] = parsePSelectors(
'& > div:focus >>>> button:focus'
);
expect(updatedSelector).toEqual([
[['&>div:focus'], '>>>>', ['button:focus']],
]);
expect(isPureCSS).toBeFalsy();
expect(hasPseudoClasses).toBeTruthy();
});
});
});

View File

@ -17,6 +17,7 @@ import type {
} from '../injected/PQuerySelector.js'; } from '../injected/PQuerySelector.js';
import {PCombinator} from '../injected/PQuerySelector.js'; import {PCombinator} from '../injected/PQuerySelector.js';
TOKENS['nesting'] = /&/g;
TOKENS['combinator'] = /\s*(>>>>?|[\s>+~])\s*/g; TOKENS['combinator'] = /\s*(>>>>?|[\s>+~])\s*/g;
const ESCAPE_REGEXP = /\\[\s\S]/g; const ESCAPE_REGEXP = /\\[\s\S]/g;
@ -94,7 +95,7 @@ export function parsePSelectors(
continue; continue;
case 'pseudo-class': case 'pseudo-class':
hasPseudoClasses = true; hasPseudoClasses = true;
continue; break;
case 'comma': case 'comma':
if (storage.length) { if (storage.length) {
compoundSelector.push(stringify(storage)); compoundSelector.push(stringify(storage));