Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/app/service/service_worker/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ export class ScriptClient extends Client {
return this.do("excludeUrl", { uuid, excludePattern, remove });
}

onlyRunOnUrl(uuid: string, matchPattern: string) {
return this.do("onlyRunOnUrl", { uuid, matchPattern });
}

allowUrl(uuid: string, matchPattern: string, excludePattern: string) {
return this.do("allowUrl", { uuid, matchPattern, excludePattern });
}

// 重置匹配项
resetMatch(uuid: string, match: string[] | undefined) {
return this.do("resetMatch", { uuid, match });
Expand Down
42 changes: 42 additions & 0 deletions src/app/service/service_worker/script.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,48 @@ describe("ScriptService selfMetadata 用户覆盖", () => {
});
});

describe("popup 站点范围快捷操作", () => {
it("仅在当前站点执行应以当前站点替换用户匹配列表", async () => {
const script = createMockScript({ selfMetadata: { match: ["*://old.example/*"] } });
vi.mocked(mockScriptDAO.get).mockResolvedValue(script);

await scriptService.onlyRunOnUrl({ uuid: script.uuid, matchPattern: "*://current.example/*" });

expect(savedSelfMetadata()).toEqual({ match: ["*://current.example/*"] });
});

it("自定义匹配未覆盖当前站点时应把当前站点加入允许列表", async () => {
const script = createMockScript({
selfMetadata: { match: ["*://allowed.example/*"], exclude: ["*://current.example/*"] },
});
vi.mocked(mockScriptDAO.get).mockResolvedValue(script);

await scriptService.allowUrl({
uuid: script.uuid,
matchPattern: "*://current.example/*",
excludePattern: "*://current.example/*",
});

expect(savedSelfMetadata()).toEqual({
match: ["*://allowed.example/*", "*://current.example/*"],
exclude: [],
});
});

it("因排除规则不生效时应移除当前站点排除而不创建匹配覆盖", async () => {
const script = createMockScript({ selfMetadata: { exclude: ["*://current.example/*"] } });
vi.mocked(mockScriptDAO.get).mockResolvedValue(script);

await scriptService.allowUrl({
uuid: script.uuid,
matchPattern: "*://current.example/*",
excludePattern: "*://current.example/*",
});

expect(savedSelfMetadata()).toEqual({ exclude: [] });
});
});

