Files
rin-mobile-userscript/README.md
T
Andre c477537826 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.
2026-08-03 10:21:05 +02:00

20 KiB
Raw Blame History

iOS Safari Userscripts — cs.rin.ru

English | Deutsch


English

A single userscript that rebuilds the phpBB3 pages of cs.rin.ru into a mobile layout for Safari on iOS. It replaces the original table layout entirely: the existing page content is hidden and a freshly built DOM is appended to <body>.

rin-mobile.user.js matches *://cs.rin.ru/forum/* and picks its view from the page type:

Page View
viewforum.php, index.php, forum root Topic and forum list as cards
search.php The query form restyled, or — for a submitted search in "Posts" mode — its hits as cards
viewtopic.php Thread as a post stream with a fixed bottom navigation bar
ucp.php?mode=login Login form, restyled in place; on the same URL after a successful submit, the resulting information page instead
anything else Untouched — no styles are injected

Screenshots

Forum list, with the sections above the topics collapsed Thread, with the in-topic search bar revealed
Forum list as cards: breadcrumb bar with magnifier, an open FOREN section with four forum cards, collapsed GLOBAL ANNOUNCEMENTS, ANNOUNCEMENTS and STICKIES strips, and the page bar showing 1 / 610 Thread view: breadcrumbs, a second bar with a search field, and a post card with avatar, author, rank and post count above the message
Search form, top: quick links and forum picker Search form, bottom: options and buttons
Search form: quick links as chips, the keyword fields and the forum picker with Main Forum preselected Search form continued: search subforums set to No, the remaining option groups, and the Search and Reset buttons

What it does

The original page is hidden and a mobile layout is built from the same data, one view per page type:

  • Lists as cards. Forum and topic rows become cards with title, description, counts and last post; category headers become section headings.
  • Section strips. Forums, announcements, stickies and topics are separated by a header carrying the section name and its card count. Announcements and stickies start collapsed — they repeat above the topics on every page of a forum. Tapping a header toggles its section, and the state is remembered per section across forums.
  • Fixed page bar. First / previous / next / last and a page indicator. Tapping the indicator opens a sheet with a number field and every page of the forum or thread, not just the handful phpBB renders.
  • Fixed breadcrumb bar with a login pill showing the account name. Without it there is no way back out of a thread, since the original page is hidden.
  • Search from anywhere. With a session, a magnifier sits next to the pill: it opens search.php, or inside a thread reveals a bar that searches the topic.
  • Readable posts. Avatar, author, rank and timestamp above the message; signatures fold into a collapsed box.
  • Forms are moved, not rebuilt. Login, search and the page after a successful login reuse the original elements, so hidden fields and the plain server-side POST stay intact. The search form starts on Main Forum with subforums off, and the board rules on the login page fold away.
  • Search hits as cards in "Posts" display mode, each with a link straight to the post. "Topics" mode falls through to the regular list view.

The script's own labels are German; anything taken from the board keeps its original wording — FOREN in the first screenshot is the script's name for a group the board does not label, while STICKIES and TOPICS are the board's own words.

It runs at document-start and injects a mobile viewport meta tag. A DEBUG flag in the source, off by default, adds a green diagnostic overlay showing the version, the chosen view and how many rows were converted.

Installation on iOS

  1. Install a userscript manager for Safari on iOS (for example Userscripts) and enable it under Settings → Safari → Extensions.
  2. Add rin-mobile.user.js to the manager's script directory.
  3. Grant the extension permission for cs.rin.ru.

Development

The script is developed on Windows in Chrome or Edge with Tampermonkey. dev/rin-mobile.dev.user.js is a loader: it contains nothing but a metadata block that pulls in the real script from disk via @require. Editing rin-mobile.user.js and reloading the page is enough — no reinstall in Tampermonkey.

⚠️ Path adjustment required

The loader in dev/ references the script by absolute path:

// @require      file:///C:/Projekte/ios_safari_userscripts/rin-mobile.user.js

