This commit is contained in:
weicw
2021-07-29 16:17:26 +08:00
commit a6eb6f83d1
127 changed files with 60792 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
<!-- tinymce富文本编辑器组件 license by http://eleadmin.com -->
<template>
<editor
:init="config"
:disabled="disabled"
:model-value="value"
@update:model-value="updateValue"/>
</template>
<script>
const BASE_URL = process.env.BASE_URL;
import tinymce from 'tinymce/tinymce';
import 'tinymce/icons/default';
import 'tinymce/themes/silver';
import 'tinymce/plugins/code';
import 'tinymce/plugins/print';
import 'tinymce/plugins/preview';
import 'tinymce/plugins/fullscreen';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/searchreplace';
import 'tinymce/plugins/save';
import 'tinymce/plugins/autosave';
import 'tinymce/plugins/link';
import 'tinymce/plugins/autolink';
import 'tinymce/plugins/image';
import 'tinymce/plugins/imagetools';
import 'tinymce/plugins/media';
import 'tinymce/plugins/table';
import 'tinymce/plugins/codesample';
import 'tinymce/plugins/lists';
import 'tinymce/plugins/advlist';
import 'tinymce/plugins/hr';
import 'tinymce/plugins/charmap';
import 'tinymce/plugins/emoticons';
import 'tinymce/plugins/anchor';
import 'tinymce/plugins/directionality';
import 'tinymce/plugins/pagebreak';
import 'tinymce/plugins/quickbars';
import 'tinymce/plugins/nonbreaking';
import 'tinymce/plugins/visualblocks';
import 'tinymce/plugins/visualchars';
import 'tinymce/plugins/wordcount';
import 'tinymce/plugins/emoticons/js/emojis';
import Editor from '@tinymce/tinymce-vue';
// 默认配置
const DEFAULT_CONFIG = {
height: 300,
branding: false,
skin_url: BASE_URL + 'tinymce/skins/ui/oxide',
content_css: BASE_URL + 'tinymce/skins/content/default/content.min.css',
language_url: BASE_URL + 'tinymce/langs/zh_CN.js',
language: 'zh_CN',
plugins: [
'code',
'print',
'preview',
'fullscreen',
'paste',
'searchreplace',
'save',
'autosave',
'link',
'autolink',
'image',
'imagetools',
'media',
'table',
'codesample',
'lists',
'advlist',
'hr',
'charmap',
'emoticons',
'anchor',
'directionality',
'pagebreak',
'quickbars',
'nonbreaking',
'visualblocks',
'visualchars',
'wordcount'
].join(' '),
toolbar: [
'fullscreen',
'preview',
'code',
'|',
'undo',
'redo',
'|',
'forecolor',
'backcolor',
'|',
'bold',
'italic',
'underline',
'strikethrough',
'|',
'alignleft',
'aligncenter',
'alignright',
'alignjustify',
'|',
'outdent',
'indent',
'|',
'numlist',
'bullist',
'|',
'formatselect',
'fontselect',
'fontsizeselect',
'|',
'link',
'image',
'media',
'emoticons',
'charmap',
'anchor',
'pagebreak',
'codesample',
'|',
'ltr',
'rtl'
].join(' '),
draggable_modal: true,
toolbar_mode: 'sliding',
images_upload_handler: (blobInfo, success) => {
success('data:image/jpeg;base64,' + blobInfo.base64());
},
file_picker_types: 'media',
file_picker_callback: () => {
}
};
// 暗黑主题
const DARK_CONFIG = {
skin_url: BASE_URL + 'tinymce/skins/ui/oxide-dark',
content_css: BASE_URL + 'tinymce/skins/content/dark/content.min.css'
};
export default {
name: 'TinymceEditor',
components: {Editor},
emits: ['update:value'],
props: {
// 值(v-model)
value: String,
// 编辑器配置
init: Object,
// 是否禁用
disabled: Boolean,
// 自动跟随框架主题
autoTheme: {
type: Boolean,
default: true
},
// 是否使用暗黑主题
darkTheme: Boolean
},
data() {
const dark = this.autoTheme ? this.$store.state.theme.darkMode : this.darkTheme;
return {
// 编辑器配置
config: Object.assign({}, DEFAULT_CONFIG, dark ? DARK_CONFIG : {}, this.init)
};
},
computed: {
// 是否是暗黑模式
darkMode() {
try {
return this.$store.state.theme.darkMode;
} catch (e) {
return false;
}
}
},
created() {
tinymce.init({});
},
methods: {
/* 更新value */
updateValue(value) {
this.$emit('update:value', value);
},
/* 切换编辑器主题 */
changeTheme(dark) {
document.head.querySelectorAll('[id^="mce-"]').forEach((elem) => {
let href = elem.getAttribute('href');
if (href.indexOf('/oxide-dark/') !== -1) {
if (!dark) {
href = href.replace('/oxide-dark/', '/oxide/');
elem.setAttribute('href', href);
}
} else {
if (dark) {
href = href.replace('/oxide/', '/oxide-dark/');
elem.setAttribute('href', href);
}
}
});
this.changeContentTheme(dark);
},
/* 切换编辑器内容区的主题 */
changeContentTheme(dark) {
document.body.querySelectorAll('iframe[id^="tiny-vue_"]').forEach((frame) => {
const win = frame.contentWindow;
if (win) {
const doc = win.document;
if (doc) {
[].forEach.call(doc.head.querySelectorAll('[id^="mce-"]'), (elem) => {
let href = elem.getAttribute('href');
if (href.indexOf('/skins/ui/') !== -1) {
if (href.indexOf('/oxide-dark/') !== -1) {
if (!dark) {
href = href.replace('/oxide-dark/', '/oxide/');
elem.setAttribute('href', href);
}
} else {
if (dark) {
href = href.replace('/oxide/', '/oxide-dark/');
elem.setAttribute('href', href);
}
}
} else if (href.indexOf('/skins/content/') !== -1) {
if (href.indexOf('/dark/') !== -1) {
if (!dark) {
href = href.replace('/dark/', '/default/');
elem.setAttribute('href', href);
}
} else {
if (dark) {
href = href.replace('/default/', '/dark/');
elem.setAttribute('href', href);
}
}
}
});
}
}
});
}
},
watch: {
darkMode() {
if (this.autoTheme) {
this.changeTheme(this.darkMode);
}
}
}
}
</script>
<style>
body .tox-tinymce-aux {
z-index: 19892000;
}
</style>