From a26f1c50145938f894687227aa347f9a248aca3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Sun, 27 Apr 2025 18:02:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/app/migrate.ts | 1 - src/app/service/content/content.ts | 1 + src/app/service/content/inject.ts | 36 ++++++ src/app/service/service_worker/index.ts | 25 ++++ src/app/service/service_worker/runtime.ts | 7 +- src/app/service/service_worker/script.ts | 90 ++++++++------ src/manifest.json | 2 +- src/pages/components/CodeEditor/index.tsx | 2 - .../options/routes/script/ScriptEditor.tsx | 116 +++++++++--------- src/pages/popup/App.tsx | 37 +++--- src/pkg/config/config.ts | 21 +++- src/pkg/utils/utils.ts | 12 ++ 13 files changed, 234 insertions(+), 118 deletions(-) diff --git a/package.json b/package.json index ba15960..c71fbeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scriptcat", - "version": "0.17.0-alpha.2", + "version": "0.17.0-alpha.4", "description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!", "author": "CodFrm", "license": "GPLv3", diff --git a/src/app/migrate.ts b/src/app/migrate.ts index a1bb9d6..4c46ffc 100644 --- a/src/app/migrate.ts +++ b/src/app/migrate.ts @@ -113,7 +113,6 @@ function renameField() { if (subscribe.length) { await Promise.all( subscribe.map((s: Subscribe) => { - console.log("1234", s); const { url, name, code, author, scripts, metadata, status, createtime, updatetime, checktime } = s; return subscribeDAO.save({ url, diff --git a/src/app/service/content/content.ts b/src/app/service/content/content.ts index 0e9e9dc..65af889 100644 --- a/src/app/service/content/content.ts +++ b/src/app/service/content/content.ts @@ -23,6 +23,7 @@ export default class ContentRuntime { // 转发给inject return sendMessage(this.msg, "inject/runtime/valueUpdate", data); }); + forwardMessage("serviceWorker", "script/isInstalled", this.server, this.extSend); forwardMessage( "serviceWorker", "runtime/gmApi", diff --git a/src/app/service/content/inject.ts b/src/app/service/content/inject.ts index 8636c3c..42b5f05 100644 --- a/src/app/service/content/inject.ts +++ b/src/app/service/content/inject.ts @@ -4,6 +4,8 @@ import ExecScript, { ValueUpdateData } from "./exec_script"; import { addStyle, ScriptFunc } from "./utils"; import { getStorageName } from "@App/pkg/utils/utils"; import { EmitEventRequest } from "../service_worker/runtime"; +import { ExternalWhitelist } from "@App/app/const"; +import { sendMessage } from "@Packages/message/client"; export class InjectRuntime { execList: ExecScript[] = []; @@ -44,6 +46,40 @@ export class InjectRuntime { val.valueUpdate(data); }); }); + // 注入允许外部调用 + this.externalMessage(); + } + + externalMessage() { + // 对外接口白名单 + let msg = this.msg; + for (let i = 0; i < ExternalWhitelist.length; i += 1) { + if (window.location.host.endsWith(ExternalWhitelist[i])) { + // 注入 + (<{ external: any }>(window)).external = window.external || {}; + (< + { + external: { + Scriptcat: { + isInstalled: (name: string, namespace: string, callback: any) => void; + }; + }; + } + >(window)).external.Scriptcat = { + async isInstalled(name: string, namespace: string, callback: any) { + const resp = await sendMessage(msg, "content/script/isInstalled", { + name, + namespace, + }); + callback(resp); + }, + }; + (<{ external: { Tampermonkey: any } }>(window)).external.Tampermonkey = (< + { external: { Scriptcat: any } } + >(window)).external.Scriptcat; + break; + } + } } execScript(script: ScriptRunResouce, scriptFunc: ScriptFunc) { diff --git a/src/app/service/service_worker/index.ts b/src/app/service/service_worker/index.ts index 7990090..d8c0f52 100644 --- a/src/app/service/service_worker/index.ts +++ b/src/app/service/service_worker/index.ts @@ -9,6 +9,8 @@ import { PopupService } from "./popup"; import { SystemConfig } from "@App/pkg/config/config"; import { SynchronizeService } from "./synchronize"; import { SubscribeService } from "./subscribe"; +import { ExtServer, ExtVersion } from "@App/app/const"; +import { systemConfig } from "@App/pages/store/global"; export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode"; @@ -78,8 +80,17 @@ export default class ServiceWorkerManager { case "checkSubscribeUpdate": subscribe.checkSubscribeUpdate(); break; + case "checkUpdate": + // 检查扩展更新 + this.checkUpdate(); + break; } }); + // 8小时检查一次扩展更新 + chrome.alarms.create("checkUpdate", { + delayInMinutes: 0, + periodInMinutes: 8 * 60, + }); // 监听配置变化 this.mq.subscribe("systemConfigChange", (msg) => { @@ -96,4 +107,18 @@ export default class ServiceWorkerManager { synchronize.cloudSyncConfigChange(config); }); } + + checkUpdate() { + fetch(`${ExtServer}api/v1/system/version?version=${ExtVersion}`) + .then((resp) => resp.json()) + .then((resp: { data: { notice: string; version: string } }) => { + systemConfig.getCheckUpdate().then((items) => { + if (items.notice !== resp.data.notice) { + systemConfig.setCheckUpdate(Object.assign(resp.data, { isRead: false })); + } else { + systemConfig.setCheckUpdate(Object.assign(resp.data, { isRead: items.isRead })); + } + }); + }); + } } diff --git a/src/app/service/service_worker/runtime.ts b/src/app/service/service_worker/runtime.ts index e0723ea..362376a 100644 --- a/src/app/service/service_worker/runtime.ts +++ b/src/app/service/service_worker/runtime.ts @@ -15,7 +15,7 @@ import { subscribeScriptDelete, subscribeScriptEnable, subscribeScriptInstall } import { ScriptService } from "./script"; import { runScript, stopScript } from "../offscreen/client"; import { getRunAt } from "./utils"; -import { randomString } from "@App/pkg/utils/utils"; +import { isUserScriptsAvailable, randomString } from "@App/pkg/utils/utils"; import Cache from "@App/app/cache"; import { dealPatternMatches, UrlMatch } from "@App/pkg/utils/match"; import { ExtensionContentMessageSend } from "@Packages/message/extension_message"; @@ -70,6 +70,11 @@ export class RuntimeService { this.group.on("runScript", this.runScript.bind(this)); this.group.on("pageLoad", this.pageLoad.bind(this)); + // 检查是否开启了开发者模式 + if(!isUserScriptsAvailable()){ + // 未开启加上警告引导 + + } // 读取inject.js注入页面 this.registerInjectScript(); // 监听脚本开启 diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index 3f75390..bb8ed23 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -21,6 +21,7 @@ import { ResourceService } from "./resource"; import { ValueService } from "./value"; import { compileScriptCode } from "../content/utils"; import { SystemConfig } from "@App/pkg/config/config"; +import i18n from "@App/locales/locales"; export class ScriptService { logger: Logger; @@ -59,50 +60,59 @@ export class ScriptService { // 读取脚本url内容, 进行安装 const logger = this.logger.with({ url: targetUrl }); logger.debug("install script"); - this.openInstallPageByUrl(targetUrl, "user").catch((e) => { - logger.error("install script error", Logger.E(e)); - // 如果打开失败, 则重定向到安装页 - chrome.scripting.executeScript({ - target: { tabId: req.tabId }, - func: function () { - history.back(); - }, - }); - // 并不再重定向当前url - chrome.declarativeNetRequest.updateDynamicRules( - { - removeRuleIds: [2], - addRules: [ - { - id: 2, - priority: 1, - action: { - type: chrome.declarativeNetRequest.RuleActionType.ALLOW, + this.openInstallPageByUrl(targetUrl, "user") + .catch((e) => { + logger.error("install script error", Logger.E(e)); + // 不再重定向当前url + chrome.declarativeNetRequest.updateDynamicRules( + { + removeRuleIds: [2], + addRules: [ + { + id: 2, + priority: 1, + action: { + type: chrome.declarativeNetRequest.RuleActionType.ALLOW, + }, + condition: { + regexFilter: targetUrl, + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: [chrome.declarativeNetRequest.RequestMethod.GET], + }, }, - condition: { - regexFilter: targetUrl, - resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], - requestMethods: [chrome.declarativeNetRequest.RequestMethod.GET], - }, - }, - ], - }, - () => { - if (chrome.runtime.lastError) { - console.error(chrome.runtime.lastError); + ], + }, + () => { + if (chrome.runtime.lastError) { + console.error(chrome.runtime.lastError); + } } - } - ); - }); + ); + }) + .finally(() => { + // 回退到到安装页 + chrome.scripting.executeScript({ + target: { tabId: req.tabId }, + func: function () { + history.back(); + }, + }); + }); }, { urls: [ - "https://docs.scriptcat.org/docs/script_installation", + "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"], } ); + // 获取i18n + let localePath = ""; + if (i18n.language !== "zh-CN") { + localePath = `/en`; + } // 重定向到脚本安装页 chrome.declarativeNetRequest.updateDynamicRules( { @@ -114,7 +124,7 @@ export class ScriptService { action: { type: chrome.declarativeNetRequest.RuleActionType.REDIRECT, redirect: { - regexSubstitution: "https://docs.scriptcat.org/docs/script_installation#url=\\0", + regexSubstitution: `https://docs.scriptcat.org${localePath}/docs/script_installation/#url=\\0`, }, }, condition: { @@ -479,6 +489,15 @@ export class ScriptService { return this.checkUpdate(uuid, "user"); } + isInstalled({ name, namespace }: { name: string; namespace: string }) { + return this.scriptDAO.findByNameAndNamespace(name, namespace).then((script) => { + if (script) { + return { installed: true, version: script.metadata.version && script.metadata.version[0] }; + } + return { installed: false }; + }); + } + init() { this.listenerScriptInstall(); @@ -494,6 +513,7 @@ export class ScriptService { this.group.on("resetMatch", this.resetMatch.bind(this)); this.group.on("resetExclude", this.resetExclude.bind(this)); this.group.on("requestCheckUpdate", this.requestCheckUpdate.bind(this)); + this.group.on("isInstalled", this.isInstalled.bind(this)); // 定时检查更新, 每10分钟检查一次 chrome.alarms.create("checkScriptUpdate", { diff --git a/src/manifest.json b/src/manifest.json index e618a41..c9e5a75 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "__MSG_scriptcat__", - "version": "0.17.0.1003", + "version": "0.17.0.1005", "author": "CodFrm", "description": "__MSG_scriptcat_description__", "options_ui": { diff --git a/src/pages/components/CodeEditor/index.tsx b/src/pages/components/CodeEditor/index.tsx index 2d49961..6daa763 100644 --- a/src/pages/components/CodeEditor/index.tsx +++ b/src/pages/components/CodeEditor/index.tsx @@ -39,11 +39,9 @@ const CodeEditor: React.ForwardRefRenderFunction<{ editor: editor.IStandaloneCod }, []); useEffect(() => { - console.log("1231", code); if (diffCode === undefined || code === undefined || !div.current) { return () => {}; } - console.log("1232"); let edit: editor.IStandaloneDiffEditor | editor.IStandaloneCodeEditor; const inlineDiv = document.getElementById(id) as HTMLDivElement; // @ts-ignore diff --git a/src/pages/options/routes/script/ScriptEditor.tsx b/src/pages/options/routes/script/ScriptEditor.tsx index 3d19706..d9fcdee 100644 --- a/src/pages/options/routes/script/ScriptEditor.tsx +++ b/src/pages/options/routes/script/ScriptEditor.tsx @@ -1,4 +1,4 @@ -import { Script, ScriptAndCode, ScriptCodeDAO, ScriptDAO } from "@App/app/repo/scripts"; +import { Script, SCRIPT_TYPE_NORMAL, ScriptAndCode, ScriptCodeDAO, ScriptDAO } from "@App/app/repo/scripts"; import CodeEditor from "@App/pages/components/CodeEditor"; import React, { useCallback, useEffect, useRef, useState } from "react"; import { useNavigate, useParams, useSearchParams } from "react-router-dom"; @@ -16,7 +16,7 @@ import { prepareScriptByCode } from "@App/pkg/utils/script"; import ScriptStorage from "@App/pages/components/ScriptStorage"; import ScriptResource from "@App/pages/components/ScriptResource"; import ScriptSetting from "@App/pages/components/ScriptSetting"; -import { scriptClient } from "@App/pages/store/features/script"; +import { runtimeClient, scriptClient } from "@App/pages/store/features/script"; import { i18nName } from "@App/locales/locales"; import { useTranslation } from "react-i18next"; @@ -188,57 +188,58 @@ function ScriptEditor() { const save = (script: Script, e: editor.IStandaloneCodeEditor): Promise