This path is hardcoded and only valid on the machine it was written for. After cloning the repository or moving the project folder, adjust the @require line in dev/rin-mobile.dev.user.js to your own location.

Use forward slashes and the file:/// prefix, including the drive letter — file:///D:/projects/ios_safari_userscripts/rin-mobile.user.js. A @require that cannot be resolved causes Tampermonkey to skip the script entirely and without an error message on the page, which looks exactly like the script not being installed at all.

Tampermonkey setup

Three settings are required; missing the first one is the most common cause of "nothing happens":

  1. chrome://extensions → Tampermonkey → enable Allow user scripts. On older Chrome versions, enable Developer mode at the top right instead. Without this, Manifest V3 blocks all injection.
  2. Same page → enable Allow access to file URLs, so @require file:// can be resolved.
  3. Tampermonkey dashboard → Settings → Externals → set the update interval to always, otherwise the loader keeps serving a cached copy of the script.

Then open the loader once via file:///.../dev/rin-mobile.dev.user.js — Tampermonkey intercepts .user.js URLs and offers to install it.

Do not run the loader and the plain script side by side. If both are enabled in Tampermonkey, the code executes twice on the same page, producing duplicate cards and two debug overlays.

Test fixtures

Layout work happens on the live site, with the loader active in Chrome. The saved pages under dev/ serve a different purpose: cs.rin.ru requires a login, and its markup is the only source for what the script has to cope with, so the pages that matter are kept as snapshots — as a reference to read, and as input for a throwaway jsdom harness when a change needs to be checked against several pages at once.

  1. Open the page while logged in, then in DevTools right-click <html> → Copy outerHTML.
  2. Save it under the page's own name — dev/viewtopic.php, dev/viewforum.php, dev/index.php, dev/ucp.php, dev/search.php.

The loader deliberately matches cs.rin.ru only, so these files are not meant to be opened in the browser. Serving them locally would take @include rules for localhost, and those match on page names common enough (index.php, anything containing search) that the script would inject its stylesheet into unrelated local projects.

A snapshot saved while logged out contains span.link_removed placeholders instead of links, and may use different markup for author names than the logged-in view — worth knowing before puzzling over a fixture that behaves differently from the real page.

Device emulation

DevTools → Device Toolbar (Ctrl+Shift+M) → Edit… → add a custom device with 430 × 932 and DPR 3 for an iPhone 15 Pro Max, device type Mobile, and an iOS Safari user agent string.

What desktop emulation cannot show

Chrome uses Blink, iOS Safari uses WebKit. These points have to be verified on the device:

  • env(safe-area-inset-bottom) in .rm-nav — always 0 in the emulator, so the clearance for the home indicator is untested.
  • A bottom position: fixed bar together with Safari's collapsing toolbar.
  • width: 100vw — on the desktop the scrollbar counts towards it and creates phantom overflow, so the debug overlay reports different numbers than iOS.
  • -webkit-text-size-adjust and Safari's automatic font scaling.
  • -webkit-backdrop-filter renders in Chrome, but looks different.

For higher fidelity without an iPhone, Playwright ships a real WebKit build for Windows (npx playwright install webkit).

Troubleshooting

If nothing happens at all, separate the two possible causes before reading any code. Check the loader's Externals tab in the Tampermonkey dashboard: an empty or failed entry means the @require path is wrong. If the entry is there and the script still does nothing, set DEBUG = true in rin-mobile.user.js — the green overlay appears on every page the script touches, so its absence means the script never ran, while an overlay reporting ansicht=keine means it ran but the URL matched no view.

If Tampermonkey keeps serving a stale copy despite the update interval, open the loader's Externals tab and trigger an update on the @require entry by hand, or disable and re-enable the loader — both discard the cached copy.

Repository layout

rin-mobile.user.js          all views: lists, thread, login, search
CLAUDE.md                   notes for working on the script
dev/
  rin-mobile.dev.user.js    loader, @require with absolute path
  *.php                     saved pages, markup reference, not in git
