import React from 'react'; import Quill from 'quill'; import ReactQuill from 'react-quill'; import 'react-quill/dist/quill.snow.css'; import './index.less'; import { generateUUID } from '../../services/Tools'; const Delta = Quill.imports.delta; const Parchment = Quill.imports.parchment; const defaultContainer = [ [{ header: '1' }, { header: '2' }], ['bold', 'underline', 'blockquote'], [{ color: [] }, { background: [] }], [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }], // ['image'], // ['link', 'video'], ['clean'], ]; const formats = [ 'header', 'font', 'size', 'bold', 'italic', 'underline', 'strike', 'blockquote', 'color', 'list', 'bullet', 'indent', 'link', 'image', // 'video', ]; class ListAttributor extends Parchment.Attributor.Style { value(node) { // console.log(node); const style = node.style || {}; return style.listStyleType; // return super.value(node); } add(node, value) { // console.log(node, value); node.style.listStyleType = value; return true; } } const ListClass = new Parchment.Attributor.Class('list-style-customer', 'ql-list', { scope: Parchment.Scope.BLOCK_BLOT, }); const ListStyleType = new ListAttributor('list-style', 'list-style-type', { scope: Parchment.Scope.BLOCK_BLOT, }); // console.log(ListStyleType); Quill.register(ListStyleType, true); Quill.register(ListClass, true); class Editor extends React.Component { constructor(props) { super(props); this.quillRef = null; this.state = {}; this.loading = 0; this.modules = { toolbar: { container: [ ], handlers: {}, }, clipboard: { // toggle to add extra line breaks when pasting HTML: matchVisual: true, matchers: [ ['ol', (node, delta) => { const style = node.style || {}; if (style.listStyleType) { delta = delta.reduce((d, op) => { // if (op.attributes && op.attributes['list-style']) { // return d.push(op); // } return d.insert(op.insert, Object.assign({}, op.attributes, { 'list-style': ListStyleType.value(node), 'list-style-customer': 'customer' })); }, new Delta()); } return delta; }], ], }, }; this.modules = Object.assign(this.modules, props.modules); if (this.modules.toolbar.container.length === 0) { this.modules.toolbar.container = defaultContainer.map(row => row); if (props.onUpload) { this.modules.toolbar.container.unshift(['image']); } } // console.log(this.modules); this.modules.toolbar.handlers.image = () => this.image(); Object.keys(this.modules.toolbar.handlers).forEach(key => { const handler = this.modules.toolbar.handlers[key]; this.modules.toolbar.handlers[key] = () => { handler(this.quillRef.getEditor()); }; }); this.formats = Object.assign({}, formats, props.formats); } progress(data) { return done => { if (this.props.onProgress) this.props.onProgress(data); done(); }; } image() { const self = this; this.container = this.quillRef.editingArea; const quill = this.quillRef.getEditor(); let fileInput = this.container.querySelector('input.ql-image[type=file]'); // fileInput if (fileInput == null) { fileInput = document.createElement('input'); fileInput.setAttribute('type', 'file'); fileInput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'); fileInput.classList.add('ql-image'); fileInput.addEventListener('change', () => { if (fileInput.files != null && fileInput.files[0] != null) { // getSelection 选择当前光标位置咯 然后在下一个range.index用它自带的embed媒介插入方式插入你已经存储在阿里上的图片了 const range = quill.getSelection(true); const file = fileInput.files[0]; const suffix = file.name.substring(file.name.lastIndexOf('.')).toLowerCase(); const name = generateUUID(); self.props .onUpload(file, self.props.path, self.progress, `${self.props.path}/${name}${suffix}`) .then(data => { self.setState({ uploading: false, load: self.state.load + 1 }); quill.insertEmbed(range.index, 'image', data.url || data); quill.setSelection(range.index + 1); }) .catch(err => { self.setState({ uploading: false, load: self.state.load + 1 }); if (self.props.onError) self.props.onError(err); }); } }); } fileInput.click(); } render() { // console.log(this.props.value); return (
{ this.quillRef = el; }} style={this.props.style} theme={this.props.theme || 'snow'} onChange={(content, delta, source, editor) => { if (this.props.onChange) this.props.onChange(content, delta, source, editor); }} defaultValue={this.props.defaultValue || ''} value={this.props.value || ''} modules={this.modules} formats={this.formats} placeholder={this.props.placeholder} />
); } } export default Editor;