Files
mnote/rust/crates/mnote-web/browser/mnote-ui-runtime.js
T

70 lines
2.4 KiB
JavaScript
Raw Normal View History

2026-06-25 21:08:17 +08:00
// MNote UI 基础运行时:全局 portal 与 toast API。
(function initMnoteUiRuntime() {
if (window.__mnoteUiRuntimeStarted) return;
window.__mnoteUiRuntimeStarted = true;
function ensurePortalRoot() {
var root = document.getElementById('mnote-portal-root');
if (root instanceof HTMLElement) return root;
root = document.createElement('div');
root.id = 'mnote-portal-root';
root.setAttribute('data-mnote-portal-root', 'true');
document.body.appendChild(root);
return root;
}
function ensureToastRegion() {
var root = ensurePortalRoot();
var region = root.querySelector('[data-mnote-toast-region="true"]');
if (region instanceof HTMLElement) return region;
region = document.createElement('div');
region.className = 'mnote-toast-region';
region.setAttribute('data-mnote-toast-region', 'true');
region.setAttribute('role', 'status');
region.setAttribute('aria-live', 'polite');
root.appendChild(region);
return region;
}
function toast(message, options) {
var text = String(message || '').trim();
if (!text) return null;
var config = options || {};
var kind = String(config.kind || config.type || 'info').trim() || 'info';
var timeoutMs = Number(config.timeoutMs || config.duration || 3200);
if (!Number.isFinite(timeoutMs) || timeoutMs < 800) timeoutMs = 3200;
var region = ensureToastRegion();
var item = document.createElement('div');
item.className = 'mnote-toast mnote-toast--' + kind;
item.setAttribute('data-mnote-toast', 'true');
item.setAttribute('data-kind', kind);
item.textContent = text;
region.appendChild(item);
requestAnimationFrame(function showToast() {
item.classList.add('mnote-toast--visible');
});
window.setTimeout(function hideToast() {
item.classList.remove('mnote-toast--visible');
window.setTimeout(function removeToast() {
if (item.parentNode) item.parentNode.removeChild(item);
}, 180);
}, timeoutMs);
return item;
}
window.mnote = window.mnote || {};
window.mnote.ensurePortalRoot = ensurePortalRoot;
window.mnote.toast = toast;
window.addEventListener('mnote:toast', function onMnoteToast(event) {
var detail = event && event.detail ? event.detail : {};
toast(detail.message, detail);
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', ensurePortalRoot, { once: true });
} else {
ensurePortalRoot();
}
})();