|
@@ -1,7 +1,5 @@
|
|
|
<template>
|
|
|
-
|
|
|
<div :class="prefixCls" :style="{ width: containerWidth }">
|
|
|
-
|
|
|
<ImgUpload
|
|
|
:fullscreen="fullscreen"
|
|
|
@uploading="handleImageUploading"
|
|
@@ -10,128 +8,137 @@
|
|
|
v-show="editorRef"
|
|
|
:disabled="disabled"
|
|
|
/>
|
|
|
- <textarea :id="tinymceId" ref="elRef" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline">
|
|
|
- </textarea>
|
|
|
- <div class="tinymce-upload-progress-box" v-if="spinning">
|
|
|
- <span>正在上传</span>
|
|
|
- </div>
|
|
|
+ <a-spin class="tinymce-upload-progress-box" tip="正在上传..."
|
|
|
+ :spinning="spinning"
|
|
|
+ :delay="500">
|
|
|
+ </a-spin>
|
|
|
+ <textarea :id="tinymceId" ref="elRef" :style="{ visibility: 'hidden' }"
|
|
|
+ v-if="!initOptions.inline"></textarea>
|
|
|
+ <slot v-else></slot>
|
|
|
|
|
|
- <!-- <slot v-else></slot>-->
|
|
|
|
|
|
</div>
|
|
|
-
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts">
|
|
|
-import type { Editor, RawEditorSettings } from "tinymce";
|
|
|
-import tinymce from "tinymce/tinymce";
|
|
|
-import "tinymce/themes/silver";
|
|
|
-import "tinymce/icons/default/icons";
|
|
|
-import "tinymce/plugins/advlist";
|
|
|
-import "tinymce/plugins/anchor";
|
|
|
-import "tinymce/plugins/autolink";
|
|
|
-import "tinymce/plugins/autosave";
|
|
|
-import "tinymce/plugins/code";
|
|
|
-import "tinymce/plugins/codesample";
|
|
|
-import "tinymce/plugins/directionality";
|
|
|
-import "tinymce/plugins/fullscreen";
|
|
|
-import "tinymce/plugins/hr";
|
|
|
-import "tinymce/plugins/insertdatetime";
|
|
|
-import "tinymce/plugins/link";
|
|
|
-import "tinymce/plugins/lists";
|
|
|
-import "tinymce/plugins/media";
|
|
|
-import "tinymce/plugins/nonbreaking";
|
|
|
-import "tinymce/plugins/noneditable";
|
|
|
-import "tinymce/plugins/pagebreak";
|
|
|
-import "tinymce/plugins/paste";
|
|
|
-import "tinymce/plugins/preview";
|
|
|
-import "tinymce/plugins/print";
|
|
|
-import "tinymce/plugins/save";
|
|
|
-import "tinymce/plugins/searchreplace";
|
|
|
-import "tinymce/plugins/spellchecker";
|
|
|
-import "tinymce/plugins/tabfocus";
|
|
|
+import type {Editor, RawEditorSettings} from 'tinymce';
|
|
|
+import tinymce from 'tinymce/tinymce';
|
|
|
+import 'tinymce/themes/silver';
|
|
|
+import 'tinymce/icons/default/icons';
|
|
|
+import 'tinymce/plugins/advlist';
|
|
|
+import 'tinymce/plugins/anchor';
|
|
|
+import 'tinymce/plugins/autolink';
|
|
|
+import 'tinymce/plugins/autosave';
|
|
|
+import 'tinymce/plugins/code';
|
|
|
+import 'tinymce/plugins/codesample';
|
|
|
+import 'tinymce/plugins/directionality';
|
|
|
+import 'tinymce/plugins/fullscreen';
|
|
|
+import 'tinymce/plugins/hr';
|
|
|
+import 'tinymce/plugins/insertdatetime';
|
|
|
+import 'tinymce/plugins/link';
|
|
|
+import 'tinymce/plugins/lists';
|
|
|
+import 'tinymce/plugins/media';
|
|
|
+import 'tinymce/plugins/nonbreaking';
|
|
|
+import 'tinymce/plugins/noneditable';
|
|
|
+import 'tinymce/plugins/pagebreak';
|
|
|
+import 'tinymce/plugins/paste';
|
|
|
+import 'tinymce/plugins/preview';
|
|
|
+import 'tinymce/plugins/print';
|
|
|
+import 'tinymce/plugins/save';
|
|
|
+import 'tinymce/plugins/searchreplace';
|
|
|
+import 'tinymce/plugins/spellchecker';
|
|
|
+import 'tinymce/plugins/tabfocus';
|
|
|
// import 'tinymce/plugins/table';
|
|
|
-import "tinymce/plugins/template";
|
|
|
-import "tinymce/plugins/textpattern";
|
|
|
-import "tinymce/plugins/visualblocks";
|
|
|
-import "tinymce/plugins/visualchars";
|
|
|
-import "tinymce/plugins/wordcount";
|
|
|
-import "tinymce/plugins/image";
|
|
|
-import "tinymce/plugins/table";
|
|
|
-import "tinymce/plugins/textcolor";
|
|
|
-import "tinymce/plugins/contextmenu";
|
|
|
-import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount } from "vue";
|
|
|
-import ImgUpload from "./ImgUpload.vue";
|
|
|
-import { toolbar, plugins, simplePlugins, simpleToolbar, menubar } from "./tinymce";
|
|
|
-import { buildShortUUID } from "/@/utils/uuid";
|
|
|
-import { bindHandlers } from "./helper";
|
|
|
-import { onMountedOrActivated } from "/@/hooks/core/onMountedOrActivated";
|
|
|
-import { useDesign } from "/@/hooks/web/useDesign";
|
|
|
-import { isNumber } from "/@/utils/is";
|
|
|
-import { useLocale } from "/@/locales/useLocale";
|
|
|
-import { useAppStore } from "/@/store/modules/app";
|
|
|
-import { uploadFile } from "/@/api/common/api";
|
|
|
-import { getFileAccessHttpUrl } from "/@/utils/common/compUtils";
|
|
|
+import 'tinymce/plugins/template';
|
|
|
+import 'tinymce/plugins/textpattern';
|
|
|
+import 'tinymce/plugins/visualblocks';
|
|
|
+import 'tinymce/plugins/visualchars';
|
|
|
+import 'tinymce/plugins/wordcount';
|
|
|
+import 'tinymce/plugins/image';
|
|
|
+import 'tinymce/plugins/table';
|
|
|
+import 'tinymce/plugins/textcolor';
|
|
|
+import 'tinymce/plugins/contextmenu';
|
|
|
+import {
|
|
|
+ defineComponent,
|
|
|
+ computed,
|
|
|
+ nextTick,
|
|
|
+ ref,
|
|
|
+ unref,
|
|
|
+ watch,
|
|
|
+ onDeactivated,
|
|
|
+ onBeforeUnmount
|
|
|
+} from 'vue';
|
|
|
+import ImgUpload from './ImgUpload.vue';
|
|
|
+import {toolbar, plugins, simplePlugins, simpleToolbar, menubar} from './tinymce';
|
|
|
+import {buildShortUUID} from '/@/utils/uuid';
|
|
|
+import {bindHandlers} from './helper';
|
|
|
+import {onMountedOrActivated} from '/@/hooks/core/onMountedOrActivated';
|
|
|
+import {useDesign} from '/@/hooks/web/useDesign';
|
|
|
+import {isNumber} from '/@/utils/is';
|
|
|
+import {useLocale} from '/@/locales/useLocale';
|
|
|
+import {useAppStore} from '/@/store/modules/app';
|
|
|
+import {uploadFile} from '/@/api/common/api';
|
|
|
+import {getFileAccessHttpUrl} from '/@/utils/common/compUtils';
|
|
|
import success from "@/views/demo/page/result/success/index.vue";
|
|
|
-
|
|
|
+import {message} from 'ant-design-vue';
|
|
|
|
|
|
const tinymceProps = {
|
|
|
path: {
|
|
|
- type: String
|
|
|
+ type: String,
|
|
|
},
|
|
|
options: {
|
|
|
type: Object as PropType<Partial<RawEditorSettings>>,
|
|
|
- default: {}
|
|
|
+ default: {},
|
|
|
},
|
|
|
value: {
|
|
|
- type: String
|
|
|
+ type: String,
|
|
|
},
|
|
|
|
|
|
toolbar: {
|
|
|
type: [Array as PropType<string[]>, String],
|
|
|
- default: toolbar
|
|
|
+ default: toolbar,
|
|
|
},
|
|
|
plugins: {
|
|
|
type: Array as PropType<string[]>,
|
|
|
- default: plugins
|
|
|
+ default: plugins,
|
|
|
},
|
|
|
menubar: {
|
|
|
type: [Object, String],
|
|
|
- default: menubar
|
|
|
+ default: menubar,
|
|
|
},
|
|
|
modelValue: {
|
|
|
- type: String
|
|
|
+ type: String,
|
|
|
},
|
|
|
height: {
|
|
|
type: [Number, String] as PropType<string | number>,
|
|
|
required: false,
|
|
|
- default: 400
|
|
|
+ default: 400,
|
|
|
},
|
|
|
width: {
|
|
|
type: [Number, String] as PropType<string | number>,
|
|
|
required: false,
|
|
|
- default: "auto"
|
|
|
+ default: 'auto',
|
|
|
},
|
|
|
showImageUpload: {
|
|
|
type: Boolean,
|
|
|
- default: true
|
|
|
- }
|
|
|
+ default: true,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
export default defineComponent({
|
|
|
- name: "Tinymce",
|
|
|
- components: { ImgUpload },
|
|
|
+ name: 'Tinymce',
|
|
|
+ components: {ImgUpload},
|
|
|
inheritAttrs: false,
|
|
|
props: tinymceProps,
|
|
|
- emits: ["change", "update:modelValue", "inited", "init-error"],
|
|
|
- setup(props, { emit, attrs }) {
|
|
|
- const spinning = ref(false);
|
|
|
+ emits: ['change', 'update:modelValue', 'inited', 'init-error'],
|
|
|
+ setup(props, {emit, attrs}) {
|
|
|
+ const spinning = ref<Boolean>(false);
|
|
|
const editorRef = ref<Nullable<Editor>>(null);
|
|
|
const fullscreen = ref(false);
|
|
|
- const tinymceId = ref<string>(buildShortUUID("tiny-vue"));
|
|
|
+ const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
|
|
|
const elRef = ref<Nullable<HTMLElement>>(null);
|
|
|
|
|
|
- const { prefixCls } = useDesign("tinymce-container");
|
|
|
+ const {prefixCls} = useDesign('tinymce-container');
|
|
|
|
|
|
const appStore = useAppStore();
|
|
|
|
|
@@ -146,111 +153,171 @@ export default defineComponent({
|
|
|
});
|
|
|
|
|
|
const skinName = computed(() => {
|
|
|
- return appStore.getDarkMode === "light" ? "jeecg" : "oxide-dark";
|
|
|
+ return appStore.getDarkMode === 'light' ? 'jeecg' : 'oxide-dark';
|
|
|
});
|
|
|
|
|
|
const langName = computed(() => {
|
|
|
const lang = useLocale().getLocale.value;
|
|
|
- return ["zh_CN", "en"].includes(lang) ? lang : "zh_CN";
|
|
|
+ return ['zh_CN', 'en'].includes(lang) ? lang : 'zh_CN';
|
|
|
});
|
|
|
|
|
|
const initOptions = computed((): RawEditorSettings => {
|
|
|
- const { height, options, toolbar, plugins, menubar } = props;
|
|
|
- const publicPath = import.meta.env.VITE_PUBLIC_PATH || "/";
|
|
|
+ const {height, options, toolbar, plugins, menubar} = props;
|
|
|
+ const publicPath = import.meta.env.VITE_PUBLIC_PATH || '/';
|
|
|
return {
|
|
|
selector: `#${unref(tinymceId)}`,
|
|
|
height,
|
|
|
toolbar,
|
|
|
menubar: menubar,
|
|
|
plugins,
|
|
|
- language_url: publicPath + "resource/tinymce/langs/" + langName.value + ".js",
|
|
|
+ language_url: publicPath + 'resource/tinymce/langs/' + langName.value + '.js',
|
|
|
language: langName.value,
|
|
|
branding: false,
|
|
|
- default_link_target: "_blank",
|
|
|
+ default_link_target: '_blank',
|
|
|
link_title: false,
|
|
|
object_resizing: true,
|
|
|
relative_urls: false,
|
|
|
remove_script_host: false,
|
|
|
convert_urls: false,
|
|
|
- toolbar_mode: "sliding",
|
|
|
+ toolbar_mode: 'sliding',
|
|
|
auto_focus: true,
|
|
|
toolbar_groups: true,
|
|
|
skin: skinName.value,
|
|
|
- skin_url: publicPath + "resource/tinymce/skins/ui/" + skinName.value,
|
|
|
+ skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value,
|
|
|
images_upload_handler: (blobInfo, success) => {
|
|
|
let params = {
|
|
|
file: blobInfo.blob(),
|
|
|
filename: blobInfo.filename(),
|
|
|
- data: { biz: "jeditor", jeditor: "1" }
|
|
|
+ data: {biz: 'jeditor', jeditor: '1'},
|
|
|
};
|
|
|
const uploadSuccess = (res) => {
|
|
|
if (res.success) {
|
|
|
- if (res.message == "local") {
|
|
|
- const img = "data:image/jpeg;base64," + blobInfo.base64();
|
|
|
+ if (res.message == 'local') {
|
|
|
+ const img = 'data:image/jpeg;base64,' + blobInfo.base64();
|
|
|
success(img);
|
|
|
} else {
|
|
|
let img = getFileAccessHttpUrl(res.message);
|
|
|
success(img);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ message.error("上传文件超时,请务必在两分钟内上传完毕")
|
|
|
+ return;
|
|
|
}
|
|
|
};
|
|
|
uploadFile(params, uploadSuccess);
|
|
|
},
|
|
|
file_picker_callback: (callback, value, meta) => {
|
|
|
+ let fileName = ""
|
|
|
+ spinning.value = true;
|
|
|
+ const tox = document.getElementsByClassName("tox-dialog")[0];
|
|
|
+ tox.style.zIndex = -20;
|
|
|
+ // console.log(meta.filetype)
|
|
|
const uploadSuccess = (res) => {
|
|
|
if (res.success) {
|
|
|
- let fileUrl = "/jeecgboot/sys/common/file/" + res.message;
|
|
|
- callback(fileUrl);
|
|
|
+ let fileUrl = '/jeecgboot/sys/common/file/' + res.message;
|
|
|
+ callback(fileUrl, {text: fileName})
|
|
|
+ } else {
|
|
|
+ message.error("上传文件超时,请务必在两分钟内上传完毕")
|
|
|
+ return;
|
|
|
}
|
|
|
};
|
|
|
- if (meta.filetype === "file") {
|
|
|
- const input = document.createElement("input");
|
|
|
- input.setAttribute("type", "file");
|
|
|
- input.onchange = async function() {
|
|
|
- const file = this.files[0]; // 为 HTMLInputElement 构造函数中的 this,指向 input 实例对象
|
|
|
+ if (meta.filetype === 'file') {
|
|
|
+ const input = document.createElement('input')
|
|
|
+ input.setAttribute('type', 'file')
|
|
|
+ input.oncancel = async function () {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ }
|
|
|
+ input.onchange = async function () {
|
|
|
+ const file = this.files[0] // 为 HTMLInputElement 构造函数中的 this,指向 input 实例对象
|
|
|
+ fileName = file.name
|
|
|
+ if (file.size / 1024 / 1024 > 2048) {
|
|
|
+ message.error("文件大小超过2G,请压缩或降低质量")
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ return
|
|
|
+ }
|
|
|
//后缀名
|
|
|
- const extension = file.name.substring(file.name.lastIndexOf(".") + 1);
|
|
|
+ const extension = file.name.substring(file.name.lastIndexOf('.') + 1)
|
|
|
let params = {
|
|
|
file: file,
|
|
|
filename: file.name,
|
|
|
- data: { biz: extension, jeditor: "1" }
|
|
|
+ data: {biz: extension, jeditor: '1'},
|
|
|
};
|
|
|
- uploadFile(params, uploadSuccess);
|
|
|
- };
|
|
|
- input.click();
|
|
|
+ uploadFile(params, uploadSuccess).finally(() => {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ input.click()
|
|
|
}
|
|
|
- if (meta.filetype === "media") {
|
|
|
- const input = document.createElement("input");
|
|
|
- input.setAttribute("type", "file");
|
|
|
- input.onchange = async function() {
|
|
|
- const file = this.files[0]; // 为 HTMLInputElement 构造函数中的 this,指向 input 实例对象
|
|
|
+ if (meta.filetype === 'media') {
|
|
|
+ const input = document.createElement('input')
|
|
|
+ input.setAttribute('type', 'file')
|
|
|
+ //设置上传视频的类型
|
|
|
+ input.setAttribute('accept', ".mp4");
|
|
|
+ input.oncancel = async function () {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ }
|
|
|
+ input.onchange = async function () {
|
|
|
+ const file = this.files[0] // 为 HTMLInputElement 构造函数中的 this,指向 input 实例对象
|
|
|
+ fileName = file.name
|
|
|
+ if (file.size / 1024 / 1024 > 2048) {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ message.error("视频大小超过2G,请压缩或降低质量")
|
|
|
+ return
|
|
|
+ }
|
|
|
let params = {
|
|
|
file: file,
|
|
|
filename: file.name,
|
|
|
- data: { biz: "video", jeditor: "1" }
|
|
|
+ data: {biz: 'video', jeditor: '1'},
|
|
|
};
|
|
|
- const tox = document.getElementsByClassName("tox-dialog")[0];
|
|
|
- const spin = document.getElementById("spinId");
|
|
|
-
|
|
|
- tox.style.zIndex = -20;
|
|
|
- spinning.value = true;
|
|
|
- console.log(tox);
|
|
|
- uploadFile(params, uploadSuccess).then(res => {
|
|
|
+ uploadFile(params, uploadSuccess).finally(() => {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ input.click()
|
|
|
+ }
|
|
|
+ if (meta.filetype === 'image') {
|
|
|
+ const input = document.createElement('input')
|
|
|
+ input.setAttribute('type', 'file')
|
|
|
+ //设置上传视频的类型
|
|
|
+ input.setAttribute('accept', ".jpg, .jpeg, .png, .gif");
|
|
|
+ input.oncancel = async function () {
|
|
|
+ spinning.value = false;
|
|
|
+ tox.style.zIndex = 2;
|
|
|
+ }
|
|
|
+ input.onchange = async function () {
|
|
|
+ const file = this.files[0] // 为 HTMLInputElement 构造函数中的 this,指向 input 实例对象
|
|
|
+ fileName = file.name
|
|
|
+ if (file.size / 1024 / 1024 > 100) {
|
|
|
+ message.error("图片大小超过100MB,请压缩或降低质量")
|
|
|
spinning.value = false;
|
|
|
tox.style.zIndex = 2;
|
|
|
- }).catch(error => {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let params = {
|
|
|
+ file: file,
|
|
|
+ filename: file.name,
|
|
|
+ data: {biz: 'jeditor', jeditor: '1'},
|
|
|
+ };
|
|
|
+ uploadFile(params, uploadSuccess).finally(() => {
|
|
|
spinning.value = false;
|
|
|
tox.style.zIndex = 2;
|
|
|
});
|
|
|
- };
|
|
|
- input.click();
|
|
|
+ }
|
|
|
+ input.click()
|
|
|
}
|
|
|
+
|
|
|
},
|
|
|
- file_url_resolver: function(data, resolve) {
|
|
|
+ file_url_resolver: function (data, resolve) {
|
|
|
|
|
|
},
|
|
|
//自定义逻辑替换 Tinymce 的默认媒体嵌入逻辑
|
|
|
- media_url_resolver: function(data, resolve) {
|
|
|
+ media_url_resolver: function (data, resolve) {
|
|
|
try {
|
|
|
let videoUri = encodeURI(data.url);
|
|
|
let embedHtml = `<p>
|
|
@@ -263,33 +330,33 @@ export default defineComponent({
|
|
|
data-mce-p-allowfullscreen="true"
|
|
|
data-mce-p-oncontextmenu="return false;"
|
|
|
data-mce-p-controlslist="nodownload"
|
|
|
- data-mce-p-src="${videoUri}" >
|
|
|
- <video src="${data.url}" width="800" height="600" controls="controls" >
|
|
|
+ data-mce-p-src=${videoUri} >
|
|
|
+ <video src=${data.url} width="800" height="600" controls="controls" >
|
|
|
</video>
|
|
|
</span>
|
|
|
</p>
|
|
|
<p style="text-align: left;"></p>`;
|
|
|
- resolve({ html: embedHtml });
|
|
|
+ resolve({html: embedHtml});
|
|
|
} catch (e) {
|
|
|
- resolve({ html: "" });
|
|
|
+ resolve({html: ""});
|
|
|
}
|
|
|
},
|
|
|
- content_css: publicPath + "resource/tinymce/skins/ui/" + skinName.value + "/content.min.css",
|
|
|
+ content_css: publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css',
|
|
|
...options,
|
|
|
setup: (editor: Editor) => {
|
|
|
editorRef.value = editor;
|
|
|
- editor.on("init", (e) => initSetup(e));
|
|
|
- }
|
|
|
+ editor.on('init', (e) => initSetup(e));
|
|
|
+ },
|
|
|
};
|
|
|
});
|
|
|
|
|
|
const disabled = computed(() => {
|
|
|
- const { options } = props;
|
|
|
- const getdDisabled = options && Reflect.get(options, "readonly");
|
|
|
+ const {options} = props;
|
|
|
+ const getdDisabled = options && Reflect.get(options, 'readonly');
|
|
|
const editor = unref(editorRef);
|
|
|
// update-begin-author:taoyan date:20220407 for: 设置disabled,图片上传没有被禁用
|
|
|
if (editor) {
|
|
|
- editor.setMode(getdDisabled || attrs.disabled === true ? "readonly" : "design");
|
|
|
+ editor.setMode(getdDisabled || attrs.disabled === true ? 'readonly' : 'design');
|
|
|
}
|
|
|
if (attrs.disabled === true) {
|
|
|
return true;
|
|
@@ -305,13 +372,13 @@ export default defineComponent({
|
|
|
if (!editor) {
|
|
|
return;
|
|
|
}
|
|
|
- editor.setMode(attrs.disabled ? "readonly" : "design");
|
|
|
+ editor.setMode(attrs.disabled ? 'readonly' : 'design');
|
|
|
}
|
|
|
);
|
|
|
|
|
|
onMountedOrActivated(() => {
|
|
|
if (!initOptions.value.inline) {
|
|
|
- tinymceId.value = buildShortUUID("tiny-vue");
|
|
|
+ tinymceId.value = buildShortUUID('tiny-vue');
|
|
|
}
|
|
|
nextTick(() => {
|
|
|
setTimeout(() => {
|
|
@@ -337,15 +404,15 @@ export default defineComponent({
|
|
|
function initEditor() {
|
|
|
const el = unref(elRef);
|
|
|
if (el) {
|
|
|
- el.style.visibility = "";
|
|
|
+ el.style.visibility = '';
|
|
|
}
|
|
|
tinymce
|
|
|
.init(unref(initOptions))
|
|
|
.then((editor) => {
|
|
|
- emit("inited", editor);
|
|
|
+ emit('inited', editor);
|
|
|
})
|
|
|
.catch((err) => {
|
|
|
- emit("init-error", err);
|
|
|
+ emit('init-error', err);
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -354,7 +421,7 @@ export default defineComponent({
|
|
|
if (!editor) {
|
|
|
return;
|
|
|
}
|
|
|
- const value = props.modelValue || "";
|
|
|
+ const value = props.modelValue || '';
|
|
|
|
|
|
editor.setContent(value);
|
|
|
bindModelHandlers(editor);
|
|
@@ -362,14 +429,14 @@ export default defineComponent({
|
|
|
}
|
|
|
|
|
|
function setValue(editor: Recordable, val: string, prevVal?: string) {
|
|
|
- if (editor && typeof val === "string" && val !== prevVal && val !== editor.getContent({ format: attrs.outputFormat })) {
|
|
|
+ if (editor && typeof val === 'string' && val !== prevVal && val !== editor.getContent({format: attrs.outputFormat})) {
|
|
|
editor.setContent(val);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function bindModelHandlers(editor: any) {
|
|
|
const modelEvents = attrs.modelEvents ? attrs.modelEvents : null;
|
|
|
- const normalizedEvents = Array.isArray(modelEvents) ? modelEvents.join(" ") : modelEvents;
|
|
|
+ const normalizedEvents = Array.isArray(modelEvents) ? modelEvents.join(' ') : modelEvents;
|
|
|
|
|
|
watch(
|
|
|
() => props.modelValue,
|
|
@@ -384,17 +451,17 @@ export default defineComponent({
|
|
|
setValue(editor, val, prevVal);
|
|
|
},
|
|
|
{
|
|
|
- immediate: true
|
|
|
+ immediate: true,
|
|
|
}
|
|
|
);
|
|
|
|
|
|
- editor.on(normalizedEvents ? normalizedEvents : "change keyup undo redo", () => {
|
|
|
- const content = editor.getContent({ format: attrs.outputFormat });
|
|
|
- emit("update:modelValue", content);
|
|
|
- emit("change", content);
|
|
|
+ editor.on(normalizedEvents ? normalizedEvents : 'change keyup undo redo', () => {
|
|
|
+ const content = editor.getContent({format: attrs.outputFormat});
|
|
|
+ emit('update:modelValue', content);
|
|
|
+ emit('change', content);
|
|
|
});
|
|
|
|
|
|
- editor.on("FullscreenStateChanged", (e) => {
|
|
|
+ editor.on('FullscreenStateChanged', (e) => {
|
|
|
fullscreen.value = e.state;
|
|
|
});
|
|
|
}
|
|
@@ -404,8 +471,8 @@ export default defineComponent({
|
|
|
if (!editor) {
|
|
|
return;
|
|
|
}
|
|
|
- editor.execCommand("mceInsertContent", false, getUploadingImgName(name));
|
|
|
- const content = editor?.getContent() ?? "";
|
|
|
+ editor.execCommand('mceInsertContent', false, getUploadingImgName(name));
|
|
|
+ const content = editor?.getContent() ?? '';
|
|
|
setValue(editor, content);
|
|
|
}
|
|
|
|
|
@@ -414,8 +481,8 @@ export default defineComponent({
|
|
|
if (!editor) {
|
|
|
return;
|
|
|
}
|
|
|
- const content = editor?.getContent() ?? "";
|
|
|
- const val = content?.replace(getUploadingImgName(name), `<img src="${url}"/>`) ?? "";
|
|
|
+ const content = editor?.getContent() ?? '';
|
|
|
+ const val = content?.replace(getUploadingImgName(name), `<img src="${url}"/>`) ?? '';
|
|
|
setValue(editor, val);
|
|
|
}
|
|
|
|
|
@@ -436,9 +503,9 @@ export default defineComponent({
|
|
|
editorRef,
|
|
|
fullscreen,
|
|
|
disabled,
|
|
|
- spinning
|
|
|
+ spinning,
|
|
|
};
|
|
|
- }
|
|
|
+ },
|
|
|
});
|
|
|
</script>
|
|
|
|
|
@@ -451,18 +518,19 @@ export default defineComponent({
|
|
|
position: relative;
|
|
|
line-height: normal;
|
|
|
|
|
|
- .tinymce-upload-progress-box {
|
|
|
- position: absolute !important;
|
|
|
- text-align: center;
|
|
|
- top: 50%;
|
|
|
- left: 50%;
|
|
|
- margin-top: -62px !important;;
|
|
|
- margin-left: -60px !important;;
|
|
|
- }
|
|
|
-
|
|
|
textarea {
|
|
|
z-index: -1;
|
|
|
visibility: hidden;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+.tinymce-upload-progress-box {
|
|
|
+ position: absolute !important;
|
|
|
+ text-align: center;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ z-index: 200;
|
|
|
+ margin-top: -350px !important;;
|
|
|
+ margin-left: -100px !important;;
|
|
|
+}
|
|
|
</style>
|