diff --git a/server/pruef-chat-optik.mjs b/server/pruef-chat-optik.mjs index 9a615581..e68efff9 100644 --- a/server/pruef-chat-optik.mjs +++ b/server/pruef-chat-optik.mjs @@ -493,6 +493,102 @@ melde("\n=== Der Fuss bleibt in der Blase ==="); await luna.seite.unroute("**/api/chat/raeume/*/nachrichten"); } + +/* ======================================================================= + MAN MUSS SEHEN, MIT WEM MAN SCHREIBT (20.09.2026) + + Gemessen am Handy, Gespraech "Team-Runde": + + 360 px -> 0 px sichtbar (98 noetig) + 390 px -> 12 px + 412 px -> 33 px + + Auf JEDEM Telefon stand also kein Name in der Kopfzeile. Man oeffnet + ein Gespraech und weiss nicht, mit wem -- und weil die Zeile nicht + leer aussieht (Zurueck-Pfeil, fuenf Knoepfe), wirkt sie nicht kaputt, + sondern nur eng. + + WARUM DER GROSSE HANDY-RUNDGANG ES NICHT GEFUNDEN HAT -- zwei eigene + Entscheidungen, die zusammen ein Loch ergaben: + + 1. Er ueberspringt, was `width > 0` nicht erfuellt. Ein auf null + gequetschtes Element ist unsichtbar, und "unsichtbar" hiess + dort "nichts zu pruefen". + 2. Er verzeiht `text-overflow: ellipsis` als ABSICHT. Das ist + richtig -- ein langer Name soll gekuerzt werden. Es ist nur + dann falsch, wenn gar nichts mehr uebrig ist. + + Beides ist einzeln vernuenftig. Deshalb steht die Pruefung hier, wo + sie genau eine Sache misst, statt die Regeln dort aufzuweichen. + ======================================================================= */ +melde("\n=== Man sieht, mit wem man schreibt ==="); +{ + let gemessen = 0; + const zuEng = []; + for (const breite of [320, 360, 390, 430]) { + await luna.seite.setViewportSize({ width: breite, height: 844 }); + await luna.seite.waitForTimeout(400); + const m = await luna.seite.evaluate(() => { + const t = document.getElementById("verlauf-titel"); + if (!t) return null; + const r = t.getBoundingClientRect(); + return { text: (t.textContent || "").trim(), sicht: Math.round(r.width), + noetig: Math.round(t.scrollWidth) }; + }); + if (!m || !m.text) continue; + gemessen++; + /* SICHTBAR MUSS SEIN, WAS GEBRAUCHT WIRD -- oder wenigstens so + viel, dass man den Namen erkennt. Ein Drittel eines Namens ist + kein Name. */ + if (m.sicht < Math.min(m.noetig, 90)) { + zuEng.push(`${breite}px: ${m.sicht} von ${m.noetig} px`); + } + } + /* DIE ZAHL GEHOERT IN DIE BEDINGUNG: Faende die Schleife gar keinen + Titel, waere "nichts zu eng" trivialerweise wahr. */ + ok(gemessen === 4 && zuEng.length === 0, + `der Gespraechsname ist auf allen ${gemessen} Breiten lesbar` + + (zuEng.length ? " — ZU ENG: " + zuEng.join(", ") : "")); + + /* ---- GEGENPROBE ------------------------------------------------ + + ERST DEN GEMESSENEN FALL NACHSTELLEN. Der erste Anlauf drehte nur + die Angabe zurueck und blieb gruen: In DIESEM Gespraech stehen + drei Knoepfe, da reicht der Platz auch ohne die Reparatur. Der + Fehler trat in einer GRUPPE auf, wo fuenf Knoepfe stehen -- + Anrufen, Video, Aufloesen, Wegraeumen, Wer-ist-drin. + + Eine Gegenprobe, die den Fall nicht herstellt, den sie pruefen + soll, ist keine. Deshalb bekommt die Knopfreihe hier die Breite, + die fuenf Knoepfe wirklich brauchen (5 x 44 + 4 x 6 Abstand). + Damit muss die alte Angabe den Namen zerdruecken -- und die neue + nicht. Beide Richtungen werden gemessen. */ + await luna.seite.setViewportSize({ width: 390, height: 844 }); + await luna.seite.waitForTimeout(300); + const ab = await luna.seite.evaluate(() => { + const eng = document.createElement("style"); + eng.textContent = ".chat__kopf-knoepfe { min-width: 244px !important; }"; + document.head.append(eng); + + const t = document.getElementById("verlauf-titel"); + const mitNeu = Math.round(t.getBoundingClientRect().width); + + const alt = document.createElement("style"); + alt.textContent = ".chat__kopf--verlauf .chat__kopf-text { flex: 1 1 0 !important; }"; + document.head.append(alt); + const mitAlt = Math.round(t.getBoundingClientRect().width); + + alt.remove(); eng.remove(); + return { mitNeu, mitAlt }; + }); + ok(ab.mitAlt < 40, + `Gegenprobe: mit der alten Angabe bleiben ${ab.mitAlt} px — die Pruefung kann auch NEIN sagen`); + ok(ab.mitNeu >= 90, + ` und mit der neuen ${ab.mitNeu} px, im selben Aufbau — die Reparatur ist der Unterschied`); + await luna.seite.setViewportSize({ width: 1280, height: 900 }); + await luna.seite.waitForTimeout(300); +} + await luna.ctx.close(); await pat.ctx.close(); await browser.close(); diff --git a/server/pruef-handy-teamdogi.mjs b/server/pruef-handy-teamdogi.mjs index 6342b19c..a2db3175 100644 --- a/server/pruef-handy-teamdogi.mjs +++ b/server/pruef-handy-teamdogi.mjs @@ -386,6 +386,45 @@ const messen = () => { return e.scrollWidth > e.clientWidth + 3 || e.scrollHeight > e.clientHeight + 3; }).slice(0, 4).map((e) => `${name(e)} „${(e.textContent || "").trim().slice(0, 28)}…"`); + /* ---- Auf fast nichts zusammengedrückter Text (20.09.2026) -------- + + ZWEI EIGENE ENTSCHEIDUNGEN ERGABEN ZUSAMMEN EIN LOCH, und es hat + einen echten Fehler durchgelassen: In der Kopfzeile eines + Gesprächs blieben vom Namen 0 bis 33 px übrig — auf JEDEM + Telefon. Man öffnete einen Chat und sah nicht, mit wem man + schreibt. + + Warum hier nichts gemeldet wurde: + + 1. `sichtbar()` verlangt `width > 0`. Ein auf null gequetschtes + Element ist unsichtbar -- und "unsichtbar" hiess "nichts zu + prüfen". Genau falsch herum: Nichts zu sehen IST der Befund. + 2. `text-overflow: ellipsis` gilt als Absicht. Das stimmt auch + -- ein langer Name soll gekürzt werden. Es stimmt nur nicht + mehr, wenn nichts übrig bleibt. + + DIE REGEL IST BEWUSST SCHMAL. "Jede Kürzung melden" wären die + ~350 Fehlalarme, die weiter oben schon einmal alles zugedeckt + haben. Gemeldet wird nur, was UNTER 40 px sichtbar ist und + mindestens das Doppelte bräuchte -- da steht kein Wort mehr, + sondern ein Buchstabe mit Punkten. */ + const zerquetscht = alle.filter((e) => { + if (e.children.length > 0) return false; + if (nurVorlesen(e)) return false; + const t = (e.textContent || "").trim(); + if (t.length < 4) return false; + const st = getComputedStyle(e); + if (st.visibility === "hidden" || st.display === "none") return false; + if (Number(st.opacity) <= 0.05) return false; + /* Steht es überhaupt im Aufbau? Ein Element in einem geschlossenen + Klappfeld ist kein Fall -- es ist gar nicht dran. */ + if (!e.offsetParent && st.position !== "fixed") return false; + const breiteHier = e.getBoundingClientRect().width; + const noetig = e.scrollWidth; + return breiteHier < 40 && noetig >= breiteHier * 2 && noetig > 60; + }).slice(0, 4).map((e) => `${name(e)} „${(e.textContent || "").trim().slice(0, 24)}…" ` + + `${Math.round(e.getBoundingClientRect().width)} statt ${Math.round(e.scrollWidth)}px`); + /* ---- Zu kleine Tippziele ----------------------------------------- */ const klein = bedienbar.filter((e) => { const r = e.getBoundingClientRect(); @@ -459,7 +498,7 @@ const messen = () => { elemente: alle.length, bedienbar: bedienbar.length, ueber: document.documentElement.scrollWidth - document.documentElement.clientWidth, - ueberstand, abgeschnitten, klein, ueberdeckt, namenlos, + ueberstand, abgeschnitten, zerquetscht, klein, ueberdeckt, namenlos, }; }; @@ -595,6 +634,9 @@ for (const [breite, hoehe, geraet] of BREITEN) { details.push(`${kurz}: ragt über den Rand — ${m.ueberstand.join(", ")}`); schlecht++; } + if (m.zerquetscht?.length) { + details.push(`${kurz}: Text auf fast nichts gedrückt — ${m.zerquetscht.join(", ")}`); schlecht++; + } if (m.abgeschnitten.length) { details.push(`${kurz}: Text abgeschnitten — ${m.abgeschnitten.join(", ")}`); schlecht++; } diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index 40c27813..e5c48b15 100644 --- a/workspace/anruf-probe.html +++ b/workspace/anruf-probe.html @@ -16,15 +16,15 @@ verdeckt. Gefunden hat es pruef-struktur. Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. --> - - + + - +