| 
					
				 | 
			
			
				@@ -0,0 +1,247 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<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' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 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() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      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.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() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    initTinymce() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const _this = this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.tinymce.init({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        selector: `#${this.tinymceId}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        language: this.languageTypeList['en'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        powerpaste_word_import: 'clean', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        convert_urls: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 整合七牛上传 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // images_dataimg_filter(img) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     const $image = $(img); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     $image.removeAttr('width'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     $image.removeAttr('height'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     if ($image[0].height && $image[0].width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       $image.attr('data-wscntype', 'image'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       $image.attr('data-wscnh', $image[0].height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       $image.attr('data-wscnw', $image[0].width); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       $image.addClass('wscnph'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   }, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   return img 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // images_upload_handler(blobInfo, success, failure, progress) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   progress(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   const token = _this.$store.getters.token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   getToken(token).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     const url = response.data.qiniu_url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     const formData = new FormData(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     formData.append('token', response.data.qiniu_token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     formData.append('key', response.data.qiniu_key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     formData.append('file', blobInfo.blob(), url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     upload(formData).then(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       success(url); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       progress(100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   }).catch(err => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     failure('出现未知问题,刷新页面,或者联系程序员') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    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> 
			 |