aboutsummaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
authortdro <tdro@noreply.example.com>2024-03-16 15:22:06 -0400
committertdro <tdro@noreply.example.com>2024-03-16 15:22:06 -0400
commit311f05450ea4860a6c9ba1cbeedf862284b8f223 (patch)
treed8f2b506d7505f15a01421563f7185596a8cd785 /assets
parentaf5c542b3ff6cbbdeec6da1b1a03e58b007fd941 (diff)
downloadcanory-311f05450ea4860a6c9ba1cbeedf862284b8f223.tar.gz
canory-311f05450ea4860a6c9ba1cbeedf862284b8f223.tar.bz2
canory-311f05450ea4860a6c9ba1cbeedf862284b8f223.zip
static/js/instantpage: Pare down
Diffstat (limited to 'assets')
-rw-r--r--assets/js/index.js234
1 files changed, 48 insertions, 186 deletions
diff --git a/assets/js/index.js b/assets/js/index.js
index f6c1686..4268a24 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -165,6 +165,21 @@
}
})();
(function() {
+ if (typeof Element !== "undefined") {
+ if (!Element.prototype.matches) {
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
+ }
+ if (!Element.prototype.closest) {
+ Element.prototype.closest = function(s) {
+ var el = this;
+ do {
+ if (el.matches(s)) return el;
+ el = el.parentElement || el.parentNode;
+ }while (el !== null && el.nodeType === 1)
+ return null;
+ };
+ }
+ }
function fetch(url, method, callback) {
const http = new XMLHttpRequest();
http.onreadystatechange = function() {
@@ -177,200 +192,47 @@
return http;
}
self.addEventListener("DOMContentLoaded", function() {
- const prefetches = new Set();
- const prefetchElement = document.createElement("link");
- const isSupported = prefetchElement.relList && prefetchElement.relList.supports && prefetchElement.relList.supports("prefetch") && window.IntersectionObserver && "isIntersecting" in IntersectionObserverEntry.prototype;
- const allowQueryString = "instantAllowQueryString" in document.body.dataset;
- const allowExternalLinks = "instantAllowExternalLinks" in document.body.dataset;
- const useWhitelist = "instantWhitelist" in document.body.dataset;
- const mousedownShortcut = "instantMousedownShortcut" in document.body.dataset;
- let mouseoverTimer;
- let lastTouchTimestamp;
- let delayOnHover = 65;
- let useMousedown = false;
- let useMousedownOnly = false;
- let useViewport = false;
- if ("instantIntensity" in document.body.dataset) {
- const intensity = document.body.dataset.instantIntensity;
- if (intensity.substr(0, "mousedown".length) == "mousedown") {
- useMousedown = true;
- if (intensity == "mousedown-only") {
- useMousedownOnly = true;
- }
- } else if (intensity.substr(0, "viewport".length) == "viewport") {
- if (!(navigator.connection && (navigator.connection.saveData || navigator.connection.effectiveType && navigator.connection.effectiveType.includes("2g")))) {
- if (intensity == "viewport") {
- if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
- useViewport = true;
- }
- } else if (intensity == "viewport-all") {
- useViewport = true;
- }
- }
- } else {
- const milliseconds = parseInt(intensity);
- if (!isNaN(milliseconds)) {
- delayOnHover = milliseconds;
- }
- }
- }
- if (isSupported) {
- const eventListenersOptions = {
- capture: true,
- passive: true
- };
- if (!useMousedownOnly) {
- document.addEventListener("touchstart", touchstartListener, eventListenersOptions);
- }
- if (!useMousedown) {
- document.addEventListener("mouseover", mouseoverListener, eventListenersOptions);
- } else if (!mousedownShortcut) {
- document.addEventListener("mousedown", mousedownListener, eventListenersOptions);
- }
- if (mousedownShortcut) {
- document.addEventListener("mousedown", mousedownShortcutListener, eventListenersOptions);
- }
- if (useViewport) {
- let triggeringFunction;
- if (window.requestIdleCallback) {
- triggeringFunction = function(callback) {
- requestIdleCallback(callback, {
- timeout: 1500
- });
- };
- } else {
- triggeringFunction = function(callback) {
- callback();
- };
- }
- triggeringFunction(function() {
- const intersectionObserver = new IntersectionObserver(function(entries) {
- entries.forEach(function(entry) {
- if (entry.isIntersecting) {
- const linkElement = entry.target;
- intersectionObserver.unobserve(linkElement);
- preload(linkElement.href);
- }
- });
- });
- document.querySelectorAll("a").forEach(function(linkElement) {
- if (isPreloadable(linkElement)) {
- intersectionObserver.observe(linkElement);
- }
- });
- });
- }
- }
- function touchstartListener(event) {
- lastTouchTimestamp = performance.now();
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- preload(linkElement.href);
- }
- function mouseoverListener(event) {
- if (performance.now() - lastTouchTimestamp < 1111) {
- return;
- }
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- linkElement.addEventListener("mouseout", mouseoutListener, {
- passive: true
+ [
+ "mouseout",
+ "mousedown",
+ "touchstart"
+ ].forEach(function(event) {
+ self.addEventListener(event, function(event) {
+ const url = event.target.closest("a");
+ if (preloadable(url) === undefined) return;
+ preload(url.href);
});
- mouseoverTimer = setTimeout(function() {
- preload(linkElement.href);
- mouseoverTimer = undefined;
- }, delayOnHover);
- }
- function mousedownListener(event) {
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- preload(linkElement.href);
- }
- function mouseoutListener(event) {
- if (event.relatedTarget && event.target.closest("a") == event.relatedTarget.closest("a")) {
- return;
- }
- if (mouseoverTimer) {
- clearTimeout(mouseoverTimer);
- mouseoverTimer = undefined;
- }
- }
- function mousedownShortcutListener(event) {
- if (performance.now() - lastTouchTimestamp < 1111) {
- return;
- }
- const linkElement = event.target.closest("a");
- if (event.which > 1 || event.metaKey || event.ctrlKey) {
- return;
- }
- if (!linkElement) {
- return;
- }
- linkElement.addEventListener("click", function(event) {
- if (event.detail == 1337) {
+ });
+ function preloadable(url) {
+ switch(true){
+ case url === null || url.href === null:
return;
- }
- event.preventDefault();
- }, {
- capture: true,
- passive: false,
- once: true
- });
- const customEvent = new MouseEvent("click", {
- view: window,
- bubbles: true,
- cancelable: false,
- detail: 1337
- });
- linkElement.dispatchEvent(customEvent);
- }
- function isPreloadable(linkElement) {
- if (!linkElement || !linkElement.href) {
- return;
- }
- if (useWhitelist && !("instant" in linkElement.dataset)) {
- return;
- }
- if (!allowExternalLinks && linkElement.origin != location.origin && !("instant" in linkElement.dataset)) {
- return;
- }
- if (![
- "http:",
- "https:"
- ].includes(linkElement.protocol)) {
- return;
- }
- if (linkElement.protocol == "http:" && location.protocol == "https:") {
- return;
- }
- if (!allowQueryString && linkElement.search && !("instant" in linkElement.dataset)) {
- return;
- }
- if (linkElement.hash && linkElement.pathname + linkElement.search == location.pathname + location.search) {
- return;
- }
- if ("noInstant" in linkElement.dataset) {
- return;
+ case url.origin !== location.origin:
+ return;
+ case [
+ "http:",
+ "https:"
+ ].includes(url.protocol) === null:
+ return;
+ case url.protocol === "http:" && location.protocol === "https:":
+ return;
+ case url.hash && url.pathname + url.search == location.pathname + location.search:
+ return;
+ default:
+ return true;
}
- return true;
}
function preload(url) {
- if (prefetches.has(url)) {
- return;
- }
const prefetcher = document.createElement("link");
prefetcher.rel = "custom-prefetch";
prefetcher.href = url;
- fetch(url, "GET", function() {
- document.head.appendChild(prefetcher);
- prefetches.add(url);
- });
+ const selector = `link[rel="${prefetcher.rel}"][href="${prefetcher.href}"]`;
+ const prefetched = document.head.contains(document.querySelector(selector));
+ if (prefetched) {
+ return;
+ }
+ document.head.appendChild(prefetcher);
+ fetch(url, "GET", function() {});
}
});
})();