userscript...
This commit is contained in:
@@ -25,10 +25,6 @@ const banner = `// ==UserScript==
|
|||||||
// @grant GM.getValue
|
// @grant GM.getValue
|
||||||
// @grant GM_deleteValue
|
// @grant GM_deleteValue
|
||||||
// @grant GM.deleteValue
|
// @grant GM.deleteValue
|
||||||
// @grant GM_addValueChangeListener
|
|
||||||
// @grant GM.addValueChangeListener
|
|
||||||
// @grant GM_removeValueChangeListener
|
|
||||||
// @grant GM.removeValueChangeListener
|
|
||||||
// @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
|
||||||
@@ -117,10 +113,11 @@ const userscriptWebpack = (config, env) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
config.entry = {
|
config.entry = {
|
||||||
userscript: paths.appSrc + "/userscript.js",
|
index: paths.appSrc + "/userscriptOptions.js",
|
||||||
|
"kiss-translator.user": paths.appSrc + "/userscript.js",
|
||||||
};
|
};
|
||||||
|
|
||||||
config.output.filename = "kiss-translator.user.js";
|
config.output.filename = "[name].js";
|
||||||
config.optimization.splitChunks = { cacheGroups: { default: false } };
|
config.optimization.splitChunks = { cacheGroups: { default: false } };
|
||||||
config.optimization.runtimeChunk = false;
|
config.optimization.runtimeChunk = false;
|
||||||
config.optimization.minimize = false;
|
config.optimization.minimize = false;
|
||||||
@@ -130,10 +127,17 @@ const userscriptWebpack = (config, env) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
config.plugins.push(
|
config.plugins.push(
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
inject: true,
|
||||||
|
chunks: ["index"],
|
||||||
|
template: paths.appHtml,
|
||||||
|
filename: "index.html",
|
||||||
|
}),
|
||||||
new webpack.BannerPlugin({
|
new webpack.BannerPlugin({
|
||||||
banner,
|
banner,
|
||||||
raw: true,
|
raw: true,
|
||||||
entryOnly: true,
|
entryOnly: true,
|
||||||
|
test: "kiss-translator.user.js",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -71,11 +71,6 @@ export function StoragesProvider({ children }) {
|
|||||||
return () => {
|
return () => {
|
||||||
if (isExt) {
|
if (isExt) {
|
||||||
browser.storage.onChanged.removeListener(handleChanged);
|
browser.storage.onChanged.removeListener(handleChanged);
|
||||||
} else if (isGm) {
|
|
||||||
(
|
|
||||||
window.GM_removeValueChangeListener ||
|
|
||||||
window.GM.removeValueChangeListener
|
|
||||||
)(handleChanged);
|
|
||||||
} else {
|
} else {
|
||||||
window.removeEventListener("storage", handleChanged);
|
window.removeEventListener("storage", handleChanged);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,18 @@ 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 (window.GM_getValue || window.GM.getValue)(key);
|
||||||
await (window.GM_setValue || window.GM.setValue)(key, val);
|
await (window.GM_setValue || window.GM.setValue)(key, val);
|
||||||
|
window.dispatchEvent(
|
||||||
|
new StorageEvent("storage", {
|
||||||
|
key,
|
||||||
|
oldValue,
|
||||||
|
newValue: val,
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const oldValue = window.localStorage.getItem(key);
|
const oldValue = window.localStorage.getItem(key);
|
||||||
window.localStorage.setItem(key, val);
|
window.localStorage.setItem(key, val);
|
||||||
// 手动唤起事件
|
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new StorageEvent("storage", {
|
new StorageEvent("storage", {
|
||||||
key,
|
key,
|
||||||
@@ -34,11 +41,18 @@ 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 (window.GM_getValue || window.GM.getValue)(key);
|
||||||
await (window.GM_deleteValue || window.GM.deleteValue)(key);
|
await (window.GM_deleteValue || window.GM.deleteValue)(key);
|
||||||
|
window.dispatchEvent(
|
||||||
|
new StorageEvent("storage", {
|
||||||
|
key,
|
||||||
|
oldValue,
|
||||||
|
newValue: null,
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const oldValue = window.localStorage.getItem(key);
|
const oldValue = window.localStorage.getItem(key);
|
||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
||||||
// 手动唤起事件
|
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new StorageEvent("storage", {
|
new StorageEvent("storage", {
|
||||||
key,
|
key,
|
||||||
@@ -76,11 +90,6 @@ async function putObj(key, obj) {
|
|||||||
function onChanged(handleChanged) {
|
function onChanged(handleChanged) {
|
||||||
if (isExt) {
|
if (isExt) {
|
||||||
browser.storage.onChanged.addListener(handleChanged);
|
browser.storage.onChanged.addListener(handleChanged);
|
||||||
} else if (isGm) {
|
|
||||||
(window.GM_addValueChangeListener || window.GM.addValueChangeListener)(
|
|
||||||
"storage",
|
|
||||||
handleChanged
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
window.addEventListener("storage", handleChanged);
|
window.addEventListener("storage", handleChanged);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import ThemeProvider from "./hooks/Theme";
|
|
||||||
import Options from "./views/Options";
|
import Options from "./views/Options";
|
||||||
import { HashRouter } from "react-router-dom";
|
|
||||||
import { StoragesProvider } from "./hooks/Storage";
|
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<StoragesProvider>
|
|
||||||
<ThemeProvider>
|
|
||||||
<HashRouter>
|
|
||||||
<Options />
|
<Options />
|
||||||
</HashRouter>
|
|
||||||
</ThemeProvider>
|
|
||||||
</StoragesProvider>
|
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
import Options from "./views/Options";
|
||||||
|
|
||||||
import { browser } from "./libs/browser";
|
import { browser } from "./libs/browser";
|
||||||
import {
|
import {
|
||||||
MSG_TRANS_TOGGLE,
|
MSG_TRANS_TOGGLE,
|
||||||
@@ -13,6 +17,17 @@ import { Translator } from "./libs/translator";
|
|||||||
* 入口函数
|
* 入口函数
|
||||||
*/
|
*/
|
||||||
(async () => {
|
(async () => {
|
||||||
|
// 设置页面
|
||||||
|
if (document.location.href.includes("localhost:3000")) {
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<Options />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { fetchInterval, fetchLimit } = await getSetting();
|
const { fetchInterval, fetchLimit } = await getSetting();
|
||||||
transPool.update(fetchInterval, fetchLimit);
|
transPool.update(fetchInterval, fetchLimit);
|
||||||
|
|
||||||
|
|||||||
37
src/userscriptOptions.js
Normal file
37
src/userscriptOptions.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
if (!document.querySelector("header")) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <p style={{ textAlign: "center" }}>loading...</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ textAlign: "center" }}>
|
||||||
|
<p>KISS Translator userscript is disabled at this browser!</p>
|
||||||
|
<p>
|
||||||
|
<a href={process.env.REACT_APP_HOMEPAGE}>Click here read more!</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
import { Routes, Route } from "react-router-dom";
|
import { Routes, Route, HashRouter } from "react-router-dom";
|
||||||
import About from "./About";
|
import About from "./About";
|
||||||
import Rules from "./Rules";
|
import Rules from "./Rules";
|
||||||
import Setting from "./Setting";
|
import Setting from "./Setting";
|
||||||
import Layout from "./Layout";
|
import Layout from "./Layout";
|
||||||
import SyncSetting from "./SyncSetting";
|
import SyncSetting from "./SyncSetting";
|
||||||
|
import { StoragesProvider } from "../../hooks/Storage";
|
||||||
|
import ThemeProvider from "../../hooks/Theme";
|
||||||
|
|
||||||
export default function Options() {
|
export default function Options() {
|
||||||
return (
|
return (
|
||||||
|
<StoragesProvider>
|
||||||
|
<ThemeProvider>
|
||||||
|
<HashRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Layout />}>
|
<Route path="/" element={<Layout />}>
|
||||||
<Route index element={<Setting />} />
|
<Route index element={<Setting />} />
|
||||||
@@ -15,5 +20,8 @@ export default function Options() {
|
|||||||
<Route path="about" element={<About />} />
|
<Route path="about" element={<About />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</HashRouter>
|
||||||
|
</ThemeProvider>
|
||||||
|
</StoragesProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user