From bc9c4937ff82ec54605a0c8757701673de2380a1 Mon Sep 17 00:00:00 2001
From: Andre <200930841+Andre-Bzk@users.noreply.github.com>
Date: Sun, 2 Aug 2026 14:38:25 +0200
Subject: [PATCH] feat: add breadcrumb navigation to both views
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
---
CLAUDE.md | 10 ++++++-
README.md | 16 +++++++++++
rin-mobile.user.js | 69 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 6de7d99..9b6fa16 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -26,7 +26,8 @@ Ein IIFE, streng der Reihe nach:
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`
+ 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'`
@@ -55,6 +56,13 @@ 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 1 of 1114`
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.
diff --git a/README.md b/README.md
index c0e33b0..287c416 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,14 @@ 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 views carry a fixed breadcrumb bar at the top, taken from the forum's own
+`Board index » … » Main Forum` trail. Without it there is no way back out of a
+thread, because the original page is hidden and phpBB links the parent forum
+nowhere else. The bar scrolls horizontally if the trail is too long for the
+screen, and is left out entirely on pages that do not carry a trail. Note that
+`Board index` leads to `index.php`, which the script does not rebuild — that
+page arrives in its desktop layout.
+
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
@@ -183,6 +191,14 @@ 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 Ansichten haben oben eine fixierte Brotkrumenleiste, übernommen aus dem
+`Board index » … » Main Forum`-Pfad des Forums. Ohne sie führt aus einem Thread
+kein Weg zurück, weil die Originalseite ausgeblendet ist und phpBB das
+Elternforum nirgends sonst verlinkt. Die Leiste lässt sich waagerecht schieben,
+wenn der Pfad breiter ist als der Bildschirm, und entfällt auf Seiten ohne
+Pfadangabe. `Board index` führt auf `index.php` — diese Seite baut das Script
+nicht um, sie erscheint im Desktop-Layout.
+
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
diff --git a/rin-mobile.user.js b/rin-mobile.user.js
index af273df..a09cc7d 100644
--- a/rin-mobile.user.js
+++ b/rin-mobile.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name RIN Mobile
// @description Mobile Ansicht fuer cs.rin.ru: Themenlisten als Karten, Threads als Beitragsstrom
-// @version 3.0
+// @version 3.1
// @match *://cs.rin.ru/forum/*
// @run-at document-start
// ==/UserScript==
@@ -9,7 +9,7 @@
(function () {
'use strict';
- var DEBUG = true;
+ var DEBUG = false;
var log = [];
function h() { return document.head || document.documentElement; }
@@ -60,6 +60,32 @@
/* Freihaltung hinter der fixierten Leiste der Threadansicht. */
.rm-root.rm-thread { padding-bottom:64px !important; }
+ /* Brotkrumen, beide Ansichten. Fixiert statt sticky: .rm-root traegt
+ overflow:hidden und wuerde als Scrollport einer sticky-Leiste dienen,
+ die darin nie klebt. Fixierte Nachfahren klammert es nicht, weil der
+ Root keinen eigenen Containing Block aufspannt. */
+ .rm-crumbs { box-sizing:border-box;
+ position:fixed; top:0; left:0; right:0; z-index:9998;
+ display:flex; align-items:center; gap:6px;
+ height:calc(44px + env(safe-area-inset-top));
+ padding:env(safe-area-inset-top) 12px 0;
+ overflow-x:auto; overflow-y:hidden;
+ -webkit-overflow-scrolling:touch; white-space:nowrap;
+ background:rgba(28,28,30,.94);
+ -webkit-backdrop-filter:blur(12px);
+ backdrop-filter:blur(12px);
+ border-bottom:1px solid rgba(128,128,128,.3); }
+ .rm-crumbs a { flex:none; padding:8px 2px; font-size:14px;
+ color:#eee !important; text-decoration:none !important; }
+ .rm-crumbs a:last-of-type { font-weight:650; }
+ .rm-crumbs .rm-sep { flex:none; font-size:13px; color:#eee; opacity:.45; }
+ /* Nur gesetzt, wenn die Leiste wirklich gebaut wurde — ohne Brotkrumen
+ im Original-DOM bleibt der Platz sonst leer reserviert. */
+ body.rm-crumbed .rm-root {
+ padding-top:calc(45px + env(safe-area-inset-top)) !important; }
+ body.rm-crumbed .rm-dbg {
+ margin-top:calc(45px + env(safe-area-inset-top)); }
+
/* === Themenliste === */
.rm-card { box-sizing:border-box !important;
@@ -222,6 +248,41 @@
document.body.appendChild(root);
}
+ // Ohne die Brotkrumen fuehrt aus der neuen Ansicht kein Weg zurueck: das
+ // Original-DOM ist ausgeblendet, und phpBB verlinkt das Elternforum nirgends
+ // sonst. Muss nach replaceBody() laufen, weil die Leiste an body haengt.
+ function addCrumbs() {
+ // Die Leiste steht zweimal im Markup, ueber und unter dem Inhalt. Die
+ // erste genuegt; a.breadcrumbs faengt Seiten ohne den Absatz drumherum.
+ var box = document.querySelector('p.breadcrumbs');
+ var items = box ? box.querySelectorAll('a')
+ : document.querySelectorAll('a.breadcrumbs');
+
+ var bar = document.createElement('div');
+ bar.className = 'rm-crumbs';
+ var n = 0;
+ Array.prototype.forEach.call(items, function (a) {
+ var t = txt(a);
+ if (!t) return;
+ if (n) {
+ var sep = document.createElement('span');
+ sep.className = 'rm-sep';
+ sep.textContent = '›';
+ bar.appendChild(sep);
+ }
+ var l = document.createElement('a');
+ l.href = a.href;
+ l.textContent = t;
+ bar.appendChild(l);
+ n++;
+ });
+
+ log.push('krumen=' + n);
+ if (!n) return;
+ document.body.appendChild(bar);
+ document.body.classList.add('rm-crumbed');
+ }
+
// ==========================================================================
// Themenliste
// ==========================================================================
@@ -344,6 +405,7 @@
if (pages.children.length) root.appendChild(pages);
replaceBody(root);
+ addCrumbs();
if (DEBUG) {
var c0 = root.querySelector('.rm-card');
@@ -714,6 +776,7 @@
root.appendChild(nav);
replaceBody(root);
+ addCrumbs();
}
// ==========================================================================
@@ -727,7 +790,7 @@
if (DEBUG) {
var d = document.createElement('div');
d.className = 'rm-dbg';
- d.textContent = 'RIN Mobile v3.0\n' + log.join('\n');
+ d.textContent = 'RIN Mobile v3.1\n' + log.join('\n');
document.body.insertBefore(d, document.body.firstChild);
}
}