1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-05 03:03:26 +00:00

add queryDeepSelector to the DOM query service

This commit is contained in:
Jonathan Prusik
2025-10-06 09:59:46 -04:00
parent 5a307633bb
commit 44a80b6a2b
2 changed files with 31 additions and 3 deletions

View File

@@ -6,5 +6,6 @@ export interface DomQueryService {
mutationObserver?: MutationObserver,
forceDeepQueryAttempt?: boolean,
): T[];
queryDeepSelector(root: Document | ShadowRoot | Element, selector: string): Element[];
checkPageContainsShadowDom(): boolean;
}

View File

@@ -141,6 +141,33 @@ export class DomQueryService implements DomQueryServiceInterface {
return Array.from(root.querySelectorAll(queryString)) as T[];
}
/**
* Queries the DOM for elements based on the given CSS selector string;
* uses special `>>>` syntax to indicate needed shadowDOM traversal.
*
* @param root - The root element to start the query from
* @param selector - The CSS selector string to match elements against
*/
queryDeepSelector(root: Element, selector: string): Element[] {
const rootScopedSelectors = selector.split(">>>");
let current: Element[] = [root];
for (const selector of rootScopedSelectors) {
const next: Element[] = [];
for (const element of current) {
next.push(...Array.from(element.querySelectorAll(selector)));
const elementShadowRoot = this.getShadowRoot(element);
if (elementShadowRoot) {
next.push(...Array.from(elementShadowRoot.querySelectorAll(selector)));
}
}
current = next;
}
return current;
}
/**
* Recursively queries all shadow roots found within the given root element.
* Will also set up a mutation observer on the shadow root if the
@@ -217,13 +244,12 @@ export class DomQueryService implements DomQueryServiceInterface {
if ((chrome as any).dom?.openOrClosedShadowRoot) {
try {
return (chrome as any).dom.openOrClosedShadowRoot(node);
// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
} catch {
return null;
}
}
// Firefox-specific implementation of `openOrClosedShadowRoot`
return (node as any).openOrClosedShadowRoot;
}
@@ -284,6 +310,7 @@ export class DomQueryService implements DomQueryServiceInterface {
}
const nodeShadowRoot = this.getShadowRoot(currentNode);
// console.log('🚀 🚀 nodeShadowRoot:', nodeShadowRoot);
if (nodeShadowRoot) {
if (mutationObserver) {
mutationObserver.observe(nodeShadowRoot, {