vibeguard/src/content/filter.ts

41 lines
1.8 KiB
TypeScript

import type { InferenceResult, Settings } from "../shared/types";
const HIDDEN = "data-vibeguard-hidden";
const ORIGINAL_DISPLAY = "data-vibeguard-display";
export function applyResult(element: Element, result: InferenceResult, settings: Settings): void {
const shouldFilter = result.label === "toxic" && result.probability >= settings.threshold;
if (!shouldFilter) { restore(element); return; }
element.setAttribute(HIDDEN, "true");
if (settings.filterMode === "hide") {
element.setAttribute(ORIGINAL_DISPLAY, (element as HTMLElement).style.display);
(element as HTMLElement).style.display = "none";
return;
}
const html = element as HTMLElement;
if (!html.dataset.vibeguardOriginalDisplay) html.dataset.vibeguardOriginalDisplay = html.style.display;
html.style.display = "none";
let placeholder = element.nextElementSibling;
if (!placeholder?.matches("[data-vibeguard-placeholder]")) {
placeholder = document.createElement("div");
placeholder.setAttribute("data-vibeguard-placeholder", "true");
element.insertAdjacentElement("afterend", placeholder);
}
placeholder.className = "vibeguard-placeholder";
placeholder.textContent = `Content hidden as toxic${settings.showScore ? ` (${Math.round(result.probability * 100)}%)` : ""}`;
const button = document.createElement("button");
button.type = "button";
button.textContent = "Show";
button.addEventListener("click", () => { restore(element); placeholder?.remove(); });
placeholder.append(" ", button);
}
export function restore(element: Element): void {
const html = element as HTMLElement;
html.style.display = html.dataset.vibeguardOriginalDisplay ?? "";
delete html.dataset.vibeguardOriginalDisplay;
element.removeAttribute(HIDDEN);
element.nextElementSibling?.matches("[data-vibeguard-placeholder]") && element.nextElementSibling.remove();
}