75 lines
3.3 KiB
PHP
75 lines
3.3 KiB
PHP
@once
|
|
@push('scripts_start')
|
|
<script>
|
|
(() => {
|
|
if (window.caiwuSettingsNavigation) return;
|
|
window.caiwuSettingsNavigation = true;
|
|
let pending;
|
|
const supports = url => url.origin === location.origin
|
|
&& /\/system-settings\/(?:(?:users|groups)(?:\/create|\/\d+\/edit)?|users\/\d+\/groups|permissions|sidebar)$/.test(url.pathname);
|
|
async function navigate(url, push = true) {
|
|
const current = document.querySelector('[data-settings-workspace]');
|
|
if (!current) return;
|
|
pending?.abort();
|
|
const controller = new AbortController();
|
|
pending = controller;
|
|
current.setAttribute('aria-busy', 'true');
|
|
try {
|
|
const response = await fetch(url, {signal:controller.signal, credentials:'same-origin'});
|
|
const page = new DOMParser().parseFromString(await response.text(), 'text/html');
|
|
const next = page.querySelector('[data-settings-workspace]');
|
|
const header = page.querySelector('#header');
|
|
if (!response.ok || !next || !header) throw new Error('unavailable');
|
|
current.replaceWith(next);
|
|
document.querySelector('#header')?.replaceWith(header);
|
|
document.title = page.title;
|
|
document.querySelectorAll('#menu-settings a[id]').forEach(link => {
|
|
const updated = page.getElementById(link.id);
|
|
if (updated) link.className = updated.className;
|
|
});
|
|
if (push) {
|
|
history.replaceState({...history.state, settingsPage:true}, '', location.href);
|
|
history.pushState({settingsPage:true}, '', url);
|
|
}
|
|
const title = header.querySelector('h1');
|
|
title?.setAttribute('tabindex', '-1');
|
|
title?.focus({preventScroll:true});
|
|
window.scrollTo(0, 0);
|
|
} catch (error) {
|
|
if (error.name === 'AbortError') return;
|
|
let alert = current.querySelector('[data-settings-navigation-error]');
|
|
if (!alert) {
|
|
alert = document.createElement('p');
|
|
alert.dataset.settingsNavigationError = '';
|
|
alert.setAttribute('role', 'alert');
|
|
alert.className = 'mb-4 text-sm text-red-700';
|
|
current.prepend(alert);
|
|
}
|
|
alert.textContent = '页面暂时无法加载,请重试。';
|
|
} finally {
|
|
current.removeAttribute('aria-busy');
|
|
}
|
|
}
|
|
document.addEventListener('click', event => {
|
|
const link = event.target.closest('a[href]');
|
|
if (!link || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || link.target) return;
|
|
const url = new URL(link.href);
|
|
if (!document.querySelector('[data-settings-workspace]') || !supports(url)) return;
|
|
event.preventDefault();
|
|
navigate(url.href);
|
|
});
|
|
document.addEventListener('change', event => {
|
|
if (!event.target.matches('[data-settings-subject]')) return;
|
|
const form = event.target.form;
|
|
const url = new URL(form.action);
|
|
url.search = new URLSearchParams(new FormData(form)).toString();
|
|
navigate(url.href);
|
|
});
|
|
window.addEventListener('popstate', event => {
|
|
if (event.state?.settingsPage && supports(new URL(location.href))) navigate(location.href, false);
|
|
});
|
|
})();
|
|
</script>
|
|
@endpush
|
|
@endonce
|