Skip to content

🚧 firefox mv3兼容 #429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
4 changes: 3 additions & 1 deletion packages/filesystem/baidu/baidu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export default class BaiduFileSystem implements FileSystem {
id: 100,
action: {
type: "modifyHeaders" as chrome.declarativeNetRequest.RuleActionType,
responseHeaders: [{ operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE, header: "cookie" }],
responseHeaders: [
{ operation: "remove" as chrome.declarativeNetRequest.HeaderOperation, header: "cookie" },
],
},
condition: {
urlFilter: url,
Expand Down
1 change: 1 addition & 0 deletions src/app/service/content/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,6 @@ export default class ContentRuntime {
);
const client = new Client(this.msg, "inject");
client.do("pageLoad", { scripts });
console.log("pageLoad", scripts);
}
}
20 changes: 13 additions & 7 deletions src/app/service/service_worker/gm_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ export default class GMApi {
const requestHeaders = [
{
header: "X-Scriptcat-GM-XHR-Request-Id",
operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE,
operation: "remove" as chrome.declarativeNetRequest.HeaderOperation,
},
] as chrome.declarativeNetRequest.ModifyHeaderInfo[];
Object.keys(headers).forEach((key) => {
Expand All @@ -391,7 +391,7 @@ export default class GMApi {
if (headers[key]) {
requestHeaders.push({
header: key,
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
operation: "set" as chrome.declarativeNetRequest.HeaderOperation,
value: headers[key],
});
}
Expand All @@ -400,7 +400,7 @@ export default class GMApi {
} else {
requestHeaders.push({
header: key,
operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE,
operation: "remove" as chrome.declarativeNetRequest.HeaderOperation,
});
delete headers[key];
}
Expand All @@ -411,14 +411,14 @@ export default class GMApi {
if (params.cookie) {
requestHeaders.push({
header: "cookie",
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
operation: "set" as chrome.declarativeNetRequest.HeaderOperation,
value: params.cookie,
});
} else {
// 否则删除cookie
requestHeaders.push({
header: "cookie",
operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE,
operation: "remove" as chrome.declarativeNetRequest.HeaderOperation,
});
}
} else if (params.cookie) {
Expand Down Expand Up @@ -923,6 +923,12 @@ export default class GMApi {

// 处理GM_xmlhttpRequest请求
handlerGmXhr() {
const reqOpt = ["requestHeaders"];
const respOpt = ["responseHeaders"];
if (!isFirefox()) {
reqOpt.push("extraHeaders");
respOpt.push("extraHeaders");
}
chrome.webRequest.onBeforeSendHeaders.addListener(
(details) => {
if (details.tabId === -1) {
Expand All @@ -940,7 +946,7 @@ export default class GMApi {
urls: ["<all_urls>"],
types: ["xmlhttprequest"],
},
["requestHeaders", "extraHeaders"]
reqOpt
);
chrome.webRequest.onHeadersReceived.addListener(
(details) => {
Expand All @@ -964,7 +970,7 @@ export default class GMApi {
urls: ["<all_urls>"],
types: ["xmlhttprequest"],
},
["responseHeaders", "extraHeaders"]
respOpt
);
}

Expand Down
69 changes: 35 additions & 34 deletions src/app/service/service_worker/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import PermissionVerify from "./permission_verify";
import { SystemConfig } from "@App/pkg/config/config";
import { ResourceService } from "./resource";
import { LocalStorageDAO } from "@App/app/repo/localStorage";
import Logger from "@App/app/logger/logger";

// 为了优化性能,存储到缓存时删除了code、value与resource
export interface ScriptMatchInfo extends ScriptRunResouce {
Expand Down Expand Up @@ -299,6 +300,7 @@ export class RuntimeService {
scripts: enableScript,
});

console.log("pageLoad", enableScript);
return Promise.resolve({ flag: scriptFlag, scripts: enableScript });
}

Expand All @@ -323,13 +325,29 @@ export class RuntimeService {
let messageFlag = await this.getMessageFlag();
if (!messageFlag) {
messageFlag = await this.messageFlag();
const injectJs = await fetch("inject.js").then((res) => res.text());
const injectJs = await fetch("/src/inject.js").then((res) => res.text());
// 替换ScriptFlag
const code = `(function (MessageFlag) {\n${injectJs}\n})('${messageFlag}')`;
chrome.userScripts.configureWorld({
csp: "script-src 'self' 'unsafe-inline' 'unsafe-eval' *",
messaging: true,
});
try {
// 注册content.js
await chrome.scripting.registerContentScripts([
{
id: "scriptcat-content",
js: ["/src/content.js"],
matches: ["<all_urls>"],
allFrames: true,
runAt: "document_start",
world: "ISOLATED",
},
]);
} catch (e) {
LoggerCore.logger().error("update inject.js error", Logger.E(e));
throw e;
}
const scripts: chrome.userScripts.RegisteredUserScript[] = [
{
id: "scriptcat-inject",
Expand All @@ -339,33 +357,20 @@ export class RuntimeService {
world: "MAIN",
runAt: "document_start",
},
// 注册content
{
id: "scriptcat-content",
js: [{ file: "src/content.js" }],
matches: ["<all_urls>"],
allFrames: true,
runAt: "document_start",
world: "USER_SCRIPT",
},
];
try {
// 如果使用getScripts来判断, 会出现找不到的问题
// 另外如果使用
await chrome.userScripts.register(scripts);
} catch (e: any) {
LoggerCore.logger().error("register inject.js error", {
error: e,
});
LoggerCore.logger().error("register inject.js error", Logger.E(e));
if (e.message?.indexOf("Duplicate script ID") !== -1) {
// 如果是重复注册, 则更新
chrome.userScripts.update(scripts, () => {
if (chrome.runtime.lastError) {
LoggerCore.logger().error("update inject.js error", {
error: chrome.runtime.lastError,
});
}
});
try {
await chrome.userScripts.update(scripts);
} catch (e) {
LoggerCore.logger().error("update inject.js error", Logger.E(e));
}
}
}
}
Expand Down Expand Up @@ -536,21 +541,17 @@ export class RuntimeService {
},
});
if (res.length > 0) {
await chrome.userScripts.update([registerScript], () => {
if (chrome.runtime.lastError) {
logger.error("update registerScript error", {
error: chrome.runtime.lastError,
});
}
});
try {
await chrome.userScripts.update([registerScript]);
} catch (e) {
logger.error("update registerScript error", Logger.E(e));
}
} else {
await chrome.userScripts.register([registerScript], () => {
if (chrome.runtime.lastError) {
logger.error("registerScript error", {
error: chrome.runtime.lastError,
});
}
});
try {
await chrome.userScripts.register([registerScript]);
} catch (e) {
logger.error("registerScript error", Logger.E(e));
}
}
await Cache.getInstance().set("registryScript:" + script.uuid, true);
}
Expand Down
8 changes: 5 additions & 3 deletions src/app/service/service_worker/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ export class ScriptService {

listenerScriptInstall() {
// 初始化脚本安装监听
console.log("init script install listener");
chrome.webRequest.onBeforeRequest.addListener(
(req: chrome.webRequest.WebRequestBodyDetails) => {
console.log(req);
// 处理url, 实现安装脚本
if (req.method !== "GET") {
return;
Expand Down Expand Up @@ -101,9 +103,9 @@ export class ScriptService {
},
{
urls: [
"https://docs.scriptcat.org/docs/script_installation/",
"https://docs.scriptcat.org/en/docs/script_installation/",
"https://www.tampermonkey.net/script_installation.php",
"https://docs.scriptcat.org/docs/script_installation/*",
"https://docs.scriptcat.org/en/docs/script_installation/*",
"https://www.tampermonkey.net/script_installation.php*",
],
types: ["main_frame"],
}
Expand Down
2 changes: 1 addition & 1 deletion src/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const loggerCore = new LoggerCore({

const client = new RuntimeClient(send);
client.pageLoad().then((data) => {
loggerCore.logger().debug("content start");
loggerCore.logger().debug("content start",chrome.runtime);
const extMsg = new ExtensionMessage();
const msg = new CustomEventMessage(data.flag, true);
const server = new Server("content", msg);
Expand Down
1 change: 1 addition & 0 deletions src/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const server = new Server("inject", msg);
server.on("pageLoad", (data: { scripts: ScriptRunResouce[] }) => {
logger.logger().debug("inject start");
// 监听事件
console.log("pageLoad", data);
const runtime = new InjectRuntime(server, msg, data.scripts);
runtime.start();
});
3 changes: 3 additions & 0 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"unlimitedStorage",
"declarativeNetRequest"
],
"optional_permissions": [
"userScripts"
],
"host_permissions": [
"<all_urls>"
],
Expand Down
20 changes: 16 additions & 4 deletions src/pages/popup/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import ScriptMenuList from "../components/ScriptMenuList";
import { popupClient } from "../store/features/script";
import { ScriptMenu } from "@App/app/service/service_worker/popup";
import { systemConfig } from "../store/global";
import { isUserScriptsAvailable } from "@App/pkg/utils/utils";
import { isFirefox, isUserScriptsAvailable } from "@App/pkg/utils/utils";

const CollapseItem = Collapse.Item;

Expand Down Expand Up @@ -86,9 +86,21 @@ function App() {
}, []);
return (
<>
{!isUserScriptsAvailable() && (
<Alert type="warning" content={<div dangerouslySetInnerHTML={{ __html: t("develop_mode_guide") }} />} />
)}
{!isUserScriptsAvailable() &&
(isFirefox() ? (
<>
<Alert type="warning" content={<div dangerouslySetInnerHTML={{ __html: t("develop_mode_guide") }} />} />
<Button
onClick={() => {
chrome.permissions.request({ permissions: ["userScripts"] });
}}
>
申请权限
</Button>
</>
) : (
<Alert type="warning" content={<div dangerouslySetInnerHTML={{ __html: t("develop_mode_guide") }} />} />
))}
<Card
size="small"
title={
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ export function isUserScriptsAvailable() {
try {
// Property access which throws if developer mode is not enabled.
chrome.userScripts;
return true;
// 兼容chrome的写法
return !!chrome.userScripts;
} catch {
// Not available.
return false;
Expand Down