one
Version:
One is a new React Framework that makes Vite serve both native and web.
177 lines • 5.31 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var ScrollBehavior_exports = {};
__export(ScrollBehavior_exports, {
ScrollBehavior: () => ScrollBehavior,
registerScrollGroup: () => registerScrollGroup
});
module.exports = __toCommonJS(ScrollBehavior_exports);
var import_react = require("react");
var import_lastAction = require("../router/lastAction.cjs");
var import_router = require("../router/router.cjs");
const KEY = "one-sr";
const GROUP_KEY = "one-sr-groups";
const getState = () => JSON.parse(sessionStorage.getItem(KEY) || "{}");
const getGroupState = () => JSON.parse(sessionStorage.getItem(GROUP_KEY) || "{}");
let isFirstLoad = true;
let activeGroups = /* @__PURE__ */new Set();
function registerScrollGroup(groupId) {
activeGroups.add(groupId);
return () => {
activeGroups.delete(groupId);
};
}
function getGroupKey(pathname) {
let longestMatch = null;
for (const group of activeGroups) {
if (pathname.startsWith(group) && (!longestMatch || group.length > longestMatch.length)) {
longestMatch = group;
}
}
return longestMatch;
}
function restorePosition() {
try {
const positions = getState();
const saved = positions[window.location.pathname];
if (typeof saved === "number") {
setTimeout(() => {
window.scrollTo(0, saved);
});
}
} catch (error) {
console.error(`Error restoring scroll position`, error);
sessionStorage.removeItem(KEY);
}
}
function restoreGroupPosition(groupId) {
try {
const positions = getGroupState();
const saved = positions[groupId];
if (typeof saved === "number") {
setTimeout(() => {
window.scrollTo(0, saved);
});
}
} catch (error) {
console.error(`Error restoring scroll position for group ${groupId}`, error);
sessionStorage.removeItem(GROUP_KEY);
}
}
let didPop = false;
let previousPathname = null;
function rememberScrollPosition() {
didPop = false;
const pathname = window.location.pathname;
const state = getState();
state[pathname] = window.scrollY;
sessionStorage.setItem(KEY, JSON.stringify(state));
const groupKey = getGroupKey(pathname);
if (groupKey) {
const groupState = getGroupState();
groupState[groupKey] = window.scrollY;
sessionStorage.setItem(GROUP_KEY, JSON.stringify(groupState));
}
previousPathname = pathname;
}
let disable = null;
function configure(props) {
if (typeof window === "undefined" || !window.addEventListener) {
return;
}
disable?.();
const popStateController = new AbortController();
window.addEventListener("popstate", () => {
didPop = true;
(0, import_lastAction.setLastAction)();
}, {
signal: popStateController.signal
});
const disposeOnLoadState = (0, import_router.subscribeToLoadingState)(state => {
if (state === "loading") {
rememberScrollPosition();
}
});
const disposeOnRootState = (0, import_router.subscribeToRootState)(state => {
if (isFirstLoad) {
isFirstLoad = false;
previousPathname = window.location.pathname;
return;
}
if (state.linkOptions?.scroll === false) {
return;
}
const {
hash
} = state;
const currentPathname = window.location.pathname;
if (hash) {
setTimeout(() => {
scrollToHash(hash);
});
} else if (didPop) {
if (props.disable !== "restore") {
restorePosition();
}
} else {
const prevGroup = previousPathname ? getGroupKey(previousPathname) : null;
const currentGroup = getGroupKey(currentPathname);
if (prevGroup && currentGroup && prevGroup === currentGroup) {
restoreGroupPosition(currentGroup);
} else if (state.linkOptions?.scrollGroup) {
restoreGroupPosition(state.linkOptions.scrollGroup);
} else {
window.scrollTo(0, 0);
}
}
previousPathname = currentPathname;
});
disable = () => {
popStateController.abort();
disposeOnLoadState();
disposeOnRootState();
};
return disable;
}
function scrollToHash(hash) {
if (!hash || !hash.startsWith("#")) return;
const id = hash.slice(1);
const el = document.getElementById(id);
if (!el) return;
el.scrollIntoView({
behavior: "instant"
});
}
function ScrollBehavior(props) {
if (process.env.VITE_ENVIRONMENT === "client") {
(0, import_react.useEffect)(() => {
if (window.location.hash) {
scrollToHash(window.location.hash);
}
}, []);
(0, import_react.useEffect)(() => {
return configure(props);
}, [props.disable]);
}
return null;
}