docs: lead with screenshots and correct outdated documentation

Both documents had drifted away from the repository they describe: they
pointed at fixtures and a helper script that are not present, documented a
local-server workflow that is no longer used, and filed one page type under
the wrong view. Following them meant setting up things that cannot work while
trusting claims that no longer held.

The README also explained every design decision before showing a single
result, so the question a reader asks first — what does this actually look
like — took the longest to answer. Screenshots and a short feature list now
carry that job. The reasoning stays where it is needed, next to the code.

Restricting the dev loader to the live site closes a side effect that only
surfaced locally: its patterns matched page names common enough that the
stylesheet would have leaked into unrelated local projects.

The version number existed in two places and had already drifted apart.
Reading it back from the metadata block leaves one place to change it.
This commit is contained in:
Andre
2026-08-03 10:21:05 +02:00
parent e7f3f56456
commit c477537826
8 changed files with 256 additions and 274 deletions
+80 -27
View File
@@ -1,18 +1,17 @@
# CLAUDE.md
Ein Userscript, das die phpBB-Seiten von `cs.rin.ru` fuer Safari auf iOS in eine
Ein Userscript, das die phpBB3-Seiten von `cs.rin.ru` fuer Safari auf iOS in eine
mobile Ansicht umbaut. Kein Build, keine Abhaengigkeiten, kein `package.json` —
die `.user.js`-Datei ist das Produkt.
| Datei | Greift auf | Zweck |
|---|---|---|
| `rin-mobile.user.js` | `*://cs.rin.ru/forum/*` | Beide Ansichten, Weiche nach Seitentyp |
| `dev/rin-mobile.dev.user.js` | zusaetzlich `localhost:*` | Loader, bindet per `@require file:///` das echte Script ein |
| `dev/viewtopic.php` | — | Fixture: gespeicherter Thread, 1114 Seiten |
| `dev/viewforum.php` | — | Fixture: Main Forum, 610 Seiten, mit Unterforen, Ankuendigungen und Stickies |
| `dev/index.php` | — | Fixture: Forumwurzel, zwei Kategorien mit Forenzeilen, keine Paginierung |
| `rin-mobile.user.js` | `*://cs.rin.ru/forum/*` | Alle Ansichten, Weiche nach Seitentyp |
| `dev/rin-mobile.dev.user.js` | `*://cs.rin.ru/forum/*` | Loader, bindet per `@require file:///` das echte Script ein |
| `dev/viewtopic.php` | — | Fixture: gespeicherter Thread, `per_page=15`, 1114 Seiten |
| `dev/viewforum.php` | — | Fixture: Main Forum, `per_page=100`, 610 Seiten, mit Unterforen, Ankuendigungen und Stickies |
| `dev/index.php` | — | Fixture: Forumwurzel, zwei Kategorien mit Forenzeilen, keine Paginierung, eingeloggt aufgenommen |
| `dev/ucp.php` | — | Fixture: Login-Formular (`mode=login`), nur ausgeloggter Zustand |
| `dev/after_login/ucp.php` | — | Fixture: dieselbe URL nach erfolgreichem Login, "Information"-Vorlage statt Formular |
| `dev/search.php` | — | Fixture: Suchformular ohne Treffer, eingeloggt aufgenommen |
| `dev/search2.php` | — | Fixture: Suchtreffer im Modus "Posts" (15 von 1438 Treffern, `t=63042`, `per_page=15`, 96 Seiten) |
@@ -20,6 +19,20 @@ Die Fixtures sind ueber `.gitignore` (`dev/*.php`) ausgeschlossen. Nach einem
frischen Klon sind sie nicht da und muessen nach der Anleitung in der README neu
gespeichert werden — die Seite verlangt einen Login.
Der Loader greift ausschliesslich auf die echte Seite. Die Fixtures sind
Markup-Vorlagen fuer das jsdom-Harness und zum Nachlesen, keine Seiten zum
Anschauen im Browser — die Layoutarbeit laeuft in Chrome auf `cs.rin.ru`
selbst. Sie lokal auszuliefern verlangte `@include`-Regeln fuer `localhost`,
und die passen auf Seitennamen, die dort haeufig genug vorkommen (`index.php`,
alles mit `search` darin), dass der globale Teil des Stylesheets
(`html, body`, `img`, jeweils `!important`) in fremde lokale Projekte geriete.
Das Nachziehen waere billig, der Fehlersuchweg dorthin nicht.
Fuer den Zustand nach erfolgreichem Login (`ucp.php?mode=login` ohne Formular,
"Information"-Vorlage) liegt derzeit keine Fixture im Repo. `buildLoginInfo()`
wurde gegen einen Mitschnitt gebaut, der nicht mehr vorhanden ist; wer den
Zweig anfassen will, muss die Seite neu aufnehmen.
## Aufbau
Ein IIFE, streng der Reihe nach:
@@ -34,9 +47,20 @@ Ein IIFE, streng der Reihe nach:
5. `pageState()`, `pageSheet()` und `pageNav()` — die Paginierung, von Liste
und Thread benutzt, nicht vom Login
6. `buildList()`, `buildThread()` beziehungsweise `buildLogin()` lesen das
Original-DOM und bauen ein `div.rm-root`; alle drei haengen zum Schluss
Original-DOM und bauen ein `div.rm-root`; alle haengen zum Schluss
ueber `addCrumbs()` die fixierte Brotkrumenleiste an, die zugleich ueber
`loginState()` die Login/Logout-Pille traegt
`loginState()` die Login/Logout-Pille traegt. Zwei der drei Ansichten
verzweigen intern weiter, weil sich mehrere Seitenformen dieselbe URL
teilen:
- `buildList()` versucht zuerst `buildSearchForm()` (grosses Suchformular
auf `search.php`), dann `buildSearchResults()` (Trefferliste im Modus
"Posts", Karten ueber `buildHit()`); erst wenn beide `false` liefern,
laeuft das gewoehnliche Zeileneinsammeln
- `buildLogin()` faellt ohne Formular auf `buildLoginInfo()` zurueck
("Information"-Vorlage nach dem Absenden)
- `buildThread()` legt ueber `buildThreadSearch()` die zweite Leiste an,
die die Lupe in den Brotkrumen per `toggleThreadSearch()` ein- und
ausblendet
7. `run()` waehlt die Ansicht und haengt bei `DEBUG` das gruene Overlay an
8. Start ueber `DOMContentLoaded`, falls `readyState === 'loading'`
@@ -125,7 +149,10 @@ Titelzelle gebildet, nie aus deren gesamtem Text.
Klassennamen aus der phpBB-Dokumentation (`forumlink`, `forumdesc`) deshalb
zunaechst nur eine Vermutung; `dev/viewforum.php` bestaetigt sie inzwischen. Der
Rueckfall auf die Form der Zeile bleibt trotzdem stehen — er kostet nichts und
traegt die Erkennung, wenn das Theme wechselt.
traegt die Erkennung, wenn das Theme wechselt. `rinDark` ist allerdings eine
Ableitung von subsilver2 und laedt dessen
`styles/subsilver2/template/forum_fn.js` mit — Klassennamen aus subsilver2 sind
deshalb eine brauchbare erste Annahme, wenn eine Seite noch keine Fixture hat.
**Die Brotkrumenleiste ist fixiert, nicht sticky.** `.rm-root` traegt
`overflow:hidden` und wuerde damit zum Scrollport einer `position:sticky`
@@ -137,8 +164,9 @@ Brotkrumen im Markup kein leerer Streifen bleibt.
**Die Login-Erkennung ist inzwischen gegen eine echte Sitzung geprueft.**
`loginState()` unterscheidet `a[href*="mode=login"]` von
`a[href*="mode=logout"]` im Menuebalken und liest den Namen aus dem Muster
`Logout [ Name ]` im Linktext. `dev/index.php` und `dev/after_login/ucp.php`
sind eingeloggt aufgenommen (`Logout [ <Benutzername> ]`) und bestaetigen das Muster.
`Logout [ Name ]` im Linktext. `dev/index.php`, `dev/search.php` und
`dev/search2.php` sind eingeloggt aufgenommen (`Logout [ <Benutzername> ]`) und
bestaetigen das Muster.
Der Fallback bleibt trotzdem stehen: passt das Muster einmal nicht — andere
Sprache, anderer Klammertyp — zeigt die Pille „Logout" ohne Namen, statt eine
Ausnahme zu werfen.
@@ -151,7 +179,9 @@ liegt aber keine Fixture vor). `buildLoginInfo()` erkennt die Vorlage deshalb
an ihrer Form — eine Kopfzeile mit genau einer `th`-Zelle, gefolgt von einer
`td.row1`-Nachrichtenzelle — nicht am Wortlaut, und uebernimmt die Zelle
unveraendert wie das Formular selbst. Findet `buildLogin()` weder Formular
noch diese Form, baut es nichts; die Originalseite bleibt sichtbar.
noch diese Form, baut es nichts; die Originalseite bleibt sichtbar. Achtung:
die Fixture, gegen die das gebaut wurde, liegt nicht mehr im Repo — der Zweig
ist derzeit nicht nachpruefbar, ohne die Seite neu aufzunehmen.
**`index.php` wird ueber `location.pathname` erkannt, nicht ueber
`here`.** Der Login-Redirect haengt "index.php" gelegentlich als Wert eines
@@ -228,6 +258,15 @@ Suchformular auf `search.php`.** Sowohl `viewforum.php` als auch
allein liesse sich das grosse Formular nicht von den kleinen unterscheiden.
Der mehrfach waehlbare Forenwaehler existiert dagegen nur im grossen Formular.
**Die Vorbelegung des Forenwaehlers haengt an der harten Forum-ID 10.**
`buildSearchForm()` waehlt `option[value="10"]` (Main Forum) vor und setzt
`input[name="sc"][value="0"]` (Unterforen: No), weil das serverseitige
Formular sonst mit leerem Waehler und „Search subforums: Yes" startet. Beides
ist eine Bequemlichkeit, keine Funktion: vergibt das Forum die IDs neu oder
benennt es das Hauptforum um, greift die Vorauswahl stumm nicht mehr — das
Formular bleibt bedienbar, steht dann aber wieder auf der Servervorgabe. Kein
Fehlerfall, aber auch nichts, was von selbst auffaellt.
**Die Textfelder des Suchformulars tragen `style="width: 300px"` direkt im
Markup.** Eine externe Regel ohne `!important` sticht dagegen nicht, egal wie
spezifisch der Selektor ist — `buildSearchForm()` entfernt das
@@ -289,9 +328,19 @@ alle `inputToButton()`. Ungeprueft, ob `-webkit-appearance:none` allein bei
einer anderen iOS-Version genuegt haette — der Wechsel auf `<button>` umgeht
die Frage, statt sie zu beantworten.
**`DEBUG` steht auf `true`** und muss vor dem Ausliefern auf `false`. Die
Versionsnummer steht doppelt: im `@version`-Header und im Text des
Debug-Overlays.
**`DEBUG` muss vor dem Ausliefern auf `false` stehen** (aktuell tut es das).
Solange es auf `true` steht, haengt `run()` das gruene Overlay an — das ist
der einzige Effekt des Flags, ein vergessenes `true` bricht nichts, sieht auf
dem Geraet aber unfertig aus.
**Die Versionsnummer steht nur im `@version`-Header.** Das Overlay liest sie
ueber `GM_info.script.version` zurueck, statt sie ein zweites Mal als Literal
zu fuehren — genau das lief zwischen 3.13 und 3.14 auseinander, ohne dass es
jemandem auffiel, weil das Overlay im Auslieferzustand ohnehin aus ist. Wer
den Overlay-Text anfasst: keinen neuen Versionsliteral einbauen. Fehlt
`GM_info` (Manager ohne diese API), zeigt das Overlay den Namen ohne Version;
das ist der gewollte Rueckfall, weil eine fehlende Angabe harmloser ist als
eine falsche.
## Testen
@@ -315,6 +364,9 @@ Drei Stolpersteine dabei:
Sinnvolle Faelle: erste Seite, zweite Seite, Mitte, letzte Seite, dazu die
Degradation ohne `per_page` und ein Thread ohne Paginierung. Fixture-Eckdaten:
`f=10&t=68689`, `per_page = 15`, 1114 Seiten, letzte Seite `start=16695`.
Am Beitrag selbst zu pruefen: alles hinter dem ersten `<hr>` im `postbody`
landet als zugeklapptes `details` („Signatur") am Kartenfuss, Beitraege ohne
`<hr>` behalten ihren Text vollstaendig im Koerper.
Dieselben Faelle gelten seit 3.5 fuer die Liste, die sich die Leiste mit dem
Thread teilt. Eckdaten von `dev/viewforum.php`: `f=10`, `per_page = 100`, 610
@@ -337,16 +389,17 @@ dieselbe Forenliste ohne die Klassen `forumlink`/`forumdesc` — die muss ueber
die Zahlenspalten dasselbe Ergebnis liefern.
Fuer den Login genuegt `dev/ucp.php` unveraendert: geprueft werden das
uebernommene Formular (Username-/Passwortfeld, `sid`, `redirect`, Submit) und
die Pille im ausgeloggten Zustand. Fuer den eingeloggten Zustand der Pille
`dev/index.php` oder `dev/after_login/ucp.php` laden — beide sind eingeloggt
uebernommene Formular (Username-/Passwortfeld, `sid`, `redirect`, Submit), der
Regeltext als zugeklapptes `details` („Regeln") und die Pille im ausgeloggten
Zustand. Fuer den eingeloggten Zustand der Pille `dev/index.php`,
`dev/search.php` oder `dev/search2.php` laden — alle drei sind eingeloggt
aufgenommen und tragen das echte `Logout [ Name ]`-Markup.
Fuer die Meldung nach dem Login genuegt `dev/after_login/ucp.php`
unveraendert, URL `ucp.php?mode=login`: geprueft werden Titel, uebernommene
Nachricht samt Link und die Pille. Zu pruefen ist ausserdem, dass `dev/ucp.php`
(das Formular, gleiche URL) weiterhin die Formular-Zweig traf und nicht in die
Meldungs-Erkennung faellt.
Die Meldung nach dem Login (`buildLoginInfo()`) ist mangels Fixture nicht
nachpruefbar. Wer sie anfasst, nimmt `ucp.php?mode=login` nach einem echten
Login neu auf; zu pruefen waeren dann Titel, uebernommene Nachricht samt Link
und die Pille — und dass `dev/ucp.php` (das Formular, gleiche URL) weiterhin
im Formular-Zweig landet und nicht in die Meldungs-Erkennung faellt.
Fuer die Forumwurzel genuegt `dev/index.php`, URL `index.php?sid=…`: zwei
Kategorien mit zusammen 16 Forenkarten, keine Paginierung. Zu pruefen ist
@@ -360,15 +413,15 @@ inline-`style`-Attribute der Textfelder und die Schnellzugriffs-Chips aus
`p.searchbar`. Zu pruefen ist ausserdem `dev/viewforum.php` auf derselben
Weiche: dessen eingebettetes `#forum-search`-Mini-Formular teilt sich Aktion
und `keywords`-Feld mit dem grossen Suchformular und darf `buildSearchForm()`
nicht faelschlich auslösen, die Forenliste muss wie gewohnt Karten liefern.
nicht faelschlich ausloesen, die Forenliste muss wie gewohnt Karten liefern.
Fuer Suchtreffer genuegt `dev/search2.php` unveraendert, URL beliebig (die
Erkennung haengt nicht an `location`, sondern an `p.topictitle` im Markup):
geprueft werden alle 15 Trefferkarten, die verschobene "Searched topic /
Search term used"-Zelle samt ihrer beiden Links, Autor und Zeitstempel pro
Treffer, die per Regex getrennten Antworten-/Views-Zahlen, der verschobene
`td.postbody`-Beitragsauszug und die Seitennavigation (`per_page=15`, 96
Seiten). Zu pruefen ist ausserdem, dass `dev/search.php` (das leere Formular)
`td.postbody`-Beitragsauszug, der „Zum Beitrag ↓"-Link am Kartenfuss und die
Seitennavigation (`per_page=15`, 96 Seiten). Zu pruefen ist ausserdem, dass `dev/search.php` (das leere Formular)
weiterhin den Formular-Zweig trifft und nicht in die Treffer-Erkennung faellt,
und dass `dev/viewforum.php` weiterhin normale Karten liefert — beide haben
kein `p.topictitle`. Der Modus "Topics" (`sr=topics`) ist mangels Fixture