mirror of
https://github.com/ecomfe/vue-echarts.git
synced 2025-10-27 10:55:07 +08:00
249 lines
5.8 KiB
TypeScript
249 lines
5.8 KiB
TypeScript
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
|
|
import "monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution";
|
|
import "monaco-editor/esm/vs/basic-languages/typescript/typescript.contribution";
|
|
import "monaco-editor/esm/vs/language/json/monaco.contribution";
|
|
import "monaco-editor/esm/vs/language/typescript/monaco.contribution";
|
|
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
|
|
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
|
|
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
|
|
|
|
const globalWithMonaco = globalThis as typeof globalThis & {
|
|
MonacoEnvironment?: {
|
|
getWorker: (moduleId: string, label: string) => Worker;
|
|
};
|
|
};
|
|
|
|
if (!globalWithMonaco.MonacoEnvironment) {
|
|
globalWithMonaco.MonacoEnvironment = {
|
|
getWorker(_: string, label: string) {
|
|
if (label === "json") {
|
|
return new jsonWorker();
|
|
}
|
|
if (label === "typescript" || label === "javascript") {
|
|
return new tsWorker();
|
|
}
|
|
return new editorWorker();
|
|
},
|
|
};
|
|
}
|
|
|
|
const diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions = {
|
|
noSemanticValidation: true,
|
|
noSyntaxValidation: true,
|
|
noSuggestionDiagnostics: true,
|
|
};
|
|
|
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions(
|
|
diagnosticsOptions,
|
|
);
|
|
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions(
|
|
diagnosticsOptions,
|
|
);
|
|
monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true);
|
|
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
|
|
|
|
export type MonacoSeverity = "error" | "warning" | "info" | "hint";
|
|
|
|
export interface MonacoMarkerLike {
|
|
startLineNumber: number;
|
|
startColumn: number;
|
|
endLineNumber: number;
|
|
endColumn: number;
|
|
message: string;
|
|
code?: string;
|
|
source?: string;
|
|
severity?: MonacoSeverity;
|
|
}
|
|
|
|
const SEVERITY_MAP: Record<MonacoSeverity, monaco.MarkerSeverity> = {
|
|
error: monaco.MarkerSeverity.Error,
|
|
warning: monaco.MarkerSeverity.Warning,
|
|
info: monaco.MarkerSeverity.Info,
|
|
hint: monaco.MarkerSeverity.Hint,
|
|
};
|
|
|
|
export interface OptionEditor {
|
|
editor: monaco.editor.IStandaloneCodeEditor;
|
|
getValue(): string;
|
|
setValue(value: string): void;
|
|
setMarkers(markers: readonly MonacoMarkerLike[]): void;
|
|
setTheme(theme: string): void;
|
|
dispose(): void;
|
|
}
|
|
|
|
export interface CodeViewer {
|
|
editor: monaco.editor.IStandaloneCodeEditor;
|
|
setValue(value: string): void;
|
|
setTheme(theme: string): void;
|
|
setLanguage(language: string): void;
|
|
dispose(): void;
|
|
}
|
|
|
|
export interface CreateOptionEditorOptions {
|
|
initialCode: string;
|
|
language?: string;
|
|
onChange?: (code: string) => void;
|
|
theme?: string;
|
|
}
|
|
|
|
export interface CreateCodeViewerOptions {
|
|
initialCode: string;
|
|
language?: string;
|
|
theme?: string;
|
|
}
|
|
|
|
const MARKER_OWNER = "ve-codegen-option";
|
|
|
|
export function createOptionEditor(
|
|
container: HTMLElement,
|
|
{
|
|
initialCode,
|
|
language = "typescript",
|
|
onChange,
|
|
theme = "vs",
|
|
}: CreateOptionEditorOptions,
|
|
): OptionEditor {
|
|
monaco.editor.setTheme(theme);
|
|
|
|
const editor = monaco.editor.create(container, {
|
|
value: initialCode,
|
|
language,
|
|
automaticLayout: true,
|
|
scrollBeyondLastLine: false,
|
|
minimap: { enabled: false },
|
|
fontSize: 13,
|
|
lineHeight: 20,
|
|
tabSize: 2,
|
|
insertSpaces: true,
|
|
wordWrap: "on",
|
|
});
|
|
|
|
const disposables: monaco.IDisposable[] = [];
|
|
|
|
if (onChange) {
|
|
disposables.push(
|
|
editor.onDidChangeModelContent(() => {
|
|
const model = editor.getModel();
|
|
if (!model) {
|
|
return;
|
|
}
|
|
onChange(model.getValue());
|
|
}),
|
|
);
|
|
}
|
|
|
|
function getValue() {
|
|
return editor.getValue();
|
|
}
|
|
|
|
function setValue(value: string) {
|
|
const model = editor.getModel();
|
|
if (!model) {
|
|
return;
|
|
}
|
|
if (model.getValue() !== value) {
|
|
model.setValue(value);
|
|
}
|
|
}
|
|
|
|
function setMarkers(markers: readonly MonacoMarkerLike[]) {
|
|
const model = editor.getModel();
|
|
if (!model) {
|
|
return;
|
|
}
|
|
const mapped = markers.map((marker) => ({
|
|
...marker,
|
|
severity: marker.severity
|
|
? SEVERITY_MAP[marker.severity]
|
|
: monaco.MarkerSeverity.Error,
|
|
}));
|
|
monaco.editor.setModelMarkers(model, MARKER_OWNER, mapped);
|
|
}
|
|
|
|
function dispose() {
|
|
disposables.forEach((item) => item.dispose());
|
|
disposables.length = 0;
|
|
const model = editor.getModel();
|
|
if (model) {
|
|
monaco.editor.setModelMarkers(model, MARKER_OWNER, []);
|
|
}
|
|
editor.dispose();
|
|
}
|
|
|
|
function setTheme(nextTheme: string) {
|
|
monaco.editor.setTheme(nextTheme);
|
|
}
|
|
|
|
return {
|
|
editor,
|
|
getValue,
|
|
setValue,
|
|
setMarkers,
|
|
setTheme,
|
|
dispose,
|
|
};
|
|
}
|
|
|
|
export function createCodeViewer(
|
|
container: HTMLElement,
|
|
{
|
|
initialCode,
|
|
language = "javascript",
|
|
theme = "vs",
|
|
}: CreateCodeViewerOptions,
|
|
): CodeViewer {
|
|
monaco.editor.setTheme(theme);
|
|
|
|
const editor = monaco.editor.create(container, {
|
|
value: initialCode,
|
|
language,
|
|
automaticLayout: true,
|
|
scrollBeyondLastLine: false,
|
|
minimap: { enabled: false },
|
|
fontSize: 13,
|
|
lineHeight: 20,
|
|
tabSize: 2,
|
|
insertSpaces: true,
|
|
wordWrap: "on",
|
|
readOnly: true,
|
|
renderLineHighlight: "none",
|
|
});
|
|
|
|
function setValue(value: string) {
|
|
const model = editor.getModel();
|
|
if (!model) {
|
|
return;
|
|
}
|
|
if (model.getValue() !== value) {
|
|
model.setValue(value);
|
|
}
|
|
}
|
|
|
|
function setTheme(nextTheme: string) {
|
|
monaco.editor.setTheme(nextTheme);
|
|
}
|
|
|
|
function setLanguage(nextLanguage: string) {
|
|
const model = editor.getModel();
|
|
if (!model) {
|
|
return;
|
|
}
|
|
monaco.editor.setModelLanguage(model, nextLanguage);
|
|
}
|
|
|
|
function dispose() {
|
|
editor.dispose();
|
|
}
|
|
|
|
return {
|
|
editor,
|
|
setValue,
|
|
setTheme,
|
|
setLanguage,
|
|
dispose,
|
|
};
|
|
}
|
|
|
|
export { monaco };
|
|
export type MonacoNamespace = typeof monaco;
|