/* * text-watchdog.js — make sure the Bible text on screen is never blank. Isolated + additive. * * Rarely a Bible tab finishes "loading" with an empty reading area (a render race). On stage that * looks like the app broke. So: check the ACTIVE bible tab every 2s and, if it is empty on two * consecutive checks, silently re-render THAT tab's already-chosen passage. * * It never opens anything you didn't open. It only re-draws the passage already loaded in the tab * you are looking at, it skips every passage-picker screen so it can't jump you into a chapter you * haven't chosen, and it gives up after 2 tries so it can never sit in a loop. * * (This file used to also restore your previous tabs on startup. That was removed — the app now * always starts fresh.) */ (function () { 'use strict'; // One-time cleanup: bin anything the old session-restore feature left on this machine, so an // upgraded install can never resurrect a remembered set of tabs. try { localStorage.removeItem('bibleapp-session'); localStorage.removeItem('bibleapp-lastPassage'); localStorage.removeItem('sessionRestoreEnabled'); } catch (_) {} /* * ---- Stylesheet watchdog ---- * Going to Settings or the Content Manager NAVIGATES the window, so coming back is a full page * load. If styles.css does not arrive (or arrives broken), the app renders as a bare list of book * names — unusable, and alarming to discover seconds before a service. Check once, shortly after * load, that our stylesheet is actually present with a sane number of rules, and if not, reload the * page ONE time. The one-shot flag makes a reload loop impossible even if the CSS is truly broken. */ function checkStylesheet() { try { var sheets = document.styleSheets, rules = 0, found = false; for (var i = 0; i < sheets.length; i++) { var href = sheets[i].href || ''; if (href.indexOf('styles.css') === -1) continue; found = true; try { rules = sheets[i].cssRules ? sheets[i].cssRules.length : 0; } catch (_) { rules = -1; } break; } // -1 means we cannot inspect it (cross-origin); that is not evidence of breakage. if (found && rules !== -1 && rules < 50) found = false; if (found) { try { sessionStorage.removeItem('cssReloadTried'); } catch (_) {} return; } var tried = false; try { tried = sessionStorage.getItem('cssReloadTried') === '1'; } catch (_) {} if (tried) { console.error('[STYLE WATCHDOG] styles.css still missing/short after a reload — leaving the page alone.'); return; } try { sessionStorage.setItem('cssReloadTried', '1'); } catch (_) {} console.warn('[STYLE WATCHDOG] styles.css missing or truncated — reloading once.'); location.reload(); } catch (_) {} } if (document.readyState === 'complete') setTimeout(checkStylesheet, 800); else window.addEventListener('load', function () { setTimeout(checkStylesheet, 800); }); var emptyStreak = 0; var retryCounts = {}; setInterval(function () { try { var app = window.bibleApp; if (!app || !app.tabs) return; var tab = app.tabs.find(function (t) { return t.id === app.activeTabId; }); if (!tab || tab.mode !== 'bible' || !tab.book) { emptyStreak = 0; return; } if (tab.isSelectingVerses || !tab.loaded) { emptyStreak = 0; return; } var sel = document.getElementById('selectionContent' + tab.id) || document.getElementById('verseCards' + tab.id) || document.getElementById('bookCards' + tab.id); if (sel && sel.offsetParent !== null) { emptyStreak = 0; return; } var el = document.getElementById('bibleText' + tab.id); if (!el) { emptyStreak = 0; return; } var empty = !(el.textContent && el.textContent.trim().length > 0); if (!empty) { emptyStreak = 0; return; } emptyStreak++; if (emptyStreak < 2) return; emptyStreak = 0; var key = tab.id + '|' + tab.book + '|' + tab.chapter + '|' + (tab.translation || ''); retryCounts[key] = (retryCounts[key] || 0) + 1; if (retryCounts[key] > 2) return; console.warn('[TEXT WATCHDOG] Blank bible text detected — re-rendering', tab.book, tab.chapter); tab.loaded = false; if (typeof app.loadPassage === 'function') app.loadPassage(tab.id); } catch (_) {} }, 2000); })();