GetQueryHandler.ts (2341B)
1 /** 2 * @license 3 * Copyright 2023 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import {ARIAQueryHandler} from '../cdp/AriaQueryHandler.js'; 8 9 import {CSSQueryHandler} from './CSSQueryHandler.js'; 10 import {customQueryHandlers} from './CustomQueryHandler.js'; 11 import {PierceQueryHandler} from './PierceQueryHandler.js'; 12 import {PQueryHandler} from './PQueryHandler.js'; 13 import {parsePSelectors} from './PSelectorParser.js'; 14 import type {QueryHandler} from './QueryHandler.js'; 15 import {PollingOptions} from './QueryHandler.js'; 16 import {TextQueryHandler} from './TextQueryHandler.js'; 17 import {XPathQueryHandler} from './XPathQueryHandler.js'; 18 19 const BUILTIN_QUERY_HANDLERS = { 20 aria: ARIAQueryHandler, 21 pierce: PierceQueryHandler, 22 xpath: XPathQueryHandler, 23 text: TextQueryHandler, 24 } as const; 25 26 const QUERY_SEPARATORS = ['=', '/']; 27 28 /** 29 * @internal 30 */ 31 export function getQueryHandlerAndSelector(selector: string): { 32 updatedSelector: string; 33 polling: PollingOptions; 34 QueryHandler: typeof QueryHandler; 35 } { 36 for (const handlerMap of [ 37 customQueryHandlers.names().map(name => { 38 return [name, customQueryHandlers.get(name)!] as const; 39 }), 40 Object.entries(BUILTIN_QUERY_HANDLERS), 41 ]) { 42 for (const [name, QueryHandler] of handlerMap) { 43 for (const separator of QUERY_SEPARATORS) { 44 const prefix = `${name}${separator}`; 45 if (selector.startsWith(prefix)) { 46 selector = selector.slice(prefix.length); 47 return { 48 updatedSelector: selector, 49 polling: 50 name === 'aria' ? PollingOptions.RAF : PollingOptions.MUTATION, 51 QueryHandler, 52 }; 53 } 54 } 55 } 56 } 57 try { 58 const [pSelector, isPureCSS, hasPseudoClasses, hasAria] = 59 parsePSelectors(selector); 60 if (isPureCSS) { 61 return { 62 updatedSelector: selector, 63 polling: hasPseudoClasses 64 ? PollingOptions.RAF 65 : PollingOptions.MUTATION, 66 QueryHandler: CSSQueryHandler, 67 }; 68 } 69 return { 70 updatedSelector: JSON.stringify(pSelector), 71 polling: hasAria ? PollingOptions.RAF : PollingOptions.MUTATION, 72 QueryHandler: PQueryHandler, 73 }; 74 } catch { 75 return { 76 updatedSelector: selector, 77 polling: PollingOptions.MUTATION, 78 QueryHandler: CSSQueryHandler, 79 }; 80 } 81 }