feat: get truly deepest element
This commit is contained in:
@@ -4080,67 +4080,63 @@ class ClientSelectorGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getDeepestElementFromPoint(
|
private getDeepestElementFromPoint(
|
||||||
elements: HTMLElement[],
|
elements: HTMLElement[],
|
||||||
x: number,
|
x: number,
|
||||||
y: number
|
y: number
|
||||||
): HTMLElement | null {
|
): HTMLElement | null {
|
||||||
if (!elements.length) return null;
|
if (!elements.length) return null;
|
||||||
|
|
||||||
const visited = new Set<HTMLElement>();
|
const visited = new Set<HTMLElement>();
|
||||||
return this.findDeepestElementRecursive(elements, x, y, visited);
|
return this.findTrulyDeepestElement(elements, x, y, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
private findDeepestElementRecursive(
|
private findTrulyDeepestElement(
|
||||||
elements: HTMLElement[],
|
elements: HTMLElement[],
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
visited: Set<HTMLElement>
|
visited: Set<HTMLElement>
|
||||||
): HTMLElement | null {
|
): HTMLElement | null {
|
||||||
if (!elements.length) return null;
|
let deepestElement: HTMLElement | null = null;
|
||||||
|
let maxDepth = -1;
|
||||||
|
|
||||||
for (const element of elements) {
|
for (const element of elements) {
|
||||||
if (visited.has(element)) continue;
|
if (visited.has(element)) continue;
|
||||||
visited.add(element);
|
visited.add(element);
|
||||||
|
|
||||||
if (element.shadowRoot) {
|
if (element.shadowRoot) {
|
||||||
let shadowElements = element.shadowRoot.elementsFromPoint(
|
const shadowElements = element.shadowRoot.elementsFromPoint(x, y) as HTMLElement[];
|
||||||
x,
|
const deeper = this.findTrulyDeepestElement(shadowElements, x, y, visited);
|
||||||
y
|
if (deeper) {
|
||||||
) as HTMLElement[];
|
const depth = this.getElementDepth(deeper);
|
||||||
|
if (depth > maxDepth) {
|
||||||
if (shadowElements.length > 0) {
|
maxDepth = depth;
|
||||||
let deepestShadowElement = shadowElements[0];
|
deepestElement = deeper;
|
||||||
|
|
||||||
if (deepestShadowElement.shadowRoot) {
|
|
||||||
const evenDeeperElement = this.findDeepestElementRecursive(
|
|
||||||
[deepestShadowElement],
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
visited
|
|
||||||
);
|
|
||||||
if (evenDeeperElement) {
|
|
||||||
return evenDeeperElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return deepestShadowElement;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return elements[0];
|
const depth = this.getElementDepth(element);
|
||||||
|
if (depth > maxDepth) {
|
||||||
|
maxDepth = depth;
|
||||||
|
deepestElement = element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getElementDepth(element: HTMLElement): number {
|
return deepestElement;
|
||||||
let depth = 0;
|
}
|
||||||
let current = element;
|
|
||||||
while (current && current !== this.lastAnalyzedDocument?.body) {
|
private getElementDepth(element: HTMLElement): number {
|
||||||
depth++;
|
let depth = 0;
|
||||||
current = current.parentElement as HTMLElement;
|
let current: HTMLElement | null = element;
|
||||||
if (depth > 50) break;
|
|
||||||
}
|
while (current && current !== this.lastAnalyzedDocument?.body) {
|
||||||
return depth;
|
depth++;
|
||||||
|
current = current.parentElement || (current.getRootNode() as ShadowRoot).host as HTMLElement | null;
|
||||||
|
if (depth > 50) break;
|
||||||
}
|
}
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean up when component unmounts or mode changes
|
* Clean up when component unmounts or mode changes
|
||||||
|
|||||||
Reference in New Issue
Block a user