debian-mirror-gitlab/app/assets/javascripts/static_site_editor/rich_content_editor/rich_content_editor.vue

151 lines
3.7 KiB
Vue
Raw Normal View History

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>