From f40809c4d280df0baca2af283d972767b32ed863 Mon Sep 17 00:00:00 2001 From: perennial Date: Fri, 18 Oct 2024 17:06:30 +1100 Subject: [PATCH] rm prefetch and use htmx preload extension --- assets/js/htmx-ext-preload@2.0.1.js | 141 ++++++++++++++++++ assets/views/artwork.jet.html | 13 +- assets/views/artworkMulti.jet.html | 2 + assets/views/blocks/novelnav.jet.html | 8 +- assets/views/blocks/pagination.jet.html | 14 +- assets/views/blocks/rankingnav.jet.html | 18 ++- assets/views/blocks/switcher.jet.html | 8 +- assets/views/blocks/underlinenav.jet.html | 4 +- assets/views/blocks/underlinenavUser.jet.html | 4 +- assets/views/discovery.jet.html | 2 + assets/views/fragments/artwork.jet.html | 6 +- assets/views/fragments/novel-tn.jet.html | 15 +- .../fragments/rankingCalendarNav.jet.html | 36 ++++- assets/views/fragments/thumbnail-at.jet.html | 6 +- assets/views/fragments/thumbnail-dt.jet.html | 6 +- assets/views/fragments/thumbnail-tt.jet.html | 1 + assets/views/index.jet.html | 55 ++++++- assets/views/layout/default.jet.html | 5 +- assets/views/novel.jet.html | 18 ++- assets/views/novelDiscovery.jet.html | 3 + assets/views/novelSeries.jet.html | 2 + assets/views/rank.jet.html | 2 + 22 files changed, 320 insertions(+), 49 deletions(-) create mode 100644 assets/js/htmx-ext-preload@2.0.1.js diff --git a/assets/js/htmx-ext-preload@2.0.1.js b/assets/js/htmx-ext-preload@2.0.1.js new file mode 100644 index 0000000..5f6e1c0 --- /dev/null +++ b/assets/js/htmx-ext-preload@2.0.1.js @@ -0,0 +1,141 @@ +// This adds the "preload" extension to htmx. By default, this will +// preload the targets of any tags with `href` or `hx-get` attributes +// if they also have a `preload` attribute as well. See documentation +// for more details +htmx.defineExtension('preload', { + + onEvent: function(name, event) { + // Only take actions on "htmx:afterProcessNode" + if (name !== 'htmx:afterProcessNode') { + return + } + + // SOME HELPER FUNCTIONS WE'LL NEED ALONG THE WAY + + // attr gets the closest non-empty value from the attribute. + var attr = function(node, property) { + if (node == undefined) { return undefined } + return node.getAttribute(property) || node.getAttribute('data-' + property) || attr(node.parentElement, property) + } + + // load handles the actual HTTP fetch, and uses htmx.ajax in cases where we're + // preloading an htmx resource (this sends the same HTTP headers as a regular htmx request) + var load = function(node) { + // Called after a successful AJAX request, to mark the + // content as loaded (and prevent additional AJAX calls.) + var done = function(html) { + if (!node.preloadAlways) { + node.preloadState = 'DONE' + } + + if (attr(node, 'preload-images') == 'true') { + document.createElement('div').innerHTML = html // create and populate a node to load linked resources, too. + } + } + + return function() { + // If this value has already been loaded, then do not try again. + if (node.preloadState !== 'READY') { + return + } + + // Special handling for HX-GET - use built-in htmx.ajax function + // so that headers match other htmx requests, then set + // node.preloadState = TRUE so that requests are not duplicated + // in the future + var hxGet = node.getAttribute('hx-get') || node.getAttribute('data-hx-get') + if (hxGet) { + htmx.ajax('GET', hxGet, { + source: node, + handler: function(elt, info) { + done(info.xhr.responseText) + } + }) + return + } + + // Otherwise, perform a standard xhr request, then set + // node.preloadState = TRUE so that requests are not duplicated + // in the future. + if (node.getAttribute('href')) { + var r = new XMLHttpRequest() + r.open('GET', node.getAttribute('href')) + r.onload = function() { done(r.responseText) } + r.send() + } + } + } + + // This function processes a specific node and sets up event handlers. + // We'll search for nodes and use it below. + var init = function(node) { + // If this node DOES NOT include a "GET" transaction, then there's nothing to do here. + if (node.getAttribute('href') + node.getAttribute('hx-get') + node.getAttribute('data-hx-get') == '') { + return + } + + // Guarantee that we only initialize each node once. + if (node.preloadState !== undefined) { + return + } + + // Get event name from config. + var on = attr(node, 'preload') || 'mousedown' + const always = on.indexOf('always') !== -1 + if (always) { + on = on.replace('always', '').trim() + } + + // FALL THROUGH to here means we need to add an EventListener + + // Apply the listener to the node + node.addEventListener(on, function(evt) { + if (node.preloadState === 'PAUSE') { // Only add one event listener + node.preloadState = 'READY' // Required for the `load` function to trigger + + // Special handling for "mouseover" events. Wait 100ms before triggering load. + if (on === 'mouseover') { + window.setTimeout(load(node), 100) + } else { + load(node)() // all other events trigger immediately. + } + } + }) + + // Special handling for certain built-in event handlers + switch (on) { + case 'mouseover': + // Mirror `touchstart` events (fires immediately) + node.addEventListener('touchstart', load(node)) + + // WHhen the mouse leaves, immediately disable the preload + node.addEventListener('mouseout', function(evt) { + if ((evt.target === node) && (node.preloadState === 'READY')) { + node.preloadState = 'PAUSE' + } + }) + break + + case 'mousedown': + // Mirror `touchstart` events (fires immediately) + node.addEventListener('touchstart', load(node)) + break + } + + // Mark the node as ready to run. + node.preloadState = 'PAUSE' + node.preloadAlways = always + htmx.trigger(node, 'preload:init') // This event can be used to load content immediately. + } + + // Search for all child nodes that have a "preload" attribute + const parent = event.target || event.detail.elt; + parent.querySelectorAll("[preload]").forEach(function(node) { + // Initialize the node with the "preload" attribute + init(node) + + // Initialize all child elements that are anchors or have `hx-get` (use with care) + node.querySelectorAll('a,[hx-get],[data-hx-get]').forEach(init) + }) + } +}) diff --git a/assets/views/artwork.jet.html b/assets/views/artwork.jet.html index 39232a0..643ca98 100644 --- a/assets/views/artwork.jet.html +++ b/assets/views/artwork.jet.html @@ -3,7 +3,9 @@ {{- block body() }} +{* +*}
@@ -17,10 +19,17 @@
diff --git a/assets/views/artworkMulti.jet.html b/assets/views/artworkMulti.jet.html index 22784a9..d1c9471 100644 --- a/assets/views/artworkMulti.jet.html +++ b/assets/views/artworkMulti.jet.html @@ -2,7 +2,9 @@ {{- block body() }} +{* +*} {{- range .Artworks }}
diff --git a/assets/views/blocks/novelnav.jet.html b/assets/views/blocks/novelnav.jet.html index 7bb2653..2b3dd1e 100644 --- a/assets/views/blocks/novelnav.jet.html +++ b/assets/views/blocks/novelnav.jet.html @@ -13,7 +13,9 @@ {{- if activeIndex > 0 }} @@ -29,7 +31,9 @@ {{- if activeIndex < len(paths) - 1 }} diff --git a/assets/views/blocks/pagination.jet.html b/assets/views/blocks/pagination.jet.html index 0a89a9d..7c2bf98 100644 --- a/assets/views/blocks/pagination.jet.html +++ b/assets/views/blocks/pagination.jet.html @@ -12,9 +12,9 @@ @@ -23,14 +23,14 @@