optimize inject script

This commit is contained in:
Gabe Yuan
2023-09-02 15:54:51 +08:00
parent c1bd6a1be6
commit b00b906484
3 changed files with 48 additions and 27 deletions

View File

@@ -1,25 +1,31 @@
import { fetchGM } from "./fetch"; import { fetchGM } from "./fetch";
import { genEventName } from "./utils";
/** const MSG_GM_xmlHttpRequest = "xmlHttpRequest";
* 之否支持unsafeWindow const MSG_GM_setValue = "setValue";
*/ const MSG_GM_getValue = "getValue";
export const isGrantUnsafe = GM?.info?.script?.grant?.includes("unsafeWindow"); const MSG_GM_deleteValue = "deleteValue";
const MSG_GM_info = "info";
/** /**
* 注入页面的脚本请求并接受GM接口信息 * 注入页面的脚本请求并接受GM接口信息
* @param {*} param0 * @param {*} param0
*/ */
export const injectScript = (ping) => { export const injectScript = (ping) => {
const MSG_GM_xmlHttpRequest = "xmlHttpRequest"; window.APP_INFO = {
const MSG_GM_setValue = "setValue"; name: process.env.REACT_APP_NAME,
const MSG_GM_getValue = "getValue"; version: process.env.REACT_APP_VERSION,
const MSG_GM_deleteValue = "deleteValue"; eventName: ping,
const MSG_GM_info = "info"; };
let GM_info; };
/**
* 适配GM脚本
*/
export const adaptScript = (ping) => {
const promiseGM = (action, args, timeout = 5000) => const promiseGM = (action, args, timeout = 5000) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
const pong = btoa(Math.random()).slice(3, 11); const pong = genEventName();
const handleEvent = (e) => { const handleEvent = (e) => {
window.removeEventListener(pong, handleEvent); window.removeEventListener(pong, handleEvent);
const { data, error } = e.detail; const { data, error } = e.detail;
@@ -46,14 +52,13 @@ export const injectScript = (ping) => {
setValue: (key, val) => promiseGM(MSG_GM_setValue, { key, val }), setValue: (key, val) => promiseGM(MSG_GM_setValue, { key, val }),
getValue: (key) => promiseGM(MSG_GM_getValue, { key }), getValue: (key) => promiseGM(MSG_GM_getValue, { key }),
deleteValue: (key) => promiseGM(MSG_GM_deleteValue, { key }), deleteValue: (key) => promiseGM(MSG_GM_deleteValue, { key }),
getInfo: () => { getInfo: async () => {
if (GM_info) { if (!window.GM_info) {
return GM_info; window.GM_info = await promiseGM(MSG_GM_info);
} }
return promiseGM(MSG_GM_info); return window.GM_info;
}, },
}; };
window.APP_NAME = process.env.REACT_APP_NAME;
}; };
/** /**
@@ -61,11 +66,6 @@ export const injectScript = (ping) => {
* @param {*} param0 * @param {*} param0
*/ */
export const handlePing = async (e) => { export const handlePing = async (e) => {
const MSG_GM_xmlHttpRequest = "xmlHttpRequest";
const MSG_GM_setValue = "setValue";
const MSG_GM_getValue = "getValue";
const MSG_GM_deleteValue = "deleteValue";
const MSG_GM_info = "info";
const { action, args, pong } = e.detail; const { action, args, pong } = e.detail;
let res; let res;
try { try {

View File

@@ -12,7 +12,7 @@ import { Translator } from "./libs/translator";
import { trySyncAllSubRules } from "./libs/subRules"; import { trySyncAllSubRules } from "./libs/subRules";
import { MSG_TRANS_TOGGLE, MSG_TRANS_PUTRULE } from "./config"; import { MSG_TRANS_TOGGLE, MSG_TRANS_PUTRULE } from "./config";
import { isIframe } from "./libs/iframe"; import { isIframe } from "./libs/iframe";
import { isGrantUnsafe, handlePing, injectScript } from "./libs/gm"; import { handlePing, injectScript } from "./libs/gm";
import { matchRule } from "./libs/rules"; import { matchRule } from "./libs/rules";
import { genEventName } from "./libs/utils"; import { genEventName } from "./libs/utils";
@@ -26,9 +26,12 @@ const init = async () => {
document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE) || document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE) ||
document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE2) document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE2)
) { ) {
if (isGrantUnsafe) { if (GM?.info?.script?.grant?.includes("unsafeWindow")) {
unsafeWindow.GM = GM; unsafeWindow.GM = GM;
unsafeWindow.APP_NAME = process.env.REACT_APP_NAME; unsafeWindow.APP_INFO = {
name: process.env.REACT_APP_NAME,
version: process.env.REACT_APP_VERSION,
};
} else { } else {
const ping = genEventName(); const ping = genEventName();
window.addEventListener(ping, handlePing); window.addEventListener(ping, handlePing);

View File

@@ -15,9 +15,11 @@ import { AlertProvider } from "../../hooks/Alert";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import Divider from "@mui/material/Divider"; import Divider from "@mui/material/Divider";
import Stack from "@mui/material/Stack"; import Stack from "@mui/material/Stack";
import { adaptScript } from "../../libs/gm";
import Alert from "@mui/material/Alert";
export default function Options() { export default function Options() {
const [error, setError] = useState(false); const [error, setError] = useState("");
const [ready, setReady] = useState(false); const [ready, setReady] = useState(false);
useEffect(() => { useEffect(() => {
@@ -26,7 +28,22 @@ export default function Options() {
// 等待GM注入 // 等待GM注入
let i = 0; let i = 0;
for (;;) { for (;;) {
if (window.APP_NAME === process.env.REACT_APP_NAME) { if (window?.APP_INFO?.name === process.env.REACT_APP_NAME) {
const { version, eventName } = window.APP_INFO;
// 检查版本是否一致
if (version !== process.env.REACT_APP_VERSION) {
setError(
`The version of the script(v${version}) and this page(v${process.env.REACT_APP_VERSION}) are inconsistent.`
);
break;
}
if (eventName) {
// 注入GM接口
adaptScript(eventName);
}
// 同步数据 // 同步数据
await trySyncSettingAndRules(); await trySyncSettingAndRules();
setReady(true); setReady(true);
@@ -34,7 +51,7 @@ export default function Options() {
} }
if (++i > 8) { if (++i > 8) {
setError(true); setError("Time out.");
break; break;
} }
@@ -51,6 +68,7 @@ export default function Options() {
if (error) { if (error) {
return ( return (
<center> <center>
<Alert severity="error">{error}</Alert>
<Divider> <Divider>
<Link <Link
href={process.env.REACT_APP_HOMEPAGE} href={process.env.REACT_APP_HOMEPAGE}