Decent
This commit is contained in:
1 parent
77bf8d9f2e
commit
ea193e1264
53 files changed
+545
-347
No files matched your search
+52
-12
@@ -1,7 +1,14 @@
|
||||
// Verse modal wiring. The modal markup lives in base.njk and the bookmark
|
||||
// lives in the service worker, so all this file does is decide which verse
|
||||
// was clicked, fill the form, and show it -- Bootstrap handles opening,
|
||||
// dismissing and focus, and htmx carries the save.
|
||||
// Page startup and verse modal wiring.
|
||||
//
|
||||
// shell.html is static and ships with an empty #content, so the first thing
|
||||
// every load does is fetch the fragment its URL names and swap it in. That is
|
||||
// the same request a boosted link makes, so there is one path into #content
|
||||
// and nothing special about a first visit.
|
||||
//
|
||||
// The rest is the modal: the markup lives in shell.html and the bookmark lives
|
||||
// in the service worker, so all this file does is decide which verse was
|
||||
// clicked, fill the form, and show it -- Bootstrap handles opening, dismissing
|
||||
// and focus, and htmx carries the save.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
@@ -65,7 +72,7 @@
|
||||
if (!el || !window.bootstrap) return;
|
||||
var info = verseInfo(span);
|
||||
currentUrl = info.url;
|
||||
el.querySelector('.verse-dialog-ref').textContent = info.ref;
|
||||
document.getElementById('verse-dialog-ref').textContent = info.ref;
|
||||
el.querySelector('input[name="ref"]').value = info.ref;
|
||||
el.querySelector('input[name="href"]').value = info.href;
|
||||
status('');
|
||||
@@ -121,13 +128,46 @@
|
||||
}
|
||||
});
|
||||
|
||||
markVerses(document);
|
||||
// -- startup ------------------------------------------------------------
|
||||
|
||||
// The shell already carries the bookmark, so this is only for the case where
|
||||
// the worker started controlling the page after it was rendered.
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(function () {
|
||||
document.body.dispatchEvent(new CustomEvent('bookmark-load'));
|
||||
}).catch(function () {});
|
||||
function fragmentUrl() {
|
||||
return (location.pathname.split('/').pop() || 'index.html') + location.search;
|
||||
}
|
||||
|
||||
// The content arrives after the document has been parsed, so the browser has
|
||||
// long given up on the fragment identifier by the time the verse exists.
|
||||
// Doing it here is what makes a link to GEN.html#v1_1 land on the verse.
|
||||
function scrollToHash() {
|
||||
if (!location.hash) return;
|
||||
var el = document.getElementById(decodeURIComponent(location.hash.slice(1)));
|
||||
if (el) el.scrollIntoView();
|
||||
}
|
||||
|
||||
// api/bookmark has no origin server -- it is answered by the worker -- so
|
||||
// there is nothing to ask until the worker is controlling this page.
|
||||
// controller, not ready: ready can resolve a tick before clients.claim()
|
||||
// takes effect, and a request sent in that gap reaches the network and 404s.
|
||||
function whenControlled(fn) {
|
||||
if (!('serviceWorker' in navigator)) return;
|
||||
if (navigator.serviceWorker.controller) return fn();
|
||||
navigator.serviceWorker.addEventListener('controllerchange', fn, { once: true });
|
||||
}
|
||||
|
||||
// Deferred scripts run before DOMContentLoaded fires, so this always lands,
|
||||
// and it lands after htmx has processed the shell.
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
htmx.ajax('GET', fragmentUrl(), { target: '#content', swap: 'innerHTML' })
|
||||
.then(scrollToHash);
|
||||
|
||||
// Registered from the page it is going to serve, not from a page of its
|
||||
// own: there is nothing to wait for and nothing to reload. This load is
|
||||
// already the real app -- the worker installs alongside it, and takes over
|
||||
// for the bookmark, the offline download and every request from then on.
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('sw.js').catch(function () {});
|
||||
}
|
||||
whenControlled(function () {
|
||||
document.body.dispatchEvent(new CustomEvent('worker-ready'));
|
||||
});
|
||||
});
|
||||
})();
|
||||
Reference in new issue
Block a user