Skip to content

Commit 49eb379

Browse files
authored
✨ 增加自定义编辑器配置和编辑器类型定义 (#708)
* wip: 自定义编辑器支持 * ✨ 增加编辑器配置和编辑器类型定义 * 修改注释 * 通过单元测试
1 parent 55223dd commit 49eb379

12 files changed

Lines changed: 237 additions & 27 deletions

File tree

rspack.config.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,6 @@ export default defineConfig({
108108
},
109109
],
110110
},
111-
{
112-
type: "asset/source",
113-
test: /\.d\.ts$/,
114-
exclude: /node_modules/,
115-
},
116111
{
117112
type: "asset/source",
118113
test: /\.tpl$/,

src/locales/ach-UG/translation.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,5 +460,16 @@
460460
"all": "crwdns10812:0crwdne10812:0",
461461
"normal-tabs": "crwdns10814:0crwdne10814:0",
462462
"incognito-tabs": "crwdns10816:0crwdne10816:0"
463-
}
463+
},
464+
"editor_config": "crwdns10818:0crwdne10818:0",
465+
"editor_config_description": "crwdns10820:0crwdne10820:0",
466+
"editor_type_definition": "crwdns10822:0crwdne10822:0",
467+
"editor_type_definition_description": "crwdns10824:0crwdne10824:0",
468+
"eslint_rules_reset": "crwdns10826:0crwdne10826:0",
469+
"eslint_rules_saved": "crwdns10828:0crwdne10828:0",
470+
"editor_config_reset": "crwdns10830:0crwdne10830:0",
471+
"editor_config_saved": "crwdns10832:0crwdne10832:0",
472+
"editor_config_format_error": "crwdns10834:0crwdne10834:0",
473+
"editor_type_definition_reset": "crwdns10836:0crwdne10836:0",
474+
"editor_type_definition_saved": "crwdns10838:0crwdne10838:0"
464475
}

src/locales/en-US/translation.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,5 +460,16 @@
460460
"all": "All",
461461
"normal-tabs": "Normal tags",
462462
"incognito-tabs": "Incognito tags"
463-
}
463+
},
464+
"editor_config": "Editor Configuration",
465+
"editor_config_description": "You can refer to the compilerOptions in <Link href=\"https://code.visualstudio.com/docs/languages/jsconfig\">jsconfig.js</Link> for configuration",
466+
"editor_type_definition": "Editor Type Definition",
467+
"editor_type_definition_description": "You can customize your own type definitions, and the script editor will automatically load these type definitions",
468+
"eslint_rules_reset": "ESLint Rules Reset",
469+
"eslint_rules_saved": "ESLint Rules Saved",
470+
"editor_config_reset": "Editor Configuration Reset",
471+
"editor_config_saved": "Editor Configuration Saved",
472+
"editor_config_format_error": "Editor Configuration Format Error",
473+
"editor_type_definition_reset": "Editor Type Definition Reset",
474+
"editor_type_definition_saved": "Editor Type Definition Saved"
464475
}

src/locales/zh-CN/translation.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,5 +460,16 @@
460460
"all": "所有标签",
461461
"normal-tabs": "普通标签",
462462
"incognito-tabs": "隐身标签"
463-
}
463+
},
464+
"editor_config": "",
465+
"editor_config_description": "",
466+
"editor_type_definition": "",
467+
"editor_type_definition_description": "",
468+
"eslint_rules_reset": "",
469+
"eslint_rules_saved": "",
470+
"editor_config_reset": "",
471+
"editor_config_saved": "",
472+
"editor_config_format_error": "",
473+
"editor_type_definition_reset": "",
474+
"editor_type_definition_saved": ""
464475
}

src/pages/components/CodeEditor/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { LinterWorker } from "@App/pkg/utils/monaco-editor";
21
import { editor, Range } from "monaco-editor";
32
import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
43
import { globalCache, systemConfig } from "@App/pages/store/global";
4+
import { LinterWorker } from "@App/pkg/utils/monaco-editor";
55

66
type Props = {
77
className?: string;

src/pages/components/CustomTrans/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { useTranslation } from "react-i18next";
44

55
// 因为i18n的Trans组件打包后出现问题,所以自己实现一个
66
export const CustomTrans: React.FC<{
7+
className?: string;
78
i18nKey: string;
8-
}> = ({ i18nKey }) => {
9+
}> = ({ className, i18nKey }) => {
910
const { t } = useTranslation();
1011
const children: (JSX.Element | string)[] = [];
1112
let content = t(i18nKey);
@@ -39,7 +40,7 @@ export const CustomTrans: React.FC<{
3940
}
4041
}
4142

42-
return <div>{children}</div>;
43+
return <div className={className}>{children}</div>;
4344
};
4445

