From 8bce4438766af0dda90bb87571f3b66c15d8683b Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 29 Oct 2025 07:38:13 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E9=80=9A=E8=BF=87GitHub=E9=93=BE=E6=8E=A5=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/script.ts | 33 +++++++++++------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index e946e4804..92bc96b12 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -5,13 +5,7 @@ import Logger from "@App/app/logger/logger"; import LoggerCore from "@App/app/logger/core"; import { cacheInstance } from "@App/app/cache"; import { CACHE_KEY_SCRIPT_INFO } from "@App/app/cache_key"; -import { - checkSilenceUpdate, - getBrowserType, - getStorageName, - openInCurrentTab, - stringMatching, -} from "@App/pkg/utils/utils"; +import { checkSilenceUpdate, getStorageName, openInCurrentTab, stringMatching } from "@App/pkg/utils/utils"; import { ltever } from "@App/pkg/utils/semver"; import type { SCMetadata, @@ -161,25 +155,28 @@ export class ScriptService { ); // 兼容 chrome 内核 < 128 处理 const condition: chrome.declarativeNetRequest.RuleCondition = { - regexFilter: "^([^#]+?)\\.user(\\.bg|\\.sub)?\\.js((\\?).*|$)", + regexFilter: "^[^#]+\\.user(\\.bg|\\.sub)?\\.js(\\?.*?)?$", resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], - }; - const browserType = getBrowserType(); - if (browserType.chrome && browserType.chromeVersion >= 128) { - condition.excludedResponseHeaders = [ + responseHeaders: [ { header: "Content-Type", - values: ["text/html"], + values: [ + "text/javascript*", + "application/javascript*", + "text/html*", + "text/plain*", + "application/octet-stream*", + "application/force-download*", + ], }, - ]; - } else { - condition.excludedRequestDomains = ["github.com"]; - } + ], + isUrlFilterCaseSensitive: true, + }; // 重定向到脚本安装页 chrome.declarativeNetRequest.updateDynamicRules( { - removeRuleIds: [1, 2], + removeRuleIds: [1], addRules: [ { id: 1, From b0e4f9fa3631a5bbf0c8fbb7b518ca420b768a1a Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 2 Nov 2025 00:48:35 +0900 Subject: [PATCH 2/4] Update script.ts --- src/app/service/service_worker/script.ts | 124 +++++++++++++++++------ 1 file changed, 92 insertions(+), 32 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 92bc96b12..89dce4cd0 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -5,7 +5,13 @@ import Logger from "@App/app/logger/logger"; import LoggerCore from "@App/app/logger/core"; import { cacheInstance } from "@App/app/cache"; import { CACHE_KEY_SCRIPT_INFO } from "@App/app/cache_key"; -import { checkSilenceUpdate, getStorageName, openInCurrentTab, stringMatching } from "@App/pkg/utils/utils"; +import { + checkSilenceUpdate, + getBrowserType, + getStorageName, + openInCurrentTab, + stringMatching, +} from "@App/pkg/utils/utils"; import { ltever } from "@App/pkg/utils/semver"; import type { SCMetadata, @@ -154,42 +160,96 @@ export class ScriptService { } ); // 兼容 chrome 内核 < 128 处理 - const condition: chrome.declarativeNetRequest.RuleCondition = { - regexFilter: "^[^#]+\\.user(\\.bg|\\.sub)?\\.js(\\?.*?)?$", - resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], - requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], - responseHeaders: [ - { - header: "Content-Type", - values: [ - "text/javascript*", - "application/javascript*", - "text/html*", - "text/plain*", - "application/octet-stream*", - "application/force-download*", + const browserType = getBrowserType(); + const addResponseHeaders = browserType.chrome && browserType.chromeVersion >= 128; + const conditions: chrome.declarativeNetRequest.RuleCondition[] = [ + { + regexFilter: "^[^?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + excludedRequestDomains: ["github.com", "gitlab.com", "gitea.com", "bitbucket.org"], + }, + { + regexFilter: + "^https?://github.com/[^\\s/?#]+/[^\\s/?#]+/releases/([^\\s.?#]+/|)[^.?#]+.user(\\.bg|\\.sub)?.js([?#][^./\\s#?]*?)*?$", + // https://github.com///releases/latest/download/file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + }, + { + regexFilter: + "^https?://github.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z]+/([^\\s.?#]+/|)[^.?#]+.user(\\.bg|\\.sub)?.js([?#][^./\\s#?]*?)*?$", + // https://github.com///raw/refs/heads/main/.../file.user.js + // https://github.com///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + }, + { + regexFilter: + "^https?://gitlab\\.com/[^\\s/?#]+/[^\\s/?#]+/-/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + // https://gitlab.com///-/raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + }, + { + regexFilter: + "^https?://gitea\\.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + // https://gitea.com///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + }, + { + regexFilter: + "^https?://bitbucket\\.org/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + // https://bitbucket.org///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + }, + ]; + const rules = conditions.map((condition, idx) => { + Object.assign(condition, { + excludedTabIds: [chrome.tabs.TAB_ID_NONE], + }); + if (addResponseHeaders) { + Object.assign(condition, { + responseHeaders: [ + { + header: "Content-Type", + values: [ + "text/javascript*", + "application/javascript*", + "text/html*", + "text/plain*", + "application/octet-stream*", + "application/force-download*", + ], + }, ], + }); + } + return { + id: 1000 + idx, + priority: 1, + action: { + type: "redirect" as chrome.declarativeNetRequest.RuleActionType, + redirect: { + regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\0`, + }, }, - ], - isUrlFilterCaseSensitive: true, - }; + condition: condition, + } as chrome.declarativeNetRequest.Rule; + }); // 重定向到脚本安装页 chrome.declarativeNetRequest.updateDynamicRules( { - removeRuleIds: [1], - addRules: [ - { - id: 1, - priority: 1, - action: { - type: "redirect" as chrome.declarativeNetRequest.RuleActionType, - redirect: { - regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\0`, - }, - }, - condition: condition, - }, - ], + removeRuleIds: [1, ...rules.map((rule) => rule.id)], + addRules: rules, }, () => { if (chrome.runtime.lastError) { From 65c3e8c90abfcadbbed4796429efe56b063a746a Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 16 Nov 2025 00:40:06 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E9=80=9A=E8=BF=87GitHub=E9=93=BE=E6=8E=A5=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/script.ts | 44 +++++++++++++++++++----- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 89dce4cd0..5333fc408 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -162,54 +162,82 @@ export class ScriptService { // 兼容 chrome 内核 < 128 处理 const browserType = getBrowserType(); const addResponseHeaders = browserType.chrome && browserType.chromeVersion >= 128; + // Chrome 84+ const conditions: chrome.declarativeNetRequest.RuleCondition[] = [ { - regexFilter: "^[^?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + regexFilter: "^([^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // Chrome 84+ + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], // Chrome 84+ + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, // Chrome 84+ + excludedRequestDomains: ["github.com", "gitlab.com", "gitea.com", "bitbucket.org"], // Chrome 101+ + }, + { + regexFilter: "^(.+?\\.user(\\.bg|\\.sub)?\\.js&response-content-type=application%2Foctet-stream)", resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ isUrlFilterCaseSensitive: false, - excludedRequestDomains: ["github.com", "gitlab.com", "gitea.com", "bitbucket.org"], + requestDomains: ["githubusercontent.com"], // Chrome 101+ }, { regexFilter: - "^https?://github.com/[^\\s/?#]+/[^\\s/?#]+/releases/([^\\s.?#]+/|)[^.?#]+.user(\\.bg|\\.sub)?.js([?#][^./\\s#?]*?)*?$", + "^(https?:\\/\\/github.com\\/[^\\s/?#]+\\/[^\\s/?#]+\\/releases/[^\\s/?#]+/download/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // https://github.com///releases/latest/download/file.user.js resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ }, { regexFilter: - "^https?://github.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z]+/([^\\s.?#]+/|)[^.?#]+.user(\\.bg|\\.sub)?.js([?#][^./\\s#?]*?)*?$", + "^(https?:\\/\\/gitlab\\.com\\/[^\\s/?#]+\\/[^\\s/?#]+\\/-\\/raw\\/[a-z0-9_/.-]+\\/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["gitlab.com"], // Chrome 101+ + }, + { + regexFilter: "^(https?:\\/\\/github\\.com\\/[^\\/]+\\/[^\\/]+\\/releases\\/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://github.com///releases/latest/download/file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ + }, + { + regexFilter: "^(https?://github.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z]+/[^?#]+?.user(\\.bg|\\.sub)?.js)", // https://github.com///raw/refs/heads/main/.../file.user.js // https://github.com///raw//.../file.user.js resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ }, { regexFilter: - "^https?://gitlab\\.com/[^\\s/?#]+/[^\\s/?#]+/-/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + "^(https?://gitlab\\.com/[^\\s/?#]+/[^\\s/?#]+/-/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // https://gitlab.com///-/raw//.../file.user.js resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], isUrlFilterCaseSensitive: false, + requestDomains: ["gitlab.com"], // Chrome 101+ }, { regexFilter: - "^https?://gitea\\.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + "^(https?://gitea\\.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // https://gitea.com///raw//.../file.user.js resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], isUrlFilterCaseSensitive: false, + requestDomains: ["gitea.com"], // Chrome 101+ }, { regexFilter: - "^https?://bitbucket\\.org/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/([^\\s.?#]+/|)[^.?#]+\\.user(\\.bg|\\.sub)?\\.js([?#][^./\\s#?]*?)*?$", + "^(https?://bitbucket\\.org/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // https://bitbucket.org///raw//.../file.user.js resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], isUrlFilterCaseSensitive: false, + requestDomains: ["bitbucket.org"], // Chrome 101+ }, ]; const rules = conditions.map((condition, idx) => { @@ -239,7 +267,7 @@ export class ScriptService { action: { type: "redirect" as chrome.declarativeNetRequest.RuleActionType, redirect: { - regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\0`, + regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\1`, }, }, condition: condition, From 1a7bd4c35d60231956f638b0376bb7fa75e04a50 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 16 Nov 2025 01:14:44 +0900 Subject: [PATCH 4/4] updateDynamicRules -> updateSessionRules --- src/app/service/service_worker/script.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 5333fc408..1a6b54d80 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -276,8 +276,7 @@ export class ScriptService { // 重定向到脚本安装页 chrome.declarativeNetRequest.updateDynamicRules( { - removeRuleIds: [1, ...rules.map((rule) => rule.id)], - addRules: rules, + removeRuleIds: [1], }, () => { if (chrome.runtime.lastError) { @@ -288,6 +287,20 @@ export class ScriptService { } } ); + chrome.declarativeNetRequest.updateSessionRules( + { + removeRuleIds: [...rules.map((rule) => rule.id)], + addRules: rules, + }, + () => { + if (chrome.runtime.lastError) { + console.error( + "chrome.runtime.lastError in chrome.declarativeNetRequest.updateSessionRules:", + chrome.runtime.lastError + ); + } + } + ); } public async openInstallPageByUrl(url: string, source: InstallSource): Promise<{ success: boolean; msg: string }> {