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_list_expand_count": "Angezeigte Skripte in der Liste",
"script_list_expand_count_desc": "Anzahl der Skripte, die je Popup-Bereich ausgeklappt werden; der Rest wird eingeklappt. Bei 0 werden alle angezeigt",
"script_update_check_frequency": "Häufigkeit der Skript-Aktualisierungsprüfung",
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_list_expand_count": "Script List Expand Count",
"script_list_expand_count_desc": "Scripts shown in each popup section; the rest are collapsed. 0 shows all of them",
"script_update_check_frequency": "Script Update Check Frequency",
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_list_expand_count": "スクリプト一覧の展開数",
"script_list_expand_count_desc": "ポップアップの各セクションで展開表示するスクリプト数です。超えた分は折りたたまれ、0 の場合はすべて表示します",
"script_update_check_frequency": "スクリプト更新の確認頻度",
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_list_expand_count": "스크립트 목록 펼침 개수",
"script_list_expand_count_desc": "팝업의 각 섹션에서 펼쳐 표시할 스크립트 개수이며, 초과분은 접힙니다. 0이면 모두 표시합니다",
"script_update_check_frequency": "스크립트 업데이트 확인 주기",
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_list_expand_count": "Scripts visíveis na lista",
"script_list_expand_count_desc": "Quantidade de scripts expandidos em cada seção do popup; o restante fica recolhido. Com 0, todos são exibidos",
"script_update_check_frequency": "Frequência de verificação 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_list_expand_count": "Количество скриптов в списке",
"script_list_expand_count_desc": "Сколько скриптов разворачивать в каждом разделе всплывающего окна; остальные сворачиваются. При 0 отображаются все",
"script_update_check_frequency": "Частота проверки обновления скрипта",
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_list_expand_count": "Listede Gösterilen Betik Sayısı",
"script_list_expand_count_desc": "Açılır penceredeki her bölümde genişletilerek gösterilecek betik sayısıdır; fazlası daraltılır. 0 olduğunda tümü gösterilir",
"script_update_check_frequency": "Betik Güncelleme Denetimi Sıklığı",
Expand Down Expand Up @@ -102,16 +104,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_list_expand_count": "Số script hiển thị trong danh sách",
"script_list_expand_count_desc": "Số script mở rộng trong mỗi mục của cửa sổ bật lên, phần còn lại sẽ thu gọn; đặt 0 thì hiển thị tất cả",
"script_update_check_frequency": "Tần suất kiểm tra cập nhật tập lệnh",
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_list_expand_count": "脚本列表展开数量",
"script_list_expand_count_desc": "弹窗中每个分组展开显示的脚本数量,超出部分折叠;填 0 表示全部显示",
"script_update_check_frequency": "脚本更新检查频率",
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_list_expand_count": "腳本清單展開數量",
"script_list_expand_count_desc": "彈出視窗中每個區段展開顯示的腳本數量,超出部分摺疊;填 0 表示全部顯示",
"script_update_check_frequency": "腳本更新檢查頻率",
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,6 +55,17 @@ 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);
});
});

// 两个展开数量此前共用「展开数量 / 超过此数量时自动折叠」文案,用户误以为它管脚本列表(#1558)
Expand Down
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 @@ -17,6 +17,7 @@ export function InterfaceSection({ register }: { register: (id: string) => (el:
const [scriptListExpandNum, setScriptListExpandNum] = useSystemConfig("script_list_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 @@ -57,6 +58,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>
<SettingRow
label={t("settings:script_list_expand_count")}
description={t("settings:script_list_expand_count_desc")}
Expand Down
Loading
Loading