From b00b9064844e641ccca783f5a7cc440f9e8bd610 Mon Sep 17 00:00:00 2001 From: Gabe Yuan Date: Sat, 2 Sep 2023 15:54:51 +0800 Subject: [PATCH] optimize inject script --- src/libs/gm.js | 42 +++++++++++++++++++------------------- src/userscript.js | 9 +++++--- src/views/Options/index.js | 24 +++++++++++++++++++--- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/libs/gm.js b/src/libs/gm.js index 21213fb..fa42257 100644 --- a/src/libs/gm.js +++ b/src/libs/gm.js @@ -1,25 +1,31 @@ import { fetchGM } from "./fetch"; +import { genEventName } from "./utils"; -/** - * 之否支持unsafeWindow - */ -export const isGrantUnsafe = GM?.info?.script?.grant?.includes("unsafeWindow"); +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"; /** * 注入页面的脚本,请求并接受GM接口信息 * @param {*} param0 */ export const injectScript = (ping) => { - 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"; - let GM_info; + window.APP_INFO = { + name: process.env.REACT_APP_NAME, + version: process.env.REACT_APP_VERSION, + eventName: ping, + }; +}; +/** + * 适配GM脚本 + */ +export const adaptScript = (ping) => { const promiseGM = (action, args, timeout = 5000) => new Promise((resolve, reject) => { - const pong = btoa(Math.random()).slice(3, 11); + const pong = genEventName(); const handleEvent = (e) => { window.removeEventListener(pong, handleEvent); const { data, error } = e.detail; @@ -46,14 +52,13 @@ export const injectScript = (ping) => { setValue: (key, val) => promiseGM(MSG_GM_setValue, { key, val }), getValue: (key) => promiseGM(MSG_GM_getValue, { key }), deleteValue: (key) => promiseGM(MSG_GM_deleteValue, { key }), - getInfo: () => { - if (GM_info) { - return GM_info; + getInfo: async () => { + if (!window.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 */ 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; let res; try { diff --git a/src/userscript.js b/src/userscript.js index 4e67bf2..31281ba 100644 --- a/src/userscript.js +++ b/src/userscript.js @@ -12,7 +12,7 @@ import { Translator } from "./libs/translator"; import { trySyncAllSubRules } from "./libs/subRules"; import { MSG_TRANS_TOGGLE, MSG_TRANS_PUTRULE } from "./config"; import { isIframe } from "./libs/iframe"; -import { isGrantUnsafe, handlePing, injectScript } from "./libs/gm"; +import { handlePing, injectScript } from "./libs/gm"; import { matchRule } from "./libs/rules"; 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_OPTIONSPAGE2) ) { - if (isGrantUnsafe) { + if (GM?.info?.script?.grant?.includes("unsafeWindow")) { 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 { const ping = genEventName(); window.addEventListener(ping, handlePing); diff --git a/src/views/Options/index.js b/src/views/Options/index.js index 4365514..16824a8 100644 --- a/src/views/Options/index.js +++ b/src/views/Options/index.js @@ -15,9 +15,11 @@ import { AlertProvider } from "../../hooks/Alert"; import Link from "@mui/material/Link"; import Divider from "@mui/material/Divider"; import Stack from "@mui/material/Stack"; +import { adaptScript } from "../../libs/gm"; +import Alert from "@mui/material/Alert"; export default function Options() { - const [error, setError] = useState(false); + const [error, setError] = useState(""); const [ready, setReady] = useState(false); useEffect(() => { @@ -26,7 +28,22 @@ export default function Options() { // 等待GM注入 let i = 0; 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(); setReady(true); @@ -34,7 +51,7 @@ export default function Options() { } if (++i > 8) { - setError(true); + setError("Time out."); break; } @@ -51,6 +68,7 @@ export default function Options() { if (error) { return (
+ {error}