diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts')
-rw-r--r-- | remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts new file mode 100644 index 0000000000..8044562348 --- /dev/null +++ b/remote/test/puppeteer/packages/puppeteer-core/src/injected/PSelectorParser.ts @@ -0,0 +1,105 @@ +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import {type Token, tokenize, TOKENS, stringify} from 'parsel-js'; + +export type CSSSelector = string; +export interface PPseudoSelector { + name: string; + value: string; +} +export const enum PCombinator { + Descendent = '>>>', + Child = '>>>>', +} +export type CompoundPSelector = Array<CSSSelector | PPseudoSelector>; +export type ComplexPSelector = Array<CompoundPSelector | PCombinator>; +export type ComplexPSelectorList = ComplexPSelector[]; + +TOKENS['combinator'] = /\s*(>>>>?|[\s>+~])\s*/g; + +const ESCAPE_REGEXP = /\\[\s\S]/g; +const unquote = (text: string): string => { + if (text.length <= 1) { + return text; + } + if ((text[0] === '"' || text[0] === "'") && text.endsWith(text[0])) { + text = text.slice(1, -1); + } + return text.replace(ESCAPE_REGEXP, match => { + return match[1] as string; + }); +}; + +export function parsePSelectors( + selector: string +): [selector: ComplexPSelectorList, isPureCSS: boolean] { + let isPureCSS = true; + const tokens = tokenize(selector); + if (tokens.length === 0) { + return [[], isPureCSS]; + } + let compoundSelector: CompoundPSelector = []; + let complexSelector: ComplexPSelector = [compoundSelector]; + const selectors: ComplexPSelectorList = [complexSelector]; + const storage: Token[] = []; + for (const token of tokens) { + switch (token.type) { + case 'combinator': + switch (token.content) { + case PCombinator.Descendent: + isPureCSS = false; + if (storage.length) { + compoundSelector.push(stringify(storage)); + storage.splice(0); + } + compoundSelector = []; + complexSelector.push(PCombinator.Descendent); + complexSelector.push(compoundSelector); + continue; + case PCombinator.Child: + isPureCSS = false; + if (storage.length) { + compoundSelector.push(stringify(storage)); + storage.splice(0); + } + compoundSelector = []; + complexSelector.push(PCombinator.Child); + complexSelector.push(compoundSelector); + continue; + } + break; + case 'pseudo-element': + if (!token.name.startsWith('-p-')) { + break; + } + isPureCSS = false; + if (storage.length) { + compoundSelector.push(stringify(storage)); + storage.splice(0); + } + compoundSelector.push({ + name: token.name.slice(3), + value: unquote(token.argument ?? ''), + }); + continue; + case 'comma': + if (storage.length) { + compoundSelector.push(stringify(storage)); + storage.splice(0); + } + compoundSelector = []; + complexSelector = [compoundSelector]; + selectors.push(complexSelector); + continue; + } + storage.push(token); + } + if (storage.length) { + compoundSelector.push(stringify(storage)); + } + return [selectors, isPureCSS]; +} |