|
|
@@ -6,21 +6,23 @@ import {defaultOptions} from './config';
|
|
|
import './language/jsonlog';
|
|
|
import './style.scss';
|
|
|
|
|
|
+//editor的属性
|
|
|
interface IEditorProps {
|
|
|
- className?: string;
|
|
|
- style?: CSSProperties;
|
|
|
- value?: string;
|
|
|
- language?: string;
|
|
|
- sync?: boolean;
|
|
|
- options?: monaco.editor.IStandaloneEditorConstructionOptions;
|
|
|
- cursorPosition?: monaco.IPosition;
|
|
|
- placeholder?: string;
|
|
|
- onChange?: (value: string, instance: monaco.editor.IStandaloneCodeEditor) => void;
|
|
|
- onBlur?: (value: string) => void;
|
|
|
- onFocus?: (value: string) => void;
|
|
|
- onCursorSelection?: (value: string) => void;
|
|
|
+ className?: string; //类名
|
|
|
+ style?: CSSProperties; //css style
|
|
|
+ value?: string; //数据
|
|
|
+ language?: string; //编程语言
|
|
|
+ sync?: boolean; //同步?
|
|
|
+ options?: monaco.editor.IStandaloneEditorConstructionOptions; //monaco构造函数那些选项
|
|
|
+ cursorPosition?: monaco.IPosition; //光标位置
|
|
|
+ placeholder?: string; //占位符
|
|
|
+ onChange?: (value: string, instance: monaco.editor.IStandaloneCodeEditor) => void; //当内容改变时的处理逻辑
|
|
|
+ onBlur?: (value: string) => void; //当光标失去焦点时的逻辑
|
|
|
+ onFocus?: (value: string) => void; //当光标聚焦时的逻辑
|
|
|
+ onCursorSelection?: (value: string) => void; //当光标选中某值的逻辑
|
|
|
}
|
|
|
|
|
|
+//editor组件,接收以下参数
|
|
|
export default function Editor({
|
|
|
className,
|
|
|
style,
|
|
|
@@ -35,32 +37,44 @@ export default function Editor({
|
|
|
onFocus,
|
|
|
onCursorSelection,
|
|
|
}: IEditorProps) {
|
|
|
+ //引用
|
|
|
const container = useRef<HTMLDivElement>(null);
|
|
|
const monacoEditor = useRef<monaco.editor.IStandaloneCodeEditor>();
|
|
|
const placeholderDOM = useRef<HTMLPreElement>(null);
|
|
|
|
|
|
+ //初始化monaco
|
|
|
const initMonaco = () => {
|
|
|
+ //如果当前container引用不为空
|
|
|
if (container.current) {
|
|
|
+ //monaco的options
|
|
|
const editorOptions = {
|
|
|
+ //配置中配置了默认的options,当没有传入相关的参数时有默认的配置
|
|
|
...defaultOptions,
|
|
|
...options,
|
|
|
- value,
|
|
|
- language: language || 'sql',
|
|
|
+ value, //value是传入的value
|
|
|
+ language: language || 'sql', //语言如果没有传,就是sql
|
|
|
};
|
|
|
|
|
|
+ //将引用赋值给monaco实例,创建monaco实例,挂在div上
|
|
|
monacoEditor.current = monaco.editor.create(container.current, editorOptions);
|
|
|
|
|
|
+ //处理placeHolder,根据value是否为空,决定placeHolder的显隐
|
|
|
handleShowPlaceholder(value);
|
|
|
|
|
|
+ //如果monaco实例已经初始化了,且传了光标位置参数
|
|
|
if (monacoEditor.current && cursorPosition) {
|
|
|
+ //在monaco实例上更新光标的位置参数
|
|
|
monacoEditor.current.setPosition(cursorPosition);
|
|
|
+ //聚焦
|
|
|
monacoEditor.current.focus();
|
|
|
+ //?
|
|
|
monacoEditor.current.revealPosition(
|
|
|
cursorPosition,
|
|
|
monaco.editor.ScrollType.Immediate,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ //初始化editor,除了monaco的初始化之外的editor的东西,主要是editor的事件
|
|
|
initEditor();
|
|
|
registerCommands();
|
|
|
}
|
|
|
@@ -69,8 +83,10 @@ export default function Editor({
|
|
|
/**
|
|
|
* TODO: I don't why lost these commands, it should be figure it out after a while
|
|
|
*/
|
|
|
+ //注册键盘命令
|
|
|
const registerCommands = () => {
|
|
|
if (monacoEditor.current) {
|
|
|
+ //添加按键监听
|
|
|
monacoEditor.current.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyZ, () => {
|
|
|
monacoEditor.current?.trigger('editor', 'undo', null);
|
|
|
});
|
|
|
@@ -101,34 +117,48 @@ export default function Editor({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ //初始化编辑器事件
|
|
|
const initEditorEvent = () => {
|
|
|
+ //如果有monaco实例
|
|
|
if (monacoEditor.current) {
|
|
|
+ //监听编辑器里内容发生改变并处理
|
|
|
+ //内容改变事件
|
|
|
monacoEditor.current.onDidChangeModelContent(() => {
|
|
|
+ //获取变化后的编辑器里的语句
|
|
|
const newValue = monacoEditor.current!.getValue();
|
|
|
+ //如果传递了变化处理函数,则调用变化处理函数处理
|
|
|
if (onChange) {
|
|
|
+
|
|
|
onChange(newValue, monacoEditor.current!);
|
|
|
}
|
|
|
+ //每次变化都需要根据value来处理placeHolder的显隐
|
|
|
handleShowPlaceholder(newValue);
|
|
|
});
|
|
|
|
|
|
+ //监听光标失去焦点事件并处理
|
|
|
monacoEditor.current.onDidBlurEditorText(() => {
|
|
|
+ //如果传递了当光标失去焦点时的处理函数,则调用函数处理
|
|
|
if (onBlur) {
|
|
|
const val = monacoEditor.current!.getValue();
|
|
|
onBlur(val);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ //监听因为打开窗体而模糊事件并处理
|
|
|
monacoEditor.current.onDidBlurEditorWidget(() => {
|
|
|
handleShowPlaceholder(monacoEditor.current!.getValue());
|
|
|
});
|
|
|
|
|
|
+ //监听光标获取焦点事件并处理
|
|
|
monacoEditor.current.onDidFocusEditorText(() => {
|
|
|
+ //如果传递了光标获取焦点处理函数,则调用函数处理
|
|
|
if (onFocus) {
|
|
|
const val = monacoEditor.current!.getValue();
|
|
|
onFocus(val);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ //监听光标选中的区域变化并处理
|
|
|
monacoEditor.current.onDidChangeCursorSelection(() => {
|
|
|
const ranges = monacoEditor.current!.getSelections() || [];
|
|
|
const model = monacoEditor.current!.getModel();
|
|
|
@@ -145,6 +175,7 @@ export default function Editor({
|
|
|
/**
|
|
|
* 改变contextMenu的定位为fixed,避免容器内overflow:hidden属性截断contextMenu
|
|
|
*/
|
|
|
+ //监听召唤出右键菜单事件并处理
|
|
|
monacoEditor.current.onContextMenu((e) => {
|
|
|
const contextMenuElement = monacoEditor.current
|
|
|
?.getDomNode()
|
|
|
@@ -169,24 +200,30 @@ export default function Editor({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ //初始化编辑器
|
|
|
const initEditor = () => {
|
|
|
initEditorEvent();
|
|
|
};
|
|
|
|
|
|
+ //处理占位符的显隐
|
|
|
const handleShowPlaceholder = (val?: string) => {
|
|
|
+ //如果没有数据,则显示placeHolder
|
|
|
if (!val) {
|
|
|
placeholderDOM.current!.style.display = 'initial';
|
|
|
+ //如果有数据,说明有文件被打开,则隐藏placeHolder
|
|
|
} else {
|
|
|
placeholderDOM.current!.style.display = 'none';
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ //销毁monaco
|
|
|
const destroyMonaco = () => {
|
|
|
if (monacoEditor.current) {
|
|
|
monacoEditor.current.dispose();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ //当value变化时,执行的副作用函数
|
|
|
useEffect(() => {
|
|
|
if (monacoEditor.current) {
|
|
|
if (sync) {
|
|
|
@@ -208,18 +245,21 @@ export default function Editor({
|
|
|
}
|
|
|
}, [value]);
|
|
|
|
|
|
+ //当语言变化时,执行的副作用函数
|
|
|
useEffect(() => {
|
|
|
if (monacoEditor.current) {
|
|
|
monaco.editor.setModelLanguage(monacoEditor.current.getModel()!, language || 'ini');
|
|
|
}
|
|
|
}, [language]);
|
|
|
|
|
|
+ //当monaco options变化时执行的副作用函数
|
|
|
useEffect(() => {
|
|
|
if (monacoEditor.current && options) {
|
|
|
monacoEditor.current.updateOptions(options);
|
|
|
}
|
|
|
}, [options]);
|
|
|
|
|
|
+ //页面加载时,执行的副作用函数
|
|
|
useEffect(() => {
|
|
|
initMonaco();
|
|
|
|
|
|
@@ -229,6 +269,7 @@ export default function Editor({
|
|
|
}, []);
|
|
|
|
|
|
return (
|
|
|
+ //div用来挂monaco-editor
|
|
|
<div
|
|
|
className={classNames('code-editor', className)}
|
|
|
style={{
|