notation: !!! als Fokusmarke — ein geteilter Zeigefinger im Text

Beim gemeinsamen Arbeiten an einem Pad (D31) fehlte das Naheliegendste: „schau
mal hier". Etherpad zeigt die Cursor der anderen im Pad, aber Werkbaum kommt
nicht an sie heran — ein fremdstämmiger Rahmen gibt keinen DOM-Zugriff, der
Klartext-Export überträgt nur Text. Eine Marke IM Text ist damit nicht der
Notbehelf, sondern der einzige Weg. Und sie hat etwas, das ein Cursor nicht hat:
alle sehen dieselbe Stelle.

Erkannt wird `!!!` nur ALLEINSTEHEND (`(^|\s)!!!(?=\s|$)`), sonst verlöre jedes
„Achtung!!!" seine Ausrufezeichen und niemand fände den Grund. Bewusst ohne
Lookbehind — Safari kennt es erst ab 16.4, und die Notation soll nicht an einer
Browserversion hängen. Position in der Extraktion (SPEC §1): nach den Tags; der
Kommentar fällt vorher weg, eine Marke hinter `%%` wirkt also nicht.

Darstellung ist DIESELBE wie die der Cursor-Zeile (D25), nicht eine vierte:
neben Fokusrahmen, Strahlenkranz (D28) und Cursor-Ring wäre ein weiterer Ring
ein Zeichen zu viel — es gibt nur einen Begriff „hier schauen". Preis: Im Bild
ist nicht zu unterscheiden, ob die eigene Cursor-Zeile oder eine fremde Marke
leuchtet; für Screenreader benennt `a11yFocusMark` es ausdrücklich.

Ins Bild geholt wird nur bei ÄNDERUNG der Marke, Schlüssel ist der Label-Text
statt der Zeilennummer (Umsortieren im Pad soll nicht neu scrollen). Ohne diese
Bedingung zöge jeder Neubau den Blick zurück und man käme nicht weg. Beides
geprüft: gleiche Marke -> Scrollstand bleibt 0, Marke gewandert -> springt auf
242 und markiert den neuen Knoten.

Beim Hinsehen gefunden: Die Pfad-Inversion verschluckte den Zeigefinger. Der
erste markierte Knoten im Test war eine nicht gewählte any-of-Alternative
(„Headless CMS") — `opacity:.32; saturate(.4)`, der Ring praktisch unsichtbar.
Der Zeiger zeigte auf nichts. Dieselbe Ausnahme wie für D28 behebt es, und hier
ist sie zwingender: „Sollten wir diese verworfene Alternative noch einmal
ansehen?" ist einer der wahrscheinlichsten Gründe, überhaupt zu zeigen. Anders
als beim optionalen Knoten (D29), wo das Zurücktreten die Aussage IST.

Nicht im Druck und nicht im Grafikexport (wie die Cursor-Zeile): Die Marke sagt
„schau jetzt hierhin", nicht „so ist der Plan". Nicht ins kanonische Beispiel
(SPEC §10) aufgenommen — das ist zugleich Test-Fixture, ein dauerhafter
Zeigefinger darin wäre eine Aussage, die niemand gemacht hat.

Verworfen war `%%!` (Kommentar-Variante, bliebe harmlos liegen und könnte die
Begründung tragen) — der Nutzer wählte `!!!`, weil es im Moment des Zeigens
schnell zu tippen ist, und genau dann will man nicht über Syntax nachdenken.
Der Preis steht in D32: die Marke bleibt sichtbar stehen, bis jemand sie löscht;
Werkbaum kann sie nicht entfernen (kein Schreibzugriff auf das Pad).

SPEC §1/§9 zuerst, dann D32, dann Code. 15 neue Tests (86 -> 101), Legende und
i18n in allen 9 Sprachen.
This commit is contained in:
mhoennig
2026-07-30 13:30:50 +02:00
parent 0a08706877
commit 816a77d9e7
12 changed files with 334 additions and 19 deletions
+16 -1
View File
@@ -116,8 +116,23 @@ Verified against Etherpad: the plain-text export sends
leading spaces, `-`/`+`/`|`, status boxes and `%%` survive Etherpad's storage
model, and `-` is not turned into a bullet list.
The pad can also be **embedded** in the editor panel: a selector in the title bar
cycles through *pad and text* (split by a draggable divider), *pad only* and *text
only*. The narrow text mirror keeps its purpose — the jump between diagram and
text works on it, and in *pad only* a jump brings it back by itself. The frame is
only loaded while it is visible, because a loaded pad connects and shows you in
the pad's list of people.
**A shared pointer:** write `!!!` on a line and that node is highlighted and
scrolled into view — for **everyone** looking at the pad, which is something a
cursor cannot do. Recognised only as a standalone token, so `Careful!!!` stays an
ordinary label. It stays in the text until someone deletes it.
**Be aware:** your plan text then lives on third-party infrastructure, and a pad
is readable by anyone who knows its address. See `docs/DECISIONS.md` D31.
is readable by anyone who knows its address. In an embedded frame Etherpad's
author cookie (`SameSite=Lax`) is not sent, so you count as a new author on every
load — fixable only on the server (`cookie.sameSite: "None"`). See
`docs/DECISIONS.md` D31 and D32.
### Running it locally