95 lines
3.1 KiB
TypeScript
95 lines
3.1 KiB
TypeScript
import { get, writable } from "svelte/store"
|
|
|
|
/*********** location **************************/
|
|
|
|
/**
|
|
* Strip trailing slash from a path, preserving root "/".
|
|
* E.g. "/about/" → "/about"
|
|
*/
|
|
const stripTrailingSlash = (path: string): string => {
|
|
if (path && path.length > 1 && path.endsWith("/")) {
|
|
return path.replace(/\/+$/, "")
|
|
}
|
|
return path
|
|
}
|
|
|
|
const initLoc = {
|
|
path: stripTrailingSlash((typeof window !== "undefined" && window.location?.pathname) || "/"),
|
|
search: (typeof window !== "undefined" && window.location?.search) || "",
|
|
hash: (typeof window !== "undefined" && window.location?.hash) || "",
|
|
push: false,
|
|
pop: false,
|
|
}
|
|
export const location = writable<LocationStore>(initLoc)
|
|
|
|
const publishLocation = (_p?: string) => {
|
|
let _s: string
|
|
let _h: string
|
|
if (_p) {
|
|
const parts = _p.split("#")
|
|
_p = parts.shift()
|
|
_h = parts.join()
|
|
if (_h) _h = "#" + _h
|
|
|
|
const parts2 = _p.split("?")
|
|
_p = parts2.shift()
|
|
_s = parts2.join()
|
|
if (_s) _s = "?" + _s
|
|
}
|
|
|
|
const rawPath = _p || (typeof window !== "undefined" && window.location?.pathname)
|
|
const newLocation: LocationStore = {
|
|
path: stripTrailingSlash(rawPath),
|
|
search: _p ? _s : typeof window !== "undefined" && window.location?.search,
|
|
hash: _p ? _h : typeof window !== "undefined" && window.location?.hash,
|
|
push: !!_p,
|
|
pop: !_p,
|
|
previousLocation: get(location),
|
|
}
|
|
location.set(newLocation)
|
|
}
|
|
|
|
if (typeof history !== "undefined") {
|
|
const historyApply: ProxyHandler<typeof history.pushState>["apply"] = (target, thisArg, argumentsList) => {
|
|
publishLocation(argumentsList && argumentsList.length >= 2 && argumentsList[2])
|
|
Reflect.apply(target, thisArg, argumentsList)
|
|
}
|
|
|
|
history.pushState = new Proxy(history.pushState, {
|
|
apply: historyApply,
|
|
})
|
|
|
|
history.replaceState = new Proxy(history.replaceState, {
|
|
apply: historyApply,
|
|
})
|
|
} // else ssr -> no history handling
|
|
|
|
typeof window !== "undefined" &&
|
|
window.addEventListener("popstate", (event) => {
|
|
publishLocation()
|
|
})
|
|
|
|
/********************** UI State Stores *****************/
|
|
|
|
// Store for mobile menu open state (shared between Header and navigation components)
|
|
export const mobileMenuOpen = writable<boolean>(false)
|
|
|
|
/********************** Current Content Page *****************/
|
|
|
|
// Store for tracking the currently displayed content page (used for cross-language linking etc.)
|
|
export const currentContentEntry = writable<{ translationKey?: string; lang?: string; path?: string } | null>(null)
|
|
|
|
/********************** override for admin ui *****************/
|
|
|
|
export const apiBaseOverride = writable<string | null>(null)
|
|
|
|
/********************** Navigation History *****************/
|
|
|
|
// Store for tracking previous path (used for conditional back button)
|
|
export const previousPath = writable<string | null>(null)
|
|
|
|
/********************** Cookie Consent *****************/
|
|
|
|
// Whether the cookie consent banner is currently visible
|
|
export const cookieConsentVisible = writable(false)
|