--- master.js 2026-10-22 23:09:01.035110051 +0000 +++ patched.js 2026-10-22 23:09:17.622678051 +0000 @@ -30,7 +30,7 @@ }; $.modal = function(el, options) { - var remove, target; + var remove, target, self = this; this.$body = $('body'); this.options = $.extend({}, $.modal.defaults, options); this.options.doFade = !isNaN(parseInt(this.options.fadeDuration, 10)); @@ -56,7 +56,8 @@ this.showSpinner(); el.trigger($.modal.AJAX_SEND); $.get(target).done(function(html) { - if (!$.modal.isActive()) return; + if (self.aborted) { self.$elm.remove(); return; } + if (!$.modal.isActive()) { self.$elm.remove(); return; } el.trigger($.modal.AJAX_SUCCESS); var current = getCurrent(); current.$elm.empty().append(html).on($.modal.CLOSE, remove); @@ -66,8 +67,11 @@ }).fail(function() { el.trigger($.modal.AJAX_FAIL); var current = getCurrent(); - current.hideSpinner(); - modals.pop(); // remove expected modal from the list + if (current === self) { + current.hideSpinner(); + current.$elm.remove(); + modals.pop(); // remove expected modal from the list + } el.trigger($.modal.AJAX_COMPLETE); }); } @@ -106,6 +110,15 @@ close: function() { modals.pop(); + if (!this.$blocker) { + // Never opened (closed while the AJAX request was still in flight). + this.aborted = true; + this.hideSpinner(); + this.$elm.remove(); + if (!$.modal.isActive()) + $(document).off('keydown.modal'); + return; + } this.unblock(); this.hide(); if (!$.modal.isActive()) @@ -124,6 +137,7 @@ }, unblock: function(now) { + if (!this.$blocker) return; if (!now && this.options.doFade) this.$blocker.fadeOut(this.options.fadeDuration, this.unblock.bind(this,true)); else {