/** @type {{ top: number, left: number } | null} */ let pendingScrollRestore = null /** * 뒤로가기 스크롤 복원 좌표를 저장한다. * @param {{ top?: number, left?: number }} position - 복원 좌표 * @returns {void} */ export const setPendingScrollRestore = (position) => { pendingScrollRestore = { top: Number(position?.top || 0), left: Number(position?.left || 0) } } /** * 저장된 스크롤 복원 좌표를 꺼낸다. * @returns {{ top: number, left: number } | null} */ export const consumePendingScrollRestore = () => { const position = pendingScrollRestore pendingScrollRestore = null return position } /** * 공개 사이트 경로에서 전환 베일을 사용할지 판별한다. * @param {string} path - 라우트 경로 * @returns {boolean} */ export const shouldUseSiteRouteVeil = (path) => { const clean = String(path || '').split('?')[0].split('#')[0] return !clean.startsWith('/admin') } /** * 라우터 이동에서 공개 전환 베일을 시작할지 판별한다. * 같은 페이지 컴포넌트의 query/hash 이동은 Nuxt page finish가 발생하지 않을 수 있어 베일을 쓰지 않는다. * @param {{ fullPath?: string, path?: string }} to - 이동 대상 라우트 * @param {{ fullPath?: string, path?: string }} from - 이전 라우트 * @returns {boolean} 전환 베일 시작 여부 */ export const shouldStartSiteRouteVeilNavigation = (to, from) => { if (to?.fullPath === from?.fullPath) { return false } if (to?.path === from?.path) { return false } return shouldUseSiteRouteVeil(to?.path) || shouldUseSiteRouteVeil(from?.path) } /** * 문서 스크롤을 최상단으로 이동한다. * @returns {void} */ export const scrollDocumentToTop = () => { if (!import.meta.client) { return } window.scrollTo(0, 0) document.documentElement.scrollTop = 0 document.body.scrollTop = 0 } /** * 문서 스크롤을 지정 좌표로 이동한다. * @param {{ top?: number, left?: number }} position - 복원 좌표 * @returns {void} */ export const scrollDocumentTo = (position) => { if (!import.meta.client) { return } const top = Number(position?.top || 0) const left = Number(position?.left || 0) window.scrollTo(left, top) document.documentElement.scrollTop = top document.body.scrollTop = top }