diff options
Diffstat (limited to 'static/js/pager.ts')
-rw-r--r-- | static/js/pager.ts | 124 |
1 files changed, 85 insertions, 39 deletions
diff --git a/static/js/pager.ts b/static/js/pager.ts index 49f3b2d..ebaf67a 100644 --- a/static/js/pager.ts +++ b/static/js/pager.ts @@ -1,49 +1,95 @@ (function () { - const url = self.location.href.split("#")[0]; - let settings = { pager: {} }; + const cookiesDisabled = !navigator.cookieEnabled; - self.addEventListener("DOMContentLoaded", function () { - if (history.scrollRestoration) history.scrollRestoration = "manual"; - if (localStorage["settings"]) { - settings = JSON.parse(localStorage["settings"]); - } - if (self.location.hash.length > 0) { - settings["pager"][url] = self.pageYOffset; - localStorage["settings"] = JSON.stringify(settings); - document.getElementById(location.hash.slice(1)).scrollIntoView(); - self.addEventListener("load", function () { - document.getElementById(location.hash.slice(1)).scrollIntoView(); - }); - return; - } - if (settings["pager"][url] > 0) { - self.scrollTo(0, settings["pager"][url]); - return; + if (cookiesDisabled) { + document.cookie = "disabled"; + document.cookie.indexOf("disabled"); + return console.warn("WARNING: Pager disabled due to cookie restrictions"); + } + + let seek; + let pager = {}; + + const state = "on"; + const key = "config.scroll.pager.urls"; + + if (!localStorage[key]) localStorage[key] = JSON.stringify(pager); + + let url = function () { return self.location.href.split("#")[0].split("?")[0]; }; + + const scrollHash = function (url) { + const hash = self.location.hash; + const fragment = hash.slice(1) && document.getElementById(hash.slice(1)); + const fragmented = hash.length > 0; + const hashed = fragmented && document.body.contains(fragment); + if (hashed) { + self.location.hash = hash; + self.location.href = hash; + if ("scroll-margin-top" in document.body.style === false && fragment.textContent !== "") { + self.scrollBy(0, -6 * parseFloat(getComputedStyle(document.documentElement).fontSize)); + } } - settings["pager"][url] = self.pageYOffset; - localStorage["settings"] = JSON.stringify(settings); - }); + return hashed; + }; + + const scrollRestore = function (url) { + if (history.scrollRestoration) history.scrollRestoration = "manual"; + if (scrollHash(url)) return; + pager = JSON.parse(localStorage[key]); + if (pager[url] > 0) { + clearInterval(seek); + self.scrollTo(0, pager[url]); + let i = 0; return seek = setInterval(function (position) { + i++; if (i > 100) clearInterval(seek); + if (document.documentElement.scrollHeight >= position + document.documentElement.clientHeight) { + clearInterval(seek); self.scrollTo(0, position); + } + }, 4, pager[url]); + } else self.scrollTo(0, 0); + pager[url] = self.pageYOffset; + localStorage[key] = JSON.stringify(pager); + }; - self.addEventListener("scroll", function () { + const scrollTrack = function (url) { const currentPosition = self.pageYOffset; - settings["pager"][url] = currentPosition; - localStorage["settings"] = JSON.stringify(settings); - }); + pager = JSON.parse(localStorage[key]); + pager[url] = currentPosition; + localStorage[key] = JSON.stringify(pager); + }; + + const scrollReverse = function (back, up, event) { + if (document.body.contains(up) && up.contains(event.target)) { + event.preventDefault(); + window.scrollTo(0, 0); + } + if (document.body.contains(back) && back.contains(event.target)) { + if (history.length < 2) return; + event.preventDefault(); + history.go(-1); + } + }; - self.addEventListener("DOMContentLoaded", function () { - const up = document.getElementById("top"); - const back = document.getElementById("back"); + ["DOMContentLoaded", "pageshow", "hashchange", "URLChangedCustomEvent"].forEach( + function (event) { + self.addEventListener(event, function (event) { + if (event.type === "pageshow") { + return event.persisted && self.scrollTo(0, pager[url()]); + } + if (event.type === "DOMContentLoaded") { + self.addEventListener("click", function (event) { + const up = document.getElementById("top"); + const back = document.getElementById("back"); + scrollReverse(back, up, event); + }); + } + scrollRestore(url()); + }); + }, + ); - self.addEventListener("click", function (event) { - if (document.body.contains(up) && up.contains(event.target)) { - event.preventDefault(); - window.scrollTo(0, 0); - } - if (document.body.contains(back) && back.contains(event.target)) { - if (history.length < 2) return; - event.preventDefault(); - history.go(-1); - } + ["click", "touchstart", "scroll"].forEach(function (event) { + self.addEventListener(event, function () { + scrollTrack(url()); }); }); })(); |