Fix sub-modal (ingredient) closing parent modal (recipe editor)

Problem: ingredient modal's closeModal called history.back(), which
triggered recipe editor's popHandler → closed recipe editor too.

Fix: modal suspend/resume system.
- When sub-modal opens, parent modal's popHandler is suspended
- When sub-modal closes, parent is resumed
- Parent popHandler ignores popstate events while suspended
- closeModal resumes parent before calling history.back()

Also: closeModal now pops exactly 1 history entry (not _historyDepth).
The _historyDepth counter tracks fullscreen entries within the modal,
which are handled by popHandler's decrements. closeModal only needs
to pop the modal's own base entry.
This commit is contained in:
4aiman 2026-05-27 22:55:43 +03:00
commit f395e8ec07

View file

@ -806,15 +806,21 @@ function showModal(html, onSubmit) {
<button id="modal-ok" class="btn-primary">Сохранить</button>
</div>
</div>`;
// Suspend parent modal if sub-modal opening on top
const parentOverlay = document.querySelector(".modal-overlay");
if (parentOverlay && parentOverlay._suspend) parentOverlay._suspend();
document.body.appendChild(overlay);
// Simple history stack: each open = pushState, each back = popState pops it.
// Modal = 1 entry. Fullscreen map/chart inside modal = 1 more entry each.
// Back always pops the top entry. No re-pushing, no flags.
let _historyDepth = 1; // how many entries this modal owns
let _suspended = false; // true when sub-modal is open on top
history.pushState({ modal: true }, "");
const popHandler = () => {
if (_suspended) return; // sub-modal handles this popstate
_historyDepth--;
// Check what's on top and collapse it
@ -855,13 +861,19 @@ function showModal(html, onSubmit) {
history.pushState({ modalFs: true }, "");
};
// Suspend/resume this modal's popHandler when a sub-modal opens on top
overlay._suspend = function() { _suspended = true; };
overlay._resume = function() { _suspended = false; };
function closeModal() {
window.removeEventListener("popstate", popHandler);
overlay.remove();
// Pop all entries this modal owns
if (_historyDepth > 0) {
for (let i = 0; i < _historyDepth; i++) history.back();
}
// Resume parent modal if this was a sub-modal
const parent = document.querySelector(".modal-overlay");
if (parent && parent._resume) parent._resume();
// Pop this modal's history entry
_modalPopHandled = true;
history.back();
}
overlay.querySelector("#modal-back").onclick = () => closeModal();