Files
rin-mobile-userscript/CLAUDE.md
T
Andre bd4fc85d38 docs: note that the test fixture is not versioned
The project instructions describe testing against a saved forum page without
mentioning that the ignore rules exclude it. A fresh clone therefore has no
fixture, and obtaining one requires a logged-in session — not something that
becomes apparent from a missing file alone.

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

5.3 KiB

CLAUDE.md

Zwei eigenstaendige Userscripts, die die phpBB-Seiten von cs.rin.ru fuer Safari auf iOS in eine mobile Ansicht umbauen. Kein Build, keine Abhaengigkeiten, kein package.json — die .user.js-Dateien sind das Produkt.

Datei Greift auf Zweck
rin-mobile.user.js *://cs.rin.ru/forum/* Themenlisten als Karten
rin-thread.user.js *://cs.rin.ru/forum/viewtopic.php* Thread als Beitragsstrom + Navigationsleiste
dev/*.dev.user.js zusaetzlich localhost:* Loader, binden per @require file:/// die echten Scripts 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.

Gemeinsames Muster beider Scripts

Beide sind nach demselben Schema gebaut, Aenderungen am einen sind oft auch am anderen faellig:

  1. IIFE mit 'use strict', DEBUG-Flag und log-Array ganz oben
  2. Viewport-Meta setzen (idempotent ueber [data-rm])
  3. Kompletter Style-Block als Template-Literal, bedingungslos injiziert
  4. build() liest das Original-DOM, baut ein neues div.rm-root
  5. Alle bisherigen body-Kinder bekommen .rm-hidden, dann wird root angehaengt
  6. run() haengt bei DEBUG das gruene Overlay oben an
  7. Start ueber DOMContentLoaded, falls readyState === 'loading'

Fallen, die nicht aus dem Code hervorgehen

Beide Stylesheets sind auf Threadseiten gleichzeitig aktiv. rin-mobile matcht *://cs.rin.ru/forum/*, also auch viewtopic.php. Sein build() steigt dort zwar aus, der Style-Block wird aber vorher injiziert. Gleich benannte Klassen kollidieren mit identischer Spezifitaet, entschieden wird nach Ladereihenfolge der Userscripts — und die ist nicht garantiert.

  • Nur bewusst geteilt: .rm-root, .rm-hidden, .rm-dbg
  • Offene Kollision: .rm-root hat in rin-mobile padding:0 !important, in rin-thread padding:0 0 64px 0 !important. Laedt rin-mobile spaeter, faellt die Freihaltung hinter der fixierten Leiste weg. Noch nicht behoben.
  • Neue Klassen im Thread-Script gegen rin-mobile.user.js gegenpruefen. .rm-goto und .rm-grid heissen genau deshalb so — .rm-jump und .rm-pages waren dort schon belegt.

Was nach body soll, muss nach der Ausblend-Schleife angehaengt werden. Die Schleife markiert alle vorhandenen body-Kinder mit .rm-hidden. Das Sheet im Thread-Script 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 in beiden Dateien auf true und muss vor dem Ausliefern in beiden auf false. Die Versionsnummer steht ebenfalls 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):

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.

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.