Skip to content

Commit

Permalink
feat(puppeteer-core): infer element type from complex selector
Browse files Browse the repository at this point in the history
  • Loading branch information
gomain committed Nov 11, 2022
1 parent 9545691 commit 15a49bf
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 5 deletions.
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/puppeteer-core/package.json
Expand Up @@ -157,6 +157,7 @@
"proxy-from-env": "1.1.0",
"rimraf": "3.0.2",
"tar-fs": "2.1.1",
"type-fest": "3.2.0",
"unbzip2-stream": "1.4.3",
"ws": "8.10.0"
}
Expand Down
74 changes: 69 additions & 5 deletions packages/puppeteer-core/src/common/types.ts
Expand Up @@ -17,6 +17,7 @@
import {JSHandle} from './JSHandle.js';
import {ElementHandle} from './ElementHandle.js';
import {LazyArg} from './LazyArg.js';
import type {LastArrayElement, Split} from 'type-fest';

/**
* @public
Expand Down Expand Up @@ -67,9 +68,72 @@ export type EvaluateFunc<T extends unknown[]> = (
/**
* @public
*/
export type NodeFor<Selector extends string> =
Selector extends keyof HTMLElementTagNameMap
? HTMLElementTagNameMap[Selector]
: Selector extends keyof SVGElementTagNameMap
? SVGElementTagNameMap[Selector]
export type NodeFor<ComplexSelector extends string> =
TypeSelectorOfCamplexSelector<ComplexSelector> extends infer TypeSelector
? TypeSelector extends keyof HTMLElementTagNameMap
? HTMLElementTagNameMap[TypeSelector]
: TypeSelector extends keyof SVGElementTagNameMap
? SVGElementTagNameMap[TypeSelector]
: Element
: Element;

type TypeSelectorOfCamplexSelector<ComplexSelector extends string> =
TypeSelectorOfCompoundSelector<
LastArrayElement<CompondSelectorsOfComplexSelector<ComplexSelector>>
>;

type TypeSelectorOfCompoundSelector<CompoundSelector extends string> =
SplitWithDelemiters<
CompoundSelector,
BeginSubclassSelectorTokens
> extends infer CompoundSelectorTokens
? // eslint-disable-next-line @typescript-eslint/no-unused-vars
CompoundSelectorTokens extends [infer TypeSelector, ...infer _]
? TypeSelector extends ''
? void
: TypeSelector
: never
: never;

type CompondSelectorsOfComplexSelector<ComplexSelector extends string> = Drop<
SplitWithDelemiters<ComplexSelector, CombinatorTokens>,
''
>;

type SplitWithDelemiters<
Input extends string,
Delemiters1 extends readonly string[]
> = Delemiters1 extends [infer FirstDelemiter, ...infer RestDelemiters]
? FirstDelemiter extends string
? RestDelemiters extends readonly string[]
? FlatmapSplitWithDelemiters<Split<Input, FirstDelemiter>, RestDelemiters>
: never
: never
: [Input];

type BeginSubclassSelectorTokens = ['.', '#', '[', ':'];

type CombinatorTokens = [' ', '>', '+', '~', '|', '|'];

type Drop<Arr extends readonly unknown[], Remove> = Arr extends [
infer Head,
...infer Tail
]
? Head extends Remove
? Drop<Tail, Remove>
: [Head, ...Drop<Tail, Remove>]
: [];

type FlatmapSplitWithDelemiters<
Inputs extends readonly string[],
Delemiters extends readonly string[]
> = Inputs extends [infer FirstInput, ...infer RestInputs]
? FirstInput extends string
? RestInputs extends readonly string[]
? [
...SplitWithDelemiters<FirstInput, Delemiters>,
...FlatmapSplitWithDelemiters<RestInputs, Delemiters>
]
: never
: never
: [];

0 comments on commit 15a49bf

Please sign in to comment.