import {
attachTooltipToHighlight,
createHighlight,
getElementsPositionInDocument,
positionHighlight
} from "../utils/highlight.js";
import { createWindowElement } from "../utils/window.js";
import { a11y } from "./a11y.js";
const icon = '';
const rules = [...a11y];
const dynamicAuditRuleKeys = ["title", "message"];
function resolveAuditRule(rule, element) {
let resolved = { ...rule };
for (const key of dynamicAuditRuleKeys) {
const value = rule[key];
if (typeof value === "string")
continue;
resolved[key] = value(element);
}
return resolved;
}
var audit_default = {
id: "astro:audit",
name: "Audit",
icon,
async init(canvas, eventTarget) {
let audits = [];
await lint();
document.addEventListener("astro:after-swap", async () => lint());
document.addEventListener("astro:page-load", async () => refreshLintPositions);
function onPageClick(event) {
const target = event.target;
if (!target)
return;
if (!target.closest)
return;
if (target.closest("astro-dev-toolbar"))
return;
eventTarget.dispatchEvent(
new CustomEvent("toggle-app", {
detail: {
state: false
}
})
);
}
eventTarget.addEventListener("app-toggled", (event) => {
if (event.detail.state === true) {
document.addEventListener("click", onPageClick, true);
} else {
document.removeEventListener("click", onPageClick, true);
}
});
async function lint() {
audits.forEach(({ highlightElement }) => {
highlightElement.remove();
});
audits = [];
canvas.getElementById("no-audit")?.remove();
const selectorCache = /* @__PURE__ */ new Map();
for (const rule of rules) {
const elements = selectorCache.get(rule.selector) ?? document.querySelectorAll(rule.selector);
let matches = [];
if (typeof rule.match === "undefined") {
matches = Array.from(elements);
} else {
for (const element of elements) {
if (rule.match(element)) {
matches.push(element);
}
}
}
for (const element of matches) {
await createAuditProblem(rule, element);
}
}
if (audits.length > 0) {
eventTarget.dispatchEvent(
new CustomEvent("toggle-notification", {
detail: {
state: true
}
})
);
} else {
eventTarget.dispatchEvent(
new CustomEvent("toggle-notification", {
detail: {
state: false
}
})
);
const window2 = createWindowElement(
`
Nice work! This app scans the page and highlights common accessibility issues for you, like a missing "alt" attribute on an image.
` ); canvas.append(window2); } ["scroll", "resize"].forEach((event) => { window.addEventListener(event, refreshLintPositions); }); } function refreshLintPositions() { const noAuditBlock = canvas.getElementById("no-audit"); if (noAuditBlock) { const devOverlayRect = document.querySelector("astro-dev-toolbar")?.shadowRoot.querySelector("#dev-toolbar-root")?.getBoundingClientRect(); noAuditBlock.style.top = `${(devOverlayRect?.top ?? 0) - (devOverlayRect?.height ?? 0) - 16}px`; } audits.forEach(({ highlightElement, auditedElement }) => { const rect = auditedElement.getBoundingClientRect(); positionHighlight(highlightElement, rect); }); } async function createAuditProblem(rule, originalElement) { const computedStyle = window.getComputedStyle(originalElement); const targetedElement = originalElement.children[0] || originalElement; if (targetedElement.offsetParent === null || computedStyle.display === "none") { return; } if (originalElement.nodeName === "IMG" && !originalElement.complete) { return; } const rect = originalElement.getBoundingClientRect(); const highlight = createHighlight(rect, "warning"); const tooltip = buildAuditTooltip(rule, originalElement); const { isFixed } = getElementsPositionInDocument(originalElement); if (isFixed) { tooltip.style.position = highlight.style.position = "fixed"; } attachTooltipToHighlight(highlight, tooltip, originalElement); canvas.append(highlight); audits.push({ highlightElement: highlight, auditedElement: originalElement }); } function buildAuditTooltip(rule, element) { const tooltip = document.createElement("astro-dev-toolbar-tooltip"); const { title, message } = resolveAuditRule(rule, element); tooltip.sections = [ { icon: "warning", title: escapeHtml(title) }, { content: escapeHtml(message) } ]; const elementFile = element.getAttribute("data-astro-source-file"); const elementPosition = element.getAttribute("data-astro-source-loc"); if (elementFile) { const elementFileWithPosition = elementFile + (elementPosition ? ":" + elementPosition : ""); tooltip.sections.push({ content: elementFileWithPosition.slice( window.__astro_dev_toolbar__.root.length - 1 // We want to keep the final slash, so minus one. ), clickDescription: "Click to go to file", async clickAction() { await fetch("/__open-in-editor?file=" + encodeURIComponent(elementFileWithPosition)); } }); } return tooltip; } function escapeHtml(unsafe) { return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); } } }; export { audit_default as default };