/* ===================================================================== pruef-nachfrage.mjs — Nichts verschwindet ohne Nachfrage. Filipe, 19.09.2026: „Es darf vor allem keine Stellen geben, an denen ein Benutzer etwas falsch machen kann, nur weil die Seite es nicht verständlich genug erklärt." Und: „Fehler möglichst verhindern, bevor sie entstehen." --------------------------------------------------------------------- WAS DAS PROBLEM WAR Das Haus hatte die richtige Bauweise — einen statt `confirm()` — und begründete sie in `aufgaben.html` sogar ausführlich. Nur stand sie IN EINER SEITE. Gemessen am 19.09.2026: **30 Stellen** in 16 Dateien griffen weiterhin zu `confirm()` oder `prompt()`. Der Unterschied ist nicht Geschmack. `confirm('Wirklich löschen?')` stellt die falsche Frage: Es fragt, ob man sicher ist, und nennt nicht, WAS passiert, was BLEIBT und ob es ZURÜCK geht. Genau das sind die drei Dinge, die man vor einem Löschen wissen will. --------------------------------------------------------------------- VIER DINGE WERDEN GEPRÜFT 1. KEIN NATIVER DIALOG mehr in einer Seiten-Datei. Ausgenommen ist allein der Notnagel in `nachfrage.js` selbst — für Browser ohne . (Ein Verbot ohne diese Ausnahme wäre falsch: Ein iPhone vor Safari 15.4 bekäme sonst gar nichts angezeigt.) 2. ANGESCHLOSSEN — jede Seite, deren Skripte `frageNach` benutzen, lädt auch `nachfrage.js`. Ohne die Datei wäre `frageNach` nicht definiert, und aus einer Rückfrage würde ein Absturz: Der Knopf täte stillschweigend nichts. ACHTUNG, hier steckte beim Bauen schon eine Falle: Die erste Fassung dieser Prüfung zählte `nachfrage.js` SELBST als Nutzer (die Datei enthält das Wort natürlich) — damit war jede Seite „Nutzer", die Prüfung immer grün und sie bewies nichts. Deshalb ist die Datei unten ausdrücklich ausgenommen. 3. GESTALTET — `.dialog` wird in einer Datei gestaltet, die JEDE Seite lädt. Vorher stand sie in `aufgaben.css`; auf `dateien.html` wäre der Dialog ein weißer Systemkasten auf dunkler Seite gewesen. Das ist keine Schönheitsfrage: Ein Kasten, der aussieht wie eine Browser-Warnung, wird weggeklickt statt gelesen. 4. VOLLSTÄNDIG — jeder Aufruf hat einen `titel` und sagt, was passiert (`was`). Ein Dialog ohne diese Angabe ist ein `confirm()` mit mehr Zeilen Code. Dazu GEGENPROBEN: Jede Prüfung muss beweisen, dass sie auch „nicht in Ordnung" sagen kann. AUFRUF: node server/pruef-nachfrage.mjs Läuft in unter zwei Sekunden, ohne Server. ===================================================================== */ import { readFileSync, readdirSync } from "node:fs"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { bestaetige, nachfrageText } from "./helfer-nachfrage.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); const WURZEL = join(HIER, ".."); const SEITEN_ORDNER = join(WURZEL, "workspace"); const JS_ORDNER = join(SEITEN_ORDNER, "assets", "js"); const CSS_ORDNER = join(SEITEN_ORDNER, "assets", "css"); /* Die eine Datei, die `confirm`/`prompt` benutzen DARF -- sie ist der Notnagel fuer Browser ohne . */ const DER_NOTNAGEL = "nachfrage.js"; let ok = 0, fehl = 0; const pruef = (name, bedingung, zusatz = "") => { if (bedingung) { ok++; console.log(` OK ${name}`); } else { fehl++; console.log(` FEHL ${name}${zusatz ? "\n " + zusatz : ""}`); } }; const lies = (p) => readFileSync(p, "utf8"); const seiten = readdirSync(SEITEN_ORDNER).filter((f) => f.endsWith(".html")); const skripte = readdirSync(JS_ORDNER).filter((f) => f.endsWith(".js")); console.log("\n=== Nachfragen: kein nativer Dialog, und keiner ohne Erklärung ===\n"); /* --------------------------------------------------------------------- 1. KEIN NATIVER DIALOG ------------------------------------------------------------------ */ /** Entfernt Kommentare, bevor gesucht wird. Ohne das zaehlt jeder * Kommentar, der `confirm()` ERWAEHNT, als Fund -- und davon gibt es * in diesem Haus absichtlich mehrere (die Begruendungen). */ function ohneKommentare(js) { return js.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1"); } const nativ = []; for (const f of skripte) { if (f === DER_NOTNAGEL) continue; const code = ohneKommentare(lies(join(JS_ORDNER, f))); for (const m of code.matchAll(/(?:^|[^.\w])(confirm|prompt)\s*\(/g)) { const zeile = code.slice(0, m.index).split("\n").length; nativ.push(`${f}:${zeile} → ${m[1]}()`); } } pruef("keine Seite benutzt noch confirm() oder prompt()", nativ.length === 0, nativ.slice(0, 8).join("\n ")); /* Und der Notnagel ist da -- sonst haetten Browser ohne gar nichts. Die ZAHL gehoert in die Bedingung, nicht nur in den Text. */ const notnagel = lies(join(JS_ORDNER, DER_NOTNAGEL)); pruef("der Notnagel für alte Browser ist vorhanden", /HTMLDialogElement/.test(notnagel) && /window\.confirm\(/.test(notnagel)); /* --------------------------------------------------------------------- 2. ANGESCHLOSSEN ------------------------------------------------------------------ */ /** Welche Skripte rufen frageNach auf? OHNE die Datei, die es * DEFINIERT -- sonst ist die Antwort immer „alle". */ const nutzer = new Set(); for (const f of skripte) { if (f === DER_NOTNAGEL) continue; if (/\bfrageNach\s*\(/.test(ohneKommentare(lies(join(JS_ORDNER, f))))) nutzer.add(f); } pruef("es gibt überhaupt Seiten, die nachfragen", nutzer.size > 0, `gefunden: ${nutzer.size}`); const ohneDatei = [], totesGewicht = [], fragendeSeiten = []; let mitNutzung = 0; for (const s of seiten) { const html = lies(join(SEITEN_ORDNER, s)); const geladen = [...html.matchAll(/