mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
v1.198.1
This commit is contained in:
207
js/hist.js
Normal file
207
js/hist.js
Normal file
@@ -0,0 +1,207 @@
|
||||
"use strict";
|
||||
|
||||
class Hist {
|
||||
static hashChange ({isForceLoad, isBlankFilterLoad = false} = {}) {
|
||||
if (Hist.isHistorySuppressed) {
|
||||
Hist.setSuppressHistory(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const [link, ...sub] = Hist.getHashParts();
|
||||
|
||||
if (link !== Hist.lastLoadedLink || sub.length === 0 || isForceLoad) {
|
||||
Hist.lastLoadedLink = link;
|
||||
if (link === HASH_BLANK) {
|
||||
isBlankFilterLoad = true;
|
||||
} else {
|
||||
const listItem = Hist.getActiveListItem(link);
|
||||
|
||||
if (listItem == null) {
|
||||
if (typeof pHandleUnknownHash === "function" && window.location.hash.length && Hist._lastUnknownLink !== link) {
|
||||
Hist._lastUnknownLink = link;
|
||||
pHandleUnknownHash(link, sub);
|
||||
return;
|
||||
} else {
|
||||
Hist._freshLoad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const toLoad = listItem.ix;
|
||||
if (toLoad === undefined) Hist._freshLoad();
|
||||
else {
|
||||
Hist.lastLoadedId = listItem.ix;
|
||||
loadHash(listItem.ix);
|
||||
document.title = `${listItem.name ? `${listItem.name} - ` : ""}5etools`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof loadSubHash === "function" && (sub.length > 0 || isForceLoad)) loadSubHash(sub);
|
||||
if (isBlankFilterLoad) Hist._freshLoad();
|
||||
}
|
||||
|
||||
static init (initialLoadComplete) {
|
||||
window.onhashchange = () => Hist.hashChange({isForceLoad: true});
|
||||
if (window.location.hash.length) {
|
||||
Hist.hashChange();
|
||||
} else {
|
||||
Hist._freshLoad();
|
||||
}
|
||||
if (initialLoadComplete) Hist.initialLoad = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the hash to be modified without triggering a hashchange
|
||||
* @param val
|
||||
*/
|
||||
static setSuppressHistory (val) {
|
||||
Hist.isHistorySuppressed = val;
|
||||
}
|
||||
|
||||
static _listPage = null;
|
||||
|
||||
static setListPage (listPage) { this._listPage = listPage; }
|
||||
|
||||
static getSelectedListItem () {
|
||||
const [link] = Hist.getHashParts();
|
||||
return Hist.getActiveListItem(link);
|
||||
}
|
||||
|
||||
static getSelectedListElementWithLocation () {
|
||||
const [link] = Hist.getHashParts();
|
||||
return Hist.getActiveListItem(link, true);
|
||||
}
|
||||
|
||||
static getHashParts () {
|
||||
return Hist.util.getHashParts(window.location.hash);
|
||||
}
|
||||
|
||||
static getActiveListItem (link, getIndex) {
|
||||
const primaryLists = this._listPage.primaryLists;
|
||||
if (primaryLists && primaryLists.length) {
|
||||
for (let x = 0; x < primaryLists.length; ++x) {
|
||||
const list = primaryLists[x];
|
||||
|
||||
const foundItemIx = list.items.findIndex(it => it.values.hash === link);
|
||||
if (~foundItemIx) {
|
||||
if (getIndex) return {item: list.items[foundItemIx], x: x, y: foundItemIx, list};
|
||||
return list.items[foundItemIx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static _freshLoad () {
|
||||
// defer this, in case the list needs to filter first
|
||||
setTimeout(() => {
|
||||
const goTo = $("#listcontainer").find(".list a").attr("href");
|
||||
if (goTo) {
|
||||
const parts = location.hash.split(HASH_PART_SEP);
|
||||
const fullHash = `${goTo}${parts.length > 1 ? `${HASH_PART_SEP}${parts.slice(1).join(HASH_PART_SEP)}` : ""}`;
|
||||
location.replace(fullHash);
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
static cleanSetHash (toSet) {
|
||||
window.location.hash = Hist.util.getCleanHash(toSet);
|
||||
}
|
||||
|
||||
static getHashSource () {
|
||||
const [link] = Hist.getHashParts();
|
||||
// by convention, the source is the last hash segment
|
||||
return link ? link.split(HASH_LIST_SEP).last() : null;
|
||||
}
|
||||
|
||||
static getSubHash (key) {
|
||||
return Hist.util.getSubHash(window.location.hash, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a subhash with the key specified, overwriting any existing.
|
||||
* @param key Subhash key.
|
||||
* @param val Subhash value. Passing a nully object removes the k/v pair.
|
||||
*/
|
||||
static setSubhash (key, val) {
|
||||
const nxtHash = Hist.util.setSubhash(window.location.hash, key, val);
|
||||
Hist.cleanSetHash(nxtHash);
|
||||
}
|
||||
|
||||
static setMainHash (hash) {
|
||||
const subHashPart = Hist.util.getHashParts(window.location.hash, key, val).slice(1).join(HASH_PART_SEP);
|
||||
Hist.cleanSetHash([hash, subHashPart].filter(Boolean).join(HASH_PART_SEP));
|
||||
}
|
||||
|
||||
static replaceHistoryHash (hash) {
|
||||
window.history.replaceState(
|
||||
{},
|
||||
document.title,
|
||||
`${location.origin}${location.pathname}${hash ? `#${hash}` : ""}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Hist.lastLoadedLink = null;
|
||||
Hist._lastUnknownLink = null;
|
||||
Hist.lastLoadedId = null;
|
||||
Hist.initialLoad = true;
|
||||
Hist.isHistorySuppressed = false;
|
||||
|
||||
Hist.util = class {
|
||||
static getCleanHash (hash) {
|
||||
return hash.replace(/,+/g, ",").replace(/,$/, "").toLowerCase();
|
||||
}
|
||||
|
||||
static _SYMS_NO_ENCODE = [/(,)/g, /(:)/g, /(=)/g];
|
||||
|
||||
static getHashParts (location, {isReturnEncoded = false} = {}) {
|
||||
if (location[0] === "#") location = location.slice(1);
|
||||
|
||||
// Handle junk from external ads
|
||||
if (location === "google_vignette") location = "";
|
||||
|
||||
if (isReturnEncoded) {
|
||||
return location
|
||||
.split(HASH_PART_SEP);
|
||||
}
|
||||
|
||||
// region Normalize encoding
|
||||
let pts = [location];
|
||||
this._SYMS_NO_ENCODE.forEach(re => {
|
||||
pts = pts.map(pt => pt.split(re)).flat();
|
||||
});
|
||||
pts = pts.map(pt => {
|
||||
if (this._SYMS_NO_ENCODE.some(re => re.test(pt))) return pt;
|
||||
return decodeURIComponent(pt).toUrlified();
|
||||
});
|
||||
location = pts.join("");
|
||||
// endregion
|
||||
|
||||
return location
|
||||
.split(HASH_PART_SEP);
|
||||
}
|
||||
|
||||
static getSubHash (location, key) {
|
||||
const [link, ...sub] = Hist.util.getHashParts(location);
|
||||
const hKey = `${key}${HASH_SUB_KV_SEP}`;
|
||||
const part = sub.find(it => it.startsWith(hKey));
|
||||
if (part) return part.slice(hKey.length);
|
||||
return null;
|
||||
}
|
||||
|
||||
static setSubhash (location, key, val) {
|
||||
if (key.endsWith(HASH_SUB_KV_SEP)) key = key.slice(0, -1);
|
||||
|
||||
const [link, ...sub] = Hist.util.getHashParts(location);
|
||||
if (!link) return "";
|
||||
|
||||
const hKey = `${key}${HASH_SUB_KV_SEP}`;
|
||||
const out = [link];
|
||||
if (sub.length) sub.filter(it => !it.startsWith(hKey)).forEach(it => out.push(it));
|
||||
if (val != null) out.push(`${hKey}${val}`);
|
||||
|
||||
return Hist.util.getCleanHash(out.join(HASH_PART_SEP));
|
||||
}
|
||||
};
|
||||
|
||||
globalThis.Hist = Hist;
|
||||
Reference in New Issue
Block a user