// ==UserScript== // @name RIN Mobile Thread // @description Mobile Beitragsansicht fuer cs.rin.ru // @version 2.2 // @match *://cs.rin.ru/forum/viewtopic.php* // @run-at document-start // ==/UserScript== (function () { 'use strict'; var DEBUG = true; var log = []; function h() { return document.head || document.documentElement; } if (!document.querySelector('meta[name="viewport"][data-rm]')) { var m = document.createElement('meta'); m.name = 'viewport'; m.content = 'width=device-width, initial-scale=1, viewport-fit=cover'; m.setAttribute('data-rm', '1'); h().appendChild(m); } var st = document.createElement('style'); st.textContent = ` html, body { max-width:100% !important; overflow-x:hidden !important; margin:0 !important; padding:0 !important; } body { font-size:16px !important; -webkit-text-size-adjust:100% !important; } .rm-dbg { background:#222; color:#0f0; font:12px/1.45 monospace; padding:8px 10px; white-space:pre-wrap; } .rm-hidden { display:none !important; } .rm-root { box-sizing:border-box !important; display:block !important; width:100vw !important; max-width:100vw !important; margin:0 !important; padding:0 0 64px 0 !important; overflow:hidden !important; } .rm-topic { box-sizing:border-box; padding:16px 14px 12px; font-size:21px; font-weight:650; line-height:1.3; overflow-wrap:break-word; } .rm-post { box-sizing:border-box !important; width:100% !important; max-width:100% !important; padding:14px !important; border-top:1px solid rgba(128,128,128,.25) !important; } .rm-head { display:flex; align-items:center; gap:9px; margin-bottom:10px; min-width:0; } .rm-av { flex:none; width:28px; height:28px; border-radius:50%; object-fit:cover; background:rgba(128,128,128,.25); } .rm-who { min-width:0; flex:1; } .rm-user { font-size:14px; font-weight:650; line-height:1.2; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .rm-sub { font-size:11px; opacity:.55; line-height:1.3; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .rm-body { font-size:17px !important; line-height:1.55 !important; overflow-wrap:break-word !important; word-break:normal !important; } .rm-body * { max-width:100% !important; } .rm-body img { height:auto !important; border-radius:6px; } .rm-body a { overflow-wrap:anywhere !important; } .rm-body table { display:block !important; overflow-x:auto !important; width:auto !important; } .rm-body pre, .rm-body code { display:block; overflow-x:auto; white-space:pre; font-size:13px; padding:10px; border-radius:8px; background:rgba(128,128,128,.14); } .rm-body blockquote, .rm-body .quote, .rm-body table.quote { display:block !important; margin:12px 0 !important; padding:8px 0 8px 12px !important; border-left:3px solid rgba(140,140,255,.5) !important; font-size:15px !important; opacity:.8 !important; background:none !important; } .rm-body ul, .rm-body ol { padding-left:22px !important; } .rm-body hr { border:0; border-top:1px solid rgba(128,128,128,.3); } .rm-sig { margin-top:12px; font-size:13px; opacity:.5; } .rm-sig summary { cursor:pointer; opacity:.8; } .rm-nav { position:fixed; left:0; right:0; bottom:0; z-index:9999; display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px calc(10px + env(safe-area-inset-bottom)); background:rgba(28,28,30,.94); -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px); border-top:1px solid rgba(128,128,128,.3); } .rm-nav a, .rm-nav span { font-size:14px; color:#eee !important; text-decoration:none !important; white-space:nowrap; } .rm-nav a { padding:7px 13px; border-radius:99px; border:1px solid rgba(160,160,160,.45); } .rm-nav .rm-pos { opacity:.6; font-size:13px; } .rm-nav .rm-off { opacity:.28; border-color:rgba(160,160,160,.2); } `; h().appendChild(st); function txt(el) { return (el ? el.textContent || '' : '') .replace(/\s+/g, ' ').trim(); } // Der Beitragstext liegt in einer verschachtelten Tabelle. closest('tr') // trifft deshalb die innere Zeile, der Autor- und Profilspalte fehlen. // Aufsteigen, bis die Zeile eine Profil- oder Autorenspalte enthaelt. function postRow(pb) { var tr = pb.closest('tr'); while (tr) { if (tr.querySelector(':scope > td.profile') || tr.querySelector(':scope > td .postauthor')) return tr; var up = tr.parentElement ? tr.parentElement.closest('tr') : null; if (!up) return tr; tr = up; } return null; } function build() { var bodies = document.querySelectorAll('span.postbody, .postbody'); log.push('postbodies=' + bodies.length); if (!bodies.length) return; var root = document.createElement('div'); root.className = 'rm-root'; var tt = document.querySelector('a.maintitle, h1, .maintitle'); if (tt) { var th = document.createElement('div'); th.className = 'rm-topic'; th.textContent = txt(tt); root.appendChild(th); } var built = 0, seen = new Set(); bodies.forEach(function (pb) { var row = postRow(pb); if (!row || seen.has(row)) return; seen.add(row); var card = document.createElement('div'); card.className = 'rm-post'; // --- Zellen dieser Zeile + der Kopfzeilen darueber --- var cells = []; Array.prototype.forEach.call(row.children, function (td) { if (!td.contains(pb)) cells.push(td); }); var pr = row.previousElementSibling, g = 0; while (pr && g++ < 3) { Array.prototype.forEach.call(pr.children, function (td) { cells.push(td); }); if (pr.querySelector('.postauthor, a[href*="profile.php"]')) break; pr = pr.previousElementSibling; } // --- Username --- var user = ''; for (var i = 0; i < cells.length && !user; i++) { var ua = cells[i].querySelector( '.postauthor, .username-coloured, a[href*="profile.php"]'); if (ua) user = txt(ua); } if (!user) { for (var i2 = 0; i2 < cells.length && !user; i2++) { var nm = cells[i2].querySelector('span.name b, span.name, b.name'); if (nm) user = txt(nm); } } user = user.replace(/^Post subject:.*/i, '').trim(); // --- Avatar --- var avImg = null, bestArea = 0; cells.forEach(function (td) { td.querySelectorAll('img').forEach(function (im) { var s = im.getAttribute('src') || ''; if (/spacer|blank|icon|rank|star|folder|button|pm|email|quote|edit|report|www|msn|aim|yim|icq|topic/i.test(s)) return; if (/avatar/i.test(s)) { avImg = im; bestArea = 1e9; return; } var w = parseInt(im.getAttribute('width'), 10) || im.naturalWidth || 0; var hh = parseInt(im.getAttribute('height'), 10) || im.naturalHeight || 0; var a = w * hh; if (w >= 40 && a > bestArea) { avImg = im; bestArea = a; } }); }); // --- Rang, Postzahl, Zeitstempel --- var allTxt = cells.map(txt).join(' '); var rank = ''; var rr = allTxt.match(/\b(Administrator|Site Admin|Global Moderator|Moderator|VIP|Uploader|Supporter|Member|Newbie|Guest)\b/i); if (rr) rank = rr[1]; var pc = allTxt.match(/Posts:\s*([\d.,]+)/i); if (pc) rank = (rank ? rank + ' · ' : '') + pc[1] + ' Posts'; var when = ''; var wm = allTxt.match(/Posted:\s*([^|]+?)(?:\s{2,}|Post subject|$)/i); if (wm) when = wm[1].trim(); // --- Kopfzeile --- var head = document.createElement('div'); head.className = 'rm-head'; var av; if (avImg) { av = document.createElement('img'); av.src = avImg.src; } else { av = document.createElement('div'); av.textContent = (user || '?').charAt(0).toUpperCase(); av.style.cssText = 'display:flex;align-items:center;' + 'justify-content:center;font-size:13px;font-weight:700;' + 'color:rgba(255,255,255,.75);'; } av.className = 'rm-av'; head.appendChild(av); var who = document.createElement('div'); who.className = 'rm-who'; var un = document.createElement('div'); un.className = 'rm-user'; un.textContent = user || 'Gast'; who.appendChild(un); var sub = document.createElement('div'); sub.className = 'rm-sub'; sub.textContent = [rank, when].filter(Boolean).join(' · '); who.appendChild(sub); head.appendChild(who); card.appendChild(head); // --- Signatur abtrennen --- var sig = null, hr = pb.querySelector('hr'); if (hr) { sig = document.createElement('details'); sig.className = 'rm-sig'; var sm = document.createElement('summary'); sm.textContent = 'Signatur'; sig.appendChild(sm); var n = hr.nextSibling; while (n) { var nx = n.nextSibling; sig.appendChild(n); n = nx; } hr.remove(); } var bodyWrap = document.createElement('div'); bodyWrap.className = 'rm-body'; bodyWrap.appendChild(pb); card.appendChild(bodyWrap); if (sig && sig.childNodes.length > 1) card.appendChild(sig); root.appendChild(card); built++; }); log.push('posts=' + built); if (!built) return; // --- Navigationsleiste --- var nav = document.createElement('div'); nav.className = 'rm-nav'; var prevA = null, nextA = null; document.querySelectorAll('a').forEach(function (a) { var t = txt(a); if (!prevA && /^(Previous|Vorherige)$/i.test(t)) prevA = a; if (!nextA && /^(Next|Weiter|Nächste)$/i.test(t)) nextA = a; }); var pos = txt(document.body).match(/Page\s+(\d+)\s+of\s+(\d+)/i); function navBtn(a, label) { var e = document.createElement('a'); e.textContent = label; if (a) e.href = a.href; else e.className = 'rm-off'; return e; } nav.appendChild(navBtn(prevA, '‹ Zurück')); var ps = document.createElement('span'); ps.className = 'rm-pos'; ps.textContent = pos ? pos[1] + ' / ' + pos[2] : ''; nav.appendChild(ps); nav.appendChild(navBtn(nextA, 'Weiter ›')); root.appendChild(nav); Array.prototype.forEach.call(document.body.children, function (el) { if (el !== root) el.classList.add('rm-hidden'); }); document.body.appendChild(root); } function run() { try { build(); } catch (e) { log.push('build: ' + e.message); } if (DEBUG) { var d = document.createElement('div'); d.className = 'rm-dbg'; d.textContent = 'RIN Thread v2.2\n' + log.join('\n'); document.body.insertBefore(d, document.body.firstChild); } } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run(); })();