diff --git a/CLAUDE.md b/CLAUDE.md index ac7eca4..3b3a32b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,18 +1,17 @@ # CLAUDE.md -Ein Userscript, das die phpBB-Seiten von `cs.rin.ru` fuer Safari auf iOS in eine +Ein Userscript, das die phpBB3-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 | -| `dev/viewforum.php` | — | Fixture: Main Forum, 610 Seiten, mit Unterforen, Ankuendigungen und Stickies | -| `dev/index.php` | — | Fixture: Forumwurzel, zwei Kategorien mit Forenzeilen, keine Paginierung | +| `rin-mobile.user.js` | `*://cs.rin.ru/forum/*` | Alle Ansichten, Weiche nach Seitentyp | +| `dev/rin-mobile.dev.user.js` | `*://cs.rin.ru/forum/*` | Loader, bindet per `@require file:///` das echte Script ein | +| `dev/viewtopic.php` | — | Fixture: gespeicherter Thread, `per_page=15`, 1114 Seiten | +| `dev/viewforum.php` | — | Fixture: Main Forum, `per_page=100`, 610 Seiten, mit Unterforen, Ankuendigungen und Stickies | +| `dev/index.php` | — | Fixture: Forumwurzel, zwei Kategorien mit Forenzeilen, keine Paginierung, eingeloggt aufgenommen | | `dev/ucp.php` | — | Fixture: Login-Formular (`mode=login`), nur ausgeloggter Zustand | -| `dev/after_login/ucp.php` | — | Fixture: dieselbe URL nach erfolgreichem Login, "Information"-Vorlage statt Formular | | `dev/search.php` | — | Fixture: Suchformular ohne Treffer, eingeloggt aufgenommen | | `dev/search2.php` | — | Fixture: Suchtreffer im Modus "Posts" (15 von 1438 Treffern, `t=63042`, `per_page=15`, 96 Seiten) | @@ -20,6 +19,20 @@ Die Fixtures sind ueber `.gitignore` (`dev/*.php`) ausgeschlossen. Nach einem frischen Klon sind sie nicht da und muessen nach der Anleitung in der README neu gespeichert werden — die Seite verlangt einen Login. +Der Loader greift ausschliesslich auf die echte Seite. Die Fixtures sind +Markup-Vorlagen fuer das jsdom-Harness und zum Nachlesen, keine Seiten zum +Anschauen im Browser — die Layoutarbeit laeuft in Chrome auf `cs.rin.ru` +selbst. Sie lokal auszuliefern verlangte `@include`-Regeln fuer `localhost`, +und die passen auf Seitennamen, die dort haeufig genug vorkommen (`index.php`, +alles mit `search` darin), dass der globale Teil des Stylesheets +(`html, body`, `img`, jeweils `!important`) in fremde lokale Projekte geriete. +Das Nachziehen waere billig, der Fehlersuchweg dorthin nicht. + +Fuer den Zustand nach erfolgreichem Login (`ucp.php?mode=login` ohne Formular, +"Information"-Vorlage) liegt derzeit keine Fixture im Repo. `buildLoginInfo()` +wurde gegen einen Mitschnitt gebaut, der nicht mehr vorhanden ist; wer den +Zweig anfassen will, muss die Seite neu aufnehmen. + ## Aufbau Ein IIFE, streng der Reihe nach: @@ -34,9 +47,20 @@ Ein IIFE, streng der Reihe nach: 5. `pageState()`, `pageSheet()` und `pageNav()` — die Paginierung, von Liste und Thread benutzt, nicht vom Login 6. `buildList()`, `buildThread()` beziehungsweise `buildLogin()` lesen das - Original-DOM und bauen ein `div.rm-root`; alle drei haengen zum Schluss + Original-DOM und bauen ein `div.rm-root`; alle haengen zum Schluss ueber `addCrumbs()` die fixierte Brotkrumenleiste an, die zugleich ueber - `loginState()` die Login/Logout-Pille traegt + `loginState()` die Login/Logout-Pille traegt. Zwei der drei Ansichten + verzweigen intern weiter, weil sich mehrere Seitenformen dieselbe URL + teilen: + - `buildList()` versucht zuerst `buildSearchForm()` (grosses Suchformular + auf `search.php`), dann `buildSearchResults()` (Trefferliste im Modus + "Posts", Karten ueber `buildHit()`); erst wenn beide `false` liefern, + laeuft das gewoehnliche Zeileneinsammeln + - `buildLogin()` faellt ohne Formular auf `buildLoginInfo()` zurueck + ("Information"-Vorlage nach dem Absenden) + - `buildThread()` legt ueber `buildThreadSearch()` die zweite Leiste an, + die die Lupe in den Brotkrumen per `toggleThreadSearch()` ein- und + ausblendet 7. `run()` waehlt die Ansicht und haengt bei `DEBUG` das gruene Overlay an 8. Start ueber `DOMContentLoaded`, falls `readyState === 'loading'` @@ -125,7 +149,10 @@ Titelzelle gebildet, nie aus deren gesamtem Text. Klassennamen aus der phpBB-Dokumentation (`forumlink`, `forumdesc`) deshalb zunaechst nur eine Vermutung; `dev/viewforum.php` bestaetigt sie inzwischen. Der Rueckfall auf die Form der Zeile bleibt trotzdem stehen — er kostet nichts und -traegt die Erkennung, wenn das Theme wechselt. +traegt die Erkennung, wenn das Theme wechselt. `rinDark` ist allerdings eine +Ableitung von subsilver2 und laedt dessen +`styles/subsilver2/template/forum_fn.js` mit — Klassennamen aus subsilver2 sind +deshalb eine brauchbare erste Annahme, wenn eine Seite noch keine Fixture hat. **Die Brotkrumenleiste ist fixiert, nicht sticky.** `.rm-root` traegt `overflow:hidden` und wuerde damit zum Scrollport einer `position:sticky` @@ -137,8 +164,9 @@ Brotkrumen im Markup kein leerer Streifen bleibt. **Die Login-Erkennung ist inzwischen gegen eine echte Sitzung geprueft.** `loginState()` unterscheidet `a[href*="mode=login"]` von `a[href*="mode=logout"]` im Menuebalken und liest den Namen aus dem Muster -`Logout [ Name ]` im Linktext. `dev/index.php` und `dev/after_login/ucp.php` -sind eingeloggt aufgenommen (`Logout [ ]`) und bestaetigen das Muster. +`Logout [ Name ]` im Linktext. `dev/index.php`, `dev/search.php` und +`dev/search2.php` sind eingeloggt aufgenommen (`Logout [ ]`) und +bestaetigen das Muster. Der Fallback bleibt trotzdem stehen: passt das Muster einmal nicht — andere Sprache, anderer Klammertyp — zeigt die Pille „Logout" ohne Namen, statt eine Ausnahme zu werfen. @@ -151,7 +179,9 @@ liegt aber keine Fixture vor). `buildLoginInfo()` erkennt die Vorlage deshalb an ihrer Form — eine Kopfzeile mit genau einer `th`-Zelle, gefolgt von einer `td.row1`-Nachrichtenzelle — nicht am Wortlaut, und uebernimmt die Zelle unveraendert wie das Formular selbst. Findet `buildLogin()` weder Formular -noch diese Form, baut es nichts; die Originalseite bleibt sichtbar. +noch diese Form, baut es nichts; die Originalseite bleibt sichtbar. Achtung: +die Fixture, gegen die das gebaut wurde, liegt nicht mehr im Repo — der Zweig +ist derzeit nicht nachpruefbar, ohne die Seite neu aufzunehmen. **`index.php` wird ueber `location.pathname` erkannt, nicht ueber `here`.** Der Login-Redirect haengt "index.php" gelegentlich als Wert eines @@ -228,6 +258,15 @@ Suchformular auf `search.php`.** Sowohl `viewforum.php` als auch allein liesse sich das grosse Formular nicht von den kleinen unterscheiden. Der mehrfach waehlbare Forenwaehler existiert dagegen nur im grossen Formular. +**Die Vorbelegung des Forenwaehlers haengt an der harten Forum-ID 10.** +`buildSearchForm()` waehlt `option[value="10"]` (Main Forum) vor und setzt +`input[name="sc"][value="0"]` (Unterforen: No), weil das serverseitige +Formular sonst mit leerem Waehler und „Search subforums: Yes" startet. Beides +ist eine Bequemlichkeit, keine Funktion: vergibt das Forum die IDs neu oder +benennt es das Hauptforum um, greift die Vorauswahl stumm nicht mehr — das +Formular bleibt bedienbar, steht dann aber wieder auf der Servervorgabe. Kein +Fehlerfall, aber auch nichts, was von selbst auffaellt. + **Die Textfelder des Suchformulars tragen `style="width: 300px"` direkt im Markup.** Eine externe Regel ohne `!important` sticht dagegen nicht, egal wie spezifisch der Selektor ist — `buildSearchForm()` entfernt das @@ -289,9 +328,19 @@ alle `inputToButton()`. Ungeprueft, ob `-webkit-appearance:none` allein bei einer anderen iOS-Version genuegt haette — der Wechsel auf `