UNPKG

scrivito

Version:

Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.

143 lines (119 loc) 3.49 kB
// @rewire import { Action, History as HistoryV4, UnregisterCallback, createBrowserHistory, } from 'history'; import type { History as HistoryV5 } from 'history-5'; import * as URI from 'urijs'; import { ArgumentError, docUrl, onReset } from 'scrivito_sdk/common'; import { createStateContainer } from 'scrivito_sdk/state'; export interface HistoryState { historyChangesCount: number; location: string; isRevisit: boolean; } let history: HistoryV4 | HistoryV5 | undefined; let unlistenToHistory: UnregisterCallback | undefined; let lastAction: undefined | Action; /** @public */ export function useHistory(historyToUse: HistoryV4): void; /** @internal */ export function useHistory(historyToUse: HistoryV4 | HistoryV5): void; /** @internal */ export function useHistory(historyToUse: HistoryV4 | HistoryV5): void { if (historyToUse.createHref({ pathname: '/' }) !== '/') { throw new ArgumentError( 'Expected a history without a preconfigured basename.' + ` For further details, see: ${docUrl('js-sdk/useHistory')}` ); } if (historyToUse === history) { return; } const isFirstHistory = !history; listenToHistory(historyToUse); history = historyToUse; if (!isFirstHistory) { historyHasChanged(); } } export function getHistoryState(): HistoryState { return { historyChangesCount: getHistoryChangesCount(), location: get(), isRevisit: lastAction === 'POP', }; } export function get(): string { const location = getHistory().location; return `${location.pathname}${location.search}${location.hash}`; } export function getHistoryChangesCount(): number { return historyChangesCountState.get() || 0; } export function push(resource: string): void { const uri = new URI(resource); getHistory().push({ pathname: uri.pathname(), search: uri.search(), hash: uri.hash(), }); } export function replace(resource: string): void { const uri = new URI(resource); getHistory().replace({ pathname: uri.pathname(), search: uri.search(), hash: uri.hash(), }); } export function isCurrentHistoryState(historyState: HistoryState): boolean { return historyState.historyChangesCount === getHistoryChangesCount(); } // For test purpose only. export function reset(): void { history = undefined; lastAction = undefined; unlistenToHistory = undefined; historyChangesCountState.clear(); } // export for test purpose only export function createInitialHistory(): HistoryV4 | HistoryV5 { return createBrowserHistory(); } function ensureHistory(): void { if (!history) { useHistory(createInitialHistory()); } } function getHistory(): HistoryV4 | HistoryV5 { ensureHistory(); return history!; } function listenToHistory(historyToListen: HistoryV4 | HistoryV5): void { if (unlistenToHistory) { unlistenToHistory(); } if (isHistoryV4(historyToListen)) { unlistenToHistory = historyToListen.listen((_location, action) => { historyHasChanged(action); }); } else { unlistenToHistory = historyToListen.listen(({ action }) => { historyHasChanged(action); }); } } function historyHasChanged(action?: Action) { lastAction = action; historyChangesCountState.set(getHistoryChangesCount() + 1); } const historyChangesCountState = createStateContainer<number>(); function isHistoryV4( historyToCheck: HistoryV4 | HistoryV5 ): historyToCheck is HistoryV4 { return historyToCheck.hasOwnProperty('length'); } onReset(reset);