import React from 'react'; // Import TinyMCE // @ts-ignore import tinymce from 'tinymce/tinymce'; // A theme is also required import 'tinymce/icons/default/index'; import 'tinymce/themes/silver'; import 'tinymce/models/dom/model'; // import 'tinymce/skins/ui/oxide/skin.css'; // Any plugins you want to use has to be imported import 'tinymce/plugins/advlist'; import 'tinymce/plugins/autolink'; import 'tinymce/plugins/autoresize'; import 'tinymce/plugins/lists'; import 'tinymce/plugins/link'; import 'tinymce/plugins/image'; import 'tinymce/plugins/charmap'; import 'tinymce/plugins/preview'; import 'tinymce/plugins/anchor'; import 'tinymce/plugins/searchreplace'; import 'tinymce/plugins/visualblocks'; import 'tinymce/plugins/code'; import 'tinymce/plugins/fullscreen'; import 'tinymce/plugins/insertdatetime'; import 'tinymce/plugins/media'; import 'tinymce/plugins/table'; import 'tinymce/plugins/help'; import 'tinymce/plugins/wordcount'; import 'tinymce/plugins/pagebreak'; import 'tinymce/plugins/visualchars'; import 'tinymce/plugins/template'; import 'tinymce/plugins/nonbreaking'; import 'tinymce/plugins/emoticons'; import 'tinymce/plugins/emoticons/js/emojis'; import 'tinymce/plugins/quickbars/plugin'; import 'tinymce/plugins/help/js/i18n/keynav/zh_CN'; import 'tinymce/plugins/help/js/i18n/keynav/en'; import 'tinymce/plugins/help/js/i18n/keynav/de'; import {LocaleProps} from 'amis-core'; interface TinymceEditorProps extends LocaleProps { model: string; onModelChange?: (value: string) => void; onFocus?: () => void; onBlur?: () => void; disabled?: boolean; config?: { onLoaded?: (tinymce: any) => void | Promise; [propName: string]: any; }; outputFormat?: 'html' | 'text'; receiver?: string; } export default class TinymceEditor extends React.Component { static defaultProps = { outputFormat: 'html' }; config?: any; editor?: any; unmounted = false; editorInitialized?: boolean = false; currentContent?: string; elementRef: React.RefObject = React.createRef(); async componentDidMount() { const locale = this.props.locale; const {onLoaded, ...rest} = this.props.config || {}; this.config = { inline: false, skin: false, content_css: false, height: 400, language: !locale || locale === 'zh-CN' ? 'zh_CN' : 'en', branding: false, plugins: [ 'advlist', 'autolink', 'autoresize', 'link', 'image', 'lists', 'charmap', 'preview', 'anchor', 'pagebreak', 'searchreplace', 'wordcount', 'visualblocks', 'visualchars', 'code', 'fullscreen', 'insertdatetime', 'media', 'nonbreaking', 'table', 'emoticons', 'template', 'help', 'quickbars' ], toolbar: 'undo redo | blocks | bold italic | alignleft aligncenter alignright alignjustify | ' + 'bullist numlist outdent indent | link image | preview media | ' + 'fontfamily fontsize forecolor backcolor emoticons | print help', quickbars_selection_toolbar: 'bold italic | link h2 h3 blockquote', quickbars_insert_toolbar: 'quickimage quicktable', menu: { file: { title: 'File', items: 'newdocument restoredraft | preview | print ' }, edit: { title: 'Edit', items: 'undo redo | cut copy paste | selectall | searchreplace' }, view: { title: 'View', items: 'code | visualaid visualchars visualblocks | preview fullscreen' }, insert: { title: 'Insert', items: 'image link media template codesample inserttable | charmap emoticons hr | pagebreak nonbreaking anchor toc | insertdatetime' }, format: { title: 'Format', items: 'bold italic underline strikethrough superscript subscript codeformat | styles blocks fontsize align | forecolor backcolor | removeformat' }, tools: { title: 'Tools', items: 'code wordcount' }, table: { title: 'Table', items: 'inserttable | cell row column | tableprops deletetable' }, help: {title: 'Help', items: 'help'} }, paste_data_images: true, // 很诡异的问题,video 会被复制放在光标上,直接用样式隐藏先 content_style: '[data-mce-bogus] video {display:none;}', ...rest, target: this.elementRef.current, readOnly: this.props.disabled, promotion: false, setup: (editor: any) => { this.editor = editor; editor.on('init', (e: Event) => { this.editorInitialized = true; this.initEditor(e, editor); }); } }; await onLoaded?.(tinymce); this.unmounted || tinymce.init(this.config); } componentDidUpdate(prevProps: TinymceEditorProps) { const props = this.props; if ( props.model !== prevProps.model && props.model !== this.currentContent ) { this.editorInitialized && this.editor?.setContent(props.model || ''); } } componentWillUnmount() { tinymce.remove(this.editor); this.unmounted = true; } initEditor(e: any, editor: any) { const {model, onModelChange, outputFormat, onFocus, onBlur} = this.props; const value = model || ''; editor.setContent(value); if (onModelChange) { editor.on('change keyup setcontent', (e: any) => { const newContent = editor.getContent({format: outputFormat}); if (newContent !== this.currentContent) { this.currentContent = newContent; onModelChange(newContent); } }); } onFocus && editor.on('focus', onFocus); onBlur && editor.on('blur', onBlur); } render() { return