|
@@ -1,243 +0,0 @@
|
|
|
-<template>
|
|
|
- <div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
|
|
|
- <textarea :id="tinymceId" class="tinymce-textarea" />
|
|
|
- <div class="editor-custom-btn-container">
|
|
|
- <editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-/**
|
|
|
- * docs:
|
|
|
- * https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
|
|
|
- */
|
|
|
-import editorImage from './components/EditorImage'
|
|
|
-import plugins from './plugins'
|
|
|
-import toolbar from './toolbar'
|
|
|
-import load from './dynamicLoadScript'
|
|
|
-import axios from 'axios'
|
|
|
-
|
|
|
-// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
|
|
|
-const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
|
|
|
-
|
|
|
-export default {
|
|
|
- name: 'Tinymce',
|
|
|
- components: { editorImage },
|
|
|
- props: {
|
|
|
- id: {
|
|
|
- type: String,
|
|
|
- default: function() {
|
|
|
- return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
|
|
- }
|
|
|
- },
|
|
|
- value: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
- toolbar: {
|
|
|
- type: Array,
|
|
|
- required: false,
|
|
|
- default() {
|
|
|
- return []
|
|
|
- }
|
|
|
- },
|
|
|
- menubar: {
|
|
|
- type: String,
|
|
|
- default: 'file edit insert view format table'
|
|
|
- },
|
|
|
- height: {
|
|
|
- type: [Number, String],
|
|
|
- required: false,
|
|
|
- default: 360
|
|
|
- },
|
|
|
- width: {
|
|
|
- type: [Number, String],
|
|
|
- required: false,
|
|
|
- default: 'auto'
|
|
|
- }
|
|
|
- },
|
|
|
- data() {
|
|
|
- const token = window.sessionStorage.getItem('fp_token')
|
|
|
- let domainUrl = process.env.VUE_APP_BASE_API
|
|
|
- return {
|
|
|
- domainUrl,
|
|
|
- token,
|
|
|
- hasChange: false,
|
|
|
- hasInit: false,
|
|
|
- tinymceId: this.id,
|
|
|
- fullscreen: false,
|
|
|
- languageTypeList: {
|
|
|
- 'en': 'en',
|
|
|
- 'zh': 'zh_CN',
|
|
|
- 'es': 'es_MX',
|
|
|
- 'ja': 'ja'
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- containerWidth() {
|
|
|
- const width = this.width
|
|
|
- if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
|
|
|
- return `${width}px`
|
|
|
- }
|
|
|
- return width
|
|
|
- }
|
|
|
- },
|
|
|
- watch: {
|
|
|
- value(val) {
|
|
|
- // if (this.hasInit) {
|
|
|
- if (!this.hasChange && this.hasInit) {
|
|
|
- this.$nextTick(() =>
|
|
|
- window.tinymce.get(this.tinymceId).setContent(val))
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- mounted() {
|
|
|
- this.init()
|
|
|
- },
|
|
|
- activated() {
|
|
|
- if (window.tinymce) {
|
|
|
- this.initTinymce()
|
|
|
- }
|
|
|
- },
|
|
|
- deactivated() {
|
|
|
- this.destroyTinymce()
|
|
|
- },
|
|
|
- destroyed() {
|
|
|
- this.destroyTinymce()
|
|
|
- },
|
|
|
- methods: {
|
|
|
- init() {
|
|
|
- // dynamic load tinymce from cdn
|
|
|
- // load(tinymceCDN, (err) => {
|
|
|
- // if (err) {
|
|
|
- // this.$message.error(err.message)
|
|
|
- // return
|
|
|
- // }
|
|
|
- // this.initTinymce()
|
|
|
- // })
|
|
|
- this.initTinymce()
|
|
|
- },
|
|
|
- initTinymce() {
|
|
|
- const _this = this
|
|
|
- window.tinymce.init({
|
|
|
- selector: `#${this.tinymceId}`,
|
|
|
- language: this.languageTypeList['zh'],
|
|
|
- height: this.height,
|
|
|
- body_class: 'panel-body ',
|
|
|
- object_resizing: false,
|
|
|
- toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
|
|
|
- menubar: this.menubar,
|
|
|
- plugins: plugins,
|
|
|
- end_container_on_empty_block: true,
|
|
|
- code_dialog_height: 450,
|
|
|
- code_dialog_width: 1000,
|
|
|
- advlist_bullet_styles: 'square',
|
|
|
- advlist_number_styles: 'default',
|
|
|
- imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
|
|
|
- default_link_target: '_blank',
|
|
|
- link_title: false,
|
|
|
- nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin
|
|
|
- init_instance_callback: editor => {
|
|
|
- if (_this.value) {
|
|
|
- editor.setContent(_this.value)
|
|
|
- }
|
|
|
- _this.hasInit = true
|
|
|
- editor.on('NodeChange Change KeyUp SetContent', () => {
|
|
|
- this.hasChange = true
|
|
|
- this.$emit('input', editor.getContent())
|
|
|
- })
|
|
|
- },
|
|
|
- setup(editor) {
|
|
|
- editor.on('FullscreenStateChanged', (e) => {
|
|
|
- _this.fullscreen = e.state
|
|
|
- })
|
|
|
- },
|
|
|
- // it will try to keep these URLs intact
|
|
|
- // https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
|
|
|
- // https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
|
|
|
- powerpaste_word_import: 'propmt',// 参数可以是propmt, merge, clear,效果自行切换对比
|
|
|
- powerpaste_html_import: 'propmt',// propmt, merge, clear
|
|
|
- powerpaste_allow_local_images: true,
|
|
|
- paste_data_images: true,
|
|
|
- images_upload_url: `${_this.domainUrl}/adm/upload/cloudpub`,
|
|
|
- automatic_uploads: true,
|
|
|
- images_upload_handler: (blobInfo, success, failure) => {
|
|
|
- const formData = new FormData();
|
|
|
- formData.append('upload', blobInfo.blob())
|
|
|
- formData.append('token', this.token)
|
|
|
- formData.append('logic_type', 'textcontent')
|
|
|
- axios.post(`${this.domainUrl}/adm/upload/cloudpub`, formData)
|
|
|
- .then(function (res) {
|
|
|
- if (res.data.errno == 0) {
|
|
|
- let file = res.data.data
|
|
|
- success(file.url)
|
|
|
- return
|
|
|
- }
|
|
|
- failure('上传失败')
|
|
|
- })
|
|
|
- .catch(function (error) {
|
|
|
- failure('上传出错')
|
|
|
- })
|
|
|
- },
|
|
|
- })
|
|
|
- },
|
|
|
- destroyTinymce() {
|
|
|
- const tinymce = window.tinymce.get(this.tinymceId)
|
|
|
- if (this.fullscreen) {
|
|
|
- tinymce.execCommand('mceFullScreen')
|
|
|
- }
|
|
|
-
|
|
|
- if (tinymce) {
|
|
|
- tinymce.destroy()
|
|
|
- }
|
|
|
- },
|
|
|
- setContent(value) {
|
|
|
- window.tinymce.get(this.tinymceId).setContent(value)
|
|
|
- },
|
|
|
- getContent() {
|
|
|
- window.tinymce.get(this.tinymceId).getContent()
|
|
|
- },
|
|
|
- imageSuccessCBK(arr) {
|
|
|
- arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-.tinymce-container {
|
|
|
- position: relative;
|
|
|
- line-height: normal;
|
|
|
-}
|
|
|
-
|
|
|
-.tinymce-container {
|
|
|
- ::v-deep {
|
|
|
- .mce-fullscreen {
|
|
|
- z-index: 10000;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.tinymce-textarea {
|
|
|
- visibility: hidden;
|
|
|
- z-index: -1;
|
|
|
-}
|
|
|
-
|
|
|
-.editor-custom-btn-container {
|
|
|
- position: absolute;
|
|
|
- right: 4px;
|
|
|
- top: 4px;
|
|
|
- /*z-index: 2005;*/
|
|
|
-}
|
|
|
-
|
|
|
-.fullscreen .editor-custom-btn-container {
|
|
|
- z-index: 10000;
|
|
|
- position: fixed;
|
|
|
-}
|
|
|
-
|
|
|
-.editor-upload-btn {
|
|
|
- display: inline-block;
|
|
|
-}
|
|
|
-</style>
|