aboutsummaryrefslogtreecommitdiff
path: root/public/js/app.js
diff options
context:
space:
mode:
authorThedro Neely <thedroneely@gmail.com>2024-01-06 19:16:12 -0500
committerThedro Neely <thedroneely@gmail.com>2024-01-06 19:16:12 -0500
commit6d745f1e8c7b870524e01ee7a4886db38634e2ae (patch)
tree4d5964c37fb3d66ed07e5ac0fad46a54d76e979d /public/js/app.js
parent3c1a341d42994efd4addb942c623bff18b2d034c (diff)
downloadthedroneely.com-6d745f1e8c7b870524e01ee7a4886db38634e2ae.tar.gz
thedroneely.com-6d745f1e8c7b870524e01ee7a4886db38634e2ae.tar.bz2
thedroneely.com-6d745f1e8c7b870524e01ee7a4886db38634e2ae.zip
app/partials: Unify headers
Make easier to maintain. Use native upload and add htm.
Diffstat (limited to 'public/js/app.js')
-rw-r--r--public/js/app.js638
1 files changed, 359 insertions, 279 deletions
diff --git a/public/js/app.js b/public/js/app.js
index b8413e6..0d540ce 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -1,108 +1,108 @@
/**
* General Functions
*/
-function posf (f, a) { for (var i=0; i < a.length; i++) { if (f(a[i])) {return i;} } return -1; }
-function apos (x, a) { return (typeof x == 'function') ? posf(x,a) : Array.prototype.indexOf.call(a,x); }
-function arem (a, x) { var i = apos(x, a); if (i >= 0) { a.splice(i, 1); } return a; }
-function afind (x, a) { var i = apos(x, a); return (i >= 0) ? a[i] : null; }
-function addClass (el, cl) { if (el) { var a = el.className.split(' '); if (!afind(cl, a)) { a.unshift(cl); el.className = a.join(' '); } } }
-function remClass (el, cl) { if (el) { var a = el.className.split(' '); arem(a, cl); el.className = a.join(' '); } }
-function runOnce(action) { runOnce = function(){}; action(); }
-
-/*
- * Context Menu functions
- */
-function contextMenuHide(element) {
- for (var i = 0; i < element.length; i++) {
- element[i].checked = false;
+function once(action) { once = function(){}; action(); }
+
+function contextMenuHide(elements) {
+ for (var i = 0; i < elements.length; i++) {
+ elements[i].checked = false;
}
}
-function contextMenuHideOutside(element, event) {
- for (var i = 0; i < element.length; i++) {
- let notClicked = !element[i].contains(event.target);
- if (notClicked && contextMenuInputs[i].checked === true) { contextMenuHide(contextMenuInputs); }
+function contextMenuHideOutside(elements, targets, event) {
+ for (var i = 0; i < elements.length; i++) {
+ let notClicked = !elements[i].contains(event.target);
+ if (notClicked && targets[i].checked === true) { contextMenuHide(targets); }
}
}
/**
* Remove url query string and hash
*/
-var url = window.location.href.split('?')[0];
-window.history.replaceState(null, '', url);
+var url = self.location.href.split('?')[0];
+self.history.replaceState(null, '', url);
/**
* Load events
*/
-var settings = { pager: {} };
-
-window.addEventListener('DOMContentLoaded', function() {
- if (history.scrollRestoration) { history.scrollRestoration = 'manual'; }
- if (localStorage['settings']) { settings = JSON.parse(localStorage['settings']); }
- var hash = document.getElementById(location.hash.slice(1));
- var hashInURL = window.location.href.indexOf("#") >= 0;
- if (hashInURL && document.body.contains(hash)) {
- settings['pager'][url] = window.pageYOffset;
- localStorage['settings'] = JSON.stringify(settings);
- hash.scrollIntoView();
- return;
- }
- if (settings['pager'][url] > 0) { window.scrollTo(0, settings['pager'][url]); return; }
- settings['pager'][url] = window.pageYOffset;
- localStorage['settings'] = JSON.stringify(settings);
-});
-
-/*
- * Click events
- */
-document.addEventListener('click', function(event) {
- contextMenuHideOutside(contextMenus, event);
-});
-
-/*
- * Touch start events
- */
-document.addEventListener('touchstart', function(event) {
- contextMenuHideOutside(contextMenus, event);
-});
-
-/**
- * Scroll events
- */
-var previousPosition = window.pageYOffset;
-var navbar = document.getElementById("navbar");
-var navbarHeight = navbar.offsetHeight;
-var scrolls = 0;
-
-var contextMenus = document.getElementsByTagName('context-menu-container');
-var contextMenuInputs = document.querySelectorAll('context-menu-container input');
-
-window.addEventListener('scroll', function() {
-
- contextMenuHide(contextMenuInputs);
-
- var currentPosition = window.pageYOffset;
- var velocity = previousPosition - currentPosition;
+var pager = {};
+
+self.addEventListener('DOMContentLoaded', function() {
+ (function () {
+ if (history.scrollRestoration) { history.scrollRestoration = 'manual'; }
+ if (localStorage['pager']) { pager = JSON.parse(localStorage['pager']); }
+ var hash = self.location.hash.slice(1) && document.getElementById(self.location.hash.slice(1));
+ var hashInURL = self.location.href.indexOf("#") >= 0;
+ if (hashInURL && document.body.contains(hash)) {
+ pager[url] = self.pageYOffset;
+ localStorage['pager'] = JSON.stringify(pager);
+ return hash.scrollIntoView();
+ }
+ if (pager[url] > 0) { return self.scrollTo(0, pager[url]); }
+ pager[url] = self.pageYOffset;
+ localStorage['pager'] = JSON.stringify(pager);
+ })();
+
+ /**
+ * Scroll events
+ */
+ var scrolls = 0;
+ var previousPosition = self.pageYOffset;
+ var navbar = document.getElementById("navbar");
+ var navbarHeight = navbar.offsetHeight;
+
+ var contextMenus = document.getElementsByTagName('context-menu-container');
+ var contextMenuInputs = document.querySelectorAll('context-menu-container input');
+
+ self.addEventListener('scroll', function() {
+ contextMenuHide(contextMenuInputs);
+
+ var currentPosition = self.pageYOffset;
+ var velocity = previousPosition - currentPosition;
+
+ pager[url] = currentPosition;
+ localStorage['pager'] = JSON.stringify(pager);
+
+ if (scrolls > 3) {
+ if (velocity > 75 || currentPosition < navbarHeight) {
+ navbar.classList.remove('hide');
+ } else if (velocity < -25) {
+ navbar.classList.add('hide');
+ } else if (currentPosition > navbarHeight) {
+ once(function () { navbar.classList.add('hide'); });
+ }
+ }
+ previousPosition = currentPosition;
+ scrolls++;
+ });
- settings['pager'][url] = currentPosition;
- localStorage['settings'] = JSON.stringify(settings);
+ /*
+ * Click events
+ */
+ self.addEventListener('click', function(event) {
+ contextMenuHideOutside(contextMenus, contextMenuInputs, event);
+ });
- if (scrolls > 3) {
- if (velocity > 75 || currentPosition < navbarHeight) {
- remClass(navbar, 'hide');
- } else if (velocity < -25) {
- addClass(navbar, 'hide');
- } else if (currentPosition > navbarHeight) {
- runOnce(function () { addClass(navbar, 'hide'); });
- }
- }
+ /*
+ * Touch start events
+ */
+ self.addEventListener('touchstart', function(event) {
+ contextMenuHideOutside(contextMenus, contextMenuInputs, event);
+ });
- previousPosition = currentPosition;
- scrolls++;
-});
+ /*
+ * Hash change events
+ */
+ self.addEventListener("hashchange", function () {
+ document.getElementById(self.location.hash.slice(1)).scrollIntoView();
+ });
-window.addEventListener("hashchange", function () {
- document.getElementById(location.hash.slice(1)).scrollIntoView();
+ /**
+ * Activate Medium Zoom
+ */
+ var imageZoom = mediumZoom('[data-image-zoom]');
+ imageZoom.on('open', function() { navbar.classList.add('hide'); });
+ imageZoom.on('close', function() { navbar.classList.remove('hide'); });
});
/**
@@ -594,248 +594,328 @@ window.addEventListener("hashchange", function () {
return mediumZoom;
});
-
-/**
- * Activate Medium Zoom
- */
-var imageZoom = mediumZoom('[data-image-zoom]');
-imageZoom.on('open', function() { addClass(navbar, 'hide'); });
-imageZoom.on('close', function() { remClass(navbar, 'hide'); });
-
-
-/**
- * Instant Page v3.0.0 - (C) 2019 Alexandre Dieulot - https://instant.page/license
- */
-let mouseoverTimer;
-let lastTouchTimestamp;
-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;
-
-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.includes('2g')))) {
- if (intensity == "viewport") {
- /* Biggest iPhone resolution (which we want): 414 × 896 = 370944
+(function () {
+ self.addEventListener("DOMContentLoaded", function () {
+ /*! instant.page v5.1.0 - (C) 2019-2020 Alexandre Dieulot - https://instant.page/license */
+
+ let mouseoverTimer;
+ let lastTouchTimestamp;
+ 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;
+ const DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION = 1111;
+
+ 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") {
+ /* Biggest iPhone resolution (which we want): 414 × 896 = 370944
* Small 7" tablet resolution (which we don’t want): 600 × 1024 = 614400
* Note that the viewport (which we check here) is smaller than the resolution due to the UI’s chrome */
- if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
- useViewport = true;
+ 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;
}
}
- 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 (isSupported) {
+ const eventListenersOptions = {
+ capture: true,
+ passive: true,
+ };
- if (!useMousedownOnly) {
- document.addEventListener('touchstart', touchstartListener, eventListenersOptions);
- }
+ if (!useMousedownOnly) {
+ document.addEventListener(
+ "touchstart",
+ touchstartListener,
+ eventListenersOptions,
+ );
+ }
- if (!useMousedown) {
- document.addEventListener('mouseover', mouseoverListener, eventListenersOptions);
- }
- else {
- document.addEventListener('mousedown', mousedownListener, 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();
+ };
+ }
- if (useViewport) {
- let triggeringFunction;
- if (window.requestIdleCallback) {
- triggeringFunction = function(callback) {
- requestIdleCallback(callback, {
- timeout: 1500,
+ 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);
+ }
+ });
});
- };
+ }
}
- else {
- triggeringFunction = function(callback) {
- callback();
- };
+
+ function touchstartListener(event) {
+ /* Chrome on Android calls mouseover before touchcancel so `lastTouchTimestamp`
+ * must be assigned on touchstart to be measured on mouseover. */
+ lastTouchTimestamp = performance.now();
+
+ const linkElement = event.target.closest("a");
+
+ if (!isPreloadable(linkElement)) {
+ return;
+ }
+
+ preload(linkElement.href);
}
- 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);
- }
- });
- });
+ function mouseoverListener(event) {
+ if (
+ performance.now() - lastTouchTimestamp <
+ DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION
+ ) {
+ return;
+ }
- document.querySelectorAll('a').forEach(function(linkElement) {
- if (isPreloadable(linkElement)) {
- intersectionObserver.observe(linkElement);
- }
- });
- });
- }
-}
+ const linkElement = event.target.closest("a");
-function touchstartListener(event) {
- /* Chrome on Android calls mouseover before touchcancel so `lastTouchTimestamp`
- * must be assigned on touchstart to be measured on mouseover. */
- lastTouchTimestamp = performance.now();
+ if (!isPreloadable(linkElement)) {
+ return;
+ }
- const linkElement = event.target.closest('a');
+ linkElement.addEventListener("mouseout", mouseoutListener, {
+ passive: true,
+ });
- if (!isPreloadable(linkElement)) {
- return;
- }
+ mouseoverTimer = setTimeout(function () {
+ preload(linkElement.href);
+ mouseoverTimer = undefined;
+ }, delayOnHover);
+ }
- preload(linkElement.href);
-}
+ function mousedownListener(event) {
+ const linkElement = event.target.closest("a");
-function mouseoverListener(event) {
- if (performance.now() - lastTouchTimestamp < 1100) {
- return;
- }
+ if (!isPreloadable(linkElement)) {
+ return;
+ }
- const linkElement = event.target.closest('a');
+ preload(linkElement.href);
+ }
- if (!isPreloadable(linkElement)) {
- return;
- }
+ function mouseoutListener(event) {
+ if (
+ event.relatedTarget &&
+ event.target.closest("a") == event.relatedTarget.closest("a")
+ ) {
+ return;
+ }
- linkElement.addEventListener('mouseout', mouseoutListener, {passive: true});
+ if (mouseoverTimer) {
+ clearTimeout(mouseoverTimer);
+ mouseoverTimer = undefined;
+ }
+ }
- mouseoverTimer = setTimeout(function() {
- preload(linkElement.href);
- mouseoverTimer = undefined;
- }, delayOnHover);
-}
+ function mousedownShortcutListener(event) {
+ if (
+ performance.now() - lastTouchTimestamp <
+ DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION
+ ) {
+ return;
+ }
-function mousedownListener(event) {
- const linkElement = event.target.closest('a');
+ const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
+ if (event.which > 1 || event.metaKey || event.ctrlKey) {
+ return;
+ }
- preload(linkElement.href);
-}
+ if (!linkElement) {
+ return;
+ }
-function mouseoutListener(event) {
- if (event.relatedTarget && event.target.closest('a') == event.relatedTarget.closest('a')) {
- return;
- }
+ linkElement.addEventListener("click", function (event) {
+ if (event.detail == 1337) {
+ return;
+ }
- if (mouseoverTimer) {
- clearTimeout(mouseoverTimer);
- mouseoverTimer = undefined;
- }
-}
+ event.preventDefault();
+ }, { capture: true, passive: false, once: true });
-function isPreloadable(linkElement) {
- if (!linkElement || !linkElement.href) {
- return;
- }
+ const customEvent = new MouseEvent("click", {
+ view: window,
+ bubbles: true,
+ cancelable: false,
+ detail: 1337,
+ });
+ linkElement.dispatchEvent(customEvent);
+ }
- if (useWhitelist && !('instant' in linkElement.dataset)) {
- return;
- }
+ function isPreloadable(linkElement) {
+ if (!linkElement || !linkElement.href) {
+ return;
+ }
- if (!allowExternalLinks && linkElement.origin != location.origin && !('instant' in linkElement.dataset)) {
- return;
- }
+ if (useWhitelist && !("instant" in linkElement.dataset)) {
+ return;
+ }
- if (!['http:', 'https:'].includes(linkElement.protocol)) {
- return;
- }
+ if (
+ !allowExternalLinks && linkElement.origin != location.origin &&
+ !("instant" in linkElement.dataset)
+ ) {
+ return;
+ }
- if (linkElement.protocol == 'http:' && location.protocol == 'https:') {
- return;
- }
+ if (!["http:", "https:"].includes(linkElement.protocol)) {
+ return;
+ }
- if (!allowQueryString && linkElement.search && !('instant' in linkElement.dataset)) {
- return;
- }
+ if (linkElement.protocol == "http:" && location.protocol == "https:") {
+ return;
+ }
- if (linkElement.hash && linkElement.pathname + linkElement.search == location.pathname + location.search) {
- return;
- }
+ if (
+ !allowQueryString && linkElement.search &&
+ !("instant" in linkElement.dataset)
+ ) {
+ return;
+ }
- if ('noInstant' in linkElement.dataset) {
- return;
- }
+ if (
+ linkElement.hash &&
+ linkElement.pathname + linkElement.search ==
+ location.pathname + location.search
+ ) {
+ return;
+ }
- return true;
-}
+ if ("noInstant" in linkElement.dataset) {
+ return;
+ }
-function preload(url) {
- if (prefetches.has(url)) {
- return;
- }
+ return true;
+ }
+
+ function preload(url) {
+ if (prefetches.has(url)) {
+ return;
+ }
- const prefetcher = document.createElement('link');
- prefetcher.rel = 'prefetch';
- prefetcher.href = url;
- document.head.appendChild(prefetcher);
+ const prefetcher = document.createElement("link");
+ prefetcher.rel = "prefetch";
+ prefetcher.href = url;
+ document.head.appendChild(prefetcher);
- prefetches.add(url);
-}
+ prefetches.add(url);
+ }
+ });
+})();
/**
* Dictionary Access Copyright (C) 2006, Paul Lutus https://arachnoid.com/javascript/dictionary_access.js GPLv2+
*/
(function () {
- const options =
- "targetWindow,width=700,height=500,toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes";
+ self.addEventListener("DOMContentLoaded", function () {
+ const options = "targetWindow,width=700,height=500,toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes";
- self.addEventListener("keydown", function (event) {
- if (event.repeat && event.key === "d") {
- selection(dictionary);
- }
- });
+ self.addEventListener("keydown", function (event) {
+ if (event.repeat && event.key === "d") {
+ selection(dictionary);
+ }
+ });
- function selection(execute) {
- let phrase = "" + window.getSelection();
- phrase = phrase.replace(/[!.:?,;"]/g, "");
- phrase = phrase.replace(/^\s*(\S*?)\s*$/g, "$1");
- if (phrase && phrase > "" && phrase.length > 1) {
- execute(phrase);
+ function selection(execute) {
+ let phrase = "" + window.getSelection();
+ phrase = phrase.replace(/[!.:?,;"]/g, "");
+ phrase = phrase.replace(/^\s*(\S*?)\s*$/g, "$1");
+ if (phrase && phrase > "" && phrase.length > 1) {
+ execute(phrase);
+ }
}
- }
- function dictionary(word) {
- window.open(
- "https://www.merriam-webster.com/dictionary/" +
- encodeURIComponent(word),
- "Definitions",
- options,
- );
- }
+ function dictionary(word) {
+ window.open(
+ "https://www.merriam-webster.com/dictionary/" + encodeURIComponent(word),
+ "Definitions",
+ options,
+ );
+ }
+ });
})();