diff --git a/src/app/service/service_worker/runtime.ts b/src/app/service/service_worker/runtime.ts index 2158754d6..7643fe492 100644 --- a/src/app/service/service_worker/runtime.ts +++ b/src/app/service/service_worker/runtime.ts @@ -51,10 +51,6 @@ import { CompiledResourceDAO } from "@App/app/repo/resource"; import { setOnTabURLChanged } from "./url_monitor"; import { scriptToMenu, type TPopupPageLoadInfo } from "./popup_scriptmenu"; -// 避免使用版本号控制导致代码理解混乱 -// 用来清除 UserScript API 里的旧缓存 -const USERSCRIPTS_REGISTER_CONTROL = "a5564f38-d9b3-43d0-8520-3a2950d6a61d"; - const ORIGINAL_URLMATCH_SUFFIX = "{ORIGINAL}"; // 用于标记原始URLPatterns的后缀 const runtimeGlobal = { @@ -260,21 +256,12 @@ export class RuntimeService { } async waitInit() { - const [registerControl, cRuntimeStartFlag, compiledResources, allScripts] = await Promise.all([ - chrome.storage.local.get("userscripts_register_control"), + const [cRuntimeStartFlag, compiledResources, allScripts] = await Promise.all([ cacheInstance.get("runtimeStartFlag"), this.compiledResourceDAO.all(), this.scriptDAO.all(), ]); - if (registerControl?.userscripts_register_control !== USERSCRIPTS_REGISTER_CONTROL) { - await Promise.allSettled([ - chrome.userScripts?.unregister(), - chrome.scripting.unregisterContentScripts(), - chrome.storage.local.set({ userscripts_register_control: USERSCRIPTS_REGISTER_CONTROL }), - ]); - } - const unregisterScriptIds = [] as string[]; // 没有 CompiledResources 表示这是 没有启用脚本 或 代码有改变需要重新安装。 // 这个情况会把所有有效脚本跟Inject&Content脚本先取消注册。后续载入时会重新以新代码注册。 @@ -579,6 +566,32 @@ export class RuntimeService { if (!this.isUserScriptsAvailable) { // 未开启加上警告引导 this.showNoDeveloperModeWarning(); + let cid: ReturnType | number; + cid = setInterval(async () => { + if (!this.isUserScriptsAvailable) { + // 注:optional permission 的设计会触发 chrome.permissions.onAdded + // this.isUserScriptsAvailable 自动转为 true, 不需要检测 + try { + const scriptId = `undefined-test-${Date.now()}`; + await chrome.userScripts.register([ + { + id: scriptId, + js: [{ code: "void 0;" }], + matches: ["https://not-found.scriptcat.org/"], + world: "USER_SCRIPT", + }, + ]); + await chrome.userScripts.unregister({ ids: [scriptId] }); + } catch (_e) { + // 预期出错,不执行后续 + return; + } + } + clearInterval(cid); + cid = 0; + // 主要针对 Allow User Scripts 设计 + chrome.runtime.reload(); + }, 500); } // 初始化:加载黑名单 @@ -1379,12 +1392,16 @@ export class RuntimeService { if (forced ? false : !this.isUserScriptsAvailable || !this.isLoadScripts) { return; } - const result = await chrome.userScripts?.getScripts({ ids: uuids }); - if (!result) return; // 没 userScripts API 权限 - const filteredIds = result.map((entry) => entry.id).filter((id) => !!id); - if (filteredIds.length > 0) { - // 修改脚本状态为disable,浏览器取消注册该脚本 - await chrome.userScripts.unregister({ ids: filteredIds }); + try { + const result = await chrome.userScripts?.getScripts({ ids: uuids }); + if (!result || typeof result !== "object" || typeof result.length !== "number") return; // 没 userScripts API 权限 + const filteredIds = result.map((entry) => entry.id).filter((id) => !!id); + if (filteredIds.length > 0) { + // 修改脚本状态为disable,浏览器取消注册该脚本 + await chrome.userScripts.unregister({ ids: filteredIds }); + } + } catch (e) { + console.error("unregistryPageScripts error:", e); } } } diff --git a/src/locales/de-DE/translation.json b/src/locales/de-DE/translation.json index 8a3730f6a..083601764 100644 --- a/src/locales/de-DE/translation.json +++ b/src/locales/de-DE/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "Backup-Verzeichnis-Adresse abrufen fehlgeschlagen", "get_backup_files_failed": "Backup-Dateien abrufen fehlgeschlagen", "request_permission": "Beantragen Sie Genehmigungen", - "develop_mode_guide": "Der 'Entwicklermodus' ist derzeit nicht aktiviert, daher können die Skripte nicht richtig ausgeführt werden. 👉Hier klicken, um zu erfahren, wie man ihn aktiviert.", + "develop_mode_guide": "Der 'Entwicklermodus' ist derzeit nicht aktiviert, daher können die Skripte nicht richtig ausgeführt werden. 👉Hier klicken, um zu erfahren, wie man ihn aktiviert", "allow_user_script_guide": "'Nutzerskripts zulassen' ist derzeit nicht aktiviert, daher können die Skripte nicht richtig ausgeführt werden. 👉Hier klicken, um zu erfahren, wie man es aktiviert", "lower_version_browser_guide": "Ihr Browser ist zu veraltet, daher können die Skripte nicht richtig ausgeführt werden. 👉Hier klicken, um mehr zu erfahren", + "click_to_reload": "👉Zum Neuladen klicken", "confirm_leave_page": "Derzeit im Bearbeitungsstatus. Das Navigieren zu anderen Seiten führt zum Verlust des aktuellen Inhalts. Navigieren?", "page_in_blacklist": "Die aktuelle Seite ist auf der Blacklist und kann keine Skripte verwenden", "baidu_netdisk": "Baidu Netdisk", diff --git a/src/locales/en-US/translation.json b/src/locales/en-US/translation.json index 21a31e130..4bd83468b 100644 --- a/src/locales/en-US/translation.json +++ b/src/locales/en-US/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "Failed to get backup directory address", "get_backup_files_failed": "Failed to fetch backups", "request_permission": "Request Permission", - "develop_mode_guide": "'Developer mode' is currently not enabled, so the scripts cannot run properly. 👉tap to learn how to enable.", + "develop_mode_guide": "'Developer mode' is currently not enabled, so the scripts cannot run properly. 👉tap to learn how to enable", "allow_user_script_guide": "'Allow User Scripts' is currently not enabled, so the scripts cannot run properly. 👉tap to learn how to enable", "lower_version_browser_guide": "Your browser is too outdated, so the scripts cannot run properly. 👉Click me to learn more", + "click_to_reload": "👉Click to Reload", "confirm_leave_page": "Currently editing status. Leaving this page will lose the current content. Do you want to leave?", "page_in_blacklist": "The current page is blacklisted, cannot use script", "baidu_netdisk": "BaiduNetdisk", diff --git a/src/locales/ja-JP/translation.json b/src/locales/ja-JP/translation.json index 117c7dd3e..f6879e076 100644 --- a/src/locales/ja-JP/translation.json +++ b/src/locales/ja-JP/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "バックアップディレクトリアドレスの取得に失敗しました", "get_backup_files_failed": "バックアップファイルの取得に失敗しました", "request_permission": "権限をリクエストする", - "develop_mode_guide": "現在「デベロッパーモード」が有効ではないため、スクリプトは正常に動作しません。👉有効化の方法はこちら。", + "develop_mode_guide": "現在「デベロッパーモード」が有効ではないため、スクリプトは正常に動作しません。👉有効化の方法はこちら", "allow_user_script_guide": "現在「ユーザー スクリプトを許可する」が有効ではないため、スクリプトは正常に動作しません。👉有効化の方法はこちら", "lower_version_browser_guide": "ご使用のブラウザは古すぎるため、スクリプトは正常に動作しません。👉詳しくはこちら", + "click_to_reload": "👉再読み込みする", "confirm_leave_page": "現在編集中です。他のページに移動すると現在の内容が失われます。移動しますか?", "page_in_blacklist": "現在のページはブラックリストにあり、スクリプトを使用できません", "baidu_netdisk": "百度ネットディスク", diff --git a/src/locales/ru-RU/translation.json b/src/locales/ru-RU/translation.json index 8eae459ef..8778a813d 100644 --- a/src/locales/ru-RU/translation.json +++ b/src/locales/ru-RU/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "Ошибка получения адреса папки резервных копий", "get_backup_files_failed": "Ошибка получения файлов резервных копий", "request_permission": "Запрос разрешения", - "develop_mode_guide": "«Режим разработчика» сейчас отключён, поэтому скрипты не могут работать корректно. 👉Нажмите, чтобы узнать, как включить.", + "develop_mode_guide": "«Режим разработчика» сейчас отключён, поэтому скрипты не могут работать корректно. 👉Нажмите, чтобы узнать, как включить", "allow_user_script_guide": "«Разрешить пользовательские скрипты» сейчас отключён, поэтому скрипты не могут работать корректно. 👉Нажмите, чтобы узнать, как включить", "lower_version_browser_guide": "Ваш браузер слишком устарел, поэтому скрипты не могут работать корректно. 👉Нажмите, чтобы узнать подробнее", + "click_to_reload": "👉Нажмите для перезагрузки", "confirm_leave_page": "В настоящее время идет редактирование. Переход на другую страницу приведет к потере текущего содержимого. Продолжить переход?", "page_in_blacklist": "Текущая страница находится в черном списке, невозможно использовать скрипты", "baidu_netdisk": "Baidu Netdisk", diff --git a/src/locales/vi-VN/translation.json b/src/locales/vi-VN/translation.json index eb8bab518..3eae73afc 100644 --- a/src/locales/vi-VN/translation.json +++ b/src/locales/vi-VN/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "Không thể lấy địa chỉ thư mục sao lưu", "get_backup_files_failed": "Không thể lấy các bản sao lưu", "request_permission": "Yêu cầu quyền", - "develop_mode_guide": "'Chế độ nhà phát triển' hiện chưa được bật, nên các script không thể hoạt động đúng cách. 👉Nhấn để xem cách bật.", + "develop_mode_guide": "'Chế độ nhà phát triển' hiện chưa được bật, nên các script không thể hoạt động đúng cách. 👉Nhấn để xem cách bật", "allow_user_script_guide": "'Cho phép tập lệnh người dùng' hiện chưa được bật, nên các script không thể hoạt động đúng cách. 👉Nhấn để xem cách bật", "lower_version_browser_guide": "Trình duyệt của bạn quá cũ, nên các script không thể hoạt động đúng cách. 👉Nhấn để xem thêm", + "click_to_reload": "👉Nhấp chuột để tải lại", "confirm_leave_page": "Hiện đang ở trạng thái chỉnh sửa. Rời khỏi trang này sẽ làm mất nội dung hiện tại. Bạn có muốn rời đi không?", "page_in_blacklist": "Trang hiện tại nằm trong danh sách đen, không thể sử dụng script", "baidu_netdisk": "Baidunetdisk", diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index d7e855c69..f8428285b 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "获取备份目录地址失败", "get_backup_files_failed": "获取备份文件失败", "request_permission": "请求权限", - "develop_mode_guide": "当前未启用“开发者模式”,脚本无法正常运行。👉点击查看启用方法。", + "develop_mode_guide": "当前未启用“开发者模式”,脚本无法正常运行。👉点击查看启用方法", "allow_user_script_guide": "当前未启用“允许运行用户脚本”,脚本无法正常运行。👉点击查看启用方法", "lower_version_browser_guide": "您的浏览器版本过低,脚本无法正常运行。👉点击了解更多", + "click_to_reload": "👉点击重新加载", "confirm_leave_page": "当前正在编辑状态,跳转其它页面将会丢失当前内容,是否跳转?", "page_in_blacklist": "当前页面在黑名单中,无法使用脚本", "baidu_netdisk": "百度网盘", diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json index 01c09d6fd..cf7875439 100644 --- a/src/locales/zh-TW/translation.json +++ b/src/locales/zh-TW/translation.json @@ -412,9 +412,10 @@ "get_backup_dir_url_failed": "取得備份目錄網址失敗", "get_backup_files_failed": "取得備份檔案失敗", "request_permission": "要求權限", - "develop_mode_guide": "目前尚未啟用「開發者模式」,腳本無法正常執行。👉點此查看啟用方式。", + "develop_mode_guide": "目前尚未啟用「開發者模式」,腳本無法正常執行。👉點此查看啟用方式", "allow_user_script_guide": "目前尚未啟用「允許使用者指令碼」,腳本無法正常執行。👉點此查看啟用方式", "lower_version_browser_guide": "您的瀏覽器版本過舊,腳本無法正常執行。👉點擊了解更多", + "click_to_reload": "👉點擊重新載入", "confirm_leave_page": "目前正在編輯狀態,跳轉其他頁面將會遺失目前內容,是否跳轉?", "page_in_blacklist": "目前頁面在黑名單中,無法使用腳本", "baidu_netdisk": "百度網盤", diff --git a/src/pages/components/PopupWarnings/index.tsx b/src/pages/components/PopupWarnings/index.tsx index 26130078c..83b45eca4 100644 --- a/src/pages/components/PopupWarnings/index.tsx +++ b/src/pages/components/PopupWarnings/index.tsx @@ -123,11 +123,29 @@ function PopupWarnings({ isBlacklist }: PopupWarningsProps) { +
+
+ { + // 点击了刷新链接 + chrome.runtime.reload(); + ev.preventDefault(); + try { + window.close(); // 因为 Vivaldi 重启插件时不会关掉 popup + } catch (e) { + console.error(e); + } + }} + > + {t("click_to_reload")} + +
} /> )} diff --git a/src/pkg/utils/utils.ts b/src/pkg/utils/utils.ts index 495504f3c..362128b8b 100644 --- a/src/pkg/utils/utils.ts +++ b/src/pkg/utils/utils.ts @@ -179,36 +179,38 @@ export async function checkUserScriptsAvailable() { // Property access which throws if developer mode is not enabled. // Method call which throws if API permission or toggle is not enabled. chrome.userScripts; - const ret: chrome.userScripts.RegisteredUserScript[] | any = await chrome.userScripts?.getScripts({ - ids: ["scriptcat-content", "undefined-id-3"], - }); + // 没有 chrome.userScripts.getScripts 表示API不可使用 + if (typeof chrome.userScripts?.getScripts !== "function") return false; + const ret = await chrome.userScripts.getScripts({ ids: ["scriptcat-content", "scriptcat-inject"] }); // 返回结果不是阵列的话表示API不可使用 - if (ret === undefined || ret === null || typeof ret[Symbol.iterator] !== "function") { + if (!ret || typeof ret !== "object" || typeof ret.length !== "number") { return false; } - if (ret[0]) { + if (ret[0]?.id) { // API内部处理实际给予扩展权限才会有返回Script - // 含有 "scriptcat-content" 或 "undefined-id-3" + // 已有注册脚本 return true; } else { - // 没有 "scriptcat-content" 和 "undefined-id-3" - // 进行 "undefined-id-3" 的注册反注册测试 + const scriptId = `undefined-id-${Date.now()}`; // 使用随机id避免并发冲突 + // 没有注册脚本 + // 进行 ${scriptId} 的注册反注册测试 // Chrome MV3 的一部分浏览器(如 Vivaldi )没正确处理 MV3 UserScripts API 权限问题 (API内部处理没有给予扩展权限) // 此时会无法注册 (1. register 报错) await chrome.userScripts.register([ { - id: "undefined-id-3", + id: scriptId, js: [{ code: "void 0;" }], matches: ["https://not-found.scriptcat.org/"], world: "USER_SCRIPT", }, ]); - // 清掉测试内容 (2. 如没有注入 undefined-id-3 成功,因脚本id不存在 unregister 报错) - await chrome.userScripts.unregister({ ids: ["undefined-id-3"] }); + // 清掉测试内容 (2. 如没有注入 ${scriptId} 成功,因脚本id不存在 unregister 报错) + await chrome.userScripts.unregister({ ids: [scriptId] }); return true; } - } catch { + } catch (e) { + console.error("checkUserScriptsAvailable error:", e); // Not available. return false; }