71 lines
1.8 KiB
PHP
71 lines
1.8 KiB
PHP
<?php
|
|
// Общий inline-контракт Back для незавершённой публичной операции (api#299/preland#9).
|
|
return <<<'JS'
|
|
(() => {
|
|
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;
|