use inject-into replace unsafeWindow
This commit is contained in:
@@ -89,7 +89,7 @@ const userscriptWebpack = (config, env) => {
|
|||||||
// @grant GM.getValue
|
// @grant GM.getValue
|
||||||
// @grant GM.deleteValue
|
// @grant GM.deleteValue
|
||||||
// @grant GM.info
|
// @grant GM.info
|
||||||
// @grant unsafeWindow
|
// @inject-into content
|
||||||
// @connect translate.googleapis.com
|
// @connect translate.googleapis.com
|
||||||
// @connect api-edge.cognitive.microsofttranslator.com
|
// @connect api-edge.cognitive.microsofttranslator.com
|
||||||
// @connect edge.microsoft.com
|
// @connect edge.microsoft.com
|
||||||
|
|||||||
@@ -37,8 +37,7 @@
|
|||||||
"react-app/jest"
|
"react-app/jest"
|
||||||
],
|
],
|
||||||
"globals": {
|
"globals": {
|
||||||
"GM": true,
|
"GM": true
|
||||||
"unsafeWindow": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { msAuth } from "./auth";
|
|||||||
* @param {*} init
|
* @param {*} init
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const fetchGM = async (input, { method = "GET", headers, body } = {}) =>
|
export const fetchGM = async (input, { method = "GET", headers, body } = {}) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
GM.xmlHttpRequest({
|
GM.xmlHttpRequest({
|
||||||
method,
|
method,
|
||||||
@@ -74,11 +74,21 @@ const fetchApi = async ({ input, init = {}, translator, token }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isGm) {
|
if (isGm) {
|
||||||
const connects = GM?.info?.script?.connects || [];
|
let info;
|
||||||
|
if (window.KISS_GM) {
|
||||||
|
info = await window.KISS_GM.getInfo();
|
||||||
|
} else {
|
||||||
|
info = GM.info;
|
||||||
|
}
|
||||||
|
const connects = info?.script?.connects || [];
|
||||||
const url = new URL(input);
|
const url = new URL(input);
|
||||||
const isSafe = connects.find((item) => url.hostname.endsWith(item));
|
const isSafe = connects.find((item) => url.hostname.endsWith(item));
|
||||||
if (isSafe) {
|
if (isSafe) {
|
||||||
return fetchGM(input, init);
|
if (window.KISS_GM) {
|
||||||
|
return window.KISS_GM.fetch(input, init);
|
||||||
|
} else {
|
||||||
|
return fetchGM(input, init);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fetch(input, init);
|
return fetch(input, init);
|
||||||
|
|||||||
@@ -1,8 +1,22 @@
|
|||||||
export const injectScript = ({ eventName }) => {
|
import { fetchGM } from "./fetch";
|
||||||
window.callGM = ({ action, args }, timeout = 5000) =>
|
|
||||||
|
/**
|
||||||
|
* 注入页面的脚本,请求并接受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;
|
||||||
|
|
||||||
|
const promiseGM = (action, args, timeout = 5000) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
|
const pong = btoa(Math.random()).slice(3, 11);
|
||||||
const handleEvent = (e) => {
|
const handleEvent = (e) => {
|
||||||
window.removeEventListener(eventName + "_pong", handleEvent);
|
window.removeEventListener(pong, handleEvent);
|
||||||
const { data, error } = e.detail;
|
const { data, error } = e.detail;
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(new Error(error));
|
reject(new Error(error));
|
||||||
@@ -11,13 +25,73 @@ export const injectScript = ({ eventName }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener(eventName + "_pong", handleEvent);
|
window.addEventListener(pong, handleEvent);
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent(eventName + "_ping", { action, args })
|
new CustomEvent(ping, { detail: { action, args, pong } })
|
||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleEvent({ detail: { error: "timeout" } });
|
window.removeEventListener(pong, handleEvent);
|
||||||
|
reject(new Error("timeout"));
|
||||||
}, timeout);
|
}, timeout);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.KISS_GM = {
|
||||||
|
fetch: (input, init) => promiseGM(MSG_GM_xmlHttpRequest, { input, init }),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return promiseGM(MSG_GM_info);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
window.APP_NAME = process.env.REACT_APP_NAME;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听并回应页面对GM接口的请求
|
||||||
|
* @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 {
|
||||||
|
switch (action) {
|
||||||
|
case MSG_GM_xmlHttpRequest:
|
||||||
|
const { input, init } = args;
|
||||||
|
res = await fetchGM(input, init);
|
||||||
|
break;
|
||||||
|
case MSG_GM_setValue:
|
||||||
|
const { key, val } = args;
|
||||||
|
await GM.setValue(key, val);
|
||||||
|
res = val;
|
||||||
|
break;
|
||||||
|
case MSG_GM_getValue:
|
||||||
|
res = await GM.getValue(args.key);
|
||||||
|
break;
|
||||||
|
case MSG_GM_deleteValue:
|
||||||
|
await GM.deleteValue(args.key);
|
||||||
|
res = "ok";
|
||||||
|
break;
|
||||||
|
case MSG_GM_info:
|
||||||
|
res = GM.info;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`message action is unavailable: ${action}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.dispatchEvent(new CustomEvent(pong, { detail: { data: res } }));
|
||||||
|
} catch (err) {
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent(pong, { detail: { error: err.message } })
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ async function set(key, val) {
|
|||||||
if (isExt) {
|
if (isExt) {
|
||||||
await browser.storage.local.set({ [key]: val });
|
await browser.storage.local.set({ [key]: val });
|
||||||
} else if (isGm) {
|
} else if (isGm) {
|
||||||
const oldValue = await GM.getValue(key);
|
const oldValue = await (window.KISS_GM || GM).getValue(key);
|
||||||
await GM.setValue(key, val);
|
await (window.KISS_GM || GM).setValue(key, val);
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new StorageEvent("storage", {
|
new StorageEvent("storage", {
|
||||||
key,
|
key,
|
||||||
@@ -31,7 +31,7 @@ async function get(key) {
|
|||||||
const val = await browser.storage.local.get([key]);
|
const val = await browser.storage.local.get([key]);
|
||||||
return val[key];
|
return val[key];
|
||||||
} else if (isGm) {
|
} else if (isGm) {
|
||||||
const val = await GM.getValue(key);
|
const val = await (window.KISS_GM || GM).getValue(key);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
return window.localStorage.getItem(key);
|
return window.localStorage.getItem(key);
|
||||||
@@ -41,8 +41,8 @@ async function del(key) {
|
|||||||
if (isExt) {
|
if (isExt) {
|
||||||
await browser.storage.local.remove([key]);
|
await browser.storage.local.remove([key]);
|
||||||
} else if (isGm) {
|
} else if (isGm) {
|
||||||
const oldValue = await GM.getValue(key);
|
const oldValue = await (window.KISS_GM || GM).getValue(key);
|
||||||
await GM.deleteValue(key);
|
await (window.KISS_GM || GM).deleteValue(key);
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new StorageEvent("storage", {
|
new StorageEvent("storage", {
|
||||||
key,
|
key,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { trySyncAllSubRules } from "./libs/rules";
|
|||||||
import { isGm } from "./libs/browser";
|
import { isGm } from "./libs/browser";
|
||||||
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 { genEventName, handlePing, injectScript } from "./libs/gm";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入口函数
|
* 入口函数
|
||||||
@@ -20,8 +21,11 @@ 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)
|
||||||
) {
|
) {
|
||||||
unsafeWindow.GM = GM;
|
// unsafeWindow.GM = GM;
|
||||||
unsafeWindow.APP_NAME = process.env.REACT_APP_NAME;
|
// unsafeWindow.APP_NAME = process.env.REACT_APP_NAME;
|
||||||
|
const ping = btoa(Math.random()).slice(3, 11);
|
||||||
|
window.addEventListener(ping, handlePing);
|
||||||
|
window.eval(`(${injectScript})("${ping}")`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user