fix: 移除遗留fmfuncs目录创建 + 清理init_service无用导入 + 文件管理器SVG图标 + 示例插件MD3改造

- init_service: 删除_load_fmfuncs方法和fmfuncs目录创建(已迁移到sdk/)
- init_service: 清理未使用的importlib.util和sys导入
- 文件管理器: 全部emoji替换为MD3 SVG矢量图标(文件夹/文件类型/右键菜单)
- 示例插件: dashboard.html改为MD3风格 CSS变量自动适配日夜主题
- 面包屑: 加底色+模糊+左右外边距
- CSS: .btn::after加pointer-events:none
- 插件开发指南: 更新2.6节MD3主题同步和完善的CSS变量/组件类参考表

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
qinglong
2026-06-12 19:00:19 +08:00
parent 9b997d8bda
commit 9de094ea54
16 changed files with 283 additions and 308 deletions
+29 -25
View File
@@ -4,10 +4,7 @@
<div class="fm-container">
<!-- Top bar: editable path + actions -->
<div class="fm-toolbar">
<div class="fm-path-bar">
<input class="fm-path-input" id="fm-path-input" type="text" spellcheck="false" title="输入路径后回车跳转">
<div class="fm-breadcrumb" id="fm-breadcrumb"></div>
</div>
<input class="fm-path-input" id="fm-path-input" type="text" spellcheck="false" title="输入路径后回车跳转">
<div class="fm-actions">
<label class="fm-toggle">
<input type="checkbox" id="fm-hidden" onchange="FilesModule.refresh()">
@@ -29,6 +26,9 @@
</div>
</div>
<!-- Breadcrumb row (own line) -->
<div class="fm-breadcrumb" id="fm-breadcrumb"></div>
<!-- File list -->
<div class="fm-list" id="fm-list">
<div style="text-align:center;color:var(--text-dim);padding:40px">加载中...</div>
@@ -59,36 +59,40 @@
<!-- Context menu -->
<div class="fm-context" id="fm-context" style="display:none">
<div class="fm-context-item" onclick="FilesModule.ctxDownload()"> 下载</div>
<div class="fm-context-item" onclick="FilesModule.ctxRename()"> 重命名</div>
<div class="fm-context-item" onclick="FilesModule.ctxEdit()">📝 编辑</div>
<div class="fm-context-item" onclick="FilesModule.ctxDownload()"><svg width="14" height="14" viewBox="0 0 24 24"><path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg> 下载</div>
<div class="fm-context-item" onclick="FilesModule.ctxRename()"><svg width="14" height="14" viewBox="0 0 24 24"><path fill="currentColor" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg> 重命名</div>
<div class="fm-context-item" onclick="FilesModule.ctxEdit()"><svg width="14" height="14" viewBox="0 0 24 24"><path fill="currentColor" d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 2l5 5h-5V4zM8 14h8v2H8v-2zm0-4h8v2H8v-2z"/></svg> 编辑</div>
<div class="fm-context-sep"></div>
<div class="fm-context-item danger" onclick="FilesModule.ctxDelete()">🗑 删除</div>
<div class="fm-context-item danger" onclick="FilesModule.ctxDelete()"><svg width="14" height="14" viewBox="0 0 24 24"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg> 删除</div>
</div>
</div>
<script>
// Load files.js for standalone mode (iframe picker)
(function(){
if(window.parent !== window && !window.FilesModule){
// Sync theme from parent window
try {
var parentTheme = window.parent.document.documentElement.getAttribute('data-theme');
if(parentTheme) document.documentElement.setAttribute('data-theme', parentTheme);
} catch(e){}
// Reset body/container for iframe — no topbar, no sidebar
if(window.parent !== window){
var s=document.createElement('style');
s.textContent='html,body{height:100%;margin:0;overflow:hidden}.fm-container{height:100%;gap:8px}.fm-list{padding-bottom:0}';
document.head.appendChild(s);
}
var cssHref = document.querySelector('link[href*=\"style.css\"]')?.href || '';
// e.g. http://host:4200/SenSu/static/css/style.css → staticBase = .../SenSu/static
var staticBase = cssHref.replace(/\/css\/style\.css.*$/, '');
// apiBase = .../SenSu (strip /static)
var apiBase = cssHref.replace(/\/static\/css\/style\.css.*$/, '');
var fmStyle=document.createElement('style');
fmStyle.textContent='html,body{height:100%;margin:0;overflow:hidden}.fm-container{height:100%;gap:8px}.fm-list{padding-bottom:0}';
document.head.appendChild(fmStyle);
// Derive paths from our own URL: /SenSu/static/pages/files.html → /SenSu
var apiBase = location.pathname.replace(/\/static\/pages\/files\.html.*$/, '');
var script = document.createElement('script');
script.src = staticBase + '/pages/files.js?v=0602';
script.src = apiBase + '/static/pages/files.js?v=0603';
script.onload = function(){
if(window.FilesModule){
window.FilesModule._apiBase = apiBase;
if(window.FilesModule.init) window.FilesModule.init();
}
if(!window.FilesModule) return;
window.FilesModule._apiBase = apiBase;
window.FilesModule.init();
};
script.onerror = function(){
document.body.innerHTML = '<div style=\"color:red;padding:20px\">Failed to load files.js</div>';
};
document.head.appendChild(script);
})();
}
</script>