/** * @file RichText * @description * @author fex */ import React from 'react'; import $ from 'jquery'; // Require Editor JS files. // import 'froala-editor/js/froala_editor.pkgd.min.js'; [ require('froala-editor/js/froala_editor.min.js'), require('froala-editor/js/plugins/align.min'), require('froala-editor/js/plugins/char_counter.min'), require('froala-editor/js/plugins/code_beautifier.min'), require('froala-editor/js/plugins/code_view.min'), require('froala-editor/js/plugins/colors.min'), require('froala-editor/js/plugins/draggable.min'), require('froala-editor/js/plugins/emoticons.min'), require('froala-editor/js/plugins/entities.min'), // require('froala-editor/js/plugins/file.min'), require('froala-editor/js/plugins/font_family.min'), require('froala-editor/js/plugins/font_size.min'), require('froala-editor/js/plugins/forms.min'), require('froala-editor/js/plugins/fullscreen.min'), require('froala-editor/js/plugins/help.min'), require('froala-editor/js/plugins/image.min'), require('froala-editor/js/plugins/image_manager.min'), require('froala-editor/js/plugins/inline_class.min'), require('froala-editor/js/plugins/inline_style.min'), require('froala-editor/js/plugins/line_breaker.min'), require('froala-editor/js/plugins/line_height.min'), require('froala-editor/js/plugins/link.min'), require('froala-editor/js/plugins/lists.min'), require('froala-editor/js/plugins/paragraph_format.min'), require('froala-editor/js/plugins/paragraph_style.min'), require('froala-editor/js/plugins/print.min'), require('froala-editor/js/plugins/quick_insert.min'), require('froala-editor/js/plugins/quote.min'), require('froala-editor/js/plugins/save.min'), require('froala-editor/js/plugins/special_characters.min'), require('froala-editor/js/plugins/table.min'), require('froala-editor/js/plugins/url.min'), require('froala-editor/js/plugins/video.min'), require('froala-editor/js/plugins/word_paste.min') ].forEach(init => init()); // Require Editor CSS files. import 'froala-editor/css/froala_style.min.css'; import 'froala-editor/css/froala_editor.pkgd.min.css'; import {resizeSensor} from '../utils/resize-sensor'; export default class FroalaEditor extends React.Component { listeningEvents: Array = []; $element: any = null; $editor: any = null; config: any = { immediateReactModelUpdate: false, reactIgnoreAttrs: null }; editorInitialized: boolean = false; oldModel: any = null; constructor(props: any) { super(props); this.textareaRef = this.textareaRef.bind(this); } componentDidUpdate() { if (JSON.stringify(this.oldModel) == JSON.stringify(this.props.model)) { return; } this.setContent(); } textareaRef(ref: any) { ref ? this.createEditor(ref) : this.destroyEditor(); } createEditor(ref: any) { if (this.editorInitialized) { return; } this.config = this.props.config || this.config; this.$element = $(ref); this.setContent(true); this.registerEvents(); resizeSensor(ref.parentElement, () => { $(ref).prev('.fr-box').find('.fr-toolbar').css('width', ''); }); this.$editor = this.$element .froalaEditor(this.config) .data('froala.editor').$el; this.initListeners(); this.editorInitialized = true; } setContent(firstTime: boolean = false) { if (!this.editorInitialized && !firstTime) { return; } if (this.props.model || this.props.model == '') { this.oldModel = this.props.model; this.setNormalTagContent(firstTime); } } setNormalTagContent(firstTime: boolean) { let self = this; function htmlSet() { self.$element.froalaEditor('html.set', self.props.model || '', true); //This will reset the undo stack everytime the model changes externally. Can we fix this? self.$element.froalaEditor('undo.reset'); self.$element.froalaEditor('undo.saveStep'); } if (firstTime) { this.registerEvent(this.$element, 'froalaEditor.initialized', htmlSet); } else { htmlSet(); } } getEditor() { if (this.$element) { return this.$element.froalaEditor.bind(this.$element); } return null; } updateModel() { if (!this.props.onModelChange) { return; } let modelContent = ''; let returnedHtml = this.$element.froalaEditor('html.get'); if (typeof returnedHtml === 'string') { modelContent = returnedHtml; } this.oldModel = modelContent; this.props.onModelChange(modelContent); } initListeners() { let self = this; // bind contentChange and keyup event to froalaModel this.registerEvent( this.$element, 'froalaEditor.contentChanged', function () { self.updateModel(); } ); if (this.config.immediateReactModelUpdate) { this.registerEvent(this.$editor, 'keyup', function () { self.updateModel(); }); } } // register event on jquery editor element registerEvent(element: any, eventName: any, callback: any) { if (!element || !eventName || !callback) { return; } this.listeningEvents.push(eventName); element.on(eventName, callback); } registerEvents() { let events = this.config.events; if (!events) { return; } for (let event in events) { if (events.hasOwnProperty(event)) { this.registerEvent(this.$element, event, events[event]); } } } destroyEditor() { if (this.$element) { this.listeningEvents && this.$element.off(this.listeningEvents.join(' ')); this.$editor.off('keyup'); this.$element.froalaEditor('destroy'); this.listeningEvents.length = 0; this.$element = null; this.editorInitialized = false; } } render() { return