mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
Comprehensive keyboard navigation improvements
- Remove study guides from homepage keyboard nav (too inline/sloppy) - Add paragraph-level nav to resource_index.html (soteriology, etc.) - Stories index: add category navigation, Enter jumps to first story in category - Story kids: add adult callout and PDF button to nav - Detail pages (topic, resource, reading_plan, parable): include paragraphs, verse items, and PDF buttons in keyboard nav - Chapter page: add 'i' for interlinear, 'p' for PDF shortcuts - Book page: add 'p' for PDF shortcut - Chapter interlinear: add 'p' for PDF shortcut 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -429,6 +429,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
e.preventDefault();
|
||||
window.location.href = '/book/' + encodeURIComponent(bibleBooks[currentBookIndex + 1]);
|
||||
}
|
||||
|
||||
// p: Download PDF
|
||||
if (e.key === 'p') {
|
||||
e.preventDefault();
|
||||
var pdfBtn = document.querySelector('.print-btn');
|
||||
if (pdfBtn) window.location.href = pdfBtn.href;
|
||||
}
|
||||
});
|
||||
|
||||
// Clicking on chapter links should just navigate normally
|
||||
|
||||
@@ -328,7 +328,7 @@ p[id^="verse-"].selected {
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-help">
|
||||
Tip: ↑/↓ or j/k to select verses • Enter to view • ←/→ for chapters
|
||||
Tip: ↑/↓ to select verses • Enter to view • ←/→ chapters • i=interlinear • p=PDF
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -515,6 +515,20 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
selectedVerseIndex = -1;
|
||||
}
|
||||
|
||||
// i: Go to interlinear view
|
||||
if (e.key === 'i') {
|
||||
e.preventDefault();
|
||||
var interlinearBtn = document.querySelector('.interlinear-btn');
|
||||
if (interlinearBtn) window.location.href = interlinearBtn.href;
|
||||
}
|
||||
|
||||
// p: Download PDF
|
||||
if (e.key === 'p') {
|
||||
e.preventDefault();
|
||||
var pdfBtn = document.querySelector('.pdf-btn');
|
||||
if (pdfBtn) window.location.href = pdfBtn.href;
|
||||
}
|
||||
});
|
||||
|
||||
// Click to select verse
|
||||
|
||||
@@ -890,6 +890,10 @@ document.addEventListener('click', function(e) {
|
||||
// Enter word mode at first word
|
||||
selectWord(0);
|
||||
}
|
||||
} else if (e.key === 'p') {
|
||||
e.preventDefault();
|
||||
var pdfBtn = document.querySelector('.print-btn');
|
||||
if (pdfBtn) window.location.href = pdfBtn.href;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -151,24 +151,6 @@
|
||||
outline-color: #6b9b7a;
|
||||
}
|
||||
|
||||
/* Study guide links */
|
||||
.study-guide-link {
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.study-guide-link.selected {
|
||||
background: rgba(74, 124, 89, 0.15);
|
||||
outline: 2px solid #4a7c59;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .study-guide-link.selected {
|
||||
background: rgba(107, 155, 122, 0.15);
|
||||
outline-color: #6b9b7a;
|
||||
}
|
||||
|
||||
/* Daily verse link */
|
||||
.daily-verse-link {
|
||||
padding: 0.15rem 0.4rem;
|
||||
@@ -477,7 +459,7 @@
|
||||
|
||||
{% for category, guides in study_guides.items() %}
|
||||
<p><span class="newthought">{{ category }}</span> —
|
||||
{% for guide in guides %}<a href="/study-guides/{{ guide.slug }}" class="study-guide-link">{{ guide.title }}</a>{% if not loop.last %}, {% endif %}{% endfor %}</p>
|
||||
{% for guide in guides %}<a href="/study-guides/{{ guide.slug }}">{{ guide.title }}</a>{% if not loop.last %}, {% endif %}{% endfor %}</p>
|
||||
{% endfor %}
|
||||
</section>
|
||||
|
||||
@@ -592,15 +574,14 @@ function handleSearch(event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Combined keyboard navigation for daily verse + search + nav links + feature cards + explore links + study guides
|
||||
// Combined keyboard navigation for daily verse + search + nav links + feature cards + explore links
|
||||
var dailyVerseLink = Array.from(document.querySelectorAll('.daily-verse-link'));
|
||||
var searchSection = document.getElementById('search-section');
|
||||
var searchItems = searchSection ? [searchSection] : [];
|
||||
var navLinks = Array.from(document.querySelectorAll('.nav-links a'));
|
||||
var featureCards = Array.from(document.querySelectorAll('.feature-card'));
|
||||
var exploreLinks = Array.from(document.querySelectorAll('.explore-link'));
|
||||
var studyGuideLinks = Array.from(document.querySelectorAll('.study-guide-link'));
|
||||
var allCards = dailyVerseLink.concat(searchItems).concat(navLinks).concat(featureCards).concat(exploreLinks).concat(studyGuideLinks);
|
||||
var allCards = dailyVerseLink.concat(searchItems).concat(navLinks).concat(featureCards).concat(exploreLinks);
|
||||
var selectedCardIndex = -1;
|
||||
|
||||
function getGridColumns() {
|
||||
@@ -609,7 +590,6 @@ function getGridColumns() {
|
||||
var searchEnd = dailyVerseEnd + searchItems.length;
|
||||
var navLinksEnd = searchEnd + navLinks.length;
|
||||
var featureCardsEnd = navLinksEnd + featureCards.length;
|
||||
var exploreLinksEnd = featureCardsEnd + exploreLinks.length;
|
||||
|
||||
if (selectedCardIndex < dailyVerseEnd) {
|
||||
// Daily verse is a single item
|
||||
@@ -626,11 +606,6 @@ function getGridColumns() {
|
||||
return navLinks.length;
|
||||
}
|
||||
|
||||
if (selectedCardIndex >= exploreLinksEnd) {
|
||||
// Study guide links - treat as single row navigation
|
||||
return studyGuideLinks.length;
|
||||
}
|
||||
|
||||
if (window.innerWidth <= 760) {
|
||||
// Mobile: feature cards = 1 col, explore = 2 cols
|
||||
return selectedCardIndex < featureCardsEnd ? 1 : 2;
|
||||
|
||||
@@ -118,20 +118,21 @@
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const verses = Array.from(document.querySelectorAll('.verse-item'));
|
||||
if (verses.length === 0) return;
|
||||
// Include description paragraphs, intro text, and verse items
|
||||
const elements = Array.from(document.querySelectorAll('.parable-description p, .intro-text, .verse-item'));
|
||||
if (elements.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectVerse(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < verses.length) {
|
||||
verses[selectedIndex].style.outline = '';
|
||||
verses[selectedIndex].style.outlineOffset = '';
|
||||
function selectElement(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = Math.max(0, Math.min(index, verses.length - 1));
|
||||
verses[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
verses[selectedIndex].style.outlineOffset = '4px';
|
||||
verses[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
elements[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -139,23 +140,24 @@
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectVerse(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectVerse(0);
|
||||
else selectVerse(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
const link = verses[selectedIndex].querySelector('.verse-ref a');
|
||||
var el = elements[selectedIndex];
|
||||
var link = el.querySelector('.verse-ref a') || el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < verses.length) {
|
||||
verses[selectedIndex].style.outline = '';
|
||||
verses[selectedIndex].style.outlineOffset = '';
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
@@ -222,20 +222,21 @@
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const days = Array.from(document.querySelectorAll('.day-entry'));
|
||||
if (days.length === 0) return;
|
||||
// Include overview, intro text, day entries, and PDF button
|
||||
const elements = Array.from(document.querySelectorAll('.plan-overview, .intro-text, .day-entry, .print-btn'));
|
||||
if (elements.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectDay(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < days.length) {
|
||||
days[selectedIndex].style.outline = '';
|
||||
days[selectedIndex].style.outlineOffset = '';
|
||||
function selectElement(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = Math.max(0, Math.min(index, days.length - 1));
|
||||
days[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
days[selectedIndex].style.outlineOffset = '2px';
|
||||
days[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
elements[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -243,18 +244,30 @@
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectDay(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectDay(0);
|
||||
else selectDay(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
const firstLink = days[selectedIndex].querySelector('.reading-ref a');
|
||||
if (firstLink) window.location.href = firstLink.href;
|
||||
var el = elements[selectedIndex];
|
||||
if (el.tagName === 'A' && el.href) {
|
||||
window.location.href = el.href;
|
||||
} else {
|
||||
var link = el.querySelector('.reading-ref a') || el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -172,20 +172,21 @@
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const verseItems = Array.from(document.querySelectorAll('.verse-item'));
|
||||
if (verseItems.length === 0) return;
|
||||
// Include description paragraphs, verse items, and PDF button
|
||||
const elements = Array.from(document.querySelectorAll('.resource-description p, .verse-item, .print-btn'));
|
||||
if (elements.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectItem(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < verseItems.length) {
|
||||
verseItems[selectedIndex].style.outline = '';
|
||||
verseItems[selectedIndex].style.outlineOffset = '';
|
||||
function selectElement(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = Math.max(0, Math.min(index, verseItems.length - 1));
|
||||
verseItems[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
verseItems[selectedIndex].style.outlineOffset = '4px';
|
||||
verseItems[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
elements[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -193,18 +194,30 @@
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectItem(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectItem(0);
|
||||
else selectItem(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
const link = verseItems[selectedIndex].querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
var el = elements[selectedIndex];
|
||||
if (el.tagName === 'A' && el.href) {
|
||||
window.location.href = el.href;
|
||||
} else {
|
||||
var link = el.querySelector('.verse-ref a') || el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -298,21 +298,21 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
tocList.appendChild(li);
|
||||
});
|
||||
|
||||
// Keyboard navigation for resource entries
|
||||
const entries = Array.from(document.querySelectorAll('.resource-entry'));
|
||||
if (entries.length === 0) return;
|
||||
// Keyboard navigation for intro, description paragraphs, and verses
|
||||
const elements = Array.from(document.querySelectorAll('.intro-text, .resource-item-description p, .verse-item'));
|
||||
if (elements.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectEntry(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < entries.length) {
|
||||
entries[selectedIndex].style.outline = '';
|
||||
entries[selectedIndex].style.outlineOffset = '';
|
||||
function selectElement(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = Math.max(0, Math.min(index, entries.length - 1));
|
||||
entries[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
entries[selectedIndex].style.outlineOffset = '4px';
|
||||
entries[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
elements[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -320,18 +320,27 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectEntry(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectEntry(0);
|
||||
else selectEntry(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
const link = entries[selectedIndex].querySelector('.resource-name a');
|
||||
var el = elements[selectedIndex];
|
||||
// Check for link in resource entry title or verse reference
|
||||
var link = el.querySelector('.resource-name a') || el.querySelector('.verse-ref a') || el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,6 +34,17 @@
|
||||
border-color: var(--link-color);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.story-toc-item.selected {
|
||||
border-color: #4a7c59;
|
||||
outline: 2px solid #4a7c59;
|
||||
outline-offset: 2px;
|
||||
background: rgba(74, 124, 89, 0.05);
|
||||
}
|
||||
[data-theme="dark"] .story-toc-item.selected {
|
||||
border-color: #6b9b7a;
|
||||
outline-color: #6b9b7a;
|
||||
background: rgba(107, 155, 122, 0.1);
|
||||
}
|
||||
.story-toc-item strong {
|
||||
display: block;
|
||||
}
|
||||
@@ -451,13 +462,26 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard navigation for story cards (2D grid)
|
||||
// Keyboard navigation for categories and story cards
|
||||
var categoryItems = Array.from(document.querySelectorAll('.story-toc-item'));
|
||||
var visibleStories = function() {
|
||||
return Array.from(document.querySelectorAll('.story-card:not(.hidden)'));
|
||||
};
|
||||
|
||||
// Track which section we're in: 'categories' or 'stories'
|
||||
var currentSection = 'stories';
|
||||
var selectedCatIndex = -1;
|
||||
var selectedCardIndex = -1;
|
||||
|
||||
function getGridColumns() {
|
||||
function getCatGridColumns() {
|
||||
var toc = document.querySelector('.story-toc ul');
|
||||
if (!toc) return 1;
|
||||
var style = getComputedStyle(toc);
|
||||
var cols = style.gridTemplateColumns.split(' ').length;
|
||||
return cols || 1;
|
||||
}
|
||||
|
||||
function getCardGridColumns() {
|
||||
var grid = document.querySelector('.stories-grid');
|
||||
if (!grid) return 1;
|
||||
var style = getComputedStyle(grid);
|
||||
@@ -465,15 +489,30 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
return cols || 1;
|
||||
}
|
||||
|
||||
function clearAllSelections() {
|
||||
categoryItems.forEach(function(c) { c.classList.remove('selected'); });
|
||||
visibleStories().forEach(function(c) {
|
||||
c.style.outline = '';
|
||||
c.style.outlineOffset = '';
|
||||
});
|
||||
}
|
||||
|
||||
function selectCategory(index) {
|
||||
clearAllSelections();
|
||||
currentSection = 'categories';
|
||||
selectedCardIndex = -1;
|
||||
selectedCatIndex = Math.max(0, Math.min(index, categoryItems.length - 1));
|
||||
categoryItems[selectedCatIndex].classList.add('selected');
|
||||
categoryItems[selectedCatIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
function selectStoryCard(index) {
|
||||
var cards = visibleStories();
|
||||
if (cards.length === 0) return;
|
||||
|
||||
if (selectedCardIndex >= 0 && selectedCardIndex < cards.length) {
|
||||
cards[selectedCardIndex].style.outline = '';
|
||||
cards[selectedCardIndex].style.outlineOffset = '';
|
||||
}
|
||||
|
||||
clearAllSelections();
|
||||
currentSection = 'stories';
|
||||
selectedCatIndex = -1;
|
||||
selectedCardIndex = Math.max(0, Math.min(index, cards.length - 1));
|
||||
cards[selectedCardIndex].style.outline = '2px solid #4a7c59';
|
||||
cards[selectedCardIndex].style.outlineOffset = '4px';
|
||||
@@ -484,32 +523,90 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
|
||||
var cards = visibleStories();
|
||||
if (cards.length === 0) return;
|
||||
|
||||
var cols = getGridColumns();
|
||||
var catCols = getCatGridColumns();
|
||||
var cardCols = getCardGridColumns();
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
if (selectedCardIndex < 0) selectStoryCard(0);
|
||||
else selectStoryCard(selectedCardIndex + cols);
|
||||
if (currentSection === 'categories') {
|
||||
// Move down within categories or transition to stories
|
||||
if (selectedCatIndex + catCols >= categoryItems.length) {
|
||||
// Transition to story cards
|
||||
selectStoryCard(0);
|
||||
} else {
|
||||
selectCategory(selectedCatIndex + catCols);
|
||||
}
|
||||
} else {
|
||||
// In stories section
|
||||
if (selectedCardIndex < 0) selectStoryCard(0);
|
||||
else selectStoryCard(selectedCardIndex + cardCols);
|
||||
}
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedCardIndex < 0) selectStoryCard(0);
|
||||
else if (selectedCardIndex - cols >= 0) selectStoryCard(selectedCardIndex - cols);
|
||||
if (currentSection === 'stories') {
|
||||
if (selectedCardIndex < 0) {
|
||||
selectStoryCard(0);
|
||||
} else if (selectedCardIndex - cardCols < 0) {
|
||||
// Transition to categories (last row)
|
||||
var lastRowStart = Math.floor((categoryItems.length - 1) / catCols) * catCols;
|
||||
selectCategory(Math.min(lastRowStart + (selectedCardIndex % cardCols), categoryItems.length - 1));
|
||||
} else {
|
||||
selectStoryCard(selectedCardIndex - cardCols);
|
||||
}
|
||||
} else {
|
||||
// In categories
|
||||
if (selectedCatIndex - catCols >= 0) {
|
||||
selectCategory(selectedCatIndex - catCols);
|
||||
}
|
||||
}
|
||||
} else if (e.key === 'ArrowRight' || e.key === 'l') {
|
||||
e.preventDefault();
|
||||
if (selectedCardIndex < 0) selectStoryCard(0);
|
||||
else selectStoryCard(selectedCardIndex + 1);
|
||||
if (currentSection === 'categories') {
|
||||
if (selectedCatIndex < categoryItems.length - 1) {
|
||||
selectCategory(selectedCatIndex + 1);
|
||||
}
|
||||
} else {
|
||||
if (selectedCardIndex < 0) selectStoryCard(0);
|
||||
else selectStoryCard(selectedCardIndex + 1);
|
||||
}
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
if (selectedCardIndex <= 0) history.back();
|
||||
else selectStoryCard(selectedCardIndex - 1);
|
||||
} else if (e.key === 'Enter' && selectedCardIndex >= 0) {
|
||||
if (currentSection === 'categories') {
|
||||
if (selectedCatIndex > 0) {
|
||||
selectCategory(selectedCatIndex - 1);
|
||||
} else {
|
||||
history.back();
|
||||
}
|
||||
} else {
|
||||
if (selectedCardIndex <= 0) history.back();
|
||||
else selectStoryCard(selectedCardIndex - 1);
|
||||
}
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
var cards = visibleStories();
|
||||
if (cards[selectedCardIndex]) {
|
||||
if (currentSection === 'categories' && selectedCatIndex >= 0) {
|
||||
// Get the target section from the category link
|
||||
var targetId = categoryItems[selectedCatIndex].getAttribute('href').substring(1);
|
||||
var targetSection = document.getElementById(targetId);
|
||||
if (targetSection) {
|
||||
// Find the first story card in this section
|
||||
var firstCard = targetSection.querySelector('.story-card:not(.hidden)');
|
||||
if (firstCard) {
|
||||
var allCards = visibleStories();
|
||||
var cardIndex = allCards.indexOf(firstCard);
|
||||
if (cardIndex >= 0) {
|
||||
selectStoryCard(cardIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentSection === 'stories' && selectedCardIndex >= 0 && cards[selectedCardIndex]) {
|
||||
window.location.href = cards[selectedCardIndex].href;
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
clearAllSelections();
|
||||
currentSection = 'stories';
|
||||
selectedCatIndex = -1;
|
||||
selectedCardIndex = -1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -371,23 +371,25 @@ hr.story-divider::before {
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
// Collect paragraphs for up/down navigation
|
||||
var paragraphs = Array.from(document.querySelectorAll('article section p'));
|
||||
// Collect paragraphs, adult callout, and PDF button for up/down navigation
|
||||
var elements = Array.from(document.querySelectorAll('article section p, .adult-callout, .print-btn'));
|
||||
// Find the index of the first paragraph (to start selection there)
|
||||
var firstParagraphIndex = elements.findIndex(function(el) { return el.tagName === 'P'; });
|
||||
var selectedIndex = -1;
|
||||
|
||||
function selectParagraph(index) {
|
||||
function selectElement(index) {
|
||||
// Remove previous selection
|
||||
if (selectedIndex >= 0 && selectedIndex < paragraphs.length) {
|
||||
paragraphs[selectedIndex].style.outline = '';
|
||||
paragraphs[selectedIndex].style.outlineOffset = '';
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
|
||||
selectedIndex = Math.max(0, Math.min(index, paragraphs.length - 1));
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
|
||||
// Add selection to new paragraph
|
||||
paragraphs[selectedIndex].style.outline = '2px solid #8b5cf6';
|
||||
paragraphs[selectedIndex].style.outlineOffset = '8px';
|
||||
paragraphs[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
// Add selection to new element
|
||||
elements[selectedIndex].style.outline = '2px solid #8b5cf6';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -395,11 +397,12 @@ hr.story-divider::before {
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectParagraph(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
// Start at first paragraph, not metadata
|
||||
selectElement(selectedIndex < 0 ? firstParagraphIndex : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectParagraph(0);
|
||||
else selectParagraph(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
@@ -407,6 +410,23 @@ hr.story-divider::before {
|
||||
e.preventDefault();
|
||||
var nextLink = document.querySelector('.nav-next .nav-link');
|
||||
if (nextLink) window.location.href = nextLink.href;
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
var el = elements[selectedIndex];
|
||||
// Check if the element itself is a link (like PDF button)
|
||||
if (el.tagName === 'A' && el.href) {
|
||||
window.location.href = el.href;
|
||||
} else {
|
||||
var link = el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -200,20 +200,21 @@
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const sections = Array.from(document.querySelectorAll('.subtopic-section'));
|
||||
if (sections.length === 0) return;
|
||||
// Include overview, intro paragraphs, verse items, and PDF button
|
||||
const elements = Array.from(document.querySelectorAll('.topic-overview, .intro-text, .verse-item, .print-btn'));
|
||||
if (elements.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectSection(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < sections.length) {
|
||||
sections[selectedIndex].style.outline = '';
|
||||
sections[selectedIndex].style.outlineOffset = '';
|
||||
function selectElement(index) {
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = Math.max(0, Math.min(index, sections.length - 1));
|
||||
sections[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
sections[selectedIndex].style.outlineOffset = '4px';
|
||||
sections[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
|
||||
elements[selectedIndex].style.outline = '2px solid #4a7c59';
|
||||
elements[selectedIndex].style.outlineOffset = '8px';
|
||||
elements[selectedIndex].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
@@ -221,23 +222,28 @@
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectSection(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex <= 0) selectSection(0);
|
||||
else selectSection(selectedIndex - 1);
|
||||
if (selectedIndex <= 0) selectElement(0);
|
||||
else selectElement(selectedIndex - 1);
|
||||
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
||||
e.preventDefault();
|
||||
history.back();
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
const firstLink = sections[selectedIndex].querySelector('.verse-ref a');
|
||||
if (firstLink) window.location.href = firstLink.href;
|
||||
var el = elements[selectedIndex];
|
||||
if (el.tagName === 'A' && el.href) {
|
||||
window.location.href = el.href;
|
||||
} else {
|
||||
var link = el.querySelector('.verse-ref a') || el.querySelector('a');
|
||||
if (link) window.location.href = link.href;
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
if (selectedIndex >= 0 && selectedIndex < sections.length) {
|
||||
sections[selectedIndex].style.outline = '';
|
||||
sections[selectedIndex].style.outlineOffset = '';
|
||||
if (selectedIndex >= 0 && selectedIndex < elements.length) {
|
||||
elements[selectedIndex].style.outline = '';
|
||||
elements[selectedIndex].style.outlineOffset = '';
|
||||
}
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user