one-click-accessibility/modules/scanner/assets/js/utils/get-element-css-selector.js
VasylD dc319c5101
[APP-1835] add potential violation for color contrast, fix selector (#369)
* [APP-1835] add potential violation for color contrast, fix selector

* [APP-1835] add potential violation for color contrast, fix selector

* [APP-1835] add potential violation for color contrast, fix selector
2025-08-06 12:31:15 +02:00

65 lines
1.5 KiB
JavaScript

import {
BACKGROUND_ELEMENT_CLASS,
COLOR_ELEMENT_CLASS,
CURRENT_ELEMENT_CLASS,
} from '@ea11y-apps/scanner/constants';
import { getElementByXPath } from '@ea11y-apps/scanner/utils/get-element-by-xpath';
export const getElementCSSSelector = (xpath) => {
let element = getElementByXPath(xpath);
if (!element || !(element instanceof Element)) {
return null;
}
const ignoredClasses = new Set([
CURRENT_ELEMENT_CLASS,
COLOR_ELEMENT_CLASS,
BACKGROUND_ELEMENT_CLASS,
]);
const parts = [];
while (element && element.nodeType === Node.ELEMENT_NODE) {
let selector = element.tagName.toLowerCase();
if (element.id) {
selector += `#${element.id}`;
parts.unshift(selector);
break; // Stop at ID
}
// Add classes unless it's <body> or ignored
if (element.className && element.tagName.toLowerCase() !== 'body') {
const classList = element.className
.trim()
.split(/\s+/)
.filter((cls) => cls && !ignoredClasses.has(cls));
if (classList.length) {
selector += '.' + classList.join('.');
}
}
// Add :nth-of-type if needed
const parent = element.parentNode;
if (
parent &&
!(
parent.tagName?.toLowerCase() === 'body' &&
element.tagName?.toLowerCase() === 'div'
)
) {
const siblings = Array.from(parent.children).filter(
(sibling) => sibling.tagName === element.tagName,
);
if (siblings.length > 1) {
const index = siblings.indexOf(element) + 1;
selector += `:nth-of-type(${index})`;
}
}
parts.unshift(selector);
element = element.parentElement;
}
return parts.join(' > ');
};