From 39905cea2bb9459ee8ed8c905514890444ae6409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Tue, 11 Aug 2026 12:15:46 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=A1=B5=E9=87=8D=E7=BD=AE=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E5=8F=AF=E7=94=A8=E6=80=A7=E4=B8=8E=20popup=20=E7=AB=99?= =?UTF-8?q?=E7=82=B9=E6=93=8D=E4=BD=9C=E5=8F=8D=E9=A6=88=EF=BC=88#1590=20?= =?UTF-8?q?=E5=89=8D=E7=BD=AE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScriptEditor/tabs/SettingsPane.test.tsx | 21 +++++++ .../routes/ScriptEditor/tabs/SettingsPane.tsx | 4 +- src/pages/popup/usePopupData.test.ts | 63 ++++++++++++++++++- src/pages/popup/usePopupData.ts | 8 ++- 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.test.tsx b/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.test.tsx index 3b98ef8b0..3ca32afc7 100644 --- a/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.test.tsx +++ b/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.test.tsx @@ -324,6 +324,27 @@ describe("SettingsPane 网站匹配/排除", () => { expect(screen.queryByText("*://exclude.com/*")).toBeNull(); }); + it("清空匹配规则后重置按钮应可用并可恢复脚本自带规则", async () => { + // 脚本自带 @match 但无用户覆盖;删除最后一项后是显式空覆盖,重置应可撤销它并恢复自带规则 + fetchScript.mockResolvedValue({ + ...sampleScript(), + selfMetadata: { exclude: ["*://exclude.com/*"] }, + }); + render(); + await screen.findByText("*://script.com/*"); + fireEvent.click(screen.getByLabelText(`${t("delete")} *://script.com/*`)); + fireEvent.click(screen.getByText(t("confirm"), { selector: "button" })); + expect(screen.queryByText("*://script.com/*")).toBeNull(); + // 存在可撤销的空覆盖,重置按钮不应被禁用 + const resetBtn = screen.getAllByText(t("reset"), { selector: "button" })[0]; + expect(resetBtn).not.toBeDisabled(); + // 点击重置应撤销空覆盖、恢复脚本自带规则 + fireEvent.click(resetBtn); + fireEvent.click(screen.getByText(t("confirm"), { selector: "button" })); + expect(resetMatch).toHaveBeenCalledWith("u1", undefined); + expect(screen.getByText("*://script.com/*")).toBeInTheDocument(); + }); + it("删除最后一项匹配应显式清空覆盖而非复活脚本自带规则", async () => { fetchScript.mockResolvedValue({ ...sampleScript(), diff --git a/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.tsx b/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.tsx index ef3bbe9eb..7e1195b1b 100644 --- a/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.tsx +++ b/src/pages/options/routes/ScriptEditor/tabs/SettingsPane.tsx @@ -380,11 +380,13 @@ function SettingsPaneContent({ uuid, data }: SettingsPaneProps & { data: Setting cancelText={t("editor:cancel")} onConfirm={() => setMatchList(kind, undefined)} > + {/* 重置即撤销用户覆盖(回落脚本自带 metadata);无覆盖时禁用,而非按列表为空判断—— + 用户删空匹配/排除后是显式空覆盖,仍应能重置恢复自带规则 */}