@@ -505,213 +505,151 @@ async function ExtStore_GetExtList() {
505505}
506506
507507// ==========================
508- // 显示插件管理模态框
508+ // 显示插件管理模态框 (重构版 - 使用 CSS 类)
509509// ==========================
510510async function showPluginManagerModal ( editor ) {
511511 if ( document . getElementById ( 'plugin-manager-modal' ) ) return ;
512-
512+ // 1. 创建遮罩层
513513 const modal = document . createElement ( 'div' ) ;
514514 modal . id = 'plugin-manager-modal' ;
515- modal . style . cssText = `
516- position: fixed;
517- top: 0; left: 0; right: 0; bottom: 0;
518- background: rgba(0,0,0,0.6);
519- display: flex;
520- justify-content: center;
521- align-items: center;
522- z-index: 10000;
523- ` ;
524-
515+ modal . className = 'plugin-manager-backdrop' ;
516+ // 2. 创建容器
525517 const container = document . createElement ( 'div' ) ;
526- container . style . cssText = `
527- background: #272822;
528- color: #f8f8f2;
529- width: 600px;
530- max-height: 80vh;
531- overflow: hidden;
532- display: flex;
533- flex-direction: column;
534- border-radius: 8px;
535- box-shadow: 0 4px 20px rgba(0,0,0,0.5);
536- border: 1px solid #444;
537- ` ;
538-
539- // 头部
518+ container . className = 'plugin-manager-container' ;
519+ // 3. 头部
540520 const header = document . createElement ( 'div' ) ;
541- header . style . cssText = `padding: 16px; border-bottom: 1px solid #444; position: relative;` ;
521+ header . className = 'plugin-manager-header' ;
542522 header . textContent = '插件管理' ;
543523 const closeBtn = document . createElement ( 'button' ) ;
524+ closeBtn . className = 'plugin-manager-close-btn' ;
544525 closeBtn . textContent = '×' ;
545- closeBtn . style . cssText = `
546- position: absolute;
547- right: 16px;
548- top: 50%;
549- transform: translateY(-50%);
550- cursor: pointer;
551- font-size: 20px;
552- line-height: 1;
553- padding: 0 8px;
554- border: none;
555- background: none;
556- color: #f8f8f2;
557- ` ;
558- closeBtn . onclick = ( ) => modal . remove ( ) ;
526+ closeBtn . title = '关闭' ;
527+ closeBtn . onclick = ( ) => {
528+ if ( modal . parentNode ) modal . parentNode . removeChild ( modal ) ;
529+ } ;
559530 header . appendChild ( closeBtn ) ;
560531 container . appendChild ( header ) ;
561-
562- // 主体
532+ // 4. 主体
563533 const body = document . createElement ( 'div' ) ;
564- body . style . cssText = `flex: 1; overflow-y: auto; padding: 16px;` ;
534+ body . className = 'plugin-manager-body' ;
565535 container . appendChild ( body ) ;
566-
567- // 保存区域
536+ // --- 保存区域 ---
568537 const saveSection = document . createElement ( 'div' ) ;
569- saveSection . style . cssText = `margin-bottom: 20px;` ;
570-
538+ saveSection . className = 'plugin-manager-save-section' ;
571539 const saveLabel = document . createElement ( 'div' ) ;
540+ saveLabel . className = 'plugin-manager-label' ;
572541 saveLabel . textContent = '保存当前代码为插件:' ;
573- saveLabel . style . cssText = `margin-bottom: 8px; font-weight: bold;` ;
574542 saveSection . appendChild ( saveLabel ) ;
575-
576543 const inputGroup = document . createElement ( 'div' ) ;
577- inputGroup . style . cssText = `display: flex; gap: 8px;` ;
578-
544+ inputGroup . className = 'plugin-manager-input-group' ;
579545 const nameInput = document . createElement ( 'input' ) ;
580546 nameInput . type = 'text' ;
581547 nameInput . placeholder = '插件名称(不可重复)' ;
582- nameInput . style . cssText = `
583- flex: 1;
584- padding: 6px 10px;
585- background: #333430;
586- color: #f8f8f2;
587- border: 1px solid #666;
588- border-radius: 4px;
589- outline: none;
590- ` ;
591- nameInput . onfocus = ( ) => ( nameInput . style . borderColor = '#888' ) ;
592- nameInput . onblur = ( ) => ( nameInput . style . borderColor = '#666' ) ;
548+ nameInput . className = 'plugin-manager-input' ;
593549 inputGroup . appendChild ( nameInput ) ;
594-
595550 const saveBtn = document . createElement ( 'button' ) ;
596551 saveBtn . textContent = '保存' ;
597- saveBtn . style . cssText = `
598- width: 80px;
599- height: 36px;
600- background: #272822;
601- color: #f8f8f2;
602- border: 1px solid #666;
603- border-radius: 4px;
604- font-size: 14px;
605- cursor: pointer;
606- transition: background 0.2s, border-color 0.2s;
607- ` ;
608- saveBtn . onmouseenter = ( ) => {
609- saveBtn . style . background = '#333430' ;
610- saveBtn . style . borderColor = '#888' ;
611- } ;
612- saveBtn . onmouseleave = ( ) => {
613- saveBtn . style . background = '#272822' ;
614- saveBtn . style . borderColor = '#666' ;
615- } ;
552+ saveBtn . className = 'plugin-manager-btn save' ; // 添加 'save' 修饰类
616553 saveBtn . onclick = async ( ) => {
617- await saveCurrentCodeAsPlugin ( editor , nameInput , ( msg , type ) => {
618- eda . sys_Message . showToastMessage ( msg , type , 2 ) ;
619- } ) ;
620- await renderPluginList ( pluginList ) ;
554+ const originalText = saveBtn . textContent ;
555+ saveBtn . textContent = '保存中...' ;
556+ saveBtn . disabled = true ;
557+ try {
558+ await saveCurrentCodeAsPlugin ( editor , nameInput , ( msg , type ) => {
559+ if ( eda && eda . sys_Message ) eda . sys_Message . showToastMessage ( msg , type , 2 ) ;
560+ } ) ;
561+ await renderPluginList ( pluginList ) ;
562+ nameInput . value = '' ; // 清空输入框
563+ } catch ( e ) {
564+ console . error ( e ) ;
565+ } finally {
566+ saveBtn . textContent = originalText ;
567+ saveBtn . disabled = false ;
568+ }
621569 } ;
622570 inputGroup . appendChild ( saveBtn ) ;
623571 saveSection . appendChild ( inputGroup ) ;
624572 body . appendChild ( saveSection ) ;
625-
626- // 插件列表标题
573+ // --- 插件列表标题 ---
627574 const listTitle = document . createElement ( 'div' ) ;
575+ listTitle . className = 'plugin-manager-list-title' ;
628576 listTitle . textContent = '已有插件:' ;
629- listTitle . style . cssText = `margin: 16px 0 8px; font-weight: bold;` ;
630577 body . appendChild ( listTitle ) ;
631-
632578 const pluginList = document . createElement ( 'div' ) ;
633- pluginList . style . cssText = `display: flex; flex-direction: column; gap: 8px;` ;
579+ pluginList . className = 'plugin-manager-list' ;
634580 body . appendChild ( pluginList ) ;
635-
636- // 渲染插件列表
581+ // --- 渲染插件列表函数 ---
637582 async function renderPluginList ( listEl ) {
638- listEl . innerHTML = '<div style="color:#75715e; font-style:italic; ">加载中...</div>' ;
583+ listEl . innerHTML = '<div class="plugin-manager-status ">加载中...</div>' ;
639584 try {
640585 const plugins = await ExtStore_GetExtList ( ) ;
641586 if ( plugins . length === 0 ) {
642- listEl . innerHTML = '<div style="color:#75715e; font-style:italic; ">暂无插件</div>' ;
587+ listEl . innerHTML = '<div class="plugin-manager-status ">暂无插件</div>' ;
643588 } else {
644589 listEl . innerHTML = '' ;
645590 for ( const plugin of plugins ) {
646591 const item = document . createElement ( 'div' ) ;
647- item . style . cssText = `
648- display: flex;
649- justify-content: space-between;
650- align-items: center;
651- padding: 6px 10px;
652- background: #333430;
653- border-radius: 4px;
654- ` ;
655-
592+ item . className = 'plugin-manager-item' ;
656593 const nameSpan = document . createElement ( 'span' ) ;
594+ nameSpan . className = 'plugin-manager-item-name' ;
657595 nameSpan . textContent = plugin . name ;
658- nameSpan . style . cssText = `color: #f8f8f2;` ;
596+ nameSpan . title = plugin . name ; // 鼠标悬停显示全名
659597 item . appendChild ( nameSpan ) ;
660-
661598 const delBtn = document . createElement ( 'button' ) ;
662599 delBtn . textContent = '删除' ;
663- delBtn . style . cssText = `
664- width: 80px;
665- height: 36px;
666- background: #272822;
667- color: #f8f8f2;
668- border: 1px solid #666;
669- border-radius: 4px;
670- font-size: 14px;
671- cursor: pointer;
672- transition: background 0.2s, border-color 0.2s;
673- ` ;
674- delBtn . onmouseenter = ( ) => {
675- delBtn . style . background = '#333430' ;
676- delBtn . style . borderColor = '#888' ;
677- delBtn . style . color = '#f92672' ;
678- } ;
679- delBtn . onmouseleave = ( ) => {
680- delBtn . style . background = '#272822' ;
681- delBtn . style . borderColor = '#666' ;
682- delBtn . style . color = '#f8f8f2' ;
683- } ;
600+ delBtn . className = 'plugin-manager-btn delete' ; // 添加 'delete' 修饰类
684601 delBtn . onclick = async ( e ) => {
685602 e . stopPropagation ( ) ;
686603 if ( ! confirm ( `确定删除插件 "${ plugin . name } "?` ) ) return ;
604+ delBtn . textContent = '删除中...' ;
605+ delBtn . disabled = true ;
687606 try {
688607 await ExtStore_DeleteExt ( plugin . name ) ;
689608 await renderPluginList ( pluginList ) ;
690- eda . sys_Message . showToastMessage ( `插件 "${ plugin . name } " 已删除` , 'info' , 1 ) ;
609+ if ( eda && eda . sys_Message ) {
610+ eda . sys_Message . showToastMessage ( `插件 "${ plugin . name } " 已删除` , 'info' , 1 ) ;
611+ }
691612 } catch ( err ) {
692613 console . error ( '删除失败:' , err ) ;
693- eda . sys_Message . showToastMessage ( `删除失败: ${ err . message } ` , 'error' , 2 ) ;
614+ if ( eda && eda . sys_Message ) {
615+ eda . sys_Message . showToastMessage ( `删除失败: ${ err . message } ` , 'error' , 2 ) ;
616+ }
617+ // 恢复按钮状态
618+ delBtn . textContent = '删除' ;
619+ delBtn . disabled = false ;
694620 }
695621 } ;
696622 item . appendChild ( delBtn ) ;
697623 listEl . appendChild ( item ) ;
698624 }
699625 }
700626 } catch ( err ) {
701- listEl . innerHTML = `<div style="color:#f92672; ">加载插件失败:${ err . message } </div>` ;
627+ listEl . innerHTML = `<div class="plugin-manager-status error ">加载插件失败:${ err . message } </div>` ;
702628 }
703629 }
704-
705630 // 初始加载
706631 await renderPluginList ( pluginList ) ;
707-
632+ // 点击遮罩层关闭
708633 modal . onclick = ( e ) => {
709- if ( e . target === modal ) modal . remove ( ) ;
634+ if ( e . target === modal ) {
635+ if ( modal . parentNode ) modal . parentNode . removeChild ( modal ) ;
636+ }
710637 } ;
711-
712- container . appendChild ( body ) ;
638+ // 组装 DOM
713639 modal . appendChild ( container ) ;
714640 document . body . appendChild ( modal ) ;
641+ // 自动聚焦输入框
642+ setTimeout ( ( ) => nameInput . focus ( ) , 50 ) ;
643+ // ESC 关闭
644+ const escHandler = ( e ) => {
645+ if ( e . key === 'Escape' ) {
646+ if ( modal . parentNode ) {
647+ modal . parentNode . removeChild ( modal ) ;
648+ document . removeEventListener ( 'keydown' , escHandler ) ;
649+ }
650+ }
651+ } ;
652+ document . addEventListener ( 'keydown' , escHandler ) ;
715653}
716654
717655// ==========================
0 commit comments