/* SAN AVELIO - CHARACTER CARD AUTO FOCUS v2 Replacement for 34304.txt. Keeps the same Forumstatic connection. Targets the real Character Studio root: #sa-st5. */ (function(){ 'use strict'; /* Allow this replacement to work even if an older cached v1 flag exists. */ window.SA_CHARACTER_CARD_AUTO_FOCUS_V1 = true; if (window.SA_CHARACTER_CARD_AUTO_FOCUS_V2) return; window.SA_CHARACTER_CARD_AUTO_FOCUS_V2 = true; var start = Date.now(); var maxWait = 10000; var settled = false; var observer = null; function isTopic(){ return /viewtopic\.php/i.test(location.href) || !!document.querySelector('.topic .post,#pun-main .post,.topicpost'); } function target(){ /* This is the actual root created by Character Studio v15/v14. */ var el = document.querySelector('#sa-st5'); if (el && el.getClientRects().length) return el; return null; } function pageY(el){ var r = el.getBoundingClientRect(); /* getBoundingClientRect already reflects CSS zoom in Chromium. pageYOffset gives the document position without us guessing the forum scale. */ return Math.max(0, Math.round(r.top + (window.pageYOffset || document.documentElement.scrollTop || 0))); } function jump(el){ if (!el) return; var y = pageY(el); /* Put the actual dossier top at the viewport top. No smooth animation: the user should arrive there immediately. */ window.scrollTo({top:y,left:0,behavior:'auto'}); /* Some SAN AVELIO/Rusff blocks settle after the first paint. Recalculate instead of reusing the old Y coordinate. */ requestAnimationFrame(function(){ window.scrollTo(0,pageY(el)); }); } function lockOn(el){ if (settled) return; jump(el); /* Images/fonts/typography patch may still shift the post. Keep correcting only during initial page load. */ [80,180,350,650,1100,1700].forEach(function(ms){ setTimeout(function(){ if (!settled) jump(el); },ms); }); setTimeout(function(){ jump(el); settled = true; if (observer) observer.disconnect(); },2200); } function attempt(){ if (settled || !isTopic()) return; var el = target(); if (el){ lockOn(el); return; } if (Date.now()-start > maxWait){ settled = true; if (observer) observer.disconnect(); } } function boot(){ if (!isTopic()) return; attempt(); if (window.MutationObserver){ observer = new MutationObserver(attempt); observer.observe(document.querySelector('#pun-main') || document.body,{ childList:true, subtree:true }); } var timer = setInterval(function(){ attempt(); if (settled) clearInterval(timer); },100); setTimeout(function(){ clearInterval(timer); if (observer) observer.disconnect(); },maxWait+500); } if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded',boot,{once:true}); } else { boot(); } })();