From 9fe4a0771dfabd4ba894fb8cf724de306af54aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Thu, 4 Sep 2025 15:32:55 +0800 Subject: [PATCH 1/4] =?UTF-8?q?wip:=20=E8=87=AA=E5=AE=9A=E4=B9=89=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/components/CodeEditor/config.ts | 3 +++ src/pages/components/CodeEditor/index.tsx | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/pages/components/CodeEditor/config.ts diff --git a/src/pages/components/CodeEditor/config.ts b/src/pages/components/CodeEditor/config.ts new file mode 100644 index 000000000..d28d16e2d --- /dev/null +++ b/src/pages/components/CodeEditor/config.ts @@ -0,0 +1,3 @@ +const config = {}; + +export const defaultConfig = JSON.stringify(config, null, 2); diff --git a/src/pages/components/CodeEditor/index.tsx b/src/pages/components/CodeEditor/index.tsx index f258dbe85..c28daf162 100644 --- a/src/pages/components/CodeEditor/index.tsx +++ b/src/pages/components/CodeEditor/index.tsx @@ -1,5 +1,5 @@ import { LinterWorker } from "@App/pkg/utils/monaco-editor"; -import { editor, Range } from "monaco-editor"; +import { editor, Range, languages } from "monaco-editor"; import React, { useEffect, useImperativeHandle, useRef, useState } from "react"; import { globalCache, systemConfig } from "@App/pages/store/global"; @@ -11,6 +11,16 @@ type Props = { code?: string; }; +languages.typescript.javascriptDefaults.setCompilerOptions({ + target: languages.typescript.ScriptTarget.ESNext, + allowNonTsExtensions: true, + alwaysStrict: true, + noUnusedParameters: true, + noImplicitUseStrict: true, + noUnusedLocals: true, + strict: true, +}); + const CodeEditor: React.ForwardRefRenderFunction<{ editor: editor.IStandaloneCodeEditor | undefined }, Props> = ( { id, className, code, diffCode, editable }, ref From 8a9419d5b348f607d3a370469819190ddf6942b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Thu, 4 Sep 2025 17:39:10 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20=E5=A2=9E=E5=8A=A0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E9=85=8D=E7=BD=AE=E5=92=8C=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ach-UG/translation.json | 13 ++- src/locales/en-US/translation.json | 13 ++- src/locales/zh-CN/translation.json | 13 ++- src/pages/components/CodeEditor/config.ts | 3 - src/pages/components/CodeEditor/index.tsx | 14 +-- src/pages/components/CustomTrans/index.tsx | 5 +- src/pages/options/main.tsx | 2 +- src/pages/options/routes/Setting.tsx | 88 ++++++++++++++++++- src/pkg/config/config.ts | 38 ++++++-- src/pkg/utils/monaco-editor/config.ts | 9 ++ .../index.ts} | 63 ++++++++++++- 11 files changed, 225 insertions(+), 36 deletions(-) delete mode 100644 src/pages/components/CodeEditor/config.ts create mode 100644 src/pkg/utils/monaco-editor/config.ts rename src/pkg/utils/{monaco-editor.ts => monaco-editor/index.ts} (67%) diff --git a/src/locales/ach-UG/translation.json b/src/locales/ach-UG/translation.json index ec678a48b..d543170be 100644 --- a/src/locales/ach-UG/translation.json +++ b/src/locales/ach-UG/translation.json @@ -460,5 +460,16 @@ "all": "crwdns10812:0crwdne10812:0", "normal-tabs": "crwdns10814:0crwdne10814:0", "incognito-tabs": "crwdns10816:0crwdne10816:0" - } + }, + "editor_config": "crwdns10818:0crwdne10818:0", + "editor_config_description": "crwdns10820:0crwdne10820:0", + "editor_type_definition": "crwdns10822:0crwdne10822:0", + "editor_type_definition_description": "crwdns10824:0crwdne10824:0", + "eslint_rules_reset": "crwdns10826:0crwdne10826:0", + "eslint_rules_saved": "crwdns10828:0crwdne10828:0", + "editor_config_reset": "crwdns10830:0crwdne10830:0", + "editor_config_saved": "crwdns10832:0crwdne10832:0", + "editor_config_format_error": "crwdns10834:0crwdne10834:0", + "editor_type_definition_reset": "crwdns10836:0crwdne10836:0", + "editor_type_definition_saved": "crwdns10838:0crwdne10838:0" } \ No newline at end of file diff --git a/src/locales/en-US/translation.json b/src/locales/en-US/translation.json index 181fd38c0..47ed4b2a5 100644 --- a/src/locales/en-US/translation.json +++ b/src/locales/en-US/translation.json @@ -460,5 +460,16 @@ "all": "All", "normal-tabs": "Normal tags", "incognito-tabs": "Incognito tags" - } + }, + "editor_config": "Editor Configuration", + "editor_config_description": "You can refer to the compilerOptions in jsconfig.js for configuration", + "editor_type_definition": "Editor Type Definition", + "editor_type_definition_description": "You can customize your own type definitions, and the script editor will automatically load these type definitions", + "eslint_rules_reset": "ESLint Rules Reset", + "eslint_rules_saved": "ESLint Rules Saved", + "editor_config_reset": "Editor Configuration Reset", + "editor_config_saved": "Editor Configuration Saved", + "editor_config_format_error": "Editor Configuration Format Error", + "editor_type_definition_reset": "Editor Type Definition Reset", + "editor_type_definition_saved": "Editor Type Definition Saved" } \ No newline at end of file diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index 7c3c81f53..5aecb014a 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -460,5 +460,16 @@ "all": "所有标签", "normal-tabs": "普通标签", "incognito-tabs": "隐身标签" - } + }, + "editor_config": "", + "editor_config_description": "", + "editor_type_definition": "", + "editor_type_definition_description": "", + "eslint_rules_reset": "", + "eslint_rules_saved": "", + "editor_config_reset": "", + "editor_config_saved": "", + "editor_config_format_error": "", + "editor_type_definition_reset": "", + "editor_type_definition_saved": "" } \ No newline at end of file diff --git a/src/pages/components/CodeEditor/config.ts b/src/pages/components/CodeEditor/config.ts deleted file mode 100644 index d28d16e2d..000000000 --- a/src/pages/components/CodeEditor/config.ts +++ /dev/null @@ -1,3 +0,0 @@ -const config = {}; - -export const defaultConfig = JSON.stringify(config, null, 2); diff --git a/src/pages/components/CodeEditor/index.tsx b/src/pages/components/CodeEditor/index.tsx index c28daf162..964f43920 100644 --- a/src/pages/components/CodeEditor/index.tsx +++ b/src/pages/components/CodeEditor/index.tsx @@ -1,7 +1,7 @@ -import { LinterWorker } from "@App/pkg/utils/monaco-editor"; -import { editor, Range, languages } from "monaco-editor"; +import { editor, Range } from "monaco-editor"; import React, { useEffect, useImperativeHandle, useRef, useState } from "react"; import { globalCache, systemConfig } from "@App/pages/store/global"; +import { LinterWorker } from "@App/pkg/utils/monaco-editor"; type Props = { className?: string; @@ -11,16 +11,6 @@ type Props = { code?: string; }; -languages.typescript.javascriptDefaults.setCompilerOptions({ - target: languages.typescript.ScriptTarget.ESNext, - allowNonTsExtensions: true, - alwaysStrict: true, - noUnusedParameters: true, - noImplicitUseStrict: true, - noUnusedLocals: true, - strict: true, -}); - const CodeEditor: React.ForwardRefRenderFunction<{ editor: editor.IStandaloneCodeEditor | undefined }, Props> = ( { id, className, code, diffCode, editable }, ref diff --git a/src/pages/components/CustomTrans/index.tsx b/src/pages/components/CustomTrans/index.tsx index 53c73f68b..c0d9c28cb 100644 --- a/src/pages/components/CustomTrans/index.tsx +++ b/src/pages/components/CustomTrans/index.tsx @@ -4,8 +4,9 @@ import { useTranslation } from "react-i18next"; // 因为i18n的Trans组件打包后出现问题,所以自己实现一个 export const CustomTrans: React.FC<{ + className?: string; i18nKey: string; -}> = ({ i18nKey }) => { +}> = ({ className, i18nKey }) => { const { t } = useTranslation(); const children: (JSX.Element | string)[] = []; let content = t(i18nKey); @@ -39,7 +40,7 @@ export const CustomTrans: React.FC<{ } } - return
{children}
; + return
{children}
; }; export default CustomTrans; diff --git a/src/pages/options/main.tsx b/src/pages/options/main.tsx index ff8669784..068de478a 100644 --- a/src/pages/options/main.tsx +++ b/src/pages/options/main.tsx @@ -11,7 +11,7 @@ import "./index.css"; import LoggerCore from "@App/app/logger/core.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts"; import DBWriter from "@App/app/logger/db_writer.ts"; -import registerEditor from "@App/pkg/utils/monaco-editor.ts"; +import registerEditor from "@App/pkg/utils/monaco-editor"; import storeSubscribe from "../store/subscribe.ts"; import migrate from "@App/app/migrate.ts"; diff --git a/src/pages/options/routes/Setting.tsx b/src/pages/options/routes/Setting.tsx index d4ecfdafb..173e4cb48 100644 --- a/src/pages/options/routes/Setting.tsx +++ b/src/pages/options/routes/Setting.tsx @@ -14,6 +14,7 @@ import FileSystemFactory from "@Packages/filesystem/factory"; import FileSystemParams from "@App/pages/components/FileSystemParams"; import { blackListSelfCheck } from "@App/pkg/utils/match"; import { obtainBlackList } from "@App/pkg/utils/utils"; +import CustomTrans from "@App/pages/components/CustomTrans"; function Setting() { const [syncDelete, setSyncDelete] = useState(); @@ -29,6 +30,8 @@ function Setting() { const [updateDisableScript, setUpdateDisableScript] = useState(false); const [silenceUpdateScript, setSilenceUpdateScript] = useState(false); const [enableEslint, setEnableEslint] = useState(false); + const [editorConfig, setEditorConfig] = useState(""); + const [editorTypeDefinition, setEditorTypeDefinition] = useState(""); const [eslintConfig, setEslintConfig] = useState(""); const [blacklist, setBlacklist] = useState(""); const [badgeNumberType, setBadgeNumberType] = useState<"none" | "run_count" | "script_count">("run_count"); @@ -67,6 +70,8 @@ function Setting() { systemConfig.getBadgeBackgroundColor(), systemConfig.getBadgeTextColor(), systemConfig.getScriptMenuDisplayType(), + systemConfig.getEditorConfig(), + systemConfig.getEditorTypeDefinition(), ]).then( ([ cloudSync, @@ -82,6 +87,8 @@ function Setting() { badgeBackgroundColor, badgeTextColor, scriptMenuDisplayType, + editorConfig, + editorTypeDefinition, ]) => { setSyncDelete(cloudSync.syncDelete); setSyncScriptStatus(cloudSync.syncStatus); @@ -100,6 +107,8 @@ function Setting() { setBadgeBackgroundColor(badgeBackgroundColor); setBadgeTextColor(badgeTextColor); setScriptMenuDisplayType(scriptMenuDisplayType); + setEditorConfig(editorConfig); + setEditorTypeDefinition(editorTypeDefinition); } ); }; @@ -445,14 +454,19 @@ function Setting() { onChange={(v) => { setEslintConfig(v); }} - onBlur={(v) => { + onBlur={() => { prettier .format(eslintConfig, { parser: "json", plugins: [prettierPluginEstree, babel], }) - .then(() => { - systemConfig.setEslintConfig(v.target.value); + .then((value) => { + if (value === "") { + Message.success(t("eslint_rules_reset")); + } else { + Message.success(t("eslint_rules_saved")); + } + systemConfig.setEslintConfig(value); }) .catch((e) => { Message.error(`${t("eslint_config_format_error")}: ${JSON.stringify(Logger.E(e))}`); @@ -461,6 +475,74 @@ function Setting() { /> )} +
+
+ {t("editor_config")} + +
+ { + setEditorConfig(v); + }} + onBlur={() => { + prettier + .format(editorConfig, { + parser: "json", + plugins: [prettierPluginEstree, babel], + }) + .then((value) => { + if (value === "") { + Message.success(t("editor_config_reset")); + } else { + Message.success(t("editor_config_saved")); + } + systemConfig.setEditorConfig(value); + }) + .catch((e) => { + Message.error(`${t("editor_config_format_error")}: ${JSON.stringify(Logger.E(e))}`); + }); + }} + /> +
+
+
+ {t("editor_type_definition")} + +
+ { + setEditorTypeDefinition(v); + }} + onBlur={() => { + if (editorTypeDefinition === "") { + Message.success(t("editor_type_definition_reset")); + } else { + Message.success(t("editor_type_definition_saved")); + } + systemConfig.setEditorTypeDefinition(editorTypeDefinition); + }} + /> +
diff --git a/src/pkg/config/config.ts b/src/pkg/config/config.ts index f7ee367ec..2c727ac9b 100644 --- a/src/pkg/config/config.ts +++ b/src/pkg/config/config.ts @@ -1,10 +1,11 @@ -import { Message } from "@arco-design/web-react"; import ChromeStorage from "./chrome_storage"; import { defaultConfig } from "../../../packages/eslint/linter-config"; +import { defaultConfig as editorDefaultConfig } from "@App/pkg/utils/monaco-editor/config"; import type { FileSystemType } from "@Packages/filesystem/factory"; import type { MessageQueue, TKeyValue } from "@Packages/message/message_queue"; import { changeLanguage, matchLanguage } from "@App/locales/locales"; import { ExtVersion } from "@App/app/const"; +import defaultTypeDefinition from "@App/template/scriptcat.d.tpl"; export const SystemConfigChange = "systemConfigChange"; @@ -186,16 +187,37 @@ export class SystemConfig { setEslintConfig(v: string) { if (v === "") { this.set("eslint_config", undefined); - Message.success("ESLint规则已重置"); return; } - try { - JSON.parse(v); - this.set("eslint_config", v); - Message.success("ESLint规则已保存"); - } catch (err: any) { - Message.error(err.toString()); + JSON.parse(v); + return this.set("eslint_config", v); + } + + getEditorConfig() { + return this.get("editor_config", editorDefaultConfig); + } + + setEditorConfig(v: string) { + if (v === "") { + this.set("editor_config", undefined); + return; + } + JSON.parse(v); + return this.set("editor_config", v); + } + + // 获取typescript类型定义 + getEditorTypeDefinition() { + return localStorage.getItem("editor_type_definition") || defaultTypeDefinition; + } + + // 由于内容过大,只能存储到chrome.storage.local中 + setEditorTypeDefinition(v: string) { + if (v === "") { + delete localStorage["editor_type_definition"]; + return; } + localStorage.setItem("editor_type_definition", v); } // 日志清理周期 diff --git a/src/pkg/utils/monaco-editor/config.ts b/src/pkg/utils/monaco-editor/config.ts new file mode 100644 index 000000000..4db488342 --- /dev/null +++ b/src/pkg/utils/monaco-editor/config.ts @@ -0,0 +1,9 @@ +import type { languages } from "monaco-editor"; + +const config = { + noSemanticValidation: true, + noSyntaxValidation: false, + onlyVisible: false, +} as languages.typescript.CompilerOptions; + +export const defaultConfig = JSON.stringify(config, null, 2); diff --git a/src/pkg/utils/monaco-editor.ts b/src/pkg/utils/monaco-editor/index.ts similarity index 67% rename from src/pkg/utils/monaco-editor.ts rename to src/pkg/utils/monaco-editor/index.ts index 821ebffbb..f304435a2 100644 --- a/src/pkg/utils/monaco-editor.ts +++ b/src/pkg/utils/monaco-editor/index.ts @@ -1,5 +1,4 @@ -import { globalCache } from "@App/pages/store/global"; -import dts from "@App/template/scriptcat.d.tpl"; +import { globalCache, systemConfig } from "@App/pages/store/global"; import EventEmitter from "eventemitter3"; import { languages } from "monaco-editor"; @@ -16,8 +15,6 @@ export default function registerEditor() { }, }; - languages.typescript.javascriptDefaults.addExtraLib(dts, "scriptcat.d.ts"); - // 悬停提示 const prompt: { [key: string]: any } = { name: "脚本名称", @@ -92,6 +89,53 @@ export default function registerEditor() { isPreferred: true, }); } + // 添加eslint-disable-next-line和eslint-disable + actions.push({ + title: `添加 eslint-disable-next-line 注释`, + diagnostics: [val], + kind: "quickfix", + edit: { + edits: [ + { + resource: model.uri, + textEdit: { + range: { + startLineNumber: val.startLineNumber, + endLineNumber: val.startLineNumber, + startColumn: 1, + endColumn: 1, + }, + text: `// eslint-disable-next-line ${typeof val.code === "string" ? val.code : val.code!.value}\n`, + }, + versionId: undefined, + }, + ], + }, + isPreferred: true, + }); + actions.push({ + title: `添加 eslint-disable 注释`, + diagnostics: [val], + kind: "quickfix", + edit: { + edits: [ + { + resource: model.uri, + textEdit: { + range: { + startLineNumber: 1, + endLineNumber: 1, + startColumn: 1, + endColumn: 1, + }, + text: `/* eslint-disable ${typeof val.code === "string" ? val.code : val.code!.value} */\n`, + }, + versionId: undefined, + }, + ], + }, + isPreferred: true, + }); } // const actions = context.markers.map((error) => { @@ -119,6 +163,17 @@ export default function registerEditor() { }; }, }); + + Promise.all([systemConfig.getEditorConfig(), systemConfig.getEditorTypeDefinition()]).then( + ([editorConfig, typeDefinition]) => { + // 设置编辑器设置 + languages.typescript.javascriptDefaults.setCompilerOptions( + JSON.parse(editorConfig) as languages.typescript.CompilerOptions + ); + // 注册类型定义 + languages.typescript.javascriptDefaults.addExtraLib(typeDefinition, "scriptcat.d.ts"); + } + ); } export class LinterWorker { From eafad4049b6674082a02c02fa5c42e286dfddbc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Thu, 4 Sep 2025 17:40:12 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pkg/config/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/config/config.ts b/src/pkg/config/config.ts index 2c727ac9b..db99bac4b 100644 --- a/src/pkg/config/config.ts +++ b/src/pkg/config/config.ts @@ -211,7 +211,7 @@ export class SystemConfig { return localStorage.getItem("editor_type_definition") || defaultTypeDefinition; } - // 由于内容过大,只能存储到chrome.storage.local中 + // 由于内容过大,只能存储到localStorage中 setEditorTypeDefinition(v: string) { if (v === "") { delete localStorage["editor_type_definition"]; From fa0173cf72a4e9feb4008db94d979479053defab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Thu, 4 Sep 2025 18:00:23 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rspack.config.ts | 5 ----- vitest.config.ts | 13 +++++++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/rspack.config.ts b/rspack.config.ts index 607b5a1e9..f47bd96b0 100644 --- a/rspack.config.ts +++ b/rspack.config.ts @@ -108,11 +108,6 @@ export default defineConfig({ }, ], }, - { - type: "asset/source", - test: /\.d\.ts$/, - exclude: /node_modules/, - }, { type: "asset/source", test: /\.tpl$/, diff --git a/vitest.config.ts b/vitest.config.ts index 5172fa4d3..80250fbf1 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,4 +1,5 @@ import path from "path"; +import fs from "fs"; import { defineConfig } from "vitest/config"; export default defineConfig({ @@ -10,6 +11,18 @@ export default defineConfig({ "monaco-editor": path.resolve(__dirname, "./tests/mocks/monaco-editor.ts"), }, }, + plugins: [ + { + name: "handle-tpl-files", + load(id) { + if (id.endsWith(".tpl")) { + // Return the content as a string asset + const content = fs.readFileSync(id, "utf-8"); + return `export default ${JSON.stringify(content)};`; + } + }, + }, + ], test: { environment: "jsdom", // List setup file