fix: 文件选择器改为页内iframe弹窗 + 乱码编码修复 + API路径修复

- pickPath()从window.open改为页内iframe模态弹窗(遮罩+关闭按钮)
- files.html添加meta charset+CSS link,独立模式自动加载files.js
- API路径统一通过_apiUrl()构建,适配主面板和iframe两种上下文
- 独立iframe模式注入body/container覆写样式(无topbar)
- 选择模式栏移至底部margin-top:auto紧凑排列
- MD3风格toggle开关(显示隐藏复选框)
- CSS版本号缓存破坏

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
qinglong
2026-06-11 21:51:42 +08:00
parent d275c78aed
commit 9b997d8bda
5 changed files with 109 additions and 34 deletions
+34 -7
View File
@@ -172,20 +172,47 @@ async function loadPluginPage(pluginName) {
}
// ═══ Global file/dir picker (reusable by any page) ═══
// Usage: pickPath('dir', function(path) { document.getElementById('my-input').value = path; })
// ═══ Global file/dir picker (in-page iframe modal) ═══
window.pickPath = function(mode, callback) {
var id = 'picker_' + Date.now();
window['_pickCallback_' + id] = callback;
var url = './static/pages/files.html?picker=1&mode=' + (mode || 'dir') + '&cb=' + id;
var w = window.open(url, 'fm-picker', 'width=680,height=520');
if (!w) { alert('请允许弹窗以使用文件选择器'); return; }
// Listen for pick result
// Create modal overlay
var overlay = document.createElement('div');
overlay.id = 'fm-picker-overlay';
overlay.style.cssText = 'position:fixed;inset:0;z-index:500;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center';
overlay.onclick = function(e) { if (e.target === overlay) closePicker(); };
var box = document.createElement('div');
box.style.cssText = 'background:var(--md-sys-color-surface-container-high);border-radius:var(--shape-lg);width:720px;height:520px;max-width:95vw;max-height:85vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--md-sys-elevation-5)';
// Header
var header = document.createElement('div');
header.style.cssText = 'display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--outline);flex-shrink:0';
header.innerHTML = '<span style="font-weight:500;color:var(--primary)">📂 选择' + (mode==='file'?'文件':'目录') + '</span>' +
'<button class="btn btn-sm btn-outlined" onclick="closePicker()" style="font-size:16px;line-height:1">✕</button>';
box.appendChild(header);
// Iframe
var iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.cssText = 'flex:1;border:none;width:100%';
box.appendChild(iframe);
overlay.appendChild(box);
document.body.appendChild(overlay);
function closePicker() {
window.removeEventListener('message', handler);
if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
}
window._closePicker = closePicker;
// Listen for pick result from iframe
window.addEventListener('message', function handler(e) {
try {
var d = JSON.parse(e.data);
if (d.action === 'fm-picked' && d.callback_id === id) {
window.removeEventListener('message', handler);
closePicker();
if (d.path && callback) callback(d.path);
}
} catch(ex) {}