1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-21 16:18:28 +01:00

[PM-13184] Filter out specific-nodes within TreeWalker query (#11415)

This commit is contained in:
Cesar Gonzalez 2024-10-09 18:14:39 -05:00 committed by GitHub
parent 1ca03e7815
commit 877dfeae7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,6 +7,27 @@ import { DomQueryService as DomQueryServiceInterface } from "./abstractions/dom-
export class DomQueryService implements DomQueryServiceInterface {
private pageContainsShadowDom: boolean;
private useTreeWalkerStrategyFlagSet = true;
private ignoredTreeWalkerNodes = new Set([
"svg",
"script",
"noscript",
"head",
"style",
"link",
"meta",
"title",
"base",
"img",
"picture",
"video",
"audio",
"object",
"source",
"track",
"param",
"map",
"area",
]);
constructor() {
void this.init();
@ -21,6 +42,7 @@ export class DomQueryService implements DomQueryServiceInterface {
* @param treeWalkerFilter - The filter callback to use for the treeWalker query
* @param mutationObserver - The MutationObserver to use for observing shadow roots
* @param forceDeepQueryAttempt - Whether to force a deep query attempt
* @param ignoredTreeWalkerNodesOverride - An optional set of node names to ignore when using the treeWalker strategy
*/
query<T>(
root: Document | ShadowRoot | Element,
@ -28,15 +50,28 @@ export class DomQueryService implements DomQueryServiceInterface {
treeWalkerFilter: CallableFunction,
mutationObserver?: MutationObserver,
forceDeepQueryAttempt?: boolean,
ignoredTreeWalkerNodesOverride?: Set<string>,
): T[] {
const ignoredTreeWalkerNodes = ignoredTreeWalkerNodesOverride || this.ignoredTreeWalkerNodes;
if (!forceDeepQueryAttempt && this.pageContainsShadowDomElements()) {
return this.queryAllTreeWalkerNodes<T>(root, treeWalkerFilter, mutationObserver);
return this.queryAllTreeWalkerNodes<T>(
root,
treeWalkerFilter,
ignoredTreeWalkerNodes,
mutationObserver,
);
}
try {
return this.deepQueryElements<T>(root, queryString, mutationObserver);
} catch {
return this.queryAllTreeWalkerNodes<T>(root, treeWalkerFilter, mutationObserver);
return this.queryAllTreeWalkerNodes<T>(
root,
treeWalkerFilter,
ignoredTreeWalkerNodes,
mutationObserver,
);
}
}
@ -207,11 +242,13 @@ export class DomQueryService implements DomQueryServiceInterface {
* and returns a collection of nodes.
* @param rootNode
* @param filterCallback
* @param ignoredTreeWalkerNodes
* @param mutationObserver
*/
private queryAllTreeWalkerNodes<T>(
rootNode: Node,
filterCallback: CallableFunction,
ignoredTreeWalkerNodes: Set<string>,
mutationObserver?: MutationObserver,
): T[] {
const treeWalkerQueryResults: T[] = [];
@ -220,6 +257,7 @@ export class DomQueryService implements DomQueryServiceInterface {
rootNode,
treeWalkerQueryResults,
filterCallback,
ignoredTreeWalkerNodes,
mutationObserver,
);
@ -233,15 +271,21 @@ export class DomQueryService implements DomQueryServiceInterface {
* @param rootNode
* @param treeWalkerQueryResults
* @param filterCallback
* @param ignoredTreeWalkerNodes
* @param mutationObserver
*/
private buildTreeWalkerNodesQueryResults<T>(
rootNode: Node,
treeWalkerQueryResults: T[],
filterCallback: CallableFunction,
ignoredTreeWalkerNodes: Set<string>,
mutationObserver?: MutationObserver,
) {
const treeWalker = document?.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT);
const treeWalker = document?.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT, (node) =>
ignoredTreeWalkerNodes.has(node.nodeName?.toLowerCase())
? NodeFilter.FILTER_REJECT
: NodeFilter.FILTER_ACCEPT,
);
let currentNode = treeWalker?.currentNode;
while (currentNode) {
@ -263,6 +307,7 @@ export class DomQueryService implements DomQueryServiceInterface {
nodeShadowRoot,
treeWalkerQueryResults,
filterCallback,
ignoredTreeWalkerNodes,
mutationObserver,
);
}