docs/
  Screenshot_mobile_*.png   the screenshots above

Deutsch

Ein Userscript, das die phpBB3-Seiten von cs.rin.ru für Safari auf iOS in eine mobile Ansicht umbaut. Es ersetzt das ursprüngliche Tabellenlayout vollständig: der vorhandene Seiteninhalt wird ausgeblendet und ein neu gebautes DOM an <body> gehängt.

rin-mobile.user.js greift auf *://cs.rin.ru/forum/* und wählt die Ansicht anhand des Seitentyps:

Seite Ansicht
viewforum.php, index.php, Forumwurzel Themen- und Forenliste als Karten
search.php Das Suchformular umgestylt oder — bei abgeschickter Suche im Modus „Posts" — die Treffer als Karten
viewtopic.php Thread als Beitragsstrom mit fixierter Navigationsleiste
ucp.php?mode=login Login-Formular, an Ort und Stelle umgestylt; auf derselben URL nach erfolgreichem Absenden stattdessen die Informationsseite
alles andere Unverändert — es werden keine Stile injiziert

Screenshots

Forenliste, die Abschnitte über den Themen zugeklappt Thread, mit eingeblendeter Suchleiste
Forenliste als Karten: Brotkrumenleiste mit Lupe, aufgeklappter Abschnitt FOREN mit vier Forenkarten, zugeklappte Streifen für GLOBAL ANNOUNCEMENTS, ANNOUNCEMENTS und STICKIES, unten die Seitenleiste mit 1 / 610 Thread-Ansicht: Brotkrumen, zweite Leiste mit Suchfeld, darunter eine Beitragskarte mit Avatar, Autor, Rang und Beitragszahl über dem Text
Suchformular, oben: Schnellzugriffe und Forenwähler Suchformular, unten: Optionen und Schaltflächen
Suchformular: Schnellzugriffe als Chips, die Feldgruppen für Suchbegriffe und der Forenwähler mit vorausgewähltem Main Forum Suchformular, Fortsetzung: Unterforen auf No, die übrigen Optionsgruppen sowie die Schaltflächen Search und Reset

Was das Script liefert

Die Originalseite wird ausgeblendet und aus denselben Daten eine mobile Ansicht gebaut, je eine pro Seitentyp:

  • Listen als Karten. Foren- und Themenzeilen werden zu Karten mit Titel, Beschreibung, Zahlen und letztem Beitrag, Kategoriezeilen zu Zwischenüberschriften.
  • Gruppenköpfe. Foren, Ankündigungen, Stickies und Themen trennt jeweils ein Kopf mit dem Namen des Abschnitts und der Zahl seiner Karten. Ankündigungen und Stickies starten zugeklappt — sie stehen auf jeder Seite eines Forums über den Themen. Ein Tipp auf den Kopf klappt seinen Abschnitt um, der Zustand gilt je Abschnitt über alle Foren hinweg.
  • Fixierte Seitenleiste. Erste / vorherige / nächste / letzte Seite und eine Positionsanzeige. Ein Tipp darauf öffnet ein Sheet mit Zahlenfeld und allen Seiten des Forums oder Threads, nicht nur der Handvoll, die phpBB rendert.
  • Fixierte Brotkrumenleiste mit einer Login-Pille, die den Kontonamen zeigt. Ohne sie führt aus einem Thread kein Weg zurück, weil die Originalseite ausgeblendet ist.
  • Suche von überall. Besteht eine Sitzung, sitzt neben der Pille eine Lupe: sie öffnet search.php oder blendet innerhalb eines Threads eine Leiste ein, die das Thema durchsucht.
  • Lesbare Beiträge. Avatar, Autor, Rang und Zeitstempel über dem Text, Signaturen wandern in einen zugeklappten Kasten.
  • Formulare werden verschoben, nicht nachgebaut. Login, Suche und die Seite nach erfolgreichem Login übernehmen die Original-Elemente, damit versteckte Felder und der schlichte serverseitige POST erhalten bleiben. Das Suchformular startet auf Main Forum ohne Unterforen, die Forenregeln im Login klappen weg.
  • Suchtreffer als Karten im Anzeigemodus „Posts", jeder mit einem Link direkt zum Beitrag. Der Modus „Topics" läuft durch die gewöhnliche Listenansicht.

