/**
* PromptModal - 自定义 prompt/confirm 对话框
* 替代 window.prompt() / window.confirm()(Electron contextIsolation 下不可用)
*/
let overlayEl: HTMLElement | null = null;
let titleEl: HTMLElement | null = null;
let bodyEl: HTMLElement | null = null;
let inputEl: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null = null;
let okBtn: HTMLButtonElement | null = null;
import { escapeHtml } from '../utils/utils.js';
let cancelBtn: HTMLButtonElement | null = null;
let resolveFn: ((value: string | null) => void) | null = null;
function ensureModal(): void {
if (overlayEl) return;
overlayEl = document.createElement('div');
overlayEl.className = 'modal-overlay';
overlayEl.id = 'promptModal';
overlayEl.style.display = 'none';
overlayEl.innerHTML = `
`;
document.querySelector('#app')!.appendChild(overlayEl);
titleEl = overlayEl.querySelector('#promptTitle')!;
bodyEl = overlayEl.querySelector('#promptBody')!;
okBtn = overlayEl.querySelector('#promptOk')! as HTMLButtonElement;
cancelBtn = overlayEl.querySelector('#promptCancel')! as HTMLButtonElement;
overlayEl.addEventListener('click', (e) => {
if (e.target === overlayEl) close(null);
});
cancelBtn.addEventListener('click', (e) => {
e.stopPropagation();
close(null);
});
okBtn.addEventListener('click', (e) => {
e.stopPropagation();
if (inputEl instanceof HTMLSelectElement) {
close(inputEl.value);
} else if (inputEl) {
close((inputEl as HTMLInputElement | HTMLTextAreaElement).value);
} else {
close('');
}
});
document.addEventListener('keydown', (e) => {
if (!overlayEl || overlayEl.style.display === 'none') return;
if (e.key === 'Escape') { e.preventDefault(); close(null); }
if (e.key === 'Enter' && !(inputEl instanceof HTMLTextAreaElement)) {
e.preventDefault();
okBtn!.click();
}
});
}
function close(value: string | null): void {
if (overlayEl) overlayEl.style.display = 'none';
if (resolveFn) {
const r = resolveFn;
resolveFn = null;
r(value);
}
}
/** 显示自定义 prompt,返回用户输入或 null(取消) */
export function showPrompt(options: {
title: string;
message?: string;
defaultValue?: string;
placeholder?: string;
type?: 'text' | 'textarea' | 'select';
options?: Array<{ value: string; label: string }>;
}): Promise {
ensureModal();
return new Promise((resolve) => {
resolveFn = resolve;
titleEl!.textContent = options.title;
let html = '';
if (options.message) {
html += `${escapeHtml(options.message)}
`;
}
if (options.type === 'select' && options.options) {
html += ``;
} else if (options.type === 'textarea') {
html += ``;
} else {
html += ``;
}
bodyEl!.innerHTML = html;
inputEl = bodyEl!.querySelector('#promptInput')! as HTMLInputElement;
overlayEl!.style.display = '';
// 聚焦并选中文本
setTimeout(() => {
if (inputEl instanceof HTMLInputElement) {
inputEl.focus();
if (options.defaultValue) inputEl.select();
} else if (inputEl instanceof HTMLTextAreaElement) {
inputEl.focus();
}
}, 50);
});
}
/** 显示自定义 confirm,返回 true/false */
export function showConfirm(message: string, title = '确认'): Promise {
ensureModal();
return new Promise((resolve) => {
resolveFn = (val) => resolve(val !== null);
titleEl!.textContent = title;
bodyEl!.innerHTML = `${escapeHtml(message)}
`;
inputEl = null;
overlayEl!.style.display = '';
okBtn!.focus();
});
}