2020-05-24 23:13:21 +05:30
|
|
|
<script>
|
|
|
|
import 'codemirror/lib/codemirror.css';
|
|
|
|
import '@toast-ui/editor/dist/toastui-editor.css';
|
|
|
|
|
2021-03-11 19:13:27 +05:30
|
|
|
import { EDITOR_TYPES, EDITOR_HEIGHT, EDITOR_PREVIEW_STYLE, CUSTOM_EVENTS } from './constants';
|
2020-07-28 23:09:34 +05:30
|
|
|
import AddImageModal from './modals/add_image/add_image_modal.vue';
|
2021-01-03 14:25:43 +05:30
|
|
|
import InsertVideoModal from './modals/insert_video_modal.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
import {
|
2020-07-28 23:09:34 +05:30
|
|
|
registerHTMLToMarkdownRenderer,
|
2020-10-24 23:57:45 +05:30
|
|
|
getEditorOptions,
|
2020-06-23 00:09:42 +05:30
|
|
|
addCustomEventListener,
|
|
|
|
removeCustomEventListener,
|
|
|
|
addImage,
|
|
|
|
getMarkdown,
|
2021-01-03 14:25:43 +05:30
|
|
|
insertVideo,
|
2020-07-28 23:09:34 +05:30
|
|
|
} from './services/editor_service';
|
2020-05-24 23:13:21 +05:30
|
|
|
|
|
|
|
export default {
|
|
|
|
components: {
|
|
|
|
ToastEditor: () =>
|
|
|
|
import(/* webpackChunkName: 'toast_editor' */ '@toast-ui/vue-editor').then(
|
2021-03-08 18:12:59 +05:30
|
|
|
(toast) => toast.Editor,
|
2020-05-24 23:13:21 +05:30
|
|
|
),
|
2020-06-23 00:09:42 +05:30
|
|
|
AddImageModal,
|
2021-01-03 14:25:43 +05:30
|
|
|
InsertVideoModal,
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
|
|
|
props: {
|
2020-07-28 23:09:34 +05:30
|
|
|
content: {
|
2020-05-24 23:13:21 +05:30
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
options: {
|
|
|
|
type: Object,
|
|
|
|
required: false,
|
2020-10-24 23:57:45 +05:30
|
|
|
default: () => null,
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
|
|
|
initialEditType: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: EDITOR_TYPES.wysiwyg,
|
|
|
|
},
|
|
|
|
height: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: EDITOR_HEIGHT,
|
|
|
|
},
|
|
|
|
previewStyle: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: EDITOR_PREVIEW_STYLE,
|
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
imageRoot: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
editorApi: null,
|
|
|
|
previousMode: null,
|
|
|
|
};
|
|
|
|
},
|
2020-05-24 23:13:21 +05:30
|
|
|
computed: {
|
2020-06-23 00:09:42 +05:30
|
|
|
editorInstance() {
|
|
|
|
return this.$refs.editor;
|
|
|
|
},
|
2021-01-03 14:25:43 +05:30
|
|
|
customEventListeners() {
|
|
|
|
return [
|
|
|
|
{ event: CUSTOM_EVENTS.openAddImageModal, listener: this.onOpenAddImageModal },
|
|
|
|
{ event: CUSTOM_EVENTS.openInsertVideoModal, listener: this.onOpenInsertVideoModal },
|
|
|
|
];
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
2020-10-24 23:57:45 +05:30
|
|
|
created() {
|
|
|
|
this.editorOptions = getEditorOptions(this.options);
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
beforeDestroy() {
|
2020-07-28 23:09:34 +05:30
|
|
|
this.removeListeners();
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
|
|
|
methods: {
|
2020-07-28 23:09:34 +05:30
|
|
|
addListeners(editorApi) {
|
2021-01-03 14:25:43 +05:30
|
|
|
this.customEventListeners.forEach(({ event, listener }) => {
|
|
|
|
addCustomEventListener(editorApi, event, listener);
|
|
|
|
});
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
editorApi.eventManager.listen('changeMode', this.onChangeMode);
|
|
|
|
},
|
|
|
|
removeListeners() {
|
2021-01-03 14:25:43 +05:30
|
|
|
this.customEventListeners.forEach(({ event, listener }) => {
|
|
|
|
removeCustomEventListener(this.editorApi, event, listener);
|
|
|
|
});
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
this.editorApi.eventManager.removeEventHandler('changeMode', this.onChangeMode);
|
|
|
|
},
|
|
|
|
resetInitialValue(newVal) {
|
|
|
|
this.editorInstance.invoke('setMarkdown', newVal);
|
|
|
|
},
|
2020-05-24 23:13:21 +05:30
|
|
|
onContentChanged() {
|
2020-06-23 00:09:42 +05:30
|
|
|
this.$emit('input', getMarkdown(this.editorInstance));
|
|
|
|
},
|
|
|
|
onLoad(editorApi) {
|
|
|
|
this.editorApi = editorApi;
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
registerHTMLToMarkdownRenderer(editorApi);
|
2020-06-23 00:09:42 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
this.addListeners(editorApi);
|
2021-02-22 17:27:13 +05:30
|
|
|
|
|
|
|
this.$emit('load', { formattedMarkdown: editorApi.getMarkdown() });
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
onOpenAddImageModal() {
|
|
|
|
this.$refs.addImageModal.show();
|
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
onAddImage({ imageUrl, altText, file }) {
|
|
|
|
const image = { imageUrl, altText };
|
|
|
|
|
|
|
|
if (file) {
|
|
|
|
this.$emit('uploadImage', { file, imageUrl });
|
|
|
|
}
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
addImage(this.editorInstance, image, file);
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
2021-01-03 14:25:43 +05:30
|
|
|
onOpenInsertVideoModal() {
|
|
|
|
this.$refs.insertVideoModal.show();
|
|
|
|
},
|
|
|
|
onInsertVideo(url) {
|
|
|
|
insertVideo(this.editorInstance, url);
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
onChangeMode(newMode) {
|
|
|
|
this.$emit('modeChange', newMode);
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
<template>
|
2020-06-23 00:09:42 +05:30
|
|
|
<div>
|
|
|
|
<toast-editor
|
|
|
|
ref="editor"
|
2020-07-28 23:09:34 +05:30
|
|
|
:initial-value="content"
|
2020-06-23 00:09:42 +05:30
|
|
|
:options="editorOptions"
|
|
|
|
:preview-style="previewStyle"
|
|
|
|
:initial-edit-type="initialEditType"
|
|
|
|
:height="height"
|
|
|
|
@change="onContentChanged"
|
|
|
|
@load="onLoad"
|
|
|
|
/>
|
2020-07-28 23:09:34 +05:30
|
|
|
<add-image-modal ref="addImageModal" :image-root="imageRoot" @addImage="onAddImage" />
|
2021-01-03 14:25:43 +05:30
|
|
|
<insert-video-modal ref="insertVideoModal" @insertVideo="onInsertVideo" />
|
2020-06-23 00:09:42 +05:30
|
|
|
</div>
|
2020-05-24 23:13:21 +05:30
|
|
|
</template>
|