Die Beschriftungen des Scripts sind deutsch, alles aus dem Forum Übernommene behält seinen Wortlaut — FOREN im ersten Screenshot ist die Bezeichnung des Scripts für eine Gruppe, die die Seite selbst nicht beschriftet, STICKIES und TOPICS sind ihre eigenen Worte.

Das Script läuft bei document-start und setzt ein mobiles Viewport-Meta-Tag. Ein DEBUG-Flag im Quelltext, standardmäßig aus, legt ein grünes Diagnose-Overlay über die Seite: Version, gewählte Ansicht und Zahl der umgewandelten Zeilen.

Installation unter iOS

  1. Einen Userscript-Manager für Safari unter iOS installieren (zum Beispiel Userscripts) und unter Einstellungen → Safari → Erweiterungen aktivieren.
  2. rin-mobile.user.js in das Script-Verzeichnis des Managers legen.
  3. Der Erweiterung die Berechtigung für cs.rin.ru erteilen.

Entwicklung

Entwickelt wird unter Windows in Chrome oder Edge mit Tampermonkey. dev/rin-mobile.dev.user.js ist ein Loader: er enthält nur einen Metadatenblock, der das eigentliche Script per @require von der Platte einbindet. Es genügt, rin-mobile.user.js zu bearbeiten und die Seite neu zu laden — keine Neuinstallation in Tampermonkey nötig.

⚠️ Pfadanpassung erforderlich

Der Loader in dev/ verweist mit einem absoluten Pfad auf das Script:

// @require      file:///C:/Projekte/ios_safari_userscripts/rin-mobile.user.js

Dieser Pfad ist fest eingetragen und gilt nur auf dem Rechner, für den er geschrieben wurde. Nach dem Klonen des Repositories oder dem Verschieben des Projektordners muss die @require-Zeile in dev/rin-mobile.dev.user.js auf den eigenen Ablageort angepasst werden.

Dabei Schrägstriche und das Präfix file:/// inklusive Laufwerksbuchstaben verwenden — file:///D:/projekte/ios_safari_userscripts/rin-mobile.user.js. Ein @require, das nicht aufgelöst werden kann, führt dazu, dass Tampermonkey das Script komplett und ohne Fehlermeldung auf der Seite überspringt. Das sieht exakt so aus, als wäre gar kein Script installiert.

Tampermonkey einrichten

Drei Einstellungen sind nötig; die erste ist die mit Abstand häufigste Ursache für „es passiert überhaupt nichts":

  1. chrome://extensions → Tampermonkey → Nutzerskripte zulassen aktivieren. Bei älteren Chrome-Versionen stattdessen den Entwicklermodus oben rechts einschalten. Ohne das blockiert Manifest V3 jede Injektion.
  2. Auf derselben Seite → Zugriff auf Datei-URLs zulassen aktivieren, damit @require file:// aufgelöst werden kann.
  3. Tampermonkey-Dashboard → Einstellungen → Externals → Update-Intervall auf immer stellen, sonst liefert der Loader weiterhin eine zwischen­ gespeicherte Fassung des Scripts aus.

Danach den Loader einmal über file:///.../dev/rin-mobile.dev.user.js öffnen — Tampermonkey fängt .user.js-URLs ab und bietet die Installation an.

Den Loader nicht parallel zum unveränderten Script betreiben. Sind beide in Tampermonkey aktiv, läuft der Code doppelt auf derselben Seite, mit doppelten Karten und zwei Debug-Overlays als Folge.

Testfixtures

