diff --git a/assets/css/frontend/remote-modal.css b/assets/css/frontend/remote-modal.css index 6783d12c..92a2fdd2 100644 --- a/assets/css/frontend/remote-modal.css +++ b/assets/css/frontend/remote-modal.css @@ -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; } diff --git a/assets/js/aksrt-runtime.js b/assets/js/aksrt-runtime.js index 0360c8b7..349575ba 100644 --- a/assets/js/aksrt-runtime.js +++ b/assets/js/aksrt-runtime.js @@ -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 = - '
' + - '
' + - '
' + - '

' + - '' + - '
' + - '
' + - '
'; - 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 = '

' + escapeHtml(err.message) + '

'; - 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 = '

' + escapeHtml(json.data && json.data.message || '') + '

'; - } - if (window.AksrtFrontend) AksrtFrontend.rehydrate(body, 'modal'); - return modal; - }) - .catch(function (err) { - aksrt.loading(body, false); - body.innerHTML = '

' + escapeHtml(err.message) + '

'; - return modal; - }); + body: params.toString(), + })); } - aksrt.loading(body, false); - return Promise.resolve(modal); + return Promise.resolve(runtime.open(base)); }; aksrt.refreshModal.close = closeRefreshModal; diff --git a/assets/js/core/modal-runtime.js b/assets/js/core/modal-runtime.js index d4d417e3..c5150ccd 100644 --- a/assets/js/core/modal-runtime.js +++ b/assets/js/core/modal-runtime.js @@ -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 + ? '

' + escapeHtml(options.title) + '

' + : ""; 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 = '
' + '
' + + titleHtml + '
' + initialHtml + "
"; var session = {