frontend: „Werkbank" — Werkbaums eigener Plan als mitgeliefertes Dokument
Der interessanteste Beispielbaum war nur über einen ?sourceUrl=-Link erreichbar. Er steht jetzt direkt im Dokument-Wähler. - Eine Quelle, keine Kopie: `?raw`-Import aus docs/examples/example-werkbaum.werkbaum — derselben Datei, die auch der ?sourceUrl=-Link lädt. Vite bettet sie in die eine Ausgabedatei ein (D19), nichts wird nachgeladen (D20). Die Beispieldatei ist damit Build-Eingabe. - `seedShippedDocs()` legt das Dokument genau EINMAL an — auch für Bestandsnutzer mit vorhandener Dokumentenliste — und merkt sich das in `werkbaum-seeded`. Ohne Merker gäbe es nur schlechte Alternativen: entweder bekämen bestehende Nutzer es nie, oder ein bewusst gelöschtes Dokument kehrte bei jedem Laden zurück. Das aktive Dokument bleibt unverändert. - Fester, nicht lokalisierter Name wie „Example" (D22). Der Reset setzt jetzt beide mitgelieferten Dokumente zurück; eigene bleiben unangetastet. Verifiziert im Browser: frischer Zustand -> Example + Werkbank, aktiv bleibt Example; Wechsel auf Werkbank rendert 75 Knoten ohne Warnung; Bestandsnutzer mit eigener Liste bekommt Werkbank ergänzt, ohne aus seinem Dokument gerissen zu werden; nach Löschen kehrt es nicht zurück. Build bleibt eine einzelne Datei (361 kB), Vitest 37/37. Offen (in D27 notiert): der Text wird nach dem Anlegen nicht mehr aktualisiert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6888762ac8
commit
6fb45ff37a
@@ -619,3 +619,37 @@ Grenzen: mindestens 90 px, höchstens 85 % — die Obergrenze steht **zusätzlic
|
||||
als `max-width`/`max-height` im CSS**, weil die gespeicherte Größe ein fester
|
||||
px-Wert ist: schrumpft das Panel später (Zug am großen Splitter, Drehung,
|
||||
Bildschirmtastatur), würde der Editor sonst auf 0 gedrückt.
|
||||
|
||||
## D27 — „Werkbank": Werkbaums eigener Plan als mitgeliefertes Dokument
|
||||
Neben dem Beispiel (D22) liegt ein zweites mitgeliefertes Dokument im Wähler:
|
||||
**„Werkbank"** — Werkbaum selbst, mit Werkbaum geplant (Bestand + mögliche
|
||||
Weiterentwicklung). Damit ist der interessanteste Beispielbaum ohne Umweg über
|
||||
einen `?sourceUrl=`-Link erreichbar; zugleich dient er als lebende
|
||||
Projektübersicht.
|
||||
|
||||
**Eine Quelle, keine Kopie.** Der Text wird per `?raw`-Import aus
|
||||
`docs/examples/example-werkbaum.werkbaum` gezogen — derselben Datei, die auch
|
||||
der `?sourceUrl=`-Link lädt. Vite bettet sie beim Build in die eine Ausgabedatei
|
||||
ein (D19), es wird nichts nachgeladen (D20). Eine zweite, abgetippte Fassung im
|
||||
Quelltext würde unweigerlich auseinanderlaufen. (Nebenwirkung: die Beispieldatei
|
||||
ist damit **Build-Eingabe** — Umbenennen bricht den Build. `vite.config.js`
|
||||
erlaubt den Zugriff außerhalb des Roots bereits über `server.fs.allow: ['..']`,
|
||||
eingeführt für das Favicon.)
|
||||
|
||||
**Genau einmal angelegt.** `seedShippedDocs()` fügt das Dokument auch
|
||||
Bestandsnutzern hinzu, die schon eine Dokumentenliste haben, und merkt sich das
|
||||
in `werkbaum-seeded`. Ohne diesen Merker gäbe es nur schlechte Alternativen:
|
||||
entweder bekämen bestehende Nutzer es nie, oder ein bewusst gelöschtes Dokument
|
||||
kehrte bei **jedem** Laden zurück. Das aktive Dokument bleibt beim Anlegen
|
||||
unverändert — niemand wird aus seinem Text gerissen.
|
||||
|
||||
**Fester Name, nicht lokalisiert** — wie „Example" (D22): Dokumentnamen sind
|
||||
Nutzerdaten. Der Reset (D22) setzt jetzt **beide** mitgelieferten Dokumente auf
|
||||
ihren Auslieferungsstand zurück; eigene Dokumente bleiben weiterhin unangetastet.
|
||||
|
||||
**Offen:** Der Text wird nach dem Anlegen nicht mehr aktualisiert. Erscheint
|
||||
später eine neuere Fassung des Plans, sieht sie nur, wer das Dokument löscht und
|
||||
zurücksetzt oder den `?sourceUrl=`-Link öffnet. Ein Ausbau könnte in
|
||||
`werkbaum-seeded` statt '1' eine Versionsnummer ablegen und ein **unverändertes**
|
||||
Dokument nachziehen (bearbeitete nie) — dieselbe Adoptions-Regel wie beim
|
||||
Beispiel in D22.
|
||||
|
||||
@@ -106,6 +106,13 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
|
||||
`werkbaum-ui`/`werkbaum-lang`/Update-Flags — **andere Dokumente bleiben stehen**
|
||||
(nicht mehr pauschal alle `werkbaum-*` löschen!). Das letzte gelöschte Dokument
|
||||
wird als Beispiel neu gesät.
|
||||
- Mitgeliefertes Dokument „Werkbank" (D27): `app.js` importiert
|
||||
`../../docs/examples/example-werkbaum.werkbaum?raw` — die Beispieldatei ist
|
||||
damit **Build-Eingabe**, Umbenennen/Verschieben bricht den Build (Zugriff
|
||||
außerhalb des Roots erlaubt `server.fs.allow:['..']`). `seedShippedDocs()` legt
|
||||
es **einmalig** an (auch für Bestandsnutzer) und merkt sich das in
|
||||
`werkbaum-seeded`; ohne den Merker käme ein gelöschtes Dokument bei jedem Laden
|
||||
zurück. `resetToDefaults()` setzt beide mitgelieferten Dokumente zurück.
|
||||
- Umbenennen ist **inline** (kein `window.prompt` — in manchen Browser-Kontexten
|
||||
unterdrückt): `renameDoc()` setzt `renamingId`, `renderDocMenu()` rendert dann
|
||||
ein `<input class="docrename">` (Enter = `commitRename`, Esc = `cancelRename`,
|
||||
|
||||
+36
-6
@@ -3,6 +3,11 @@ import { parse } from './parser.js';
|
||||
import { computeCheapSet } from './model.js';
|
||||
import { esc, renderTreeHtml } from './render.js';
|
||||
import { formatWarning } from './warnings.js';
|
||||
/* Werkbaum, mit Werkbaum geplant — als mitgeliefertes Dokument „Werkbank" (D27).
|
||||
Dieselbe Datei, die auch per ?sourceUrl= geladen werden kann; `?raw` bettet
|
||||
sie beim Build in die eine Ausgabedatei ein (D19), es wird nichts nachgeladen
|
||||
(D20). Quelle bleibt docs/examples/ — keine Kopie, die auseinanderläuft. */
|
||||
import WERKBAUM_DOC from '../../docs/examples/example-werkbaum.werkbaum?raw';
|
||||
|
||||
const INITIAL = `%% Project structure – Sprint 14
|
||||
[~] Website relaunch (XL) https://wiki.example.com/relaunch
|
||||
@@ -1296,6 +1301,7 @@ fsBtn.addEventListener('click', () => {
|
||||
erhalten. Sprache liegt weiterhin in 'werkbaum-lang'. */
|
||||
const LS_UI = 'werkbaum-ui', LS_SRC = 'werkbaum-src';
|
||||
const LS_DOCS = 'werkbaum-docs', LS_ACTIVE = 'werkbaum-active';
|
||||
const LS_SEEDED = 'werkbaum-seeded'; /* mitgelieferte Dokumente schon angelegt? */
|
||||
let restoring = false; /* unterdrückt Speichern während des Wiederherstellens */
|
||||
let hadStoredUI = false; /* gab es beim Laden schon gespeicherte GUI-Einstellungen? */
|
||||
|
||||
@@ -1310,6 +1316,9 @@ let hadStoredUI = false; /* gab es beim Laden schon gespeicherte GUI-Einstellun
|
||||
unabhängig von der UI-Sprache englisch — wie der Beispieltext selbst (breiteres
|
||||
Publikum). */
|
||||
const EXAMPLE_ID = 'example', EXAMPLE_NAME = 'Example';
|
||||
/* Zweites mitgeliefertes Dokument: Werkbaum selbst (D27). Fester Name wie beim
|
||||
Beispiel — Dokumentnamen sind Nutzerdaten und werden nicht übersetzt (D22). */
|
||||
const WERKBAUM_ID = 'werkbaum', WERKBAUM_NAME = 'Werkbank';
|
||||
let docs = []; /* [{id, name, text}] */
|
||||
let activeId = null;
|
||||
function uid(){ return 'd' + Date.now().toString(36) + Math.random().toString(36).slice(2, 7); }
|
||||
@@ -1329,6 +1338,20 @@ function persistDocs(){
|
||||
if(d) localStorage.setItem(LS_SRC, d.text); /* Spiegel für Fallback/Migration */
|
||||
}catch(_){}
|
||||
}
|
||||
/* „Werkbank" (D27) genau EINMAL anlegen — auch für Bestandsnutzer, die schon
|
||||
eine Dokumentenliste haben. Der Merker `LS_SEEDED` sorgt dafür, dass ein
|
||||
bewusst gelöschtes Dokument nicht bei jedem Laden zurückkehrt; ein späterer
|
||||
Ausbau kann dort eine Versionsnummer statt '1' ablegen. */
|
||||
function seedShippedDocs(){
|
||||
let seeded = null;
|
||||
try{ seeded = localStorage.getItem(LS_SEEDED); }catch(_){}
|
||||
if(seeded) return;
|
||||
if(!docs.some(d => d.id === WERKBAUM_ID)){
|
||||
docs.push({ id: WERKBAUM_ID, name: WERKBAUM_NAME, text: WERKBAUM_DOC });
|
||||
}
|
||||
try{ localStorage.setItem(LS_SEEDED, '1'); }catch(_){}
|
||||
}
|
||||
|
||||
/* Aus dem localStorage laden; bei fehlender Dokumentenliste den bestehenden
|
||||
Einzeltext (oder INITIAL) als erstes Dokument migrieren. */
|
||||
function loadDocs(){
|
||||
@@ -1352,6 +1375,7 @@ function loadDocs(){
|
||||
docs[0].id = EXAMPLE_ID;
|
||||
docs[0].name = EXAMPLE_NAME;
|
||||
}
|
||||
seedShippedDocs();
|
||||
activeId = docs.some(d => d.id === a) ? a : docs[0].id;
|
||||
}
|
||||
function saveSrc(){
|
||||
@@ -2023,14 +2047,20 @@ function resetToDefaults(){
|
||||
['werkbaum-ui','werkbaum-lang','werkbaum-html-hash','werkbaum-update-available','werkbaum-update-log']
|
||||
.forEach(k => { try{ localStorage.removeItem(k); }catch(_){} });
|
||||
|
||||
/* Nur das Beispiel-Dokument auf den Ausgangstext zurücksetzen; existiert es
|
||||
nicht (mehr), wird es neu angelegt. Andere Dokumente bleiben unberührt. */
|
||||
const ex = docs.find(d => d.id === EXAMPLE_ID);
|
||||
if(ex){ ex.text = INITIAL; ex.name = EXAMPLE_NAME; }
|
||||
else { docs.unshift({ id: EXAMPLE_ID, name: EXAMPLE_NAME, text: INITIAL }); }
|
||||
/* Nur die MITGELIEFERTEN Dokumente auf ihren Ausgangstext zurücksetzen;
|
||||
existiert eines nicht (mehr), wird es neu angelegt. Eigene Dokumente des
|
||||
Nutzers bleiben unberührt (D22/D27). */
|
||||
const reseed = (id, name, text, vorn) => {
|
||||
const d = docs.find(x => x.id === id);
|
||||
if(d){ d.text = text; d.name = name; }
|
||||
else if(vorn) docs.unshift({ id, name, text });
|
||||
else docs.push({ id, name, text });
|
||||
};
|
||||
reseed(EXAMPLE_ID, EXAMPLE_NAME, INITIAL, true);
|
||||
reseed(WERKBAUM_ID, WERKBAUM_NAME, WERKBAUM_DOC, false);
|
||||
activeId = EXAMPLE_ID;
|
||||
persistDocs();
|
||||
logUpdate('🔄 Beispiel-Dokument und Einstellungen zurückgesetzt');
|
||||
logUpdate('🔄 Mitgelieferte Dokumente und Einstellungen zurückgesetzt');
|
||||
|
||||
/* Kurze Verzögerung, damit Logging sichtbar wird, dann reload */
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user