Files
rin-mobile-userscript/CLAUDE.md
T
Andre eff957ed07 refactor: merge the two userscripts into one
The list script matched the whole forum, thread pages included, and injected its
stylesheet there before bailing out of its own build. Both stylesheets were
therefore live on every thread, and rules sharing a class name resolved by
userscript load order rather than by intent — a layout that could differ between
two machines with the same files installed. One of those clashes was already
costing the clearance behind the fixed bar.

A single script picks its view from the page type instead, which turns the
shared class namespace from a hazard into a plain fact of the file, resolved
with a modifier on the root element. Pages outside either view now stay
untouched, where before they still received a full stylesheet.

Two things the merge brought to light: the global image rule was overriding the
avatar dimensions, which only went unnoticed because square avatars happen to
scale to the same result, and a zero-width space had been sitting in the source
as a literal character rather than an escape.

Installations carrying the old thread script have to remove it; the remaining
one keeps its name and updates in place.

Claude-Session: https://claude.ai/code/session_0158owAAsXAfFiT3hGkQt1Xk
2026-08-02 14:24:29 +02:00

122 lines
5.6 KiB
Markdown

# CLAUDE.md
Ein Userscript, das die phpBB-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 |
Das Fixture ist ueber `.gitignore` (`dev/*.php`) ausgeschlossen. Nach einem
frischen Klon ist es nicht da und muss nach der Anleitung in der README neu
gespeichert werden — die Seite verlangt einen Login.
## Aufbau
Ein IIFE, streng der Reihe nach:
1. `DEBUG`-Flag und `log`-Array
2. Weiche: `view` ist `'thread'`, `'liste'` oder `''` — abgeleitet aus
`location.pathname + location.search`
3. Nur bei gesetztem `view`: Viewport-Meta (idempotent ueber `[data-rm]`) und
der komplette Style-Block als Template-Literal
4. `replaceBody(root)` blendet alle bisherigen `body`-Kinder aus und haengt die
neue Ansicht an
5. `buildList()` beziehungsweise `buildThread()` lesen das Original-DOM und
bauen ein `div.rm-root`
6. `run()` waehlt die Ansicht und haengt bei `DEBUG` das gruene Overlay an
7. Start ueber `DOMContentLoaded`, falls `readyState === 'loading'`
Auf Seiten ausserhalb der Weiche (`posting.php`, Profile, …) passiert nichts,
insbesondere wird kein Stylesheet injiziert.
## Fallen, die nicht aus dem Code hervorgehen
**Beide Ansichten teilen sich einen Klassennamensraum.** Das war der Grund fuer
die Zusammenlegung: als getrennte Scripts matchte `rin-mobile` auch
`viewtopic.php` und injizierte dort sein Stylesheet, obwohl es nichts baute.
Gleich benannte Regeln kollidierten mit identischer Spezifitaet, und die
Ladereihenfolge der Userscripts entschied ueber das Layout.
- Geteilt: `.rm-root`, `.rm-hidden`, `.rm-dbg`, die globale `img`-Regel
- Unterschiede zwischen den Ansichten ueber einen Modifier am Root loesen,
nicht ueber zwei Regeln mit demselben Selektor. `.rm-root.rm-thread` haelt
so die 64px hinter der fixierten Leiste frei.
- Namen sind ansichtsspezifisch zu halten: `.rm-jump`/`.rm-pages` gehoeren der
Liste, `.rm-goto`/`.rm-grid` dem Thread-Sheet.
- `.rm-av` braucht `!important` auf Breite und Hoehe, sonst gewinnt die globale
`img { height:auto !important }`-Regel gegen die Avatarmasse.
**Was nach `body` soll, muss nach `replaceBody()` angehaengt werden.**
Die Funktion markiert *alle* vorhandenen `body`-Kinder mit `.rm-hidden`. Das
Sheet wird deshalb erst beim ersten Antippen gebaut — das loest das Problem
nebenbei mit.
**`Page X of Y` steht als `Page <strong>1</strong> of <strong>1114</strong>`
im Markup.** Ein Grep im Roh-HTML nach `Page 1 of` findet nichts, die Regex auf
`txt(document.body)` greift trotzdem. Nicht vorschnell fuer kaputt halten.
**`per_page` kommt aus der `jumpto()`-Funktion der Seite**
(`var per_page = '15';`). Nur damit lassen sich Seiten-URLs als
`start = (Seite - 1) * per_page` selbst bauen. Die gerenderten Seitenlinks
taugen nicht als Quelle — phpBB zeigt bei 1114 Seiten nur `1, 2, 3, 4, 5 … 1114`.
Ohne `per_page` degradiert die Leiste auf erste Seite plus die
Original-Zurueck/Weiter-Links, das Sheet verschwindet.
**`postRow()` steigt bewusst mehrere `tr` hoch.** Der Beitragstext liegt in
einer verschachtelten Tabelle, `closest('tr')` trifft die innere Zeile ohne
Autor- und Profilspalte.
**`DEBUG` steht auf `true`** und muss vor dem Ausliefern auf `false`. Die
Versionsnummer steht doppelt: im `@version`-Header und im Text des
Debug-Overlays.
## Testen
Es gibt keine Testsuite. Bewaehrt hat sich ein Wegwerf-Harness mit jsdom im
Scratchpad (nicht im Repo ablegen — das Projekt soll abhaengigkeitsfrei
bleiben):
```js
const dom = new JSDOM(html, { url: 'https://cs.rin.ru/forum/viewtopic.php?f=10&t=68689&start=45' });
```
Drei Stolpersteine dabei:
- JSDOM parst asynchron fertig. Nach `eval(src)` rund 60 ms warten, sonst hat
das Script noch auf `DOMContentLoaded` gewartet und nichts gebaut.
- `location.href` ist in JSDOM nicht ueberschreibbar. Fuer Navigationstests im
eingelesenen Quelltext `location.href = u;` durch einen Hook ersetzen.
- `requestAnimationFrame` und `scrollIntoView` fehlen und muessen gestubbt
werden.
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`.
Fuer die Weiche und die Listenansicht genuegt eine handgeschriebene Tabelle mit
`a.topictitle`-Zeilen. Zu pruefen ist dabei auch eine Seite ausserhalb der
Weiche wie `posting.php`: dort darf weder eine Ansicht gebaut noch ein
`<style>` injiziert werden.
Am Geraet zu pruefen bleibt, was Blink nicht zeigt: `env(safe-area-inset-*)`,
fixierte Leisten gegen Safaris ein- und ausfahrende Toolbar,
`-webkit-backdrop-filter`, Schriftskalierung. Details und die
Tampermonkey-Einrichtung stehen in der README.
## Konventionen
- **ES5-Stil im Script-Code:** `var`, `function`, keine Arrow Functions, kein
`let`/`const`. Template-Literals und `Set` sind in Gebrauch. Keine
Transpilation, kein Linter.
- **Kommentare deutsch, Umlaute als `ae`/`oe`/`ue` transliteriert.** Echte
Umlaute nur in Strings und Regexes, die im UI landen.
- Kommentare begruenden, warum etwas so gebaut ist (welche DOM-Eigenheit von
phpBB dahintersteckt), nicht was der Code tut.
- CSS-Klassen durchgaengig mit `rm-` praefixiert.
- Neue nutzersichtbare Funktionen in der README dokumentieren — zweisprachig,
siehe globale Anweisung.