Die Layoutarbeit findet auf der echten Seite statt, mit dem Loader aktiv in Chrome. Die gespeicherten Seiten unter dev/ dienen etwas anderem: cs.rin.ru verlangt einen Login, und sein Markup ist die einzige Quelle dafür, womit das Script zurechtkommen muss. Die relevanten Seiten liegen deshalb als Mitschnitt vor — zum Nachlesen und als Eingabe für ein Wegwerf-Harness mit jsdom, wenn eine Änderung gegen mehrere Seiten auf einmal zu prüfen ist.

  1. Die Seite eingeloggt öffnen, in den DevTools mit der rechten Maustaste auf <html> → Copy outerHTML.
  2. Unter dem Namen der Seite ablegen — dev/viewtopic.php, dev/viewforum.php, dev/index.php, dev/ucp.php, dev/search.php.

Der Loader greift bewusst nur auf cs.rin.ru, diese Dateien sind also nicht zum Öffnen im Browser gedacht. Sie lokal auszuliefern verlangte @include-Regeln für localhost, und die passen auf Seitennamen, die dort häufig genug vorkommen (index.php, alles mit „search" darin), dass das Script sein Stylesheet in fremde lokale Projekte injizieren würde.

Ein ausgeloggt gespeicherter Mitschnitt enthält statt der Links span.link_removed-Platzhalter und kann Autorennamen anders auszeichnen als die eingeloggte Ansicht — gut zu wissen, bevor man über eine Fixture rätselt, die sich anders verhält als die echte Seite.

Geräte-Emulation

DevTools → Device Toolbar (Strg+Umschalt+M) → Edit… → eigenes Gerät mit 430 × 932 und DPR 3 für ein iPhone 15 Pro Max anlegen, Gerätetyp Mobile, dazu einen iOS-Safari-User-Agent eintragen.

Was die Desktop-Emulation nicht zeigt

Chrome verwendet Blink, iOS Safari verwendet WebKit. Diese Punkte müssen am Gerät geprüft werden:

  • env(safe-area-inset-bottom) in .rm-nav — im Emulator immer 0, die Freihaltung für den Home-Indicator bleibt also ungetestet.
  • Eine unten fixierte Leiste zusammen mit Safaris ein- und ausfahrender Toolbar.
  • width: 100vw — auf dem Desktop zählt die Scrollbar mit und erzeugt Phantom-Overflow, das Debug-Overlay meldet dort andere Zahlen als unter iOS.
  • -webkit-text-size-adjust und Safaris automatische Schriftvergrößerung.
  • -webkit-backdrop-filter rendert in Chrome, sieht aber anders aus.

Für höhere Treue ohne iPhone bringt Playwright einen echten WebKit-Build für Windows mit (npx playwright install webkit).

Fehlersuche

Passiert überhaupt nichts, zuerst die beiden möglichen Ursachen trennen, bevor Code gelesen wird. Im Tampermonkey-Dashboard den Tab Externals des Loaders prüfen: ein leerer oder fehlgeschlagener Eintrag bedeutet, dass der @require-Pfad falsch ist. Ist der Eintrag da und trotzdem passiert nichts, in rin-mobile.user.js DEBUG = true setzen — das grüne Overlay erscheint auf jeder Seite, die das Script anfasst. Bleibt es aus, lief das Script gar nicht; meldet es ansicht=keine, lief es, aber die URL passte auf keine Ansicht.

Liefert Tampermonkey trotz Update-Intervall weiterhin einen veralteten Stand aus, im Tab Externals des Loaders den @require-Eintrag von Hand aktualisieren oder den Loader einmal deaktivieren und wieder aktivieren — beides verwirft die zwischengespeicherte Fassung.

Aufbau des Repositories

rin-mobile.user.js          alle Ansichten: Listen, Thread, Login, Suche
CLAUDE.md                   Notizen zur Arbeit am Script
dev/
  rin-mobile.dev.user.js    Loader, @require mit absolutem Pfad
  *.php                     gespeicherte Seiten, Markup-Vorlage, nicht in git
docs/
  Screenshot_mobile_*.png   die Screenshots oben