88 lines
4.3 KiB
JavaScript
88 lines
4.3 KiB
JavaScript
/*
|
|||
|
|
* 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);
|
||
|
|
})();
|