UNPKG

acklen-keystone

Version:

Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose

201 lines (173 loc) 4.57 kB
import Field from '../Field'; import React from 'react'; import ckeditor from 'ckeditor'; import ckfinder from 'ckfinder'; import { FormInput } from '../../../admin/client/App/elemental'; import evalDependsOn from '../../utils/evalDependsOn'; var lastId = 0; function getId () { return 'keystone-html-' + lastId++; } function removeEditorInstance (id) { if (ckeditor.instances[id]) { ckeditor.instances[id].destroy(); } } module.exports = Field.create({ displayName: 'HtmlField', statics: { type: 'Html', }, getInitialState () { return { id: getId(), isFocused: false, editorActive: false, }; }, initEditor () { if (!this.props.wysiwyg) return; if (!ckeditor.instances[this.state.id]) { var opts = this.getOptions(); this._currentValue = this.props.value; this.editor = ckeditor.replace(this.state.id, { contentsCss: opts.content_css || '', allowedContent: true, }); ckfinder.setupCKEditor(this.editor); this.editor.on('change', this.valueChanged); if (evalDependsOn(this.props.dependsOn, this.props.values)) { this.setState({ editorActive: true }); } } }, removeEditor (state) { removeEditorInstance(state.id); this.setState({ editorActive: false }); }, componentDidUpdate (prevProps, prevState) { if (prevState.isCollapsed && !this.state.isCollapsed) { this.initEditor(); } if (this.props.wysiwyg) { if (evalDependsOn(this.props.dependsOn, this.props.values)) { if (!this.state.editorActive) { this.initEditor(); } } else if (this.state.editorActive) { this.removeEditor(prevState); } } }, componentWillReceiveProps (nextProps) { if (this.editor && this._currentValue !== nextProps.value) { this.editor.setData(nextProps.value); } }, componentWillUnmount () { this.removeEditor(this.state); }, valueChanged (event) { var content; if (event.editor) { content = event.editor.getData(); } else { content = event.target.value; } this._currentValue = content; this.props.onChange({ path: this.props.path, value: content, }); }, getOptions () { var plugins = ['code', 'link']; var options = Object.assign( {}, Keystone.wysiwyg.options, this.props.wysiwyg ); var toolbar = options.overrideToolbar ? '' : 'bold italic | alignleft aligncenter alignright | bullist numlist | outdent indent | removeformat | link '; var i; if (options.enableImages) { plugins.push('image'); toolbar += ' | image'; } if (options.enableCloudinaryUploads || options.enableS3Uploads) { plugins.push('uploadimage'); toolbar += options.enableImages ? ' uploadimage' : ' | uploadimage'; } if (options.additionalButtons) { var additionalButtons = options.additionalButtons.split(','); for (i = 0; i < additionalButtons.length; i++) { toolbar += (' | ' + additionalButtons[i]); } } if (options.additionalPlugins) { var additionalPlugins = options.additionalPlugins.split(','); for (i = 0; i < additionalPlugins.length; i++) { plugins.push(additionalPlugins[i]); } } if (options.importcss) { plugins.push('importcss'); var importcssOptions = { content_css: options.importcss, importcss_append: true, importcss_merge_classes: true, }; Object.assign(options.additionalOptions, importcssOptions); } if (!options.overrideToolbar) { toolbar += ' | code'; } var opts = { selector: '#' + this.state.id, toolbar: toolbar, plugins: plugins, menubar: options.menubar || false, skin: options.skin || 'keystone', }; if (this.shouldRenderField()) { opts.uploadimage_form_url = options.enableS3Uploads ? Keystone.adminPath + '/api/s3/upload' : Keystone.adminPath + '/api/cloudinary/upload'; } else { Object.assign(opts, { mode: 'textareas', readonly: true, menubar: false, toolbar: 'code', statusbar: false, }); } if (options.additionalOptions) { Object.assign(opts, options.additionalOptions); } return opts; }, renderField () { var className = this.state.isFocused ? 'is-focused' : ''; var style = { height: this.props.height, }; return ( <div className={className}> <FormInput id={this.state.id} multiline name={this.getInputName(this.props.path)} onChange={this.valueChanged} className={this.props.wysiwyg ? 'wysiwyg' : 'code'} style={style} value={this.props.value} /> </div> ); }, renderValue () { return ( <FormInput multiline noedit> {this.props.value} </FormInput> ); }, });