describe("resetMatch / resetExclude - 编辑器匹配列表", () => {
it("传入 undefined(重置)应删除用户覆盖", async () => {
const script = createMockScript({ selfMetadata: { match: ["*://user.com/*"] } });
Expand Down
29 changes: 29 additions & 0 deletions src/app/service/service_worker/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,33 @@ export class ScriptService {
});
}

async onlyRunOnUrl({ uuid, matchPattern }: { uuid: string; matchPattern: string }) {
return this.resetMatch({ uuid, match: [matchPattern] });
}

async allowUrl({
uuid,
matchPattern,
excludePattern,
}: {
uuid: string;
matchPattern: string;
excludePattern: string;
}) {
let script = await this.scriptDAO.get(uuid);
if (!script) throw new Error("script not found");
if (script.selfMetadata?.match !== undefined) {
script = selfMetadataUpdate(script, "match", new Set([...script.selfMetadata.match, matchPattern]));
}
const excludeSet = new Set(script.selfMetadata?.exclude || script.metadata?.exclude || []);
excludeSet.delete(excludePattern);
script = selfMetadataUpdate(script, "exclude", excludeSet);
return this.scriptDAO.update(uuid, script).then(() => {
this.publishInstallScript(script, { update: true });
return true;
});
}

async resetExclude({ uuid, exclude }: { uuid: string; exclude: string[] | undefined }) {
let script = await this.scriptDAO.get(uuid);
if (!script) {
Expand Down Expand Up @@ -1668,6 +1695,8 @@ export class ScriptService {
this.group.on("getFilterResult", this.getFilterResult.bind(this));
this.group.on("getScriptRunResourceByUUID", this.getScriptRunResourceByUUID.bind(this));
this.group.on("excludeUrl", this.excludeUrl.bind(this));
this.group.on("onlyRunOnUrl", this.onlyRunOnUrl.bind(this));
this.group.on("allowUrl", this.allowUrl.bind(this));
this.group.on("resetMatch", this.resetMatch.bind(this));
this.group.on("resetExclude", this.resetExclude.bind(this));
this.group.on("requestCheckUpdate", this.requestCheckUpdate.bind(this));
Expand Down
2 changes: 2 additions & 0 deletions src/locales/de-DE/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Kopieren",
"exclude_on": "Wiederherstellen auf $0 zur Ausführung",
"exclude_off": "Ausschließen auf $0 zur Ausführung",
"only_on_site": "Nur auf $0 ausführen",
"allow_on_site": "Ausführung auf $0 zulassen",
"confirm_error": "Bestätigung fehlgeschlagen",
"import": "Importieren",
"error": "Fehler",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/de-DE/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Popup-Layout",
"compact_popup_layout": "Kompaktes Popup-Layout",
"compact_popup_layout_desc": "Verringert die Abstände zwischen Bereichen und Skriptzeilen im Popup",
"popup_site_scope_actions": "Aktionen für den Website-Bereich",
"popup_site_scope_actions_desc": "Zeigt im Popup Schnellaktionen an, um ein Skript auf der aktuellen Website einzuschränken oder zuzulassen",
"script_update_check_frequency": "Häufigkeit der Skript-Aktualisierungsprüfung",
"script_auto_update_frequency": "Frequenz der automatischen Skript-Update-Prüfung",
"control_script_update_behavior": "Skript-Update-Verhalten kontrollieren",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en-US/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Copy",
"exclude_on": "Reinstate $0's execution",
"exclude_off": "Exclude $0's execution",
"only_on_site": "Run only on $0",
"allow_on_site": "Allow execution on $0",
"confirm_error": "Confirmation Failed",
"import": "Import",
"error": "Error",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en-US/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Popup Layout",
"compact_popup_layout": "Compact Popup Layout",
"compact_popup_layout_desc": "Reduce spacing between popup sections and script rows",
"popup_site_scope_actions": "Site scope actions",
"popup_site_scope_actions_desc": "Show quick actions in the popup to restrict or allow a script on the current site",
"script_update_check_frequency": "Script Update Check Frequency",
"script_auto_update_frequency": "Script automatic update check frequency",
"control_script_update_behavior": "Control script update behavior",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ja-JP/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "コピー",
"exclude_on": "$0の実行を復元",
"exclude_off": "$0の実行を除外",
"only_on_site": "$0 でのみ実行",
"allow_on_site": "$0 での実行を許可",
"confirm_error": "確認に失敗しました",
"import": "インポート",
"error": "エラー",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ja-JP/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "ポップアップレイアウト",
"compact_popup_layout": "コンパクトなポップアップ",
"compact_popup_layout_desc": "ポップアップのセクションとスクリプト行の間隔を狭くします",
"popup_site_scope_actions": "サイト範囲の操作",
"popup_site_scope_actions_desc": "現在のサイトでスクリプトの実行を制限または許可するクイック操作をポップアップに表示します",
"script_update_check_frequency": "スクリプト更新の確認頻度",
"script_auto_update_frequency": "スクリプトの自動更新確認頻度",
"control_script_update_behavior": "スクリプト更新の動作を制御",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ko-KR/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "복사",
"exclude_on": "$0에서 다시 실행",
"exclude_off": "$0에서 실행 제외",
"only_on_site": "$0에서만 실행",
"allow_on_site": "$0에서 실행 허용",
"confirm_error": "확인 실패",
"import": "가져오기",
"error": "오류",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ko-KR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "팝업 레이아웃",
"compact_popup_layout": "간격을 줄인 팝업 레이아웃",
"compact_popup_layout_desc": "팝업 섹션과 스크립트 행 사이의 간격을 줄입니다",
"popup_site_scope_actions": "사이트 범위 작업",
"popup_site_scope_actions_desc": "현재 사이트에서 스크립트를 제한하거나 허용하는 빠른 작업을 팝업에 표시합니다",
"script_update_check_frequency": "스크립트 업데이트 확인 주기",
"script_auto_update_frequency": "스크립트 자동 업데이트 확인 주기",
"control_script_update_behavior": "스크립트 업데이트 동작 제어",
Expand Down
4 changes: 3 additions & 1 deletion src/locales/pt-BR/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Copiar",
"exclude_on": "Restaurar a execução de $0",
"exclude_off": "Impedir a execução em $0",
"only_on_site": "Executar somente em $0",
"allow_on_site": "Permitir execução em $0",
"confirm_error": "Falha na confirmação",
"import": "Importar",
"error": "Erro",
Expand Down Expand Up @@ -94,4 +96,4 @@
"s3_secret_access_key": "Chave de acesso secreta",
"s3_custom_endpoint": "Endpoint personalizado (opcional)",
"cancel": "Cancelar"
}
}
2 changes: 2 additions & 0 deletions src/locales/pt-BR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Layout do popup",
"compact_popup_layout": "Layout compacto do popup",
"compact_popup_layout_desc": "Reduzir o espaçamento entre as seções do popup e as linhas de scripts",
"popup_site_scope_actions": "Ações de escopo do site",
"popup_site_scope_actions_desc": "Mostrar no popup ações rápidas para restringir ou permitir um script no site atual",
"script_update_check_frequency": "Frequência de verificação de atualização de scripts",
"script_auto_update_frequency": "Frequência de verificação automática de atualização de scripts",
"control_script_update_behavior": "Controlar o comportamento de atualização de scripts",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ru-RU/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Копировать",
"exclude_on": "Восстановить в $0 выполнении",
"exclude_off": "Исключить в $0 выполнении",
"only_on_site": "Выполнять только на $0",
"allow_on_site": "Разрешить выполнение на $0",
"confirm_error": "Ошибка подтверждения",
"import": "Импорт",
"error": "Ошибка",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/ru-RU/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Макет всплывающего окна",
"compact_popup_layout": "Компактное всплывающее окно",
"compact_popup_layout_desc": "Уменьшает отступы между разделами и строками скриптов во всплывающем окне",
"popup_site_scope_actions": "Действия для области сайтов",
"popup_site_scope_actions_desc": "Показывать во всплывающем окне быстрые действия для ограничения или разрешения скрипта на текущем сайте",
"script_update_check_frequency": "Частота проверки обновления скрипта",
"script_auto_update_frequency": "Частота автоматической проверки обновлений скриптов",
"control_script_update_behavior": "Управление поведением обновления скриптов",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/tr-TR/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Kopyala",
"exclude_on": "$0 yürütmesini yeniden etkinleştir",
"exclude_off": "$0 yürütmesini dışla",
"only_on_site": "Yalnızca $0 üzerinde çalıştır",
"allow_on_site": "$0 üzerinde çalışmasına izin ver",
"confirm_error": "Onay başarısız",
"import": "İçe Aktar",
"error": "Hata",
Expand Down
14 changes: 8 additions & 6 deletions src/locales/tr-TR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Açılır Pencere Düzeni",
"compact_popup_layout": "Kompakt Açılır Pencere Düzeni",
"compact_popup_layout_desc": "Açılır penceredeki bölümler ve betik satırları arasındaki boşluğu azaltır",
"popup_site_scope_actions": "Site kapsamı işlemleri",
"popup_site_scope_actions_desc": "Geçerli sitede bir betiği kısıtlamak veya çalışmasına izin vermek için açılır pencerede hızlı işlemler gösterir",
"script_update_check_frequency": "Betik Güncelleme Denetimi Sıklığı",
"script_auto_update_frequency": "Betik Otomatik Güncelleme Denetimi Sıklığı",
"control_script_update_behavior": "Betik güncelleme davranışını kontrol et",
Expand Down Expand Up @@ -100,16 +102,16 @@
"title": "Arka Planda Çalıştırmayı Etkinleştir",
"description": "Etkinleştirildiğinde, tüm pencereleri kapattıktan sonra tarayıcı arka planda çalışmaya devam eder ve siz tarayıcıyı manuel olarak kapatana kadar sistem tepsisine küçülür. Bu, arka plan betiklerinin çalışmaya devam etmesini sağlar.",
"enable_failed": "Etkinleştirilemedi",
"enable_success": "Etkinleştirildi",
"disable_failed": "Devre Dışı Bırakılamadı",
"disable_success": "Devre Dışı Bırakıldı",
"prompt_title": "Arka planda çalıştırma etkinleştirilsin mi?",
"prompt_description": "Bu bir {{scriptType}}. Arka planda çalıştırmayı etkinleştirmek, tarayıcı kapatıldıktan sonra betiğin çalışmaya devam etmesini sağlar.",
"enable_success": "Etkinleştirildi",
"disable_failed": "Devre Dışı Bırakılamadı",
"disable_success": "Devre Dışı Bırakıldı",
"prompt_title": "Arka planda çalıştırma etkinleştirilsin mi?",
"prompt_description": "Bu bir {{scriptType}}. Arka planda çalıştırmayı etkinleştirmek, tarayıcı kapatıldıktan sonra betiğin çalışmaya devam etmesini sağlar.",
"enable_now": "Şimdi Etkinleştir",
"maybe_later": "Daha Sonra",
"settings_hint": "Bu seçeneği istediğiniz zaman ayarlardan değiştirebilirsiniz."
},
"keep_scripts_alive": {
"keep_scripts_alive": {
"title": "Arka Plan ve Zamanlanmış Betikleri Canlı Tut",
"description": "ScriptCat'in arka plan çalışma ortamını etkin tutarak Arka Plan Betikleri ve Zamanlanmış Betiklerin çalışmaya devam etmesini sağlar. Bu özellik deneyseldir, tarayıcı tarafından garanti edilmez ve biraz daha fazla kaynak kullanabilir.",
"enable_failed": "Etkinleştirilemedi",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/vi-VN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "Sao chép",
"exclude_on": "Cho phép chạy lại $0",
"exclude_off": "Loại trừ chạy $0",
"only_on_site": "Chỉ chạy trên $0",
"allow_on_site": "Cho phép chạy trên $0",
"confirm_error": "Xác nhận thất bại",
"import": "Nhập",
"error": "Lỗi",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/vi-VN/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "Bố cục cửa sổ bật lên",
"compact_popup_layout": "Bố cục cửa sổ bật lên thu gọn",
"compact_popup_layout_desc": "Giảm khoảng cách giữa các mục và hàng script trong cửa sổ bật lên",
"popup_site_scope_actions": "Thao tác phạm vi trang",
"popup_site_scope_actions_desc": "Hiển thị thao tác nhanh trong cửa sổ bật lên để giới hạn hoặc cho phép script trên trang hiện tại",
"script_update_check_frequency": "Tần suất kiểm tra cập nhật tập lệnh",
"script_auto_update_frequency": "Tần suất kiểm tra cập nhật script tự động",
"control_script_update_behavior": "Kiểm soát hành vi cập nhật script",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "复制",
"exclude_on": "恢复在 $0 上执行",
"exclude_off": "排除在 $0 上执行",
"only_on_site": "仅在 $0 执行",
"allow_on_site": "允许在 $0 执行",
"confirm_error": "确认失败",
"import": "导入",
"error": "错误",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/zh-CN/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "弹窗布局",
"compact_popup_layout": "紧凑弹窗布局",
"compact_popup_layout_desc": "减少弹窗分组与脚本行之间的间距",
"popup_site_scope_actions": "站点范围快捷操作",
"popup_site_scope_actions_desc": "在弹窗中显示仅在当前站点执行或允许当前站点执行的快捷操作",
"script_update_check_frequency": "脚本更新检查频率",
"script_auto_update_frequency": "脚本自动检查更新的频率",
"control_script_update_behavior": "控制脚本更新的行为",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/zh-TW/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"copy": "複製",
"exclude_on": "恢復 $0 的執行",
"exclude_off": "排除 $0 的執行",
"only_on_site": "僅在 $0 執行",
"allow_on_site": "允許在 $0 執行",
"confirm_error": "確認失敗",
"import": "匯入",
"error": "錯誤",
Expand Down
2 changes: 2 additions & 0 deletions src/locales/zh-TW/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"popup_layout": "彈出視窗版面",
"compact_popup_layout": "緊湊彈出視窗版面",
"compact_popup_layout_desc": "縮小彈出視窗區段與腳本列的間距",
"popup_site_scope_actions": "站點範圍快速操作",
"popup_site_scope_actions_desc": "在彈出視窗中顯示僅在目前站點執行或允許目前站點執行的快速操作",
"script_update_check_frequency": "腳本更新檢查頻率",
"script_auto_update_frequency": "腳本自動檢查更新的頻率",
"control_script_update_behavior": "控制腳本更新的行為",
Expand Down
6 changes: 4 additions & 2 deletions src/pages/options/routes/ScriptEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,15 @@ export default function ScriptEditor() {
return;
}
const code = await loadScriptCode(uuid);
dispatch({ type: "open", tab: { uuid, script, code, subView: "code", isChanged: false } });
const requestedView = searchParams.get("view");
const subView: SubView = requestedView === "setting" ? "setting" : "code";
dispatch({ type: "open", tab: { uuid, script, code, subView, isChanged: false } });
} else {
const tab = await emptyScript(template || "", target);
dispatch({ type: "open", tab });
}
},
[t]
[searchParams, t]
);

// 初始化:列表就绪后根据 URL uuid 打开
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,15 @@ describe("界面分区-popup 布局", () => {
fireEvent.click(compactSwitch);
expect(set).toHaveBeenCalledWith("popup_compact_layout", false);
});

it("站点范围快捷操作应默认关闭并保存开启结果", async () => {
get.mockResolvedValue(undefined);
render(<InterfaceSection register={() => () => {}} />);

const siteScopeSwitch = await screen.findByRole("switch", { name: "站点范围快捷操作" });
expect(siteScopeSwitch).not.toBeChecked();

fireEvent.click(siteScopeSwitch);
expect(set).toHaveBeenCalledWith("popup_site_scope_actions", true);
});
});
11 changes: 11 additions & 0 deletions src/pages/options/routes/Setting/sections/InterfaceSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function InterfaceSection({ register }: { register: (id: string) => (el:
const [expandNum, setExpandNum] = useSystemConfig("menu_expand_num");
const [favicon, setFavicon] = useSystemConfig("favicon_service");
const [popupCompactLayout, setPopupCompactLayout] = useSystemConfig("popup_compact_layout");
const [popupSiteScopeActions, setPopupSiteScopeActions] = useSystemConfig("popup_site_scope_actions");

return (
<SettingCard id="interface" title={t("settings:interface_settings")} register={register}>
Expand Down Expand Up @@ -56,6 +57,16 @@ export function InterfaceSection({ register }: { register: (id: string) => (el:
onCheckedChange={setPopupCompactLayout}
/>
</SettingRow>
<SettingRow
label={t("settings:popup_site_scope_actions")}
description={t("settings:popup_site_scope_actions_desc")}
>
<Switch
aria-label={t("settings:popup_site_scope_actions")}
checked={popupSiteScopeActions ?? false}
onCheckedChange={setPopupSiteScopeActions}
/>
</SettingRow>
<div className="text-[13px] font-semibold text-foreground pt-1">{t("settings:script_menu")}</div>
<SettingRow
label={t("settings:display_right_click_menu")}
Expand Down
Loading
Loading