Add resource reader spacebar support on reference pages

This commit is contained in:
2025-11-30 11:42:44 -05:00
parent 93c5c70cb9
commit 04a693870b
12 changed files with 102 additions and 4 deletions
+22 -4
View File
@@ -1845,11 +1845,29 @@
showKeyboardHelp();
break;
case ' ':
// Space: Read aloud selected text (green box selection or verse text)
var selectedText = KJVSpeech.getSelectedText();
if (selectedText) {
// Space: Read aloud selected text (with optional resource-reader handling)
if (document.body && document.body.dataset && document.body.dataset.resourceReader === 'true') {
e.preventDefault();
KJVSpeech.toggle(selectedText);
var highlighted = document.querySelector('[style*="outline: 2px solid"]') || document.querySelector('[style*="outline:2px solid"]');
var candidates = Array.from(document.querySelectorAll('article p, section p, li, blockquote')).filter(function(el) {
return (el.textContent || '').trim().length > 10;
});
var target = highlighted || (candidates.length ? candidates[0] : null);
if (target) {
// Clone and strip sidenotes/marginnotes if present
var clone = target.cloneNode(true);
clone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle').forEach(function(el) { el.remove(); });
var text = (clone.textContent || clone.innerText || '').trim();
if (text && window.KJVSpeech && typeof window.KJVSpeech.toggle === 'function') {
KJVSpeech.toggle(text);
}
}
} else {
var selectedText = KJVSpeech.getSelectedText();
if (selectedText) {
e.preventDefault();
KJVSpeech.toggle(selectedText);
}
}
break;
}
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Angels</h1>
<p class="subtitle">Angelic Beings in Holy Scripture</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Covenants</h1>
<p class="subtitle">God's Covenantal Framework Throughout Redemptive History</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Festivals</h1>
<p class="subtitle">The Sacred Feasts of Israel and Their Prophetic Significance</p>
@@ -81,6 +81,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Geography</h1>
<p class="subtitle">The lands of Scripture</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Prophets</h1>
<p class="subtitle">Messengers of the Most High</p>
@@ -102,6 +102,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Biblical Timeline</h1>
<p class="subtitle">Major events from Creation to the early Church</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Fruits of the Spirit</h1>
<p class="subtitle">The Nine Graces of Galatians 5:22-23</p>
+40
View File
@@ -368,6 +368,30 @@ document.addEventListener('DOMContentLoaded', function() {
return false;
}
function getTextContent(el) {
if (!el) return '';
const clone = el.cloneNode(true);
clone.querySelectorAll('.sidenote, .marginnote, .sidenote-number, .margin-toggle').forEach(x => x.remove());
return (clone.textContent || clone.innerText || '').trim();
}
function readElement(el) {
if (!el || !('speechSynthesis' in window)) return;
if (window.KJVSpeech && typeof window.KJVSpeech.stop === 'function') {
window.KJVSpeech.stop();
}
const text = getTextContent(el);
if (!text) return;
const utter = new SpeechSynthesisUtterance(text);
const voices = speechSynthesis.getVoices();
const englishVoice = voices.find(v => v.lang && v.lang.toLowerCase().startsWith('en') && v.name.includes('Daniel')) ||
voices.find(v => v.lang && v.lang.toLowerCase().startsWith('en-gb')) ||
voices.find(v => v.lang && v.lang.toLowerCase().startsWith('en'));
if (englishVoice) utter.voice = englishVoice;
speechSynthesis.cancel();
speechSynthesis.speak(utter);
}
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
@@ -491,8 +515,24 @@ document.addEventListener('DOMContentLoaded', function() {
} else if (e.key === 't') {
e.preventDefault();
selectTocBlock();
} else if (e.key === ' ') {
e.preventDefault();
if (selectedIndex >= 0) {
readElement(contentElements[selectedIndex]);
} else {
// if nothing selected, read first visible content
const visibleIdx = KJVNav.findFirstVisibleIndex(contentElements);
if (visibleIdx >= 0) {
selectElement(visibleIdx);
readElement(contentElements[visibleIdx]);
}
}
}
});
});
</script>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
+4
View File
@@ -192,6 +192,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Parables of Jesus</h1>
<p class="subtitle">Teaching in Earthly Stories with Heavenly Meanings</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>The Twelve Apostles</h1>
<p class="subtitle">Those Whom He Chose to Be With Him</p>
@@ -187,6 +187,10 @@
</style>
{% endblock %}
<script>
document.body.dataset.resourceReader = 'true';
</script>
{% block content %}
<h1>Women of the Bible</h1>
<p class="subtitle">Faithful Witnesses Throughout Redemptive History</p>