From 6c808ed5adb73c2552b34bfdfebfd83b5a0119d8 Mon Sep 17 00:00:00 2001 From: Youzini-afk <13153778771cx@gmail.com> Date: Tue, 14 Apr 2026 16:59:26 +0800 Subject: [PATCH] fix: harden panel entry bootstrap --- ui/panel-bridge.js | 80 +++++++++++++++++++++++++++++++++++----------- ui/panel.js | 36 ++++++++++++--------- 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/ui/panel-bridge.js b/ui/panel-bridge.js index 52bb7b9..92b886f 100644 --- a/ui/panel-bridge.js +++ b/ui/panel-bridge.js @@ -27,43 +27,85 @@ export function openPanelController(runtime) { } function injectOptionsMenuEntry(runtime) { - if (runtime.document.getElementById("option_st_bme_panel")) { + const doc = runtime.document; + if (!doc || doc.getElementById("option_st_bme_panel")) { return true; } - - const $menuItem = runtime.$(` - - - 记忆图谱 - - `).on("click", async () => { + const menuItem = doc.createElement("a"); + menuItem.id = "option_st_bme_panel"; + menuItem.innerHTML = + '记忆图谱'; + menuItem.addEventListener("click", async () => { try { await ensurePanelBridgeReady(runtime); openPanelController(runtime); - runtime.$("#options").hide(); + runtime.$?.("#options")?.hide?.(); } catch (error) { runtime.console.error("[ST-BME] 点击菜单打开面板失败:", error); globalThis.toastr?.error?.("记忆图谱面板加载失败,请查看控制台报错", "ST-BME"); } }); - const $optionsContent = runtime.$("#options .options-content"); - const $anchor = runtime.$("#option_toggle_logprobs"); + const anchor = doc.getElementById("option_toggle_logprobs"); + const optionsContent = doc.querySelector("#options .options-content"); - if ($anchor.length > 0) { - $anchor.after($menuItem); - return true; - } else if ($optionsContent.length > 0) { - $optionsContent.append($menuItem); + if (anchor?.parentNode) { + anchor.parentNode.insertBefore(menuItem, anchor.nextSibling); + return true; + } + if (optionsContent) { + optionsContent.appendChild(menuItem); return true; } - return false; } +function injectFloatingBootstrap(runtime) { + const doc = runtime.document; + if (!doc) return false; + let fab = doc.getElementById("bme-floating-ball"); + if (!fab) { + fab = doc.createElement("div"); + fab.id = "bme-floating-ball"; + fab.setAttribute("data-status", "idle"); + fab.setAttribute("data-bme-bootstrap", "true"); + fab.innerHTML = ` + + BME 记忆图谱 + `; + const mountTarget = doc.body || doc.documentElement; + if (!mountTarget) return false; + mountTarget.appendChild(fab); + } + if (fab.dataset.bmeBridgeBound === "true") { + return true; + } + fab.dataset.bmeBridgeBound = "true"; + fab.addEventListener("click", async () => { + try { + await ensurePanelBridgeReady(runtime); + openPanelController(runtime); + } catch (error) { + runtime.console.error("[ST-BME] 点击悬浮球打开面板失败:", error); + globalThis.toastr?.error?.("记忆图谱面板加载失败,请查看控制台报错", "ST-BME"); + } + }); + return true; +} + function scheduleOptionsMenuInjection(runtime, attempt = 0) { - if (injectOptionsMenuEntry(runtime)) { - return; + try { + injectFloatingBootstrap(runtime); + } catch (error) { + runtime.console.warn("[ST-BME] 悬浮球入口预注入失败:", error); + } + + try { + if (injectOptionsMenuEntry(runtime)) { + return; + } + } catch (error) { + runtime.console.warn("[ST-BME] 菜单入口注入失败,稍后重试:", error); } if (attempt >= MENU_ENTRY_MAX_ATTEMPTS) { diff --git a/ui/panel.js b/ui/panel.js index d0ef2e3..238aa8c 100644 --- a/ui/panel.js +++ b/ui/panel.js @@ -1021,21 +1021,21 @@ function _bindFabToggle() { } function _initFloatingBall() { - const existing = document.getElementById("bme-floating-ball"); - if (existing) { - _fabEl = existing; - ensureFabMountedAtRoot(); - syncFabPosition(); - return; + let fab = document.getElementById("bme-floating-ball"); + if (!fab) { + fab = document.createElement("div"); + fab.id = "bme-floating-ball"; + fab.setAttribute("data-status", "idle"); + fab.innerHTML = ` + + BME 记忆图谱 + `; + } else if (!fab.querySelector(".bme-fab-icon")) { + fab.innerHTML = ` + + BME 记忆图谱 + `; } - - const fab = document.createElement("div"); - fab.id = "bme-floating-ball"; - fab.setAttribute("data-status", "idle"); - fab.innerHTML = ` - - BME 记忆图谱 - `; _fabEl = fab; ensureFabMountedAtRoot(); @@ -1047,11 +1047,17 @@ function _initFloatingBall() { if (saved) { fab.dataset.positionMode = "saved"; applyFabPosition(saved, fab); - } else { + } else if (!fab.style.left || !fab.style.top) { fab.dataset.positionMode = "default"; syncFabPosition(); } + if (fab.dataset.bmeFabBound === "true") { + return; + } + fab.dataset.bmeFabBound = "true"; + delete fab.dataset.bmeBootstrap; + // 拖拽 + 点击逻辑 let isDragging = false; let hasMoved = false;