diff --git a/public/react/src/common/quillForEditor/FillBlot.js b/public/react/src/common/quillForEditor/FillBlot.js new file mode 100644 index 000000000..d36f2d4b1 --- /dev/null +++ b/public/react/src/common/quillForEditor/FillBlot.js @@ -0,0 +1,38 @@ +/* + * @Description: 填空 + * @Author: tangjiang + * @Github: + * @Date: 2020-01-06 09:02:29 + * @LastEditors : tangjiang + * @LastEditTime : 2020-01-06 16:04:46 + */ +import Quill from 'quill'; + +let Inline = Quill.import('blots/inline'); + +class FillBlot extends Inline { + static create (value) { + const node = super.cerate(); + node.classList.add('icon icon-bianji2'); + node.setAttribute('data-fill', 'fill'); + node.addEventListener('DOMNodeRemoved', function () { + alert(123); + }, false); + return node; + } + + static value (node) { + return { + dataSet: node.getAttribute('data-fill'), + onDOMNodeRemoved: () => { + alert('123456'); + } + } + } +} + + +FillBlot.blotName = "fill"; +FillBlot.tagName = "span"; + +export default FillBlot; diff --git a/public/react/src/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index f3f359a80..326ca21ae 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-12-18 08:49:30 * @LastEditors : tangjiang - * @LastEditTime : 2019-12-31 15:11:37 + * @LastEditTime : 2020-01-06 16:45:50 */ import './index.scss'; import 'quill/dist/quill.core.css'; // 核心样式 @@ -18,8 +18,11 @@ import deepEqual from './deepEqual.js' import { fetchUploadImage } from '../../services/ojService.js'; import { getImageUrl } from 'educoder' import ImageBlot from './ImageBlot'; +// import Toolbar from 'quill/modules/toolbar'; +import FillBlot from './FillBlot'; const Size = Quill.import('attributors/style/size'); const Font = Quill.import('formats/font'); + // const Color = Quill.import('attributes/style/color'); Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false]; Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif']; @@ -29,6 +32,8 @@ window.katex = katex; Quill.register(ImageBlot); Quill.register(Size); Quill.register(Font, true); +// Quill.register({'modules/toolbar': Toolbar}); +Quill.register(FillBlot); // Quill.register(Color); function QuillForEditor ({ @@ -42,6 +47,7 @@ function QuillForEditor ({ wrapStyle = {}, showUploadImage, onContentChange, + // addFill, // 点击填空成功的回调 // getQuillContent }) { // toolbar 默认值 @@ -62,6 +68,8 @@ function QuillForEditor ({ // quill 实例 const [quill, setQuill] = useState(null); const [selection, setSelection] = useState(null); + const [fillCount, setFillCount] = useState(0); + const [quillCtx, setQuillCtx] = useState({}); // 文本内容变化时 const handleOnChange = content => { @@ -70,18 +78,23 @@ function QuillForEditor ({ }; const renderOptions = options || defaultConfig; + // quill 配置信息 const quillOption = { modules: { toolbar: renderOptions + // toolbar: { + // container: renderOptions + // } }, readOnly, placeholder, - theme: readOnly ? 'bubble' : 'snow' + theme: readOnly ? 'bubble' : 'snow', }; useEffect(() => { + const quillNode = document.createElement('div'); editorRef.current.appendChild(quillNode); const _quill = new Quill(editorRef.current, quillOption); @@ -121,13 +134,20 @@ function QuillForEditor ({ } } }); + + _quill.getModule('toolbar').addHandler('fill', (e) => { + setFillCount(fillCount + 1); + const range = _quill.getSelection(true); + _quill.insertText(range.index, '▁'); + // 点击填空图标时,插入一个下划线 + // 1. 获取编辑器内容 + }); }, []); // 设置值 useEffect(() => { if (!quill) return - // debugger; const previous = quill.getContents() if (value && value.hasOwnProperty('ops')) { @@ -173,7 +193,36 @@ function QuillForEditor ({ let handler; quill.on( 'text-change', - (handler = () => { + (handler = (delta, oldDelta, source) => { + // let del = false; + // let delLen = 1; + // delta.ops.forEach(o => { + // // 存在删除并且只删除一个 + // if (o.delete) { + // del = true; + // } + // }); + // 删除编辑器内容 + // if (del) { + // delLen = delta.ops[0].retain || 1; // 删除数组的长度 + // // 获取删除的内容并判断其它是否有填空内容 + // console.log('原编辑器内容', oldDelta); + // console.log('编辑器内容', quillCtx); + // } + // 获取删除的内容 + // oldDelta + // if (del) { + // const ops = oldDelta.ops; + // const len = ops.length; + // // if (ops[len - 1] && ops[len - 1].insert) { + // // const str = ops[len - 1].insert; + // // const _len = str.length; + // // const _last = str.substr(_len - 1); + // // console.log('删除的一项', _last); + // // } + // } + const _ctx = quill.getContents(); + setQuillCtx(_ctx); handleOnChange(quill.getContents()); // getContents: 检索编辑器内容 }) ); diff --git a/public/react/src/common/quillForEditor/index.scss b/public/react/src/common/quillForEditor/index.scss index 96cd45edd..eca8c4485 100644 --- a/public/react/src/common/quillForEditor/index.scss +++ b/public/react/src/common/quillForEditor/index.scss @@ -110,4 +110,21 @@ content: "微软雅黑"; font-family: "Microsoft YaHei"; } + + // 填空图标 + .ql-snow .ql-fill{ + display: inline-block; + position: relative; + color: #05101A; + // font-size: 18px; + vertical-align: top; + &::before{ + position: absolute; + left: 50%; + top: -1px; + content: '\e709'; + font-family: 'iconfont'; + margin-left: -7px; + } + } } \ No newline at end of file diff --git a/public/react/src/modules/developer/newOrEditTask/index.js b/public/react/src/modules/developer/newOrEditTask/index.js index 24d2ebd7d..9be899b9c 100644 --- a/public/react/src/modules/developer/newOrEditTask/index.js +++ b/public/react/src/modules/developer/newOrEditTask/index.js @@ -213,7 +213,7 @@ const NewOrEditTask = (props) => { { renderQuit() }
- +
diff --git a/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/README.md b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/README.md new file mode 100644 index 000000000..bbec5eb50 --- /dev/null +++ b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/README.md @@ -0,0 +1,69 @@ + +## QuillForEditor 使用 [https://quilljs.com/] + + ### 导入 + + - 目录 src/common/quillForEditor (默认加载当前文件夹下的 index.js 文件) + + ### 参数 + + | 字段 | 描述 | + | ----- | ----- | + | placeholder | 提示信息 | + | readOnly | 只读(只读取模式时,没有 工具栏且内容不可编辑,通过用于展示quill内容) | + | autoFocus | 自动获得焦点 | + | options | 配置参数, 指定工具栏内容 | + | value | 文本编辑器内容 | + | imgAttrs | 指定上传图片的尺寸 | + | style | 指定quill容器样式 | + | wrapStyle | 指定包裹quill容器的样式| + | onContentChange | 当编辑器内容变化时调用此回调函数 | + | showUploadImage | 点击放大上传成功后的图片, 返回上传成功后的图片 url, (评论时点击图片这么大)| + + + + ### 添加工具栏 + + - 默认所有的 + + ``` + const options = [ + 'bold', // 加粗 + 'italic', // 斜体 + 'underline', // 下划线 + {size: ['12px', '14px', '16px', '18px', '20px']}, // 字体大小 + {align: []}, // 对齐方式 + {list: 'ordered'}, // 有序列表 + {list: 'bullet'}, // 无序列表 + {script: 'sub'}, // 下标 x2 + {script: 'super'}, // 上标 平方 (x2) + { 'color': [] }, // 字体颜色 + { 'background': [] }, // 背景色 + {header: [1,2,3,4,5,false]}, // H1,H2 ... + 'blockquote', // 文件左边加一个边框样式 + 'code-block', // 块内容 + 'link', // 链接 + 'image', // 图片 + 'video', // 视频 + 'formula', // 数学公式 + 'clean' // 清除 + ] + ``` + + + ### 使用 + + ```` + import QuillForEditor from 'xxx'; + + + + ```` + diff --git a/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js index 3345997c7..1d2742647 100644 --- a/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js +++ b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js @@ -1,14 +1,10 @@ /* - * @Description: + * @Description: * @Author: tangjiang - * @Github: + * @Github: * @Date: 2019-11-20 10:35:40 * @LastEditors : tangjiang -<<<<<<< HEAD - * @LastEditTime : 2020-01-03 17:35:45 -======= - * @LastEditTime : 2020-01-03 19:02:17 ->>>>>>> dev_aliyun + * @LastEditTime : 2020-01-06 16:17:22 */ import './index.scss'; // import 'katex/dist/katex.css'; @@ -79,7 +75,7 @@ class EditTab extends React.Component { this.setState({ scrollEl: oWrap, targetEl: oTarget, - offsetTop: offsetTop, // 记录初始位置 + offsetTop: offsetTop, // 记录初始位置 scrollHeight, }, () => { this.state.scrollEl.addEventListener('scroll', this.handleScroll, false); @@ -93,7 +89,7 @@ class EditTab extends React.Component { // componentDidUpdate (nextProp) { // console.log(nextProp); // } - + componentWillUnmount (nextPro) { this.state.scrollEl.removeEventListener('scroll', this.handleScroll, false); } @@ -116,7 +112,7 @@ class EditTab extends React.Component { } } - // 改变任务名称 + // 改变任务名称 handleNameChange = (e) => { const value = e.target.value; this.props.validateOJName(value); @@ -171,8 +167,8 @@ class EditTab extends React.Component { } render () { - const { - ojForm, + const { + ojForm, ojFormValidate, // testCases = [], // 测试用例集合 addTestCase, // 添加测试用例 @@ -183,10 +179,9 @@ class EditTab extends React.Component { tag_discipline_id, knowledges } = this.props; - // console.log('knowledge======>>>>>>', knowledges); + console.log('knowledge======>>>>>>', knowledges); // const {knowledges} = this.state; // 表单label - // console.log('props=====>>>>', this.props); const myLabel = (name, subTitle, nostar) => { if (subTitle) { return ( @@ -225,8 +220,8 @@ class EditTab extends React.Component { return ) } - + // 知识点 const handleKnowledgeChange = (values= []) => { const _result = []; @@ -349,11 +344,11 @@ class EditTab extends React.Component { // 保存选择的知识点 this.props.saveTagDisciplineId(_result); } - + return (
- {myLabel(jcLabel['difficult'])}} validateStatus={ojFormValidate.difficult.validateStatus} @@ -365,7 +360,7 @@ class EditTab extends React.Component { - {myLabel(jcLabel['sub_discipline_id'], '合理的课程分类有利于快速检索')}} validateStatus={ojFormValidate.sub_discipline_id.validateStatus} @@ -375,7 +370,7 @@ class EditTab extends React.Component { {/* */} - {/* {myLabel(jcLabel['knowledge'], '', 'nostar')}} > - - - {myLabel(jcLabel['timeLimit'], '程序允许时间限制时长,单位:秒')}} validateStatus={ojFormValidate.timeLimit.validateStatus} @@ -405,7 +400,7 @@ class EditTab extends React.Component { - {myLabel(jcLabel['language'])}} validateStatus={ojFormValidate.language.validateStatus} @@ -417,7 +412,7 @@ class EditTab extends React.Component { - {myLabel(jcLabel['name'])}} validateStatus={ojFormValidate.name.validateStatus} @@ -432,24 +427,24 @@ class EditTab extends React.Component { onChange={this.handleNameChange} /> - - {myLabel(jcLabel['description'])}} validateStatus={ojFormValidate.description.validateStatus} help={ojFormValidate.description.errMsg} colon={ false } > - - - {/* {myLabel(jcLabel['openOrNot'], '社区:您的任务将向整个社会公开')}} validateStatus={ojFormValidate.openOrNot.validateStatus} @@ -460,9 +455,9 @@ class EditTab extends React.Component { {getOptions('openOrNot')} */} - +
- + {/* 添加测试用例 */}

测试用例

@@ -481,11 +476,11 @@ class EditTab extends React.Component { const mapStateToProps = (state) => { const ojFormReducer = state.ojFormReducer; const { - ojForm, - position, - testCases, + ojForm, + position, + testCases, openTestCodeIndex, - testCasesValidate, + testCasesValidate, ojFormValidate, courseQuestions, tag_discipline_id, diff --git a/public/react/src/modules/developer/split_pane_resizer.scss b/public/react/src/modules/developer/split_pane_resizer.scss index 8d4ad171c..2c1101433 100644 --- a/public/react/src/modules/developer/split_pane_resizer.scss +++ b/public/react/src/modules/developer/split_pane_resizer.scss @@ -217,3 +217,42 @@ .Resizer.disabled:hover { border-color: transparent; } + +.outer-split-pane{ + & > .Resizer{ + position: relative; + &::before, + &::after{ + position: absolute; + right: -12px; + top: 50%; + transition: opacity, background .3s; + } + &::before{ + content: ''; + border-radius: 50%; + background: rgba(235,235,235,.3); + width: 24px; + height: 24px; + // font-size: 12px; + } + &::after{ + content: '\e712'; + font-family: 'iconfont'; + transform: scale(.7); + color: #666; + margin-top: -2px; + right: -14px; + opacity: .3; + } + + &:hover{ + &::before{ + background: rgba(235,235,235, 1); + } + &::after{ + opacity: 1; + } + } + } +} diff --git a/public/react/src/modules/developer/studentStudy/index.js b/public/react/src/modules/developer/studentStudy/index.js index 2ef8c4ba9..0c8c7012f 100644 --- a/public/react/src/modules/developer/studentStudy/index.js +++ b/public/react/src/modules/developer/studentStudy/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-23 10:53:19 * @LastEditors : tangjiang - * @LastEditTime : 2019-12-27 16:22:47 + * @LastEditTime : 2020-01-06 15:27:34 */ import './index.scss'; import React, { useEffect, useState } from 'react'; @@ -144,7 +144,7 @@ function StudentStudy (props) {
- +
diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index e226b9b68..755034465 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -303,18 +303,18 @@ class SingleEditor extends Component{ 题干:

- {/* this.setState({ question_title: val})}*/} - {/* ref="titleEditor"*/} - - {/*>*/} - - + this.setState({ question_title: val})} + ref="titleEditor" + + > + + {/**/}
{/* {!question_id ? '新建' : '编辑'} */}