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
This commit is contained in:
Andre
2026-08-02 14:24:29 +02:00
parent bd4fc85d38
commit eff957ed07
6 changed files with 634 additions and 665 deletions
+57 -61
View File
@@ -6,14 +6,18 @@
## English
Two userscripts that rebuild the phpBB2 pages of `cs.rin.ru` into a mobile card
layout for Safari on iOS. Both replace the original table layout entirely: the
A single userscript that rebuilds the phpBB2 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>`.
| Script | Matches | Purpose |
|---|---|---|
| `rin-mobile.user.js` | `*://cs.rin.ru/forum/*` | Topic lists (`viewforum.php`, `search.php`) as cards |
| `rin-thread.user.js` | `*://cs.rin.ru/forum/viewtopic.php*` | Single thread as a post stream with a fixed bottom navigation bar |
`rin-mobile.user.js` matches `*://cs.rin.ru/forum/*` and picks its view from the
page type:
| Page | View |
|---|---|
| `viewforum.php`, `search.php`, forum root | Topic list as cards |
| `viewtopic.php` | Thread as a post stream with a fixed bottom navigation bar |
| anything else | Untouched — no styles are injected |
The thread navigation bar holds first / previous / next / last and a page
indicator. Tapping the indicator opens a sheet with a number field and a grid of
@@ -23,32 +27,31 @@ them. `per_page` is read from the `jumpto()` function the forum embeds in the
page; without it, only first page and the original previous/next links remain
available.
Both scripts run at `document-start`, inject a mobile viewport meta tag, and
carry a `DEBUG` flag. While `DEBUG` is `true`, a green diagnostic overlay is
prepended to the page showing how many rows were found and converted. Set it to
`false` in both files before daily use.
The script runs at `document-start`, injects a mobile viewport meta tag, and
carries a `DEBUG` flag. While `DEBUG` is `true`, a green diagnostic overlay is
prepended to the page showing which view was chosen and how many rows were
converted. Set it to `false` before daily use.
### 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` and `rin-thread.user.js` to the manager's script
directory.
2. Add `rin-mobile.user.js` to the manager's script directory.
3. Grant the extension permission for `cs.rin.ru`.
---
### Development
The scripts are developed on Windows in Chrome or Edge with Tampermonkey. The
files in `dev/` are loaders: they contain nothing but a metadata block that
pulls in the real script from disk via `@require`. Editing
`rin-mobile.user.js` or `rin-thread.user.js` and reloading the page is enough —
no reinstall in Tampermonkey.
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 loaders in `dev/` reference the scripts by **absolute path**:
The loader in `dev/` references the script by **absolute path**:
```js
// @require file:///C:/Projekte/ios_safari_userscripts/rin-mobile.user.js
@@ -56,10 +59,7 @@ The loaders in `dev/` reference the scripts by **absolute path**:
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 **both** loaders to your own location:
- `dev/rin-mobile.dev.user.js`
- `dev/rin-thread.dev.user.js`
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`
@@ -81,11 +81,11 @@ Three settings are required; missing the first one is the most common cause of
to **always**, otherwise the loader keeps serving a cached copy of the
script.
Then open the loaders once via `file:///.../dev/rin-mobile.dev.user.js` —
Tampermonkey intercepts `.user.js` URLs and offers to install them.
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 loaders and the plain scripts side by side. If both are enabled
in Tampermonkey, the code executes twice on the same page, producing duplicate
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
@@ -100,11 +100,11 @@ against local copies:
The file name matters twice over. The `.html` extension makes the server send
the file as HTML instead of offering it as a download, and the retained
`viewtopic.php` / `viewforum.php` part is what the loaders' `@include` rules
`viewtopic.php` / `viewforum.php` part is what the loader's `@include` rules
and the page-type check in `rin-mobile.user.js` match against.
Forum images and stylesheets are missing from such a snapshot. That is fine for
layout work, because the scripts rebuild the DOM anyway — only avatars stay
layout work, because the script rebuilds the DOM anyway — only avatars stay
empty, since their `src` is carried over unchanged.
Note that a snapshot saved while logged out contains `span.link_removed`
@@ -151,26 +151,28 @@ the `file://` require with a local HTTP server, which does not cache:
### Repository layout
```
rin-mobile.user.js topic list → cards
rin-thread.user.js thread → post stream
rin-mobile.user.js topic list → cards, thread → post stream
dev/
rin-mobile.dev.user.js loader, @require with absolute path
rin-thread.dev.user.js loader, @require with absolute path
```
---
## Deutsch
Zwei Userscripts, die die phpBB2-Seiten von `cs.rin.ru` für Safari auf iOS in
eine mobile Kartenansicht umbauen. Beide ersetzen das ursprüngliche
Tabellenlayout vollständig: der vorhandene Seiteninhalt wird ausgeblendet und
ein neu gebautes DOM an `<body>` gehängt.
Ein Userscript, das die phpBB2-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.
| Script | Greift auf | Zweck |
|---|---|---|
| `rin-mobile.user.js` | `*://cs.rin.ru/forum/*` | Themenlisten (`viewforum.php`, `search.php`) als Karten |
| `rin-thread.user.js` | `*://cs.rin.ru/forum/viewtopic.php*` | Einzelner Thread als Beitragsstrom mit fixierter Navigationsleiste |
`rin-mobile.user.js` greift auf `*://cs.rin.ru/forum/*` und wählt die Ansicht
anhand des Seitentyps:
| Seite | Ansicht |
|---|---|
| `viewforum.php`, `search.php`, Forumwurzel | Themenliste als Karten |
| `viewtopic.php` | Thread als Beitragsstrom mit fixierter Navigationsleiste |
| alles andere | Unverändert — es werden keine Stile injiziert |
Die Navigationsleiste im Thread enthält erste / vorherige / nächste / letzte
Seite und eine Positionsanzeige. Ein Tipp darauf öffnet ein Sheet mit
@@ -181,33 +183,32 @@ Seitenlinks übernommen, weil phpBB davon immer nur eine Handvoll anzeigt.
einbettet; fehlt sie, bleiben nur die erste Seite und die ursprünglichen
Zurück-/Weiter-Links nutzbar.
Beide laufen bei `document-start`, setzen ein mobiles Viewport-Meta-Tag und
haben ein `DEBUG`-Flag. Solange `DEBUG` auf `true` steht, wird ein grünes
Diagnose-Overlay über die Seite gelegt, das zeigt, wie viele Zeilen gefunden und
umgewandelt wurden. Für den täglichen Gebrauch in beiden Dateien auf `false`
Das Script läuft bei `document-start`, setzt ein mobiles Viewport-Meta-Tag und
hat ein `DEBUG`-Flag. Solange `DEBUG` auf `true` steht, wird ein grünes
Diagnose-Overlay über die Seite gelegt, das zeigt, welche Ansicht gewählt wurde
und wie viele Zeilen umgewandelt wurden. Für den täglichen Gebrauch auf `false`
setzen.
### 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` und `rin-thread.user.js` in das Script-Verzeichnis des
Managers legen.
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. Die Dateien
in `dev/` sind Loader: sie enthalten nur einen Metadatenblock, der das
eigentliche Script per `@require` von der Platte einbindet. Es genügt,
`rin-mobile.user.js` oder `rin-thread.user.js` zu bearbeiten und die Seite neu
zu laden — keine Neuinstallation in Tampermonkey nötig.
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
Die Loader in `dev/` verweisen mit einem **absoluten Pfad** auf die Scripts:
Der Loader in `dev/` verweist mit einem **absoluten Pfad** auf das Script:
```js
// @require file:///C:/Projekte/ios_safari_userscripts/rin-mobile.user.js
@@ -215,11 +216,8 @@ Die Loader in `dev/` verweisen mit einem **absoluten Pfad** auf die Scripts:
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 **beiden** Loadern auf den eigenen
Ablageort angepasst werden:
- `dev/rin-mobile.dev.user.js`
- `dev/rin-thread.dev.user.js`
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`.
@@ -242,10 +240,10 @@ für „es passiert überhaupt nichts":
**immer** stellen, sonst liefert der Loader weiterhin eine zwischen­
gespeicherte Fassung des Scripts aus.
Danach die Loader einmal über `file:///.../dev/rin-mobile.dev.user.js` öffnen —
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.
Die Loader nicht parallel zu den unveränderten Scripts betreiben. Sind beide in
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.
@@ -291,9 +289,7 @@ zwischenspeichert:
### Aufbau des Repositories
```
rin-mobile.user.js Themenliste → Karten
rin-thread.user.js Thread → Beitragsstrom
rin-mobile.user.js Themenliste → Karten, Thread → Beitragsstrom
dev/
rin-mobile.dev.user.js Loader, @require mit absolutem Pfad
rin-thread.dev.user.js Loader, @require mit absolutem Pfad
```