|
|
|
@@ -3,20 +3,28 @@
|
|
|
|
|
|
|
|
|
|
import { storedLocation } from '$lib/stores/settings';
|
|
|
|
|
|
|
|
|
|
// a #zoom/lat/lng(/bearing/pitch) hash on OUR url is piped through to the
|
|
|
|
|
// map, so map positions can be bookmarked/shared via ombrella links
|
|
|
|
|
// (the reverse direction is not possible: the iframe is cross-origin, so
|
|
|
|
|
// its internal hash changes are unreadable from here)
|
|
|
|
|
// Hash piping, both directions:
|
|
|
|
|
// - inbound: a #zoom/lat/lng(/bearing/pitch) hash on OUR url seeds the
|
|
|
|
|
// map, so positions can be bookmarked/shared via drizzli links
|
|
|
|
|
// - outbound: the (cross-origin) map posts its hash here on every moveend;
|
|
|
|
|
// we mirror it into our url with replaceState. hashOverride is only set
|
|
|
|
|
// once on mount, so these mirror updates never reload the iframe.
|
|
|
|
|
let hashOverride = $state<string | null>(null);
|
|
|
|
|
|
|
|
|
|
const MAP_HASH_RE = /^#\d+(\.\d+)?\/-?\d+(\.\d+)?\/-?\d+(\.\d+)?/;
|
|
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
|
const readHash = () => {
|
|
|
|
|
const hash = window.location.hash;
|
|
|
|
|
hashOverride = /^#\d+(\.\d+)?\/-?\d+(\.\d+)?\/-?\d+(\.\d+)?/.test(hash) ? hash : null;
|
|
|
|
|
const initialHash = window.location.hash;
|
|
|
|
|
hashOverride = MAP_HASH_RE.test(initialHash) ? initialHash : null;
|
|
|
|
|
|
|
|
|
|
const onMessage = (event: MessageEvent) => {
|
|
|
|
|
if (event.origin !== 'https://maps.open-meteo.com') return;
|
|
|
|
|
const { type, hash } = (event.data ?? {}) as { type?: string; hash?: string };
|
|
|
|
|
if (type !== 'om-maps:hash' || !hash || !MAP_HASH_RE.test(hash)) return;
|
|
|
|
|
history.replaceState(history.state, '', hash);
|
|
|
|
|
};
|
|
|
|
|
readHash();
|
|
|
|
|
window.addEventListener('hashchange', readHash);
|
|
|
|
|
return () => window.removeEventListener('hashchange', readHash);
|
|
|
|
|
window.addEventListener('message', onMessage);
|
|
|
|
|
return () => window.removeEventListener('message', onMessage);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// the embedded map understands maplibre's #zoom/lat/lng hash, so the iframe
|
|
|
|
|