feat: ein neues Dokument beginnt mit seinem Namen (D51)
„+ Neu" legte das Dokument unter „Unbenannt" an und setzte den Cursor ins leere Textfeld; das Umbenennen war ein eigener, zweiter Gang durchs Menü — und wurde entsprechend oft nicht gemacht. Jetzt öffnet sich unmittelbar das Inline-Umbenennen (D22) mit ausgewähltem Vorschlag: tippen ersetzt ihn, Enter bestätigt. Das Dokument existiert vorher: angelegt, gespeichert und aktiviert wie bisher, nur der Fokus geht ins Namensfeld statt ins Textfeld. Ein Abbruch verwirft nichts — Esc behält den Vorschlag. Der Gegenentwurf (erst benennen, dann anlegen) hätte ein Dokument im Schwebezustand gebraucht. Nach dem Benennen geht es im Textfeld weiter — Anlegen heißt schreiben wollen. Der Merker `renameIsNew` unterscheidet diesen Fall vom gewöhnlichen Umbenennen aus dem Menü, das unverändert bleibt (Menü bleibt offen, Fokus wandert nicht); `closeDocMenu()` setzt ihn mit zurück, sonst trüge ein abgebrochener Vorgang seine Sonderbehandlung in den nächsten hinein. Nachgemessen: Nach „+ Neu" hat das Eingabefeld den Fokus und der Vorschlag ist vollständig markiert. Enter mit „Sprint 15" -> Titelzeile, `werkbaum-docs` und Fokus im leeren Textfeld stimmen. Esc -> Vorschlag bleibt, Menü zu, Fokus im Text. Bestehendes Dokument umbenennen -> Menü bleibt offen, Fokus bleibt. 236 Tests grün. Grenze der Prüfung, benannt: Der Fokusverlust ließ sich nur als zugestelltes Ereignis prüfen, nicht als echter Fokuswechsel — ein synthetisches `.blur()` löst im Automaten keinen aus. Gegenprobe am unveränderten Pfad zeigt dasselbe, es ist also die Werkzeuggrenze und keine Regression (Lehre aus D25). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
ec338eb558
commit
e554b6d9b8
@@ -3247,3 +3247,44 @@ und bei 320 px.
|
||||
`overflow` gibt, entscheidet damit über alles, was aus ihr herausragen soll —
|
||||
Menüs, Tooltips, Overlays. In `frontend/CLAUDE.md` steht das jetzt bei der
|
||||
Kopfzeilen-Stolperfalle.
|
||||
|
||||
## D51 — Ein neues Dokument beginnt mit seinem Namen
|
||||
Bisher legte „+ Neu" das Dokument unter „Unbenannt" an und setzte den Cursor
|
||||
ins leere Textfeld. Das Umbenennen war ein eigener, zweiter Gang durchs Menü —
|
||||
und wurde entsprechend oft nicht gemacht: Wer drei Pläne führt, hat drei
|
||||
„Unbenannt". Jetzt öffnet sich unmittelbar das Inline-Umbenennen (D22) mit
|
||||
**ausgewähltem** Vorschlag; tippen ersetzt ihn, Enter bestätigt.
|
||||
|
||||
**Das Dokument existiert vorher.** Angelegt, gespeichert und aktiviert wird wie
|
||||
bisher; nur der Fokus geht ins Namensfeld statt ins Textfeld. Ein **Abbruch
|
||||
verwirft nichts** — Esc behält den Vorschlag „Unbenannt", so wie es vorher der
|
||||
Normalfall war. Der Gegenentwurf (erst benennen, dann anlegen) hätte ein
|
||||
Dokument im Schwebezustand gebraucht und die Frage aufgeworfen, was bei Esc
|
||||
passiert; das ist mehr Mechanik für weniger Verlässlichkeit.
|
||||
|
||||
**Nach dem Benennen geht es im Textfeld weiter.** Anlegen heißt schreiben
|
||||
wollen — den Namen zu vergeben ist die erste Hälfte der Geste, nicht ihr Zweck.
|
||||
Der Merker `renameIsNew` unterscheidet diesen Fall vom gewöhnlichen Umbenennen
|
||||
aus dem Menü, das unverändert bleibt (Menü bleibt offen, Fokus wandert nicht).
|
||||
Er wird in `closeDocMenu()` mit zurückgesetzt, sonst trüge ein abgebrochener
|
||||
Vorgang seine Sonderbehandlung in den nächsten hinein.
|
||||
|
||||
Für alle drei Wege aus dem Eingabefeld gilt dasselbe: **Enter**, **Esc** und
|
||||
**Fokusverlust** benennen (bzw. behalten den Vorschlag), schließen das Menü und
|
||||
setzen den Cursor in den Text. Auf dem Telefon ist das zugleich der Moment, in
|
||||
dem die Bildschirmtastatur gebraucht wird — `keyboardOnJump(false)` steht schon
|
||||
da, aus demselben Grund (D25: neues, leeres Dokument = tippen ist gemeint).
|
||||
|
||||
**Nachgemessen:** Nach „+ Neu" trägt das Eingabefeld den Fokus, der Vorschlag
|
||||
ist vollständig markiert (`selectionStart` 0 bis Länge). Enter mit „Sprint 15":
|
||||
Titelzeile, `werkbaum-docs` und der Fokus im leeren Textfeld stimmen. Esc:
|
||||
Vorschlag bleibt, Menü zu, Fokus im Text. Umbenennen eines bestehenden
|
||||
Dokuments: Menü bleibt offen, Fokus bleibt, wo er war.
|
||||
|
||||
**Grenze der Prüfung, benannt:** Der Fokusverlust ließ sich nur als
|
||||
**zugestelltes Ereignis** prüfen, nicht als echter Fokuswechsel — ein
|
||||
synthetisches `.blur()` löst im Automaten keinen aus. Gegenprobe am
|
||||
**unveränderten** Pfad (bestehendes Dokument umbenennen): dort passiert
|
||||
ebenfalls nichts, es ist also die Werkzeuggrenze und keine Regression. Dieselbe
|
||||
Lehre wie in D25 und D17-Nachtrag 4 — was die Geräteumgebung stellt, beweist
|
||||
der Emulator nicht.
|
||||
|
||||
+26
-3
@@ -2603,6 +2603,9 @@ function updateDocName(){
|
||||
updatePadLink(); /* Schreibschutz + Pad-Knopf hängen am aktiven Dokument (D31) */
|
||||
}
|
||||
let renamingId = null; /* id des gerade inline umbenannten Dokuments (oder null) */
|
||||
/* Kam das Umbenennen von einem frisch angelegten Dokument? Dann geht es danach
|
||||
im Textfeld weiter — Anlegen heißt schreiben wollen (D51). */
|
||||
let renameIsNew = false;
|
||||
function renderDocMenu(){
|
||||
docList.innerHTML = docs.map(d => {
|
||||
if(d.id === renamingId){
|
||||
@@ -2664,7 +2667,7 @@ function restoreDoc(){
|
||||
closeDocMenu();
|
||||
}
|
||||
function openDocMenu(){ renderDocMenu(); updateRestoreBtn(); docMenu.hidden = false; docTrigger.setAttribute('aria-expanded', 'true'); }
|
||||
function closeDocMenu(){ renamingId = null; docMenu.hidden = true; docTrigger.setAttribute('aria-expanded', 'false'); }
|
||||
function closeDocMenu(){ renamingId = null; renameIsNew = false; docMenu.hidden = true; docTrigger.setAttribute('aria-expanded', 'false'); }
|
||||
function toggleDocMenu(){ docMenu.hidden ? openDocMenu() : closeDocMenu(); }
|
||||
/* Beim Wechseln/Anlegen/Löschen zuerst den aktuellen Editortext ins aktive
|
||||
Dokument sichern, dann das Ziel laden und neu rendern. */
|
||||
@@ -2728,6 +2731,11 @@ function switchDoc(id){
|
||||
loadActiveIntoEditor();
|
||||
persistDocs();
|
||||
}
|
||||
/* Ein neues Dokument beginnt mit seinem Namen (D51): Statt es unter „Neues
|
||||
Dokument" abzulegen und den Cursor ins leere Textfeld zu setzen, öffnet sich
|
||||
sofort das Inline-Umbenennen mit **ausgewähltem** Vorschlag — tippen ersetzt
|
||||
ihn, Enter bestätigt. Wer nichts eingibt, behält den Vorschlag; das Dokument
|
||||
ist bereits angelegt, ein Abbruch verwirft es nicht. */
|
||||
function newDoc(){
|
||||
flushActive();
|
||||
const d = { id: uid(), name: uniqueName(t('docNewName')), text: '' };
|
||||
@@ -2737,11 +2745,23 @@ function newDoc(){
|
||||
loadActiveIntoEditor();
|
||||
persistDocs();
|
||||
keyboardOnJump(false); /* neues, leeres Dokument = tippen ist gemeint */
|
||||
renamingId = d.id;
|
||||
renameIsNew = true;
|
||||
renderDocMenu(); /* setzt den Fokus ins Eingabefeld und markiert es */
|
||||
}
|
||||
/* Nach dem Benennen eines frisch angelegten Dokuments geht es im Textfeld
|
||||
weiter — die zweite Hälfte derselben Geste. Gilt auch für Esc: Der Vorschlag
|
||||
bleibt dann stehen, das Dokument existiert ohnehin. */
|
||||
function finishNewDoc(){
|
||||
if(!renameIsNew) return;
|
||||
renameIsNew = false;
|
||||
closeDocMenu();
|
||||
src.focus();
|
||||
}
|
||||
function renameDoc(){
|
||||
if(!activeDoc()) return;
|
||||
renamingId = activeId; /* aktives Dokument inline umbenennen */
|
||||
renameIsNew = false;
|
||||
renderDocMenu();
|
||||
}
|
||||
function commitRename(){
|
||||
@@ -2752,8 +2772,9 @@ function commitRename(){
|
||||
renamingId = null;
|
||||
if(d && val){ d.name = val; persistDocs(); updateDocName(); }
|
||||
renderDocMenu();
|
||||
finishNewDoc();
|
||||
}
|
||||
function cancelRename(){ renamingId = null; renderDocMenu(); }
|
||||
function cancelRename(){ renamingId = null; renderDocMenu(); finishNewDoc(); }
|
||||
function deleteDoc(){
|
||||
const d = activeDoc();
|
||||
if(!d) return;
|
||||
@@ -3091,7 +3112,9 @@ docList.addEventListener('click', e => {
|
||||
switchDoc(btn.dataset.id);
|
||||
closeDocMenu();
|
||||
});
|
||||
document.getElementById('docNew').addEventListener('click', e => { e.stopPropagation(); newDoc(); renderDocMenu(); });
|
||||
/* `newDoc()` zeichnet das Menü selbst neu — es geht direkt ins Umbenennen
|
||||
(D51), und ein zweiter Durchlauf baute das Eingabefeld nur noch einmal auf. */
|
||||
document.getElementById('docNew').addEventListener('click', e => { e.stopPropagation(); newDoc(); });
|
||||
document.getElementById('docRename').addEventListener('click', e => { e.stopPropagation(); renameDoc(); });
|
||||
document.getElementById('docDelete').addEventListener('click', e => { e.stopPropagation(); deleteDoc(); });
|
||||
document.getElementById('docRestore').addEventListener('click', e => { e.stopPropagation(); restoreDoc(); });
|
||||
|
||||
Reference in New Issue
Block a user