diff --git a/.env b/.env
new file mode 100644
index 0000000..b8475cc
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+VITE_MONACO_URL=/monaco-editor
\ No newline at end of file
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..af18361
--- /dev/null
+++ b/.env.production
@@ -0,0 +1 @@
+VITE_MONACO_URL=//unpkg.com/monaco-editor@0.47.0
\ No newline at end of file
diff --git a/index.html b/index.html
index b7c3083..b9fcb63 100644
--- a/index.html
+++ b/index.html
@@ -1,14 +1,16 @@
-
-
-
-
- GOST API Manage
-
-
-
-
-
-
-
-
-
+
+
+
+
+ GOST API Manage
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 946a412..c521d7d 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,6 @@
"qs": "^6.11.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-monaco-editor": "^0.54.0",
"uuid": "^9.0.1"
},
"devDependencies": {
diff --git a/src/Pages/Manage.tsx b/src/Pages/Manage.tsx
index 26071a4..5aef0e5 100644
--- a/src/Pages/Manage.tsx
+++ b/src/Pages/Manage.tsx
@@ -21,8 +21,7 @@ import {
useServerConfig,
} from "../uitls/server";
import { download, jsonFormat } from "../uitls";
-import { MonacoEditor } from "../uitls/userMonacoWorker";
-import Ctx from "../uitls/ctx";
+import { CodeEditor } from "../uitls/useMonacoEdit";
import * as API from "../api";
import ListCard, { ProCard } from "../components/ListCard";
import ChainCard from "../components/ListCard/Chains";
@@ -291,17 +290,17 @@ const Manage = () => {
{/* {jsonFormat(gostConfig!)} */}
-
+ >
diff --git a/src/components/Forms/Json.tsx b/src/components/Forms/Json.tsx
index 91d1410..60f5d61 100644
--- a/src/components/Forms/Json.tsx
+++ b/src/components/Forms/Json.tsx
@@ -3,12 +3,11 @@ import ReactDOM from "react-dom/client";
import { Button, Dropdown, Form, FormInstance, Space } from "antd";
import { DownOutlined } from "@ant-design/icons";
import { jsonFormat, jsonStringFormat, jsonParse, jsonEdit } from "../../uitls";
-import * as monaco from "monaco-editor";
-import { MonacoEditor, getModel, model, modelUri } from "../../uitls/userMonacoWorker";
import { Template } from "../../templates";
// import { render } from "react-dom";
// import { useServerConfig } from "../../uitls/server";
import ModalForm, { ModalFormProps } from "../ModalForm";
+import { CodeEditor } from "../../uitls/useMonacoEdit";
const template2menu: any = (template: Template) => {
const { children, ...other } = template;
@@ -180,21 +179,20 @@ const JsonForm: React.FC = (props) => {
},
]}
>
-
+ }} />
+ {/* */}
>
diff --git a/src/monaco.d.ts b/src/monaco.d.ts
new file mode 100644
index 0000000..85fb4cc
--- /dev/null
+++ b/src/monaco.d.ts
@@ -0,0 +1,4 @@
+namespace globalThis {
+ const monacoIsReady: Promise;
+ const monaco: any;
+}
diff --git a/src/uitls/useMonacoEdit.tsx b/src/uitls/useMonacoEdit.tsx
new file mode 100644
index 0000000..2696251
--- /dev/null
+++ b/src/uitls/useMonacoEdit.tsx
@@ -0,0 +1,194 @@
+import React, { useEffect, useRef, useState } from "react";
+import { useBindValue } from "./use";
+import type * as Monaco from "monaco-editor";
+import classnames from "classnames";
+
+(function () {
+ const require = (window as any).require;
+ let monacoURL;
+ const MONACO_URL = import.meta.env.VITE_MONACO_URL || '/monaco-editor';
+ if(/^(http[s]:)?\/\//.test(MONACO_URL)){
+ monacoURL = MONACO_URL + '/min/vs'
+ }else{
+ const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
+ monacoURL = new URL(`${MONACO_URL}/min/vs`, baseURL).href;
+ }
+
+ // if(import.meta.env.PROD && import.meta.env.VITE_MONACO_URL){
+ // monacoURL = import.meta.env.VITE_MONACO_URL + '/min/vs';
+ // }else{
+ // const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
+ // monacoURL = new URL("./monaco-editor/min/vs", baseURL).href;
+ // }
+
+ // console.log(`import_meta_env_BASE_URL`, import.meta.env.BASE_URL);
+ // console.log("baseURL", baseURL);
+ // const monacoURL = `//unpkg.com/monaco-editor@0.47.0/min/vs`
+ require.config({ paths: { vs: `${monacoURL}` } });
+ require.config({
+ "vs/nls": {
+ availableLanguages: {
+ "*": "zh-cn",
+ },
+ },
+ });
+ (window as any).monacoIsReady = new Promise((resolve, reject) => {
+ require(["vs/editor/editor.main"], function () {
+ resolve(monaco);
+ });
+ });
+})();
+
+monacoIsReady.then(() => {
+ // monacoPython.register(); //注册 关键字,内置函数 代码提示 ;
+ monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
+ allowComments: true,
+ trailingCommas: "warning",
+ validate: true,
+ });
+ // monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
+});
+
+type CodeEditorProps = {
+ className?: string;
+ style?: React.CSSProperties;
+ language?: string;
+ value?: string;
+ theme?: string;
+ height?: string | number;
+ defaultValue?: string;
+ onChange?: (value: string) => void;
+ options?: Monaco.editor.IStandaloneEditorConstructionOptions;
+};
+
+const defOptions: Monaco.editor.IStandaloneEditorConstructionOptions = {
+ minimap: { enabled: false },
+ automaticLayout: true,
+};
+
+const CodeEditor_: React.ForwardRefRenderFunction<
+ Monaco.editor.IStandaloneCodeEditor,
+ CodeEditorProps
+> = (props, ref) => {
+ const { onChange, options, height, className, theme = "vs", style } = props;
+ const [language, setLanguage] = useBindValue(props.language, "javascript");
+ const [value, setValue] = useBindValue(props.value, props.defaultValue, "");
+ const [isReady, setReady] = useState(false);
+ const divEl = useRef(null);
+ const editor = useRef(null);
+ const self = useRef({});
+
+ React.useImperativeHandle(ref, () => {
+ return editor.current!;
+ });
+
+ React.useImperativeHandle(
+ self,
+ () => {
+ return {
+ onChange,
+ };
+ },
+ [onChange]
+ );
+
+ useEffect(() => {
+ // let editor: any;
+ if (divEl.current) {
+ const el = divEl.current;
+ let _editor: Monaco.editor.IStandaloneCodeEditor;
+ monacoIsReady.then(() => {
+ _editor = editor.current = monaco.editor.create(el, {
+ value: value,
+ language: language,
+ theme,
+ ...defOptions,
+ ...options,
+ });
+ console.log("editor.current", editor.current.getDomNode());
+ _editor.onDidChangeModelContent(function (event: any) {
+ const _value = _editor.getValue();
+ setValue(_value);
+ self.current?.onChange?.(_value);
+ });
+
+ _editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.KeyX, (e) => {
+ _editor.getAction("my-autoWrap-toggle")?.run();
+ });
+
+ _editor.addAction({
+ id: "my-autoWrap-toggle",
+ label: "切换自动换行",
+ keybindings: [
+ monaco.KeyMod.Alt | monaco.KeyCode.KeyZ,
+ // monaco.KeyMod.chord(
+ // monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK,
+ // monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyM
+ // ),
+ ],
+
+ // A precondition for this action.
+ // precondition: null,
+
+ // A rule to evaluate on top of the precondition in order to dispatch the keybindings.
+ // keybindingContext: null,
+
+ // contextMenuGroupId: "navigation",
+ // contextMenuOrder: 1.5,
+
+ // Method that will be executed when the action is triggered.
+ // @param editor The editor instance is passed in as a convenience
+ run: function (ed, arg) {
+ // alert("i'm running => " + ed.getPosition());
+ // console.log("my-autoWrap-toggle", arg);
+ const workWrap = ed.getOption(monaco.editor.EditorOption.wordWrap);
+ ed.updateOptions({
+ wordWrap: workWrap === "on" ? "off" : "on",
+ });
+ },
+ });
+
+ setReady(true);
+ });
+ // let xc: any;
+ // const resizeObserver = new ResizeObserver((entries) => {
+ // // _editor?.layout();
+ // // console.log("resizeObserver");
+ // if (xc) clearTimeout(xc);
+ // xc = setTimeout(() => {
+ // _editor?.layout();
+ // }, 100);
+ // });
+ // resizeObserver.observe(el);
+ return () => {
+ _editor?.dispose?.();
+ // resizeObserver.unobserve(el);
+ // resizeObserver.disconnect();
+ };
+ }
+ }, []);
+
+ useEffect(() => {
+ if (editor.current) {
+ if (value != editor.current.getValue()) {
+ editor.current.setValue(value);
+ }
+ }
+ }, [value]);
+
+ return (
+
+ );
+};
+
+export const CodeEditor = React.forwardRef(CodeEditor_);
diff --git a/src/uitls/userMonacoWorker.ts b/src/uitls/userMonacoWorker.ts.bak
similarity index 58%
rename from src/uitls/userMonacoWorker.ts
rename to src/uitls/userMonacoWorker.ts.bak
index 7bb49b3..430b551 100644
--- a/src/uitls/userMonacoWorker.ts
+++ b/src/uitls/userMonacoWorker.ts.bak
@@ -1,8 +1,9 @@
/* eslint-disable */
+import MonacoEditor from "react-monaco-editor";
+// import { monaco } from "react-monaco-editor";
import * as monaco from "monaco-editor";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
-import MonacoEditor from "react-monaco-editor";
// import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
// import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
// import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
@@ -31,46 +32,47 @@ self.MonacoEnvironment = {
},
};
-var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
-var getModel = (value: string) => {
- return monaco.editor.createModel(value, "json", modelUri);
-};
-var model = getModel('');
+// var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
+// var getModel = (value: string) => {
+// return monaco.editor.createModel(value, "json", modelUri);
+// };
+// var model = getModel("");
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
allowComments: true,
trailingCommas: "warning",
validate: true,
// json 数据格式测试
- schemas: [
- {
- uri: "http://gost/config.json", // id of the first schema
- fileMatch: [modelUri.toString()], // associate with our model
- schema: {
- type: "object",
- properties: {
- p1: {
- enum: ["v1", "v2"],
- },
- p2: {
- $ref: "http://myserver/bar-schema.json", // reference the second schema
- },
- },
- },
- },
- {
- uri: "http://myserver/bar-schema.json", // id of the second schema
- schema: {
- type: "object",
- properties: {
- q1: {
- enum: ["x1", "x2"],
- },
- },
- },
- },
- ],
+ // schemas: [
+ // {
+ // uri: "http://gost/config.json", // id of the first schema
+ // fileMatch: [modelUri.toString()], // associate with our model
+ // schema: {
+ // type: "object",
+ // properties: {
+ // p1: {
+ // enum: ["v1", "v2"],
+ // },
+ // p2: {
+ // $ref: "http://myserver/bar-schema.json", // reference the second schema
+ // },
+ // },
+ // },
+ // },
+ // {
+ // uri: "http://myserver/bar-schema.json", // id of the second schema
+ // schema: {
+ // type: "object",
+ // properties: {
+ // q1: {
+ // enum: ["x1", "x2"],
+ // },
+ // },
+ // },
+ // },
+ // ],
});
+
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
-export { MonacoEditor, modelUri, getModel, model };
+export { MonacoEditor };
diff --git a/vite.config.ts b/vite.config.ts
index c5af135..744786c 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -21,7 +21,7 @@ export default defineConfig(({ command, mode }) => {
output: {
// manualChunks 配置
manualChunks: {
- monaco: ["monaco-editor"],
+ // monaco: ["monaco-editor"],
antd: ["antd"],
},
},