fix: Bildschirmtastatur quetscht den Editor nicht mehr zusammen
Die eigentliche Ursache der Meldung — meine erste Diagnose (Titelzeilen-Tipp im
alten Splitter-Modell) war für 1.1.39 richtig, aber nicht das, was der Nutzer
auf dem Pages-Build sah.
setAppHeight() schreibt visualViewport.height nach --app-height, und
body{height:var(--app-height)} macht daraus die Höhe der ganzen Seite. Genau
diesen Wert verkleinert die Bildschirmtastatur — dafür ist visualViewport
gemacht. Nachgemessen linear: Textfeldhöhe = --app-height minus ~206 px feste
Aufbauten. 812 px -> 606 px Text, 440 -> 234, 260 -> 54 px, also drei Zeilen.
Das ist das gemeldete „komplett zusammengeklappt".
Sichtbar ausschließlich auf echten Geräten: In der Emulation gibt es keine
Tastatur, deshalb liefen alle drei Reproduktionsversuche vorher ins Leere.
Unterschieden wird am Fokus, nicht an der Größe: Tastatur und überlagernde
Browserleiste (Brave, der ursprüngliche Anlass des Mechanismus) erzeugen
dieselbe Signatur — vv.height fällt, innerHeight bleibt. Die Tastatur steht
aber nur, wenn ein editierbares Feld den Fokus hat. Solange das so ist, bleibt
die letzte tastaturfreie Höhe stehen; die Seite behält ihre Größe und der
Browser schiebt den Ausschnitt zur Schreibmarke.
Mit nachgebildetem visualViewport geprüft: mit Fokus im Textfeld 812/606 px
(unverändert), ohne Fokus 440/234 px — die Brave-Leiste wirkt also weiter.
orientationchange durchbricht die Sperre (sonst behielte die Seite beim Drehen
während des Tippens das alte Hochformat); der focusout-Timer ruft
() => setAppHeight(), sonst reichte er ein wahres `force` durch.
D17 (Nachtrag 4) und frontend/CLAUDE.md nachgezogen, samt der Lehre: Ein
„nicht reproduzierbar" aus dem Emulator ist bei geräteabhängigen Meldungen
kein Befund (vgl. D25 zu synthetischen TouchEvents).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1bda54ae59
commit
6463a76e1e
@@ -292,6 +292,12 @@ Es gibt keinen Splitter und kein Titelzeilen-Tippen mehr, den Bereich wechselt
|
||||
auslösen (Maus-Klick, emulierter Touch und synthetische Touch-Folge, jeweils
|
||||
ohne Bereichswechsel).
|
||||
|
||||
**Das war aber nur die halbe Wahrheit — siehe Nachtrag 4.** Der Nutzer meldete
|
||||
denselben Fehler auf dem Pages-Build, der das Ein-Bereich-Modell bereits
|
||||
enthielt. Die obige Diagnose war für die alte Fassung richtig und trotzdem
|
||||
nicht die Ursache seiner Beobachtung; die eigentliche stand woanders und war
|
||||
mit Emulation grundsätzlich nicht zu finden.
|
||||
|
||||
Der zweite Teil der Meldung deckte aber eine echte Lücke auf: Für die Richtung
|
||||
**Text → Diagramm** gibt es nur Alt+Klick bzw. Alt+Enter (D25) — und Alt gibt
|
||||
es auf dem Telefon nicht. Die Gegenrichtung hat dort ihren langen Druck, diese
|
||||
@@ -315,6 +321,50 @@ Geste und kann nicht versehentlich auslösen. Steht der Cursor auf einer Zeile
|
||||
ohne Knoten (Kommentar, Leerzeile), wird nur umgeschaltet — dieselbe stille
|
||||
Regel wie überall sonst bei dieser Geste.
|
||||
|
||||
**Nachtrag 4 — die eigentliche Ursache: `--app-height` folgte der
|
||||
Bildschirmtastatur.** Nach Nachtrag 3 blieb der Fehler auf dem Pages-Build
|
||||
bestehen („dort klappt der Text komplett zusammen, sobald ich irgendwo den
|
||||
Cursor reinsetze"). Gefunden über die einzige Frage, die nach zwei
|
||||
fehlgeschlagenen Emulations-Versuchen noch trägt: **Was ist auf einem echten
|
||||
Telefon anders?** Antwort: die Tastatur.
|
||||
|
||||
`setAppHeight()` schreibt `window.visualViewport.height` nach `--app-height`,
|
||||
und `body{height:var(--app-height)}` macht daraus die Höhe der ganzen Seite.
|
||||
Genau diesen Wert verkleinert die Bildschirmtastatur — dafür ist
|
||||
`visualViewport` gemacht. Nachgemessen ist der Zusammenhang linear:
|
||||
Textfeldhöhe = `--app-height` − rund 206 px feste Aufbauten (Kopfzeile 57,
|
||||
Titelzeile 44, Fußzeile 36, Innenabstände). Bei 812 px bleiben 606 px Text,
|
||||
bei 440 px noch 234, bei 260 px — realistisch für ein kleines Gerät mit
|
||||
Tastatur und Browserleiste — nur **54 px**, also drei Zeilen. Das ist das
|
||||
gemeldete „komplett zusammengeklappt", und es tritt **ausschließlich auf
|
||||
echten Geräten** auf: In der Emulation gibt es keine Tastatur, deshalb liefen
|
||||
alle drei Reproduktionsversuche aus Nachtrag 3 ins Leere.
|
||||
|
||||
**Unterschieden wird am Fokus, nicht an der Größe.** Die Tastatur und eine
|
||||
überlagernde Browserleiste (Brave — der ursprüngliche Anlass des Mechanismus)
|
||||
erzeugen dieselbe Signatur: `visualViewport.height` fällt, `innerHeight`
|
||||
bleibt. An den Zahlen sind sie nicht zu trennen. Am Zustand schon: Die
|
||||
Tastatur steht nur, wenn ein **editierbares** Feld den Fokus hat. Solange das
|
||||
so ist, bleibt die zuletzt tastaturfreie Höhe stehen. Die Seite behält damit
|
||||
ihre Größe, und der Browser schiebt den sichtbaren Ausschnitt zur
|
||||
Schreibmarke — das Verhalten jeder anderen App. Nachgemessen mit
|
||||
nachgebildetem `visualViewport`: mit Fokus im Textfeld 812/606 px (unverändert),
|
||||
ohne Fokus 440/234 px (die Brave-Leiste wirkt also weiter).
|
||||
|
||||
**Drehen muss die Sperre durchbrechen** (`setAppHeight(true)` bei
|
||||
`orientationchange`) — sonst behielte die Seite beim Drehen während des
|
||||
Tippens die Höhe des alten Hochformats. Dazu ein `focusout`-Nachzug für
|
||||
Browser, die das Schließen der Tastatur nicht als `resize` melden. Und der
|
||||
Timer dort ruft `() => setAppHeight()`, nicht `setAppHeight` direkt: Ein
|
||||
durchgereichtes Argument wäre wahr und hebelte die Fokus-Sperre aus.
|
||||
|
||||
**Lehre, schon zweimal bezahlt:** D25 hielt fest, dass synthetische
|
||||
`TouchEvent`s nur die eigene Ereignis-Logik beweisen. Dieselbe Grenze gilt für
|
||||
alles, was die **Geräteumgebung** stellt — Bildschirmtastatur, Browserleisten,
|
||||
Nutzergesten-Regeln. Ein „lässt sich nicht reproduzieren" aus dem Emulator ist
|
||||
bei solchen Meldungen kein Befund, sondern nur die Feststellung, dass das
|
||||
Werkzeug die Ursache nicht enthält.
|
||||
|
||||
**Das Debug-Panel minimiert sich jetzt, statt sich zu schließen.** Ein Klick
|
||||
entfernte es bisher ganz — was nichts half, weil der 15-Sekunden-Takt es sofort
|
||||
wieder aufbaute; auf dem Telefon verdeckte es damit dauerhaft die untere rechte
|
||||
|
||||
@@ -398,6 +398,18 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
|
||||
**einzige** Touch-Navigation Text → Diagramm (Alt gibt es dort nicht). Keinen
|
||||
langen Druck ins Textfeld legen — der gehört dem OS (Wortauswahl,
|
||||
Auswahlgriffe), anders als im Diagramm, wo D25 ihn sich nehmen konnte.
|
||||
- `--app-height` (`setAppHeight()`, D17-Nachtrag 4): `body{height:var(--app-height)}`
|
||||
kommt aus `visualViewport.height` — nötig gegen überlagernde Browserleisten
|
||||
(Brave). **Die Bildschirmtastatur verkleinert denselben Wert** und quetschte
|
||||
damit den Editor zusammen, sobald der Cursor ins Textfeld kam (Textfeldhöhe =
|
||||
`--app-height` − ~206 px feste Aufbauten; bei 260 px Viewport bleiben 54 px).
|
||||
Deshalb die Fokus-Sperre `editingNow()`: Solange ein editierbares Feld den
|
||||
Fokus hat, bleibt die letzte tastaturfreie Höhe stehen. Tastatur und
|
||||
Browserleiste sind an den **Zahlen** nicht zu unterscheiden (beide: `vv.height`
|
||||
fällt, `innerHeight` bleibt) — nur am Fokus. `orientationchange` ruft
|
||||
`setAppHeight(true)` und durchbricht die Sperre; der `focusout`-Timer muss
|
||||
`() => setAppHeight()` sein, sonst reicht er ein wahres `force` durch.
|
||||
**Nur auf echten Geräten sichtbar** — in der Emulation gibt es keine Tastatur.
|
||||
**Der verborgene Bereich ist `display:none` und misst sich damit zu null** —
|
||||
`setMobilePane()` MUSS neu zeichnen: zum Diagramm hin dieselben vier Schritte
|
||||
wie `applyLayout` (`applyOptStairs`/`alignStems`/`drawCheapPath`/
|
||||
|
||||
+31
-5
@@ -2862,17 +2862,43 @@ function isMobile(){ return mqMobile.matches; }
|
||||
zeichnen: 100dvh meldet dann weiterhin die volle Höhe, und Footer/Editor-
|
||||
Titelzeile verschwinden dahinter. visualViewport.height liefert die wirklich
|
||||
sichtbare Fläche. Fällt es weg, greift die CSS-Kaskade (dvh/vh). */
|
||||
function setAppHeight(){
|
||||
/* ABER: Die **Bildschirmtastatur** verkleinert genau diesen Wert — dafür ist
|
||||
`visualViewport` gemacht. Ungefiltert übernommen quetscht sie den Editor
|
||||
zusammen, sobald man den Cursor ins Textfeld setzt: Die Textfeldhöhe ist
|
||||
`--app-height` minus rund 206 px feste Aufbauten (Kopfzeile, Titelzeile,
|
||||
Fußzeile), aus 812 px werden also mit offener Tastatur schnell 260 px und
|
||||
damit ein Textfeld von 54 px. Genau das war die Fehlermeldung — und sie
|
||||
zeigt sich **nur auf echten Geräten**, weil es in der Emulation keine
|
||||
Tastatur gibt.
|
||||
Unterschieden wird am **Fokus**: Die Tastatur steht nur, wenn ein
|
||||
editierbares Feld den Fokus hat. Solange das so ist, bleibt die zuletzt
|
||||
tastaturfreie Höhe stehen — die Seite behält ihre Größe und der Browser
|
||||
schiebt den sichtbaren Ausschnitt zur Schreibmarke, wie in jeder anderen
|
||||
App. Die Brave-Leiste (der eigentliche Anlass) wird davon nicht berührt,
|
||||
sie erscheint ohne Fokus im Textfeld. */
|
||||
function editingNow(){
|
||||
const el = document.activeElement;
|
||||
if(!el) return false;
|
||||
return el.tagName === 'TEXTAREA' || el.tagName === 'INPUT' || el.isContentEditable;
|
||||
}
|
||||
function setAppHeight(force){
|
||||
if(!force && editingNow()) return;
|
||||
const vv = window.visualViewport;
|
||||
const h = vv ? vv.height : window.innerHeight;
|
||||
document.documentElement.style.setProperty('--app-height', Math.round(h) + 'px');
|
||||
}
|
||||
setAppHeight();
|
||||
window.addEventListener('resize', setAppHeight);
|
||||
window.addEventListener('orientationchange', setAppHeight);
|
||||
setAppHeight(true);
|
||||
window.addEventListener('resize', () => setAppHeight());
|
||||
/* Drehen MUSS auch beim Tippen greifen — sonst behielte die Seite die Höhe des
|
||||
alten Hochformats. */
|
||||
window.addEventListener('orientationchange', () => setAppHeight(true));
|
||||
if(window.visualViewport){
|
||||
window.visualViewport.addEventListener('resize', setAppHeight);
|
||||
window.visualViewport.addEventListener('resize', () => setAppHeight());
|
||||
}
|
||||
/* Nach dem Verlassen des Textfelds nachziehen: Die meisten Browser melden das
|
||||
Schließen der Tastatur ohnehin als `resize`, aber dann steht der Fokus schon
|
||||
woanders — und falls die Meldung ausbleibt, holt es dieser Weg nach. */
|
||||
window.addEventListener('focusout', () => setTimeout(() => setAppHeight(), 250));
|
||||
/* ---------- Legende: auf/zu + Splitter zum Editor (D26) ----------
|
||||
Die Legende ist ein gewöhnlicher Container (kein <details> mehr, siehe
|
||||
style.css/D26); der Auf-/Zu-Zustand hängt an der Klasse `open`. */
|
||||
|
||||
Reference in New Issue
Block a user