diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml
index 12a4b11f..63d7fe71 100644
--- a/.mokogitea/workflows/issue-branch.yml
+++ b/.mokogitea/workflows/issue-branch.yml
@@ -4,8 +4,8 @@
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
-# INGROUP: MokoCLI.Automation
-# VERSION: 01.00.00
+# INGROUP: mokocli.Automation
+# VERSION: 02.63.11
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
diff --git a/SECURITY.md b/SECURITY.md
index 02864e8f..a4aa3c27 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla
INGROUP: Template-Joomla.Documentation
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
PATH: /SECURITY.md
-VERSION: 02.63.00
+VERSION: 02.63.11
BRIEF: Security vulnerability reporting and handling policy
-->
diff --git a/source/packages/MokoSuiteClient b/source/packages/MokoSuiteClient
index 81b2453e..050b05d6 160000
--- a/source/packages/MokoSuiteClient
+++ b/source/packages/MokoSuiteClient
@@ -1 +1 @@
-Subproject commit 81b2453e758754ac63e439d61b05f23f4783afea
+Subproject commit 050b05d6efae146a7dc002d434a90cfaf7ba827d
diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini
index 4d4bb101..fa663c7f 100644
--- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini
+++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini
@@ -350,6 +350,13 @@ COM_MOKOJOOMBACKUP_RUNBACKUP_BACK_TO_DASHBOARD="Back to dashboard"
COM_MOKOJOOMBACKUP_RUNBACKUP_VIEW_RECORD="View backup record"
COM_MOKOJOOMBACKUP_RUNBACKUP_LEAVE_WARNING="A backup is in progress. Leaving now will cancel it."
COM_MOKOJOOMBACKUP_RUNBACKUP_AUTOCONTINUE="Automatically continue the update when the backup finishes"
+COM_MOKOJOOMBACKUP_RUNBACKUP_DONT_CLOSE="Please do not close this window or switch to another window until the backup finishes."
+COM_MOKOJOOMBACKUP_RUNBACKUP_UPDATE_RUNNING="Backup complete. The update is now running — please wait and do not close this window…"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL="Cancel backup"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM1="Cancel the backup that is in progress?"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM2="Are you sure? The backup will be stopped and the update will NOT continue."
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCELLING="Cancelling…"
+COM_MOKOJOOMBACKUP_RUNBACKUP_FAILED_NO_UPDATE="Backup failed — the update was not started. Retry the backup, or go back without updating."
COM_MOKOJOOMBACKUP_RUNBACKUP_CONTINUE_UPDATE="Continue the update"
COM_MOKOJOOMBACKUP_CONFIG_CLEANUP="Cleanup Defaults"
diff --git a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini
index 7f32636b..61f2219d 100644
--- a/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini
+++ b/source/packages/com_mokosuitebackup/language/en-US/com_mokosuitebackup.ini
@@ -72,6 +72,13 @@ COM_MOKOJOOMBACKUP_RUNBACKUP_BACK_TO_DASHBOARD="Back to dashboard"
COM_MOKOJOOMBACKUP_RUNBACKUP_VIEW_RECORD="View backup record"
COM_MOKOJOOMBACKUP_RUNBACKUP_LEAVE_WARNING="A backup is in progress. Leaving now will cancel it."
COM_MOKOJOOMBACKUP_RUNBACKUP_AUTOCONTINUE="Automatically continue the update when the backup finishes"
+COM_MOKOJOOMBACKUP_RUNBACKUP_DONT_CLOSE="Please do not close this window or switch to another window until the backup finishes."
+COM_MOKOJOOMBACKUP_RUNBACKUP_UPDATE_RUNNING="Backup complete. The update is now running — please wait and do not close this window…"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL="Cancel backup"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM1="Cancel the backup that is in progress?"
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM2="Are you sure? The backup will be stopped and the update will NOT continue."
+COM_MOKOJOOMBACKUP_RUNBACKUP_CANCELLING="Cancelling…"
+COM_MOKOJOOMBACKUP_RUNBACKUP_FAILED_NO_UPDATE="Backup failed — the update was not started. Retry the backup, or go back without updating."
COM_MOKOJOOMBACKUP_RUNBACKUP_CONTINUE_UPDATE="Continue the update"
COM_MOKOJOOMBACKUP_CONFIG_CLEANUP="Cleanup Defaults"
diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml
index 3810b08e..ba5cb28b 100644
--- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml
@@ -17,7 +17,7 @@
display label there.
-->
MokoSuiteBackup
- 02.63.00
+ 02.63.112026-06-02Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.04.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.04.sql
new file mode 100644
index 00000000..0a0a0e65
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.04.sql
@@ -0,0 +1 @@
+/* 02.62.04 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.05.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.05.sql
new file mode 100644
index 00000000..539344ce
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.62.05.sql
@@ -0,0 +1 @@
+/* 02.62.05 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.01.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.01.sql
new file mode 100644
index 00000000..6dafb481
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.01.sql
@@ -0,0 +1 @@
+/* 02.63.01 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.02.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.02.sql
new file mode 100644
index 00000000..e65aa85e
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.02.sql
@@ -0,0 +1 @@
+/* 02.63.02 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.05.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.05.sql
new file mode 100644
index 00000000..bc575e1c
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.05.sql
@@ -0,0 +1 @@
+/* 02.63.05 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.06.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.06.sql
new file mode 100644
index 00000000..7bee5460
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.06.sql
@@ -0,0 +1 @@
+/* 02.63.06 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.07.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.07.sql
new file mode 100644
index 00000000..7d7e154f
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.07.sql
@@ -0,0 +1 @@
+/* 02.63.07 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.09.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.09.sql
new file mode 100644
index 00000000..788cbe28
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.09.sql
@@ -0,0 +1 @@
+/* 02.63.09 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.10.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.10.sql
new file mode 100644
index 00000000..39025eb1
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.10.sql
@@ -0,0 +1 @@
+/* 02.63.10 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.11.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.11.sql
new file mode 100644
index 00000000..a03acbd5
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/02.63.11.sql
@@ -0,0 +1 @@
+/* 02.63.11 — no schema changes */
diff --git a/source/packages/com_mokosuitebackup/tmpl/runbackup/default.php b/source/packages/com_mokosuitebackup/tmpl/runbackup/default.php
index 6b2f0a3d..7fb1e458 100644
--- a/source/packages/com_mokosuitebackup/tmpl/runbackup/default.php
+++ b/source/packages/com_mokosuitebackup/tmpl/runbackup/default.php
@@ -87,6 +87,10 @@ $config = [
'viewRecord' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_VIEW_RECORD'),
'leaveWarn' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_LEAVE_WARNING'),
'continueUpdate' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_CONTINUE_UPDATE'),
+ 'cancelConfirm1' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM1'),
+ 'cancelConfirm2' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_CANCEL_CONFIRM2'),
+ 'cancelling' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_CANCELLING'),
+ 'failedNoUpdate' => Text::_('COM_MOKOJOOMBACKUP_RUNBACKUP_FAILED_NO_UPDATE'),
],
];
@@ -120,6 +124,11 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
@@ -152,6 +168,7 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
var CFG = ;
var L = CFG.labels || {};
var running = false;
+ var cancelled = false;
var lastRecordId = 0;
var el = {
@@ -159,6 +176,7 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
track: document.querySelector('.msb-rb-progress'),
phase: document.getElementById('msb-rb-phase'),
status: document.getElementById('msb-rb-status'),
+ warn: document.getElementById('msb-rb-warn'),
title: document.getElementById('msb-rb-title'),
actions: document.getElementById('msb-rb-actions'),
retry: document.getElementById('msb-rb-retry'),
@@ -166,9 +184,38 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
continue: document.getElementById('msb-rb-continue'),
dashboard: document.getElementById('msb-rb-dashboard'),
autocontinue: document.getElementById('msb-rb-autocontinue'),
- autocontinueWrap: document.getElementById('msb-rb-autocontinue-wrap')
+ autocontinueWrap: document.getElementById('msb-rb-autocontinue-wrap'),
+ cancel: document.getElementById('msb-rb-cancel'),
+ cancelWrap: document.getElementById('msb-rb-cancel-wrap')
};
+ function hideCancel() { if (el.cancelWrap) { el.cancelWrap.classList.add('d-none'); } }
+
+ /* Cancel the running backup — requires DOUBLE confirmation. Stops the step
+ loop, tells the server to cancel the record, and leaves to the dashboard
+ WITHOUT continuing any pending update. */
+ if (el.cancel) {
+ el.cancel.addEventListener('click', function () {
+ if (!running || cancelled) { return; }
+ if (!window.confirm(L.cancelConfirm1 || 'Cancel the backup that is in progress?')) { return; }
+ if (!window.confirm(L.cancelConfirm2 || 'Are you sure? The backup will be stopped and the update will NOT continue.')) { return; }
+
+ cancelled = true;
+ running = false; /* also disarms the leave-warning */
+ el.cancel.disabled = true;
+ if (el.warn) { el.warn.classList.add('d-none'); }
+ setStatus(L.cancelling || 'Cancelling…');
+
+ var go = function () { window.location.href = CFG.dashboardUrl; };
+ /* Best-effort server-side cancel of the record, then leave. */
+ if (lastRecordId > 0) {
+ post({ task: 'ajax.cancelBackup', id: lastRecordId }).then(go, go);
+ } else {
+ go();
+ }
+ });
+ }
+
function setBar(pct, striped) {
pct = Math.max(0, Math.min(100, parseInt(pct, 10) || 0));
el.bar.style.width = pct + '%';
@@ -204,6 +251,8 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
el.bar.classList.add('is-success');
setBar(100, false);
el.title.textContent = L.complete || 'Backup complete';
+ if (el.warn) { el.warn.classList.add('d-none'); }
+ hideCancel();
/* Set the one-shot skip flag for THIS action so the following
server-side onExtensionBefore(Update|Uninstall) backup is skipped once
@@ -254,30 +303,34 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
running = false;
el.bar.classList.remove('is-animated');
el.bar.classList.add('is-danger');
+ if (el.warn) { el.warn.classList.add('d-none'); }
el.title.textContent = L.failed || 'Backup failed';
- setStatus(message || 'Backup failed');
+ /* Pre-update/uninstall flow: the backup failed, so the update must NOT
+ run. We deliberately do NOT offer a "continue without backup" option
+ here — the only ways forward are to retry the backup or go back. */
+ setStatus(CFG.returnUrl ? (L.failedNoUpdate || 'Backup failed — the update was not started. Retry the backup, or go back without updating.') : (message || 'Backup failed'));
+ hideCancel();
showActions();
el.retry.textContent = L.retry || 'Retry';
el.retry.classList.remove('d-none');
el.retry.onclick = function () {
el.retry.classList.add('d-none');
- el.continue.classList.add('d-none');
el.bar.classList.remove('is-danger');
el.bar.classList.add('is-animated');
run();
};
- if (CFG.returnUrl) {
- showBtn(el.continue, L.continue || 'Continue without backup', CFG.returnUrl);
- }
showBtn(el.dashboard, L.dashboard || 'Back to dashboard', CFG.dashboardUrl);
}
async function run() {
if (running) { return; }
running = true;
+ cancelled = false;
el.actions.classList.add('d-none');
+ if (el.cancelWrap) { el.cancelWrap.classList.remove('d-none'); }
+ if (el.cancel) { el.cancel.disabled = false; }
setBar(0, true);
setPhase('');
setStatus(L.starting || 'Starting backup…');
@@ -295,7 +348,7 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
if (init.record_id) { lastRecordId = init.record_id; }
var done = false;
- while (!done) {
+ while (!done && !cancelled) {
var step = await post({ task: 'ajax.step', session_id: init.session_id });
if (!step || step.error) {
@@ -309,16 +362,27 @@ $this->getDocument()->addStyleSheet(Uri::root(true) . '/media/com_mokosuitebacku
done = step.done || false;
}
+ /* User cancelled mid-flight — the click handler already stops the
+ loop and navigates away, so do not fall through to completion. */
+ if (cancelled) { return; }
+
running = false;
await onComplete();
} catch (err) {
+ if (cancelled) { return; }
onError(err && err.message ? err.message : String(err));
}
}
- /* Warn before leaving while a backup is mid-flight. */
+ /* Warn before closing/leaving the window while a backup is mid-flight.
+ Return the message too — some browsers need it, others show a generic
+ prompt, but any non-empty value triggers the confirmation dialog. */
window.addEventListener('beforeunload', function (e) {
- if (running) { e.preventDefault(); e.returnValue = L.leaveWarn || ''; }
+ if (!running) { return undefined; }
+ var msg = L.leaveWarn || 'A backup is in progress. Leaving now will cancel it.';
+ e.preventDefault();
+ e.returnValue = msg;
+ return msg;
});
if (CFG.autostart) {
diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml
index 635e02ce..280471a7 100644
--- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml
+++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml
@@ -8,7 +8,7 @@
-->
Module - MokoSuiteBackup - cPanel
- 02.63.00
+ 02.63.112026-06-23Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
index 37f84e85..db6cd99e 100644
--- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Action Log - MokoSuiteBackup
- 02.63.00
+ 02.63.112026-06-04Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
index 84bba0bb..9486c862 100644
--- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Console - MokoSuiteBackup
- 02.63.00
+ 02.63.112026-06-04Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
index 846f70b7..228a6777 100644
--- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Content - MokoSuiteBackup
- 02.63.00
+ 02.63.112026-06-04Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
index 16e56133..9b41d94d 100644
--- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
@@ -1,7 +1,7 @@
Quick Icon - MokoSuiteBackup
- 02.63.00
+ 02.63.112026-06-02Moko Consultinghello@mokoconsulting.tech
diff --git a/source/packages/plg_system_mokosuitebackup/language/en-GB/plg_system_mokosuitebackup.ini b/source/packages/plg_system_mokosuitebackup/language/en-GB/plg_system_mokosuitebackup.ini
index a465eb30..7cc78952 100644
--- a/source/packages/plg_system_mokosuitebackup/language/en-GB/plg_system_mokosuitebackup.ini
+++ b/source/packages/plg_system_mokosuitebackup/language/en-GB/plg_system_mokosuitebackup.ini
@@ -14,3 +14,4 @@ PLG_SYSTEM_MOKOJOOMBACKUP_BACKING_UP="Backing up…"
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_COMPLETE="Backup complete — safe to update."
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_FAILED="Backup failed"
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_STARTING="Starting backup…"
+PLG_SYSTEM_MOKOSUITEBACKUP_UPDATE_RUNNING="Backup complete. The update is now running — please wait and do not close this window…"
diff --git a/source/packages/plg_system_mokosuitebackup/language/en-US/plg_system_mokosuitebackup.ini b/source/packages/plg_system_mokosuitebackup/language/en-US/plg_system_mokosuitebackup.ini
index 03a35287..12552aea 100644
--- a/source/packages/plg_system_mokosuitebackup/language/en-US/plg_system_mokosuitebackup.ini
+++ b/source/packages/plg_system_mokosuitebackup/language/en-US/plg_system_mokosuitebackup.ini
@@ -14,3 +14,4 @@ PLG_SYSTEM_MOKOJOOMBACKUP_BACKING_UP="Backing up…"
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_COMPLETE="Backup complete — safe to update."
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_FAILED="Backup failed"
PLG_SYSTEM_MOKOJOOMBACKUP_BACKUP_STARTING="Starting backup…"
+PLG_SYSTEM_MOKOSUITEBACKUP_UPDATE_RUNNING="Backup complete. The update is now running — please wait and do not close this window…"
diff --git a/source/packages/plg_system_mokosuitebackup/media/js/installer-backup.js b/source/packages/plg_system_mokosuitebackup/media/js/installer-backup.js
index e3f5ac4a..ea20bef0 100644
--- a/source/packages/plg_system_mokosuitebackup/media/js/installer-backup.js
+++ b/source/packages/plg_system_mokosuitebackup/media/js/installer-backup.js
@@ -101,6 +101,31 @@
window.location.href = target;
}, true);
+ /* Full-screen "update is running" overlay shown while the re-fired update
+ POST processes, so the user knows it is working and not to close/switch. */
+ function showUpdateOverlay() {
+ if (document.getElementById('msb-update-overlay')) { return; }
+
+ var o = document.createElement('div');
+ o.id = 'msb-update-overlay';
+ o.setAttribute('role', 'status');
+ o.style.cssText = 'position:fixed;inset:0;z-index:2147483647;background:#000;color:#fff;'
+ + 'display:flex;flex-direction:column;align-items:center;justify-content:center;'
+ + 'text-align:center;padding:2rem;font-size:1.15rem;font-weight:600;';
+
+ var spin = document.createElement('span');
+ spin.className = 'spinner-border mb-3';
+ spin.setAttribute('aria-hidden', 'true');
+
+ var msg = document.createElement('div');
+ msg.textContent = (cfg && cfg.updateRunningText)
+ || 'Backup complete. The update is now running — please wait and do not close this window…';
+
+ o.appendChild(spin);
+ o.appendChild(msg);
+ document.body.appendChild(o);
+ }
+
/* On return from the backup screen: restore the selection and re-fire. */
function resume() {
var params = new URLSearchParams(window.location.search);
@@ -131,20 +156,40 @@
if (box) { box.checked = true; }
});
- /* Joomla's list-check reads boxchecked — set it so the re-fire passes. */
+ /* Restore boxchecked AND fire its `change` event. Joomla's toolbar web
+ component (joomla-toolbar-button) keeps a list-selection button
+ DISABLED until boxchecked changes via a change event — setting the
+ value alone leaves the button disabled, so executeTask() would no-op
+ and the update never submits (it just returns to the list). */
var bc = form.querySelector('input[name="boxchecked"]');
- if (bc) { bc.value = (data.cids || []).length; }
+ if (bc) {
+ bc.value = (data.cids || []).length;
+ bc.dispatchEvent(new Event('change', { bubbles: true }));
+ }
}
window.__msbResuming = true;
- var btn = document.querySelector('[task="' + data.task + '"]');
+ /* Show a full-screen "update is running" overlay so the user gets clear
+ feedback that the update is proceeding while the re-fired POST runs.
+ It persists until the page navigates away (the update finishes and
+ redirects), matching the black full-screen backup screen. */
+ showUpdateOverlay();
- if (btn) {
- window.setTimeout(function () { btn.click(); }, 300);
- } else if (window.Joomla && typeof Joomla.submitbutton === 'function') {
- Joomla.submitbutton(data.task);
- }
+ /* Re-fire the toolbar action. The `task` attribute is on the OUTER
+ , but its click handler is bound to the INNER
+