index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import React from 'react';
  2. import ReactQuill from 'react-quill';
  3. import 'react-quill/dist/quill.snow.css';
  4. import { uuid } from '../../services/Tools';
  5. const modules = {
  6. toolbar: {
  7. container: [
  8. [{ header: '1' }, { header: '2' }],
  9. [
  10. 'bold',
  11. 'underline',
  12. 'blockquote',
  13. // { color: ['red', 'green', 'blue', 'orange', 'violet', '#d0d1d2', 'black'] },
  14. ],
  15. [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
  16. // ['image'],
  17. // ['link', 'video'],
  18. // ['clean'],
  19. ],
  20. handlers: {},
  21. },
  22. clipboard: {
  23. // toggle to add extra line breaks when pasting HTML:
  24. matchVisual: false,
  25. },
  26. };
  27. const formats = [
  28. 'header',
  29. 'font',
  30. 'size',
  31. 'bold',
  32. 'italic',
  33. 'underline',
  34. 'strike',
  35. 'blockquote',
  36. 'color',
  37. 'list',
  38. 'bullet',
  39. 'indent',
  40. 'link',
  41. 'image',
  42. // 'video',
  43. ];
  44. class Editor extends React.Component {
  45. constructor(props) {
  46. super(props);
  47. this.quillRef = null;
  48. this.state = {};
  49. this.modules = Object.assign({}, modules, props.modules);
  50. // console.log(this.modules);
  51. this.modules.toolbar.handlers.image = () => this.image();
  52. Object.keys(this.modules.toolbar.handlers).forEach(key => {
  53. const handler = this.modules.toolbar.handlers[key];
  54. this.modules.toolbar.handlers[key] = () => {
  55. handler(this.quillRef.getEditor());
  56. };
  57. });
  58. this.formats = Object.assign({}, formats, props.formats);
  59. }
  60. progress(data) {
  61. return done => {
  62. if (this.props.onProgress) this.props.onProgress(data);
  63. done();
  64. };
  65. }
  66. image() {
  67. const self = this;
  68. this.container = this.quillRef.editingArea;
  69. const quill = this.quillRef.getEditor();
  70. let fileInput = this.container.querySelector('input.ql-image[type=file]'); // fileInput
  71. if (fileInput == null) {
  72. fileInput = document.createElement('input');
  73. fileInput.setAttribute('type', 'file');
  74. fileInput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
  75. fileInput.classList.add('ql-image');
  76. fileInput.addEventListener('change', () => {
  77. if (fileInput.files != null && fileInput.files[0] != null) {
  78. // getSelection 选择当前光标位置咯 然后在下一个range.index用它自带的embed媒介插入方式插入你已经存储在阿里上的图片了
  79. const range = quill.getSelection(true);
  80. const file = fileInput.files[0];
  81. const suffix = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
  82. const name = uuid();
  83. self.props
  84. .onUpload(file, self.props.path, self.progress, `${self.props.path}/${name}${suffix}`)
  85. .then(data => {
  86. self.setState({ uploading: false, load: self.state.load + 1 });
  87. quill.insertEmbed(range.index, 'image', data.url || data);
  88. quill.setSelection(range.index + 1);
  89. })
  90. .catch(err => {
  91. self.setState({ uploading: false, load: self.state.load + 1 });
  92. if (self.props.onError) self.props.onError(err);
  93. });
  94. }
  95. });
  96. }
  97. fileInput.click();
  98. }
  99. render() {
  100. return (
  101. <div>
  102. <ReactQuill
  103. ref={el => {
  104. this.quillRef = el;
  105. }}
  106. defaultValue={this.props.value}
  107. style={this.props.style}
  108. theme={this.props.theme || 'snow'}
  109. onChange={(content, delta, source, editor) => this.props.onChange && this.props.onChange(content, delta, source, editor)}
  110. // value={new Delta(this.props.value)}
  111. modules={this.modules}
  112. formats={this.formats}
  113. placeholder={this.props.placeholder}
  114. />
  115. </div>
  116. );
  117. }
  118. }
  119. export default Editor;