15
15
*/
16
16
17
17
import { createAttributeEngine } from './attributeSelectorEngine' ;
18
- import { createCSSEngine } from './cssSelectorEngine' ;
19
18
import { SelectorEngine , SelectorRoot } from './selectorEngine' ;
20
19
import { createTextSelector } from './textSelectorEngine' ;
21
20
import { XPathEngine } from './xpathSelectorEngine' ;
22
- import { ParsedSelector , ParsedSelectorV1 , parseSelector , selectorsV2Enabled , selectorsV2EngineNames } from '../common/selectorParser' ;
21
+ import { ParsedSelector , ParsedSelectorPart , parseSelector } from '../common/selectorParser' ;
23
22
import { FatalDOMError } from '../common/domErrors' ;
24
- import { SelectorEvaluatorImpl , SelectorEngine as SelectorEngineV2 , QueryContext , isVisible , parentElementOrShadowHost } from './selectorEvaluator' ;
23
+ import { SelectorEvaluatorImpl , isVisible , parentElementOrShadowHost } from './selectorEvaluator' ;
24
+ import { createCSSEngine } from './cssSelectorEngine' ;
25
25
26
26
type Predicate < T > = ( progress : InjectedScriptProgress , continuePolling : symbol ) => T | symbol ;
27
27
@@ -43,7 +43,6 @@ export type InjectedScriptPoll<T> = {
43
43
export class InjectedScript {
44
44
private _enginesV1 : Map < string , SelectorEngine > ;
45
45
private _evaluator : SelectorEvaluatorImpl ;
46
- private _engineNames : Set < string > ;
47
46
48
47
constructor ( customEngines : { name : string , engine : SelectorEngine } [ ] ) {
49
48
this . _enginesV1 = new Map ( ) ;
@@ -64,37 +63,32 @@ export class InjectedScript {
64
63
for ( const { name, engine } of customEngines )
65
64
this . _enginesV1 . set ( name , engine ) ;
66
65
67
- const wrapped = new Map < string , SelectorEngineV2 > ( ) ;
68
- for ( const { name, engine } of customEngines )
69
- wrapped . set ( name , wrapV2 ( name , engine ) ) ;
70
- this . _evaluator = new SelectorEvaluatorImpl ( wrapped ) ;
71
-
72
- this . _engineNames = new Set ( this . _enginesV1 . keys ( ) ) ;
73
- if ( selectorsV2Enabled ( ) ) {
74
- for ( const name of selectorsV2EngineNames ( ) )
75
- this . _engineNames . add ( name ) ;
76
- }
66
+ // No custom engines in V2 for now.
67
+ this . _evaluator = new SelectorEvaluatorImpl ( new Map ( ) ) ;
77
68
}
78
69
79
70
parseSelector ( selector : string ) : ParsedSelector {
80
- return parseSelector ( selector , this . _engineNames ) ;
71
+ const result = parseSelector ( selector ) ;
72
+ for ( const part of result . parts ) {
73
+ if ( ! Array . isArray ( part ) && ! this . _enginesV1 . has ( part . name ) )
74
+ throw new Error ( `Unknown engine "${ part . name } " while parsing selector ${ selector } ` ) ;
75
+ }
76
+ return result ;
81
77
}
82
78
83
79
querySelector ( selector : ParsedSelector , root : Node ) : Element | undefined {
84
80
if ( ! ( root as any ) [ 'querySelector' ] )
85
81
throw new Error ( 'Node is not queryable.' ) ;
86
- if ( selector . v1 )
87
- return this . _querySelectorRecursivelyV1 ( root as SelectorRoot , selector . v1 , 0 ) ;
88
- return this . _evaluator . evaluate ( { scope : root as Document | Element , pierceShadow : true } , selector . v2 ! ) [ 0 ] ;
82
+ return this . _querySelectorRecursively ( root as SelectorRoot , selector , 0 ) ;
89
83
}
90
84
91
- private _querySelectorRecursivelyV1 ( root : SelectorRoot , selector : ParsedSelectorV1 , index : number ) : Element | undefined {
85
+ private _querySelectorRecursively ( root : SelectorRoot , selector : ParsedSelector , index : number ) : Element | undefined {
92
86
const current = selector . parts [ index ] ;
93
87
if ( index === selector . parts . length - 1 )
94
- return this . _enginesV1 . get ( current . name ) ! . query ( root , current . body ) ;
95
- const all = this . _enginesV1 . get ( current . name ) ! . queryAll ( root , current . body ) ;
88
+ return this . _queryEngine ( current , root ) ;
89
+ const all = this . _queryEngineAll ( current , root ) ;
96
90
for ( const next of all ) {
97
- const result = this . _querySelectorRecursivelyV1 ( next , selector , index + 1 ) ;
91
+ const result = this . _querySelectorRecursively ( next , selector , index + 1 ) ;
98
92
if ( result )
99
93
return selector . capture === index ? next : result ;
100
94
}
@@ -103,22 +97,16 @@ export class InjectedScript {
103
97
querySelectorAll ( selector : ParsedSelector , root : Node ) : Element [ ] {
104
98
if ( ! ( root as any ) [ 'querySelectorAll' ] )
105
99
throw new Error ( 'Node is not queryable.' ) ;
106
- if ( selector . v1 )
107
- return this . _querySelectorAllV1 ( selector . v1 , root as SelectorRoot ) ;
108
- return this . _evaluator . evaluate ( { scope : root as Document | Element , pierceShadow : true } , selector . v2 ! ) ;
109
- }
110
-
111
- private _querySelectorAllV1 ( selector : ParsedSelectorV1 , root : SelectorRoot ) : Element [ ] {
112
100
const capture = selector . capture === undefined ? selector . parts . length - 1 : selector . capture ;
113
101
// Query all elements up to the capture.
114
- const partsToQuerAll = selector . parts . slice ( 0 , capture + 1 ) ;
102
+ const partsToQueryAll = selector . parts . slice ( 0 , capture + 1 ) ;
115
103
// Check they have a descendant matching everything after the capture.
116
104
const partsToCheckOne = selector . parts . slice ( capture + 1 ) ;
117
105
let set = new Set < SelectorRoot > ( [ root as SelectorRoot ] ) ;
118
- for ( const { name , body } of partsToQuerAll ) {
106
+ for ( const part of partsToQueryAll ) {
119
107
const newSet = new Set < Element > ( ) ;
120
108
for ( const prev of set ) {
121
- for ( const next of this . _enginesV1 . get ( name ) ! . queryAll ( prev , body ) ) {
109
+ for ( const next of this . _queryEngineAll ( part , prev ) ) {
122
110
if ( newSet . has ( next ) )
123
111
continue ;
124
112
newSet . add ( next ) ;
@@ -130,7 +118,19 @@ export class InjectedScript {
130
118
if ( ! partsToCheckOne . length )
131
119
return candidates ;
132
120
const partial = { parts : partsToCheckOne } ;
133
- return candidates . filter ( e => ! ! this . _querySelectorRecursivelyV1 ( e , partial , 0 ) ) ;
121
+ return candidates . filter ( e => ! ! this . _querySelectorRecursively ( e , partial , 0 ) ) ;
122
+ }
123
+
124
+ private _queryEngine ( part : ParsedSelectorPart , root : SelectorRoot ) : Element | undefined {
125
+ if ( Array . isArray ( part ) )
126
+ return this . _evaluator . evaluate ( { scope : root as Document | Element , pierceShadow : true } , part ) [ 0 ] ;
127
+ return this . _enginesV1 . get ( part . name ) ! . query ( root , part . body ) ;
128
+ }
129
+
130
+ private _queryEngineAll ( part : ParsedSelectorPart , root : SelectorRoot ) : Element [ ] {
131
+ if ( Array . isArray ( part ) )
132
+ return this . _evaluator . evaluate ( { scope : root as Document | Element , pierceShadow : true } , part ) ;
133
+ return this . _enginesV1 . get ( part . name ) ! . queryAll ( root , part . body ) ;
134
134
}
135
135
136
136
extend ( source : string , params : any ) : any {
@@ -667,16 +667,6 @@ export class InjectedScript {
667
667
}
668
668
}
669
669
670
- function wrapV2 ( name : string , engine : SelectorEngine ) : SelectorEngineV2 {
671
- return {
672
- query ( context : QueryContext , args : string [ ] ) : Element [ ] {
673
- if ( args . length !== 1 || typeof args [ 0 ] !== 'string' )
674
- throw new Error ( `engine "${ name } " expects a single string` ) ;
675
- return engine . queryAll ( context . scope , args [ 0 ] ) ;
676
- }
677
- } ;
678
- }
679
-
680
670
const autoClosingTags = new Set ( [ 'AREA' , 'BASE' , 'BR' , 'COL' , 'COMMAND' , 'EMBED' , 'HR' , 'IMG' , 'INPUT' , 'KEYGEN' , 'LINK' , 'MENUITEM' , 'META' , 'PARAM' , 'SOURCE' , 'TRACK' , 'WBR' ] ) ;
681
671
const booleanAttributes = new Set ( [ 'checked' , 'selected' , 'disabled' , 'readonly' , 'multiple' ] ) ;
682
672
0 commit comments