feat: add depth limitations

This commit is contained in:
Rohit
2025-08-11 16:03:28 +05:30
parent 96339f5568
commit b2f6211c22

View File

@@ -2494,70 +2494,38 @@ class ClientSelectorGenerator {
}; };
private getAllDescendantsIncludingShadow( private getAllDescendantsIncludingShadow(
parentElement: HTMLElement parentElement: HTMLElement,
maxDepth: number = 20
): HTMLElement[] { ): HTMLElement[] {
const allDescendants: HTMLElement[] = []; const allDescendants: HTMLElement[] = [];
const visited = new Set<HTMLElement>(); const visited = new Set<HTMLElement>();
const shadowRootsSeen = new Set<ShadowRoot>();
const traverseShadowRoot = (shadowRoot: ShadowRoot, depth: number = 0) => { const traverse = (element: HTMLElement, currentDepth: number) => {
if (depth > 10) return; if (currentDepth >= maxDepth || visited.has(element)) {
return;
}
visited.add(element);
try { if (element !== parentElement) {
const shadowElements = Array.from( allDescendants.push(element);
shadowRoot.querySelectorAll("*") }
) as HTMLElement[];
shadowElements.forEach((shadowElement) => { // Traverse light DOM children
if (!visited.has(shadowElement)) { const children = Array.from(element.children) as HTMLElement[];
visited.add(shadowElement); for (const child of children) {
allDescendants.push(shadowElement); traverse(child, currentDepth + 1);
}
if ( // Traverse shadow DOM if it exists
shadowElement.shadowRoot && if (element.shadowRoot) {
!shadowRootsSeen.has(shadowElement.shadowRoot) const shadowChildren = Array.from(element.shadowRoot.children) as HTMLElement[];
) { for (const shadowChild of shadowChildren) {
shadowRootsSeen.add(shadowElement.shadowRoot); traverse(shadowChild, currentDepth + 1);
traverseShadowRoot(shadowElement.shadowRoot, depth + 1); }
}
}
});
Array.from(shadowRoot.children).forEach((child) => {
const htmlChild = child as HTMLElement;
if (
htmlChild.shadowRoot &&
!shadowRootsSeen.has(htmlChild.shadowRoot)
) {
shadowRootsSeen.add(htmlChild.shadowRoot);
traverseShadowRoot(htmlChild.shadowRoot, depth + 1);
}
});
} catch (error) {
console.warn(`Error traversing shadow root:`, error);
} }
}; };
const regularDescendants = Array.from( traverse(parentElement, 0);
parentElement.querySelectorAll("*")
) as HTMLElement[];
regularDescendants.forEach((descendant) => {
if (!visited.has(descendant)) {
visited.add(descendant);
allDescendants.push(descendant);
}
});
const elementsWithShadow = [parentElement, ...regularDescendants].filter(
(el) => el.shadowRoot
);
elementsWithShadow.forEach((element) => {
if (!shadowRootsSeen.has(element.shadowRoot!)) {
shadowRootsSeen.add(element.shadowRoot!);
traverseShadowRoot(element.shadowRoot!, 0);
}
});
return allDescendants; return allDescendants;
} }
@@ -2577,6 +2545,8 @@ class ClientSelectorGenerator {
if (processedElements.has(descendant)) return; if (processedElements.has(descendant)) return;
processedElements.add(descendant); processedElements.add(descendant);
if (!this.isMeaningfulElement(descendant)) return;
const absolutePath = this.buildOptimizedAbsoluteXPath( const absolutePath = this.buildOptimizedAbsoluteXPath(
descendant, descendant,
listSelector, listSelector,
@@ -2766,16 +2736,20 @@ class ClientSelectorGenerator {
rootElement: HTMLElement, rootElement: HTMLElement,
otherListElements: HTMLElement[] = [] otherListElements: HTMLElement[] = []
): string | null { ): string | null {
if (!this.elementContains(rootElement, targetElement) || targetElement === rootElement) { if (
!this.elementContains(rootElement, targetElement) ||
targetElement === rootElement
) {
return null; return null;
} }
const pathParts: string[] = []; const pathParts: string[] = [];
let current: HTMLElement | null = targetElement; let current: HTMLElement | null = targetElement;
let pathDepth = 0;
const MAX_PATH_DEPTH = 20;
// Build path from target up to root // Build path from target up to root
while (current && current !== rootElement) { while (current && current !== rootElement && pathDepth < MAX_PATH_DEPTH) {
// Calculate conflicts for each element in the path
const classes = this.getCommonClassesAcrossLists( const classes = this.getCommonClassesAcrossLists(
current, current,
otherListElements otherListElements
@@ -2806,11 +2780,15 @@ class ClientSelectorGenerator {
pathParts.unshift(pathPart); pathParts.unshift(pathPart);
} }
// Move to parent (either regular parent or shadow host) current =
current = current.parentElement || current.parentElement ||
((current.getRootNode() as ShadowRoot).host as HTMLElement | null); ((current.getRootNode() as ShadowRoot).host as HTMLElement | null);
pathDepth++;
}
if (!current) break; if (current !== rootElement) {
return null;
} }
return pathParts.length > 0 ? "/" + pathParts.join("/") : null; return pathParts.length > 0 ? "/" + pathParts.join("/") : null;