Files
rin-mobile-userscript/CLAUDE.md
T
Andre bc9c4937ff feat: add breadcrumb navigation to both views
Replacing the page hides the forum's own trail along with everything else,
so a thread became a dead end: the only ways back to the parent forum were
the browser's back button or editing the URL by hand. Deep in a long thread
neither is workable.

The bar has to be fixed rather than sticky. The view root carries
overflow:hidden to contain phantom horizontal overflow, which would make it
the scrollport a sticky bar sticks to — one that never scrolls. Its top
clearance hangs off a body class so pages without a trail keep their full
height instead of an empty strip.

Board index still leads to a page the script does not rebuild; that would
need a forum overview of its own.

Debug flag off for daily use.
2026-08-02 14:38:25 +02:00

6.1 KiB

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; beide haengen zum Schluss ueber addCrumbs() die fixierte Brotkrumenleiste an
  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.

Die Brotkrumenleiste ist fixiert, nicht sticky. .rm-root traegt overflow:hidden und wuerde damit zum Scrollport einer position:sticky -Leiste, in dem nie gescrollt wird — sie klebte nie. Fixierte Nachfahren klammert das overflow dagegen nicht, weil der Root keinen Containing Block aufspannt. Die Freihaltung oben haengt an body.rm-crumbed, damit ohne Brotkrumen im Markup kein leerer Streifen bleibt.

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):

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.