mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 01:38:19 +08:00
ui: preferredEditor: monaco
This commit is contained in:
1 parent
b82a26c903
commit
f29dc43fec
12 files changed
+55
-15
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import Vditor from 'vditor';
|
||||
import { config } from './index';
|
||||
|
||||
export default class MarkdownEditor extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.ref = React.createRef();
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await new Promise((resolve) => {
|
||||
this.editor = new Vditor(this.ref.current, {
|
||||
...config,
|
||||
after: resolve,
|
||||
input(value) { this.props.onChange(value); },
|
||||
cache: { id: Math.random().toString() },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.editor.destory();
|
||||
this.editor.detach();
|
||||
}
|
||||
|
||||
value() {
|
||||
return this.editor.getValue();
|
||||
}
|
||||
|
||||
focus() {
|
||||
return this.editor.focus();
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div ref={this.ref}></div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { AutoloadPage } from 'vj/misc/Page';
|
||||
import delay from 'vj/utils/delay';
|
||||
import CmEditor from '.';
|
||||
|
||||
function runSubstitute($container) {
|
||||
const selector = ['textarea[data-markdown]'];
|
||||
$container.find(selector.join(', ')).get().forEach((element) => {
|
||||
CmEditor.getOrConstruct($(element));
|
||||
});
|
||||
}
|
||||
|
||||
const cmEditorPage = new AutoloadPage('cmEditorPage', () => {
|
||||
runSubstitute($('body'));
|
||||
$(document).on('vjContentNew', async (e) => {
|
||||
await delay(0);
|
||||
runSubstitute($(e.target));
|
||||
});
|
||||
});
|
||||
|
||||
export default cmEditorPage;
|
||||
@@ -0,0 +1,8 @@
|
||||
.vditor
|
||||
margin-bottom: rem(10px)
|
||||
|
||||
.vditor-preview__action
|
||||
display: none
|
||||
|
||||
.vditor ol
|
||||
list-style: decimal
|
||||
@@ -0,0 +1,120 @@
|
||||
import _ from 'lodash';
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
|
||||
export const config = {
|
||||
toolbar: [
|
||||
'emoji', 'headings', 'bold', 'italic', 'strike', 'link', '|',
|
||||
'list', 'ordered-list', 'check', 'outdent', 'indent', '|',
|
||||
'quote', 'line', 'code', 'inline-code', 'table', '|',
|
||||
'upload', 'edit-mode', 'fullscreen', 'export',
|
||||
],
|
||||
mode: UserContext.preferredEditorType || 'sv',
|
||||
toolbarConfig: {
|
||||
pin: true,
|
||||
},
|
||||
cdn: `${UiContext.cdn_prefix}vditor`,
|
||||
counter: {
|
||||
enable: true,
|
||||
max: 65536,
|
||||
},
|
||||
preview: {
|
||||
math: {
|
||||
inlineDigit: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default class Editor extends DOMAttachedObject {
|
||||
static DOMAttachKey = 'vjEditorInstance';
|
||||
|
||||
constructor($dom, options = {}) {
|
||||
super($dom);
|
||||
this.options = options;
|
||||
if (UserContext.preferredEditorType === 'monaco') this.initMonaco();
|
||||
else this.initVditor();
|
||||
}
|
||||
|
||||
async initMonaco() {
|
||||
const monaco = await import('monaco-editor/esm/vs/editor/editor.api');
|
||||
const { $dom } = this;
|
||||
const hasFocus = $dom.is(':focus');
|
||||
const origin = $dom.get(0);
|
||||
const ele = document.createElement('div');
|
||||
$(ele).height(550);
|
||||
$(ele).width('100%');
|
||||
$(ele).addClass('textbox');
|
||||
$dom.hide();
|
||||
origin.parentElement.appendChild(ele);
|
||||
const value = $dom.val();
|
||||
const {
|
||||
onChange, language = 'markdown', theme = 'vs-light', model = `file://model-${Math.random().toString(16)}`,
|
||||
} = this.options;
|
||||
this.model = monaco.editor.createModel(value, language, monaco.Uri.parse(model));
|
||||
this.editor = monaco.editor.create(
|
||||
ele,
|
||||
{
|
||||
theme,
|
||||
lineNumbers: true,
|
||||
glyphMargin: true,
|
||||
lightbulb: {
|
||||
enabled: true,
|
||||
},
|
||||
model: this.model,
|
||||
}
|
||||
);
|
||||
this._subscription = this.editor.onDidChangeModelContent(() => {
|
||||
const val = this.editor.getValue();
|
||||
$dom.val(val);
|
||||
$dom.text(val);
|
||||
if (onChange) onChange(val);
|
||||
});
|
||||
this.isValid = true;
|
||||
if (hasFocus) this.editor.focus();
|
||||
}
|
||||
|
||||
async initVditor() {
|
||||
const { default: Vditor } = await import('vditor');
|
||||
const { $dom } = this;
|
||||
const hasFocus = $dom.is(':focus');
|
||||
const origin = $dom.get(0);
|
||||
const ele = document.createElement('div');
|
||||
const value = $dom.val();
|
||||
const { onChange } = this.options;
|
||||
await new Promise((resolve) => {
|
||||
this.editor = new Vditor(ele, {
|
||||
...config,
|
||||
...this.options,
|
||||
after: resolve,
|
||||
input(v) {
|
||||
$dom.val(v);
|
||||
$dom.text(v);
|
||||
if (onChange) onChange(v);
|
||||
},
|
||||
value,
|
||||
cache: { id: Math.random().toString() },
|
||||
});
|
||||
});
|
||||
$(ele).addClass('textbox');
|
||||
$dom.hide();
|
||||
origin.parentElement.appendChild(ele);
|
||||
this.isValid = true;
|
||||
if (hasFocus) this.focus();
|
||||
}
|
||||
|
||||
ensureValid() {
|
||||
if (!this.isValid) throw new Error('Editor is not loaded');
|
||||
}
|
||||
|
||||
value(val) {
|
||||
this.ensureValid();
|
||||
if (val) return this.editor.setValue(val);
|
||||
return this.editor.getValue();
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.ensureValid();
|
||||
this.editor.focus();
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(Editor, DOMAttachedObject);
|
||||
@@ -0,0 +1,32 @@
|
||||
import _ from 'lodash';
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
import Editor from './index';
|
||||
|
||||
export default class TextareaHandler extends DOMAttachedObject {
|
||||
static DOMAttachKey = 'vjTextareaHandlerInstance';
|
||||
|
||||
getCmEditor() {
|
||||
return Editor.get(this.$dom);
|
||||
}
|
||||
|
||||
isCmEditor() {
|
||||
const editor = this.getCmEditor();
|
||||
return !!(editor && editor.isValid);
|
||||
}
|
||||
|
||||
val(...argv) {
|
||||
if (this.isCmEditor()) {
|
||||
return this.getCmEditor().value(...argv);
|
||||
}
|
||||
return this.$dom.val(...argv);
|
||||
}
|
||||
|
||||
focus() {
|
||||
if (this.isCmEditor()) {
|
||||
this.getCmEditor().focus();
|
||||
}
|
||||
this.$dom.focus();
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(TextareaHandler, DOMAttachedObject);
|
||||
Reference in new issue
Block a user