暂无日志
@@ -517,29 +517,38 @@
right.className = 'prompt-head-right';
const upBtn = document.createElement('button');
+ upBtn.type = 'button';
upBtn.className = 'btn btn-sm';
upBtn.textContent = '↑';
upBtn.disabled = idx === 0;
- upBtn.addEventListener('click', () => {
+ upBtn.addEventListener('click', ev => {
+ ev.preventDefault();
+ ev.stopPropagation();
if (idx === 0) return;
[cfg.promptBlocks[idx - 1], cfg.promptBlocks[idx]] = [cfg.promptBlocks[idx], cfg.promptBlocks[idx - 1]];
renderPromptList(); scheduleSave();
});
const downBtn = document.createElement('button');
+ downBtn.type = 'button';
downBtn.className = 'btn btn-sm';
downBtn.textContent = '↓';
downBtn.disabled = idx === total - 1;
- downBtn.addEventListener('click', () => {
+ downBtn.addEventListener('click', ev => {
+ ev.preventDefault();
+ ev.stopPropagation();
if (idx >= total - 1) return;
[cfg.promptBlocks[idx], cfg.promptBlocks[idx + 1]] = [cfg.promptBlocks[idx + 1], cfg.promptBlocks[idx]];
renderPromptList(); scheduleSave();
});
const delBtn = document.createElement('button');
+ delBtn.type = 'button';
delBtn.className = 'btn btn-sm btn-del';
delBtn.textContent = '删除';
- delBtn.addEventListener('click', () => {
+ delBtn.addEventListener('click', ev => {
+ ev.preventDefault();
+ ev.stopPropagation();
cfg.promptBlocks.splice(idx, 1);
renderPromptList(); scheduleSave();
});
@@ -757,21 +766,40 @@
/* ── Event bindings ── */
function bindEvents() {
+ document.addEventListener('submit', ev => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ document.querySelectorAll('button').forEach(btn => {
+ if (!btn.getAttribute('type')) btn.setAttribute('type', 'button');
+ });
+
+ const bindButtonAction = (id, handler) => {
+ const element = $(id);
+ if (!element) return;
+ element.addEventListener('click', ev => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ handler(ev);
+ });
+ };
+
$$('.nav-item, .mobile-nav-item').forEach(item => {
item.addEventListener('click', () => activateTab(item.dataset.view));
});
- $('ep_close').addEventListener('click', () => post('xb-ena:close'));
+ bindButtonAction('ep_close', () => post('xb-ena:close'));
$('ep_enabled').addEventListener('change', () => setBadge(toBool($('ep_enabled').value, true)));
- $('ep_run_test').addEventListener('click', () => {
+ bindButtonAction('ep_run_test', () => {
const text = $('ep_test_input').value.trim() || '(测试输入)我想让你帮我规划下一步剧情。';
post('xb-ena:run-test', { text });
setLocalStatus('ep_test_status', '测试中…', 'loading');
});
- $('ep_toggle_key').addEventListener('click', () => {
+ bindButtonAction('ep_toggle_key', () => {
const input = $('ep_api_key');
const btn = $('ep_toggle_key');
if (input.type === 'password') {
@@ -783,11 +811,11 @@
$('ep_prefix_mode').addEventListener('change', updatePrefixModeUI);
- $('ep_fetch_models').addEventListener('click', () => {
+ bindButtonAction('ep_fetch_models', () => {
post('xb-ena:fetch-models');
setLocalStatus('ep_api_status', '拉取中…', 'loading');
});
- $('ep_test_conn').addEventListener('click', () => {
+ bindButtonAction('ep_test_conn', () => {
post('xb-ena:fetch-models');
setLocalStatus('ep_api_status', '测试中…', 'loading');
});
@@ -801,13 +829,13 @@
$('ep_keep_tags').value = normalized.join(', ');
});
- $('ep_add_prompt').addEventListener('click', () => {
+ bindButtonAction('ep_add_prompt', () => {
cfg.promptBlocks = cfg.promptBlocks || [];
cfg.promptBlocks.push({ id: genId(), role: 'system', name: '新块', content: '' });
renderPromptList(); scheduleSave();
});
- $('ep_reset_prompt').addEventListener('click', () => {
+ bindButtonAction('ep_reset_prompt', () => {
if (!confirm('确定恢复默认提示词块?当前提示词块将被覆盖。')) return;
if (pendingSave) return;
const requestId = `ena_reset_${Date.now()}`;
@@ -825,7 +853,7 @@
renderPromptList(); scheduleSave();
});
- $('ep_tpl_save').addEventListener('click', () => {
+ bindButtonAction('ep_tpl_save', () => {
const name = $('ep_tpl_select').value;
if (!name) { setSaveIndicator('error', '请先选择或创建模板'); return; }
cfg.promptTemplates = cfg.promptTemplates || {};
@@ -834,7 +862,7 @@
renderTemplateSelect(name); scheduleSave();
});
- $('ep_tpl_saveas').addEventListener('click', () => {
+ bindButtonAction('ep_tpl_saveas', () => {
const name = prompt('新模板名称');
if (!name) return;
cfg.promptTemplates = cfg.promptTemplates || {};
@@ -843,7 +871,7 @@
renderTemplateSelect(name); scheduleSave();
});
- $('ep_tpl_delete').addEventListener('click', () => {
+ bindButtonAction('ep_tpl_delete', () => {
const name = $('ep_tpl_select').value;
if (!name) return;
const backup = structuredClone(cfg.promptTemplates[name]);
@@ -853,7 +881,7 @@
showUndoBar(name, backup);
});
- $('ep_tpl_undo_btn').addEventListener('click', () => {
+ bindButtonAction('ep_tpl_undo_btn', () => {
if (!undoState) return;
cfg.promptTemplates = cfg.promptTemplates || {};
cfg.promptTemplates[undoState.name] = undoState.blocks;
@@ -862,28 +890,28 @@
clearUndo(); scheduleSave();
});
- $('ep_debug_worldbook').addEventListener('click', () => {
+ bindButtonAction('ep_debug_worldbook', () => {
$('ep_debug_output').classList.add('visible');
$('ep_debug_output').textContent = '诊断中…';
post('xb-ena:debug-worldbook');
});
- $('ep_debug_char').addEventListener('click', () => {
+ bindButtonAction('ep_debug_char', () => {
$('ep_debug_output').classList.add('visible');
$('ep_debug_output').textContent = '诊断中…';
post('xb-ena:debug-char');
});
- $('ep_test_planner').addEventListener('click', () => {
+ bindButtonAction('ep_test_planner', () => {
post('xb-ena:run-test', { text: '(测试输入)请规划下一步剧情走向。' });
$('ep_debug_output').classList.add('visible');
$('ep_debug_output').textContent = '规划测试中…';
});
- $('ep_open_logs').addEventListener('click', () => post('xb-ena:logs-request'));
- $('ep_log_clear').addEventListener('click', () => {
+ bindButtonAction('ep_open_logs', () => post('xb-ena:logs-request'));
+ bindButtonAction('ep_log_clear', () => {
if (!confirm('确定清空所有日志?')) return;
post('xb-ena:logs-clear');
});
- $('ep_log_export').addEventListener('click', () => {
+ bindButtonAction('ep_log_export', () => {
const blob = new Blob([JSON.stringify(logs || [], null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');