fix(modal): route refresh modal through runtime

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 23:28:13 +08:00
co-authored by Claude Fable 5
parent d79b063bf9
commit bdfe3a461d
3 changed files with 53 additions and 93 deletions
+14
View File
@@ -71,6 +71,20 @@ body.aksrt-remote-modal-open {
transform: translateY(0);
}
.aksrt-remote-modal__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 16px 18px 0;
}
.aksrt-remote-modal__title {
margin: 0;
font-size: 17px;
line-height: 1.35;
}
.aksrt-remote-modal__content {
padding: 18px 18px 16px;
}
+33 -93
View File
@@ -317,120 +317,60 @@
// §10.10 — refreshModal: remote content modal
// ══════════════════════════════════════════════════════════════
var _refreshModalEl = null;
function getRefreshModalEl() {
if (_refreshModalEl && _refreshModalEl.parentNode) return _refreshModalEl;
_refreshModalEl = document.createElement('div');
_refreshModalEl.className = 'aksrt-refresh-modal';
_refreshModalEl.innerHTML =
'<div class="aksrt-refresh-modal__overlay"></div>' +
'<div class="aksrt-refresh-modal__dialog">' +
'<div class="aksrt-refresh-modal__header">' +
'<h3 class="aksrt-refresh-modal__title"></h3>' +
'<button type="button" class="aksrt-refresh-modal__close">&times;</button>' +
'</div>' +
'<div class="aksrt-refresh-modal__body"></div>' +
'</div>';
document.body.appendChild(_refreshModalEl);
_refreshModalEl.querySelector('.aksrt-refresh-modal__close').addEventListener('click', closeRefreshModal);
_refreshModalEl.querySelector('.aksrt-refresh-modal__overlay').addEventListener('click', function (e) {
if (e.target === e.currentTarget) closeRefreshModal();
});
return _refreshModalEl;
}
function closeRefreshModal() {
if (!_refreshModalEl) return;
_refreshModalEl.classList.remove('is-open', 'from-bottom');
document.body.classList.remove('modal-open');
setTimeout(function () {
var body = _refreshModalEl.querySelector('.aksrt-refresh-modal__body');
if (body) body.innerHTML = '';
}, 300);
if (window.AksrtModalRuntime && typeof window.AksrtModalRuntime.close === 'function') {
window.AksrtModalRuntime.close('refresh-modal');
}
}
aksrt.refreshModal = function (opts) {
opts = opts || {};
var modal = getRefreshModalEl();
var body = modal.querySelector('.aksrt-refresh-modal__body');
var title = modal.querySelector('.aksrt-refresh-modal__title');
var runtime = window.AksrtModalRuntime;
if (!runtime || typeof runtime.open !== 'function' || typeof runtime.openRemote !== 'function') {
return Promise.reject(new Error('modal runtime unavailable'));
}
if (opts.title) title.textContent = opts.title;
else title.textContent = '';
var base = {
title: opts.title || '',
className: opts.class || '',
bottom: opts.mobile_from_bottom === true,
mobileBottom: opts.mobile_from_bottom === true,
cache: opts.cache !== false,
cacheTtl: opts.cacheTtl || 15000,
cacheTags: opts.cacheTags || opts.tags || [],
kind: opts.kind || 'generic',
};
var isMobile = window.innerWidth < 768;
modal.classList.toggle('from-bottom', !!(opts.mobile_from_bottom && isMobile));
if (opts.class) modal.querySelector('.aksrt-refresh-modal__dialog').className = 'aksrt-refresh-modal__dialog ' + opts.class;
body.innerHTML = '';
aksrt.loading(body, true);
modal.classList.add('is-open');
document.body.classList.add('modal-open');
if (opts.content) {
aksrt.loading(body, false);
body.innerHTML = opts.content;
if (window.AksrtFrontend) AksrtFrontend.rehydrate(body, 'modal');
return Promise.resolve(modal);
if (opts.content !== undefined) {
return Promise.resolve(runtime.open(Object.assign({}, base, { html: opts.content })))
.catch(function () { return null; });
}
if (opts.remote) {
return fetch(opts.remote, { credentials: 'same-origin' })
.then(function (r) { return r.text(); })
.then(function (html) {
aksrt.loading(body, false);
body.innerHTML = html;
if (window.AksrtFrontend) AksrtFrontend.rehydrate(body, 'modal');
return modal;
})
.catch(function (err) {
aksrt.loading(body, false);
body.innerHTML = '<p class="aksrt-refresh-modal__error">' + escapeHtml(err.message) + '</p>';
return modal;
});
return runtime.openRemote(Object.assign({}, base, {
url: opts.remote,
method: opts.method || 'GET',
}));
}
if (opts.action) {
var ajaxUrl = (window.aksrtData && aksrtData.ajaxUrl) || '/wp-admin/admin-ajax.php';
var ajaxUrl = (window.aksrtData && window.aksrtData.ajaxUrl) || '/wp-admin/admin-ajax.php';
var params = new URLSearchParams();
params.set('action', opts.action);
if (window.aksrtData && aksrtData.nonce) params.set('nonce', aksrtData.nonce);
if (window.aksrtData && window.aksrtData.nonce) params.set('nonce', window.aksrtData.nonce);
if (opts.data) {
Object.keys(opts.data).forEach(function (k) { params.set(k, opts.data[k]); });
Object.keys(opts.data).forEach(function (key) { params.set(key, opts.data[key]); });
}
return fetch(ajaxUrl, {
return runtime.openRemote(Object.assign({}, base, {
url: ajaxUrl,
method: 'POST',
cache: false,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
credentials: 'same-origin',
body: params.toString()
})
.then(function (r) { return r.json(); })
.then(function (json) {
aksrt.loading(body, false);
if (json && json.data && json.data.html) {
body.innerHTML = json.data.html;
} else if (json && json.data && json.data.show_modal) {
body.innerHTML = json.data.show_modal;
} else {
body.innerHTML = '<p>' + escapeHtml(json.data && json.data.message || '') + '</p>';
}
if (window.AksrtFrontend) AksrtFrontend.rehydrate(body, 'modal');
return modal;
})
.catch(function (err) {
aksrt.loading(body, false);
body.innerHTML = '<p class="aksrt-refresh-modal__error">' + escapeHtml(err.message) + '</p>';
return modal;
});
body: params.toString(),
}));
}
aksrt.loading(body, false);
return Promise.resolve(modal);
return Promise.resolve(runtime.open(base));
};
aksrt.refreshModal.close = closeRefreshModal;
+6
View File
@@ -136,6 +136,10 @@
var bottom = options.bottom === true || (options.mobileBottom !== false && isMobile());
var heightStyle = options.height ? "min-height:" + parseInt(options.height, 10) + "px;" : "";
var initialHtml = options.html !== undefined ? options.html : skeleton(options);
var titleId = "aksrt-modal-title-" + String(sequence + 1);
var titleHtml = options.title
? '<header class="aksrt-remote-modal__header"><h3 class="aksrt-remote-modal__title" id="' + titleId + '">' + escapeHtml(options.title) + '</h3><button type="button" class="aksrt-remote-modal__close" data-aksrt-modal-close aria-label="关闭">&times;</button></header>'
: "";
shell.className =
"aksrt-remote-modal" +
@@ -143,10 +147,12 @@
(options.className ? " " + options.className : "");
shell.setAttribute("role", "dialog");
shell.setAttribute("aria-modal", "true");
if (options.title) shell.setAttribute("aria-labelledby", titleId);
shell.setAttribute("tabindex", "-1");
shell.innerHTML =
'<div class="aksrt-remote-modal__overlay" data-aksrt-remote-modal-close></div>' +
'<div class="aksrt-remote-modal__dialog" style="' + heightStyle + '">' +
titleHtml +
'<div class="aksrt-remote-modal__content">' + initialHtml + "</div></div>";
var session = {