- );
-}
-
-export default ReactQuill;
diff --git a/public/react/src/common/reactQuill/deepEqual.js b/public/react/src/common/reactQuill/deepEqual.js
deleted file mode 100644
index 6f2b276bf..000000000
--- a/public/react/src/common/reactQuill/deepEqual.js
+++ /dev/null
@@ -1,47 +0,0 @@
-function deepEqual (prev, current) {
- if (prev === current) { // 基本类型比较,值,类型都相同 或者同为 null or undefined
- return true;
- }
-
- if ((!prev && current)
- || (prev && !current)
- || (!prev && !current)
- ) {
- return false;
- }
-
- if (Array.isArray(prev)) {
- if (!Array.isArray(current)) return false;
- if (prev.length !== current.length) return false;
-
- for (let i = 0; i < prev.length; i++) {
- if (!deepEqual(current[i], prev[i])) {
- return false;
- }
- }
- return true;
- }
-
- if (typeof current === 'object') {
- if (typeof prev !== 'object') return false;
- const prevKeys = Object.keys(prev);
- const curKeys = Object.keys(current);
-
- if (prevKeys.length !== curKeys.length) return false;
-
- prevKeys.sort();
- curKeys.sort();
-
- for (let i = 0; i < prevKeys.length; i++) {
- if (prevKeys[i] !== curKeys[i]) return false;
- const key = prevKeys[i];
- if (!deepEqual(prev[key], current[key])) return false;
- }
-
- return true;
- }
-
- return false;
-}
-
-export default deepEqual;
diff --git a/public/react/src/common/reactQuill/flatten.js b/public/react/src/common/reactQuill/flatten.js
deleted file mode 100644
index 237cb543f..000000000
--- a/public/react/src/common/reactQuill/flatten.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * @Description: 将多维数组转变成一维数组
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-09 09:35:01
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-16 11:36:22
- */
-function flatten (array) {
- return flatten.rec(array, []);
-}
-
-flatten.rec = function flatten (array, result) {
-
- for (let item of array) {
- if (Array.isArray(item)) {
- flatten(item, result);
- } else {
- result.push(item);
- }
- }
-
- return result;
-}
-
-export default flatten;
diff --git a/public/react/src/common/reactQuill/index.js b/public/react/src/common/reactQuill/index.js
deleted file mode 100644
index 56a1a8d1f..000000000
--- a/public/react/src/common/reactQuill/index.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * @Description: 入口文件
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-17 10:41:48
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-17 20:34:40
- */
-import React, { useState, useCallback, useEffect } from 'react';
-import ReactQuill from './lib';
-
-function Wrapper (props) {
- // 默认工具栏配置项
- const toolbarConfig = [
- ['bold', 'italic', 'underline'],
- [{align: []}, {list: 'ordered'}, {list: 'bullet'}], // 列表
- [{script: 'sub'}, {script: 'super'}],
- [{header: [1,2,3,4,5,false]}],
- ['blockquote', 'code-block'],
- ['link', 'image', 'video'],
- ['formula'],
- ['clean']
- ];
-
- const [placeholder] = useState(props.placeholder || 'placeholder');
- const [disableBold] = useState(false);
- const [value, setValue] = useState(props.value || '');
- const [toolbar, setToolbar] = useState(toolbarConfig);
- const [theme, setTheme] = useState(props.theme || 'snow');
- const [readOnly] = useState(props.readOnly || false);
-
- const {
- onContentChagne, // 当编辑器内容变化时调用该函数
- showUploadImage, // 显示上传图片, 返回url,主要用于点击图片放大
- } = props;
-
- // 配置信息
- const options = {
- modules: {
- toolbar: toolbar,
- clipboard: {
- matchVisual: false
- }
- },
- readOnly: readOnly,
- theme: theme
- }
- // 配置信息
- useEffect (() => {
- if (props.options) {
- setToolbar(props.options);
- }
- setTheme(props.theme || 'snow');
- setValue(props.value);
- }, [props]);
-
- // 当内容变化时
- const handleOnChange = useCallback(
- contents => {
- if (disableBold) {
- setValue({
- ops: contents.ops.map(x => {
- x = {...x};
- if (x && x.attributes && x.attributes.bold) {
- x.attributes = { ...x.attributes };
- delete x.attributes.bold;
- if (!Object.keys(x.attributes).length) {
- delete x.attributes;
- }
- }
- return x;
- })
- });
- } else {
- setValue(contents);
- }
- onContentChagne && onContentChagne(contents);
- }, [disableBold]
- );
-
- // 图片上传
- const handleUploadImage = (files) => {
- console.log('选择的图片信息', files);
- }
-
- // 显示图片
- const handleShowUploadImage = (url) => {
- // console.log('上传的图片url:', url);
- showUploadImage && showUploadImage(url);
- }
-
- return (
-
- handleShowUploadImage(url)}
- />
-
- );
-}
-
-export default Wrapper;
-// ReactDOM.render(
, document.querySelector('#root'));
diff --git a/public/react/src/common/reactQuill/index.scss b/public/react/src/common/reactQuill/index.scss
deleted file mode 100644
index b6da52bf5..000000000
--- a/public/react/src/common/reactQuill/index.scss
+++ /dev/null
@@ -1,32 +0,0 @@
-#quill-toolbar{
- .quill-btn{
- vertical-align: middle;
- }
- .quill_image{
- display: inline-block;
- position: relative;
- vertical-align: middle;
- width: 28px;
- height: 24px;
- overflow: hidden;
- .image_input{
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- opacity: 0;
- }
- .ql-image{
- position: relative;
- left: 0;
- top: 0;
- }
- }
-}
-
-.react_quill_area{
- .ql-toolbar:not(:last-child) {
- display: none;
- }
-}
\ No newline at end of file
diff --git a/public/react/src/common/reactQuill/lib.js b/public/react/src/common/reactQuill/lib.js
deleted file mode 100644
index 430a95bb7..000000000
--- a/public/react/src/common/reactQuill/lib.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * @Description: 导出 ReactQuill
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-09 09:08:24
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-16 11:37:13
- */
-import ReactQuill from './ReactQuill';
-import useQuill from './useQuill';
-
-export default ReactQuill;
-export { useQuill };
diff --git a/public/react/src/common/reactQuill/useDeepEqualMemo.js b/public/react/src/common/reactQuill/useDeepEqualMemo.js
deleted file mode 100644
index 948e21781..000000000
--- a/public/react/src/common/reactQuill/useDeepEqualMemo.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * @Description:
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-12 19:48:55
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-16 11:38:16
- */
-import { useState, useEffect } from 'react';
-import deepEqual from './deepEqual';
-
-function useDeepEqual (input) {
-
- const [value, setValue] = useState(input);
-
- useEffect(() => {
-
- if (!deepEqual(input, value)) {
- setValue(input)
- }
-
- }, [input, value]);
-
- return value;
-}
-
-export default useDeepEqual;
diff --git a/public/react/src/common/reactQuill/useMountQuill.js b/public/react/src/common/reactQuill/useMountQuill.js
deleted file mode 100644
index c2313c480..000000000
--- a/public/react/src/common/reactQuill/useMountQuill.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * @Description: 创建 reactQuill实例
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-09 09:31:42
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-17 20:42:05
- */
-import Quill from 'quill'; // 导入quill
-import { useState, useEffect, useMemo } from 'react';
-import flatten from './flatten.js';
-import useDeepEqualMemo from './useDeepEqualMemo';
-import Katex from 'katex';
-import ImageBlot from './ImageBlot';
-import { fetchUploadImage } from '../../services/ojService.js';
-import { getImageUrl } from 'educoder'
-window.katex = Katex;
-
-Quill.register(ImageBlot);
-
-function useMountQuill ({
- element,
- options: passedOptions,
- uploadImage,
- showUploadImage,
- imgAttrs = {} // 指定图片的宽高属性
-}) {
-
- // 是否引入 katex
- const [katexLoaded, setKatexLoaded] = useState(Boolean(window.katex))
- const [quill, setQuill] = useState(null);
-
- const options = useDeepEqualMemo(passedOptions);
- console.log('use mount quill: ', passedOptions);
-
- // 判断options中是否包含公式
- const requireKatex = useMemo(() => {
- return flatten(options.modules.toolbar).includes('formula');
- }, [options]);
-
- // 加载katex
- useEffect(() => {
- if (!requireKatex) return;
- if (katexLoaded) return;
-
- const interval = setInterval(() => {
- if (window.katex) {
- setKatexLoaded(true);
- clearInterval(interval);
- }
- });
-
- return () => { // 定义回调清除定时器
- clearInterval(interval);
- }
-
- }, [
- setKatexLoaded,
- katexLoaded,
- requireKatex
- ]);
-
- // 加载 quill
- useEffect(() => {
- if (!element) return;
- if (requireKatex && !katexLoaded) {
- element.innerHTML = `
-
- Loading Katex...
-
- `
- }
- // 清空内容
- element.innerHTML = '';
- console.log(element);
- // 创建 quill 节点
- const quillNode = document.createElement('div');
- element.appendChild(quillNode); // 将quill节点追回到 element 元素中
-
- const quill = new Quill(element, options);
- setQuill(quill);
- // 加载上传图片功能
- if (typeof uploadImage === 'function') {
- quill.getModule('toolbar').addHandler('image', (e) => {
- // 创建type类型输入框加载本地图片
- const input = document.createElement('input');
- input.setAttribute('type', 'file');
- input.setAttribute('accept', 'image/*');
- input.click();
-
- input.onchange = async (e) => {
- const file = input.files[0]; // 获取文件信息
- const formData = new FormData();
- formData.append('file', file);
-
- // const reader = new FileReader();
- // reader.readAsDataURL(file);
- // console.log('文件信息===>>', reader);
- // reader.onload = function (e) {
- // debugger;
- // console.log('文件信息===>>', e.target.result);
- // const image = new Image();
- // image.src = e.target.result;
-
- // image.onload = function () {
- // // file.width =
- // console.log(image.width, image.height);
- // }
- // }
-
- const range = quill.getSelection(true);
- let fileUrl = ''; // 保存上传成功后图片的url
- // 上传文件
- const result = await fetchUploadImage(formData);
- // 获取上传图片的url
- if (result.data && result.data.id) {
- fileUrl = getImageUrl(`api/attachments/${result.data.id}`);
- }
- // 根据id获取文件路径
- const { width, height } = imgAttrs;
- // console.log('上传图片的url:', fileUrl);
- if (fileUrl) {
- quill.insertEmbed(range.index, 'image', {
- url: fileUrl,
- alt: '',
- onClick: showUploadImage,
- width,
- height
- });
- }
- }
- });
- }
-
- return () => {
- element.innerHTML = '';
- }
- }, [
- element,
- options,
- requireKatex,
- katexLoaded,
- ]);
-
- return quill;
-}
-
-export default useMountQuill;
diff --git a/public/react/src/common/reactQuill/useQuill.js b/public/react/src/common/reactQuill/useQuill.js
deleted file mode 100644
index b959dbc52..000000000
--- a/public/react/src/common/reactQuill/useQuill.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * @Description:
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-09 09:09:50
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-17 15:46:50
- */
-import useQuillPlaceholder from './useQuillPlaceholder';
-import useQuillValueSync from './useQuillValueSync';
-import useQuillOnChange from './useQuillOnChange';
-import useMountQuill from './useMountQuill';
-import { useEffect } from 'react';
-
-function useQuill ({
- disallowColors,
- placeholder,
- uploadImage,
- onChange,
- options,
- value,
- element,
- showUploadImage
-}) {
-
- // 获取 quill 实例
- const quill = useMountQuill({
- element,
- options,
- uploadImage,
- showUploadImage
- });
-
- useEffect(() => {
- if (disallowColors && quill) {
- quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
- delta.ops = delta.ops.map(op => {
- if (op.attributes && op.attributes.color) {
- const { color, ...attributes } = op.attributes;
- return {
- ...op,
- attributes
- }
- }
- return op;
- });
- return delta;
- });
- }
- }, [
- disallowColors,
- quill
- ]);
-
- useQuillPlaceholder(quill, placeholder);
- useQuillValueSync(quill, value);
- useQuillOnChange(quill, onChange);
-}
-
-export default useQuill;
diff --git a/public/react/src/common/reactQuill/useQuillOnChange.js b/public/react/src/common/reactQuill/useQuillOnChange.js
deleted file mode 100644
index 45333a4e1..000000000
--- a/public/react/src/common/reactQuill/useQuillOnChange.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * @Description:
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-12 19:49:11
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-16 11:39:27
- */
-import { useEffect } from 'react';
-
-function useQuillOnChange (quill, onChange) {
-
- useEffect(() => {
-
- if (!quill) return;
- if (typeof onChange !== 'function') return;
-
- let handler;
-
- quill.on(
- 'text-change',
- (handler = () => {
- onChange(quill.getContents()); // getContents: 检索编辑器内容
- })
- );
-
- return () => {
- quill.off('text-change', handler);
- }
- }, [quill, onChange]);
-}
-
-export default useQuillOnChange;
diff --git a/public/react/src/common/reactQuill/useQuillPlaceholder.js b/public/react/src/common/reactQuill/useQuillPlaceholder.js
deleted file mode 100644
index ccc341568..000000000
--- a/public/react/src/common/reactQuill/useQuillPlaceholder.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * @Description:
- * @Author: tangjiang
- * @Github:
- * @Date: 2019-12-09 09:28:34
- * @LastEditors: tangjiang
- * @LastEditTime: 2019-12-16 11:39:48
- */
-import { useEffect } from 'react'
-
-function useQuillPlaceholder (
- quill,
- placeholder
-) {
-
- useEffect(() => {
- if (!quill || !quill.root) return;
- quill.root.dataset.placeholder = placeholder;
- }, [quill, placeholder]);
-}
-
-export default useQuillPlaceholder;
diff --git a/public/react/src/common/reactQuill/useQuillValueSync.js b/public/react/src/common/reactQuill/useQuillValueSync.js
deleted file mode 100644
index 696d88949..000000000
--- a/public/react/src/common/reactQuill/useQuillValueSync.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useEffect, useState } from 'react'
-import deepEqual from './deepEqual.js'
-
-function useQuillValueSync(quill, value) {
- const [selection, setSelection] = useState(null)
-
- useEffect(() => {
- if (!quill) return
-
- const previous = quill.getContents()
- const current = value
-
- if (!deepEqual(previous, current)) {
- setSelection(quill.getSelection())
- if (typeof value === 'string') {
- quill.clipboard.dangerouslyPasteHTML(value, 'api')
- } else {
- quill.setContents(value)
- }
- }
- }, [quill, value, setSelection])
-
- useEffect(() => {
- if (quill && selection) {
- quill.setSelection(selection)
- setSelection(null)
- }
- }, [quill, selection, setSelection])
-}
-
-export default useQuillValueSync
diff --git a/public/react/src/modules/developer/studentStudy/rightpane/index.js b/public/react/src/modules/developer/studentStudy/rightpane/index.js
index 628524063..a90e8e348 100644
--- a/public/react/src/modules/developer/studentStudy/rightpane/index.js
+++ b/public/react/src/modules/developer/studentStudy/rightpane/index.js
@@ -50,7 +50,6 @@ const RightPane = (props) => {
let timer = null; // 定时器
// 代码块内容变化时
const handleCodeChange = (value) => {
- // console.log('编辑器代码 ======》》》》》》》》》++++++++++', value);
saveUserInputCode(value);
// setEditorCode(value);
if (!timer) {
diff --git a/public/react/src/redux/actions/ojForUser.js b/public/react/src/redux/actions/ojForUser.js
index b53498e42..32ff2aee5 100644
--- a/public/react/src/redux/actions/ojForUser.js
+++ b/public/react/src/redux/actions/ojForUser.js
@@ -133,33 +133,29 @@ export const saveUserCodeForInterval = (identifier, code) => {
* @param {*} inputValue 输入值: 自定义 | 系统返回的
* @param {*} type 测评类型 debug | submit
*/
-//原来的方法未能区分从编辑入口进来的情况,这时代码也是更新了的。
+//原来的方法未能区分从编辑入口进来的情况,这时代码也是更新了的。以及ctrl+z undo未能触发chnage事件 monaco-editor的bug。 这里去除isUpdateCode
export const updateCode = (identifier, inputValue, type) => {
return (dispatch, getState) => {
- const { editor_code, isUpdateCode } = getState().ojForUserReducer;
- if (isUpdateCode) {
- fetchUpdateCode(identifier, {
- code: Base64.encode(editor_code)
- }).then(res => {
- if (res) {
- if (res.data.status === 401) {
- dispatch({ // 改变 loading 值
- type: types.LOADING_STATUS,
- payload: false
- });
- return;
- };
- dispatch({
- type: types.IS_UPDATE_CODE,
- flag: false
+ const { editor_code } = getState().ojForUserReducer;
+ fetchUpdateCode(identifier, {
+ code: Base64.encode(editor_code)
+ }).then(res => {
+ if (res) {
+ if (res.data.status === 401) {
+ dispatch({ // 改变 loading 值
+ type: types.LOADING_STATUS,
+ payload: false
});
- dispatch(debuggerCode(identifier, inputValue, type));
- }
- });
- } else {
- // 没有更新时,直接调用调试接口
- dispatch(debuggerCode(identifier, inputValue, type));
- }
+ return;
+ };
+ dispatch({
+ type: types.IS_UPDATE_CODE,
+ flag: false
+ });
+ dispatch(debuggerCode(identifier, inputValue, type));
+ }
+ });
+
}
}
@@ -370,14 +366,6 @@ export const saveUserInputCode = (code) => {
}
}
-// 监听是否更新代码块内容
-// export const isUpdateCodeCtx = (flag) => {
-// return {
-// type: types.IS_UPDATE_CODE,
-// payload: flag
-// };
-// }
-
// 改变学员测评 tab 值
export const changeUserCodeTab = (key) => {
return {
@@ -392,7 +380,7 @@ export const changeUserCodeTab = (key) => {
*/
export const submitUserCode = (identifier, inputValue, type) => {
return (dispatch, getState) => {
- const { editor_code, isUpdateCode, hack } = getState().ojForUserReducer;
+ const { editor_code, hack } = getState().ojForUserReducer;
function userCodeSubmit() {
fetchUserCodeSubmit(identifier).then(res => {
if (res.status === 200) {
@@ -413,32 +401,29 @@ export const submitUserCode = (identifier, inputValue, type) => {
});
});
}
- if (isUpdateCode) {
- fetchUpdateCode(identifier, {
- code: Base64.encode(editor_code)
- }).then(res => {
- // 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
- if (res.data.status === 401) {
- dispatch({
- type: types.SUBMIT_LOADING_STATUS,
- payload: false
- });
- return;
- };
- dispatch({
- type: types.IS_UPDATE_CODE,
- flag: false
- });
- userCodeSubmit();
- }).catch(() => {
+ fetchUpdateCode(identifier, {
+ code: Base64.encode(editor_code)
+ }).then(res => {
+ // 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
+ if (res.data.status === 401) {
dispatch({
type: types.SUBMIT_LOADING_STATUS,
payload: false
- })
+ });
+ return;
+ };
+ dispatch({
+ type: types.IS_UPDATE_CODE,
+ flag: false
});
- } else {
userCodeSubmit();
- }
+ }).catch(() => {
+ dispatch({
+ type: types.SUBMIT_LOADING_STATUS,
+ payload: false
+ })
+ });
+
}
}