{ let active = false; let hasHistoryEntry = false; let releasingHistoryEntry = false; let returningToSentinel = false; function pushGuardEntries() { // Помечаем и текущую запись Tour, и sentinel сверху. Иначе первый Back // останавливался на немаркированной записи, а второй мог уйти в about:blank. window.history.replaceState({ publicOperationGuard: true }, '', window.location.href); window.history.pushState({ publicOperationGuard: true }, '', window.location.href); hasHistoryEntry = true; } function onPopState(event) { if (releasingHistoryEntry) { releasingHistoryEntry = false; return; } if (active) { if (returningToSentinel) { returningToSentinel = false; return; } returningToSentinel = true; window.history.go(1); } } function deactivate(onReleased) { if (!active) { if (onReleased) { if (releasingHistoryEntry) { window.addEventListener('popstate', onReleased, { once: true }); } else { onReleased(); } } return; } active = false; if (hasHistoryEntry) { hasHistoryEntry = false; releasingHistoryEntry = true; if (onReleased) window.addEventListener('popstate', onReleased, { once: true }); window.history.back(); return; } if (onReleased) onReleased(); } window.addEventListener('popstate', onPopState); window.PublicNavigationGuard = { activate() { if (active) return; releasingHistoryEntry = false; returningToSentinel = false; active = true; pushGuardEntries(); }, deactivate, allowNavigation: deactivate, }; })(); JS;