4546
export default CustomTrans;

src/pages/options/main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import "./index.css";
1111
import LoggerCore from "@App/app/logger/core.ts";
1212
import { LoggerDAO } from "@App/app/repo/logger.ts";
1313
import DBWriter from "@App/app/logger/db_writer.ts";
14-
import registerEditor from "@App/pkg/utils/monaco-editor.ts";
14+
import registerEditor from "@App/pkg/utils/monaco-editor";
1515
import storeSubscribe from "../store/subscribe.ts";
1616
import migrate from "@App/app/migrate.ts";
1717

src/pages/options/routes/Setting.tsx

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import FileSystemFactory from "@Packages/filesystem/factory";
1414
import FileSystemParams from "@App/pages/components/FileSystemParams";
1515
import { blackListSelfCheck } from "@App/pkg/utils/match";
1616
import { obtainBlackList } from "@App/pkg/utils/utils";
17+
import CustomTrans from "@App/pages/components/CustomTrans";
1718

1819
function Setting() {
1920
const [syncDelete, setSyncDelete] = useState<boolean>();
@@ -29,6 +30,8 @@ function Setting() {
2930
const [updateDisableScript, setUpdateDisableScript] = useState(false);
3031
const [silenceUpdateScript, setSilenceUpdateScript] = useState(false);
3132
const [enableEslint, setEnableEslint] = useState(false);
33+
const [editorConfig, setEditorConfig] = useState("");
34+
const [editorTypeDefinition, setEditorTypeDefinition] = useState("");
3235
const [eslintConfig, setEslintConfig] = useState("");
3336
const [blacklist, setBlacklist] = useState<string>("");
3437
const [badgeNumberType, setBadgeNumberType] = useState<"none" | "run_count" | "script_count">("run_count");
@@ -67,6 +70,8 @@ function Setting() {
6770
systemConfig.getBadgeBackgroundColor(),
6871
systemConfig.getBadgeTextColor(),
6972
systemConfig.getScriptMenuDisplayType(),
73+
systemConfig.getEditorConfig(),
74+
systemConfig.getEditorTypeDefinition(),
7075
]).then(
7176
([
7277
cloudSync,
@@ -82,6 +87,8 @@ function Setting() {
8287
badgeBackgroundColor,
8388
badgeTextColor,
8489
scriptMenuDisplayType,
90+
editorConfig,
91+
editorTypeDefinition,
8592
]) => {
8693
setSyncDelete(cloudSync.syncDelete);
8794
setSyncScriptStatus(cloudSync.syncStatus);
@@ -100,6 +107,8 @@ function Setting() {
100107
setBadgeBackgroundColor(badgeBackgroundColor);
101108
setBadgeTextColor(badgeTextColor);
102109
setScriptMenuDisplayType(scriptMenuDisplayType);
110+
setEditorConfig(editorConfig);
111+
setEditorTypeDefinition(editorTypeDefinition);
103112
}
104113
);
105114
};
@@ -445,14 +454,19 @@ function Setting() {
445454
onChange={(v) => {
446455
setEslintConfig(v);
447456
}}
448-
onBlur={(v) => {
457+
onBlur={() => {
449458
prettier
450459
.format(eslintConfig, {
451460
parser: "json",
452461
plugins: [prettierPluginEstree, babel],
453462
})
454-
.then(() => {
455-
systemConfig.setEslintConfig(v.target.value);
463+
.then((value) => {
464+
if (value === "") {
465+
Message.success(t("eslint_rules_reset"));
466+
} else {
467+
Message.success(t("eslint_rules_saved"));
468+
}
469+
systemConfig.setEslintConfig(value);
456470
})
457471
.catch((e) => {
458472
Message.error(`${t("eslint_config_format_error")}: ${JSON.stringify(Logger.E(e))}`);
@@ -461,6 +475,74 @@ function Setting() {
461475
/>
462476
</div>
463477
)}
478+
<div>
479+
<div className="flex items-start justify-between mb-3">
480+
<span className="font-medium min-w-20">{t("editor_config")}</span>
481+
<CustomTrans
482+
className="text-xs max-w-80 text-right ml-6 flex-shrink-0"
483+
i18nKey="editor_config_description"
484+
/>
485+
</div>
486+
<Input.TextArea
487+
placeholder={t("editor_config")!}
488+
autoSize={{
489+
minRows: 4,
490+
maxRows: 8,
491+
}}
492+
value={editorConfig}
493+
onChange={(v) => {
494+
setEditorConfig(v);
495+
}}
496+
onBlur={() => {
497+
prettier
498+
.format(editorConfig, {
499+
parser: "json",
500+
plugins: [prettierPluginEstree, babel],
501+
})
502+
.then((value) => {
503+
if (value === "") {
504+
Message.success(t("editor_config_reset"));
505+
} else {
506+
Message.success(t("editor_config_saved"));
507+
}
508+
systemConfig.setEditorConfig(value);
509+
})
510+
.catch((e) => {
511+
Message.error(`${t("editor_config_format_error")}: ${JSON.stringify(Logger.E(e))}`);
512+
});
513+
}}
514+
/>
515+
</div>
516+
<div>
517+
<div className="flex items-start justify-between mb-3">
518+
<span className="font-medium min-w-20">{t("editor_type_definition")}</span>
519+
<span
520+
className="text-xs max-w-100 text-right ml-6 flex-shrink-0"
521+
dangerouslySetInnerHTML={{
522+
__html: t("editor_type_definition_description"),
523+
}}
524+
></span>
525+
</div>
526+
<Input.TextArea
527+
placeholder={t("editor_type_definition")!}
528+
autoSize={{
529+
minRows: 4,
530+
maxRows: 8,
531+
}}
532+
value={editorTypeDefinition}
533+
onChange={(v) => {
534+
setEditorTypeDefinition(v);
535+
}}
536+
onBlur={() => {
537+
if (editorTypeDefinition === "") {
538+
Message.success(t("editor_type_definition_reset"));
539+
} else {
540+
Message.success(t("editor_type_definition_saved"));
541+
}
542+
systemConfig.setEditorTypeDefinition(editorTypeDefinition);
543+
}}
544+
/>
545+
</div>
464546
</Space>
465547
</Card>
466548
</Space>

src/pkg/config/config.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { Message } from "@arco-design/web-react";
21
import ChromeStorage from "./chrome_storage";
32
import { defaultConfig } from "../../../packages/eslint/linter-config";
3+
import { defaultConfig as editorDefaultConfig } from "@App/pkg/utils/monaco-editor/config";
44
import type { FileSystemType } from "@Packages/filesystem/factory";
55
import type { MessageQueue, TKeyValue } from "@Packages/message/message_queue";
66
import { changeLanguage, matchLanguage } from "@App/locales/locales";
77
import { ExtVersion } from "@App/app/const";
8+
import defaultTypeDefinition from "@App/template/scriptcat.d.tpl";
89

910
export const SystemConfigChange = "systemConfigChange";
1011

@@ -186,16 +187,37 @@ export class SystemConfig {
186187
setEslintConfig(v: string) {
187188
if (v === "") {
188189
this.set("eslint_config", undefined);
189-
Message.success("ESLint规则已重置");
190190
return;
191191
}
192-
try {
193-
JSON.parse(v);
194-
this.set("eslint_config", v);
195-
Message.success("ESLint规则已保存");
196-
} catch (err: any) {
197-
Message.error(err.toString());
192+
JSON.parse(v);
193+
return this.set("eslint_config", v);
194+
}
195+
196+
getEditorConfig() {
197+
return this.get<string>("editor_config", editorDefaultConfig);
198+
}
199+
200+
setEditorConfig(v: string) {
201+
if (v === "") {
202+
this.set("editor_config", undefined);
203+
return;
204+
}
205+
JSON.parse(v);
206+
return this.set("editor_config", v);
207+
}
208+
209+
// 获取typescript类型定义
210+
getEditorTypeDefinition() {
211+
return localStorage.getItem("editor_type_definition") || defaultTypeDefinition;
212+
}
213+
214+
// 由于内容过大,只能存储到localStorage中
215+
setEditorTypeDefinition(v: string) {
216+
if (v === "") {
217+
delete localStorage["editor_type_definition"];
218+
return;
198219
}
220+
localStorage.setItem("editor_type_definition", v);
199221
}
200222

201223
// 日志清理周期
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { languages } from "monaco-editor";
2+
3+
const config = {
4+
noSemanticValidation: true,
5+
noSyntaxValidation: false,
6+
onlyVisible: false,
7+
} as languages.typescript.CompilerOptions;
8+
9+
export const defaultConfig = JSON.stringify(config, null, 2);

0 commit comments

Comments
 (0)