diff --git a/package-lock.json b/package-lock.json
index 55cb63549..4aa513cec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4962,6 +4962,11 @@
"domelementtype": "1"
}
},
+ "dompurify": {
+ "version": "2.0.15",
+ "resolved": "https://registry.npm.taobao.org/dompurify/download/dompurify-2.0.15.tgz?cache=0&sync_timestamp=1607352578938&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdompurify%2Fdownload%2Fdompurify-2.0.15.tgz",
+ "integrity": "sha1-gOMA/D6JVHvQrxr/LrqIzhf8neo="
+ },
"domutils": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
diff --git a/package.json b/package.json
index 42d6722cf..0ce7bac13 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"codemirror": "^5.53.0",
"connected-react-router": "4.4.1",
"css-loader": "^3.5.2",
+ "dompurify": "^2.0.15",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"echarts": "^4.7.0",
diff --git a/src/common/marked.js b/src/common/marked.js
index f81f7b13e..3be3ba2b3 100644
--- a/src/common/marked.js
+++ b/src/common/marked.js
@@ -48,7 +48,7 @@ function buildToc(coll, k, level, ctx) {
});
ctx.push("")
}
- ctx.push("")
+ ctx.push("");
k = buildToc(coll, k, level, ctx)
return k
}
@@ -157,7 +157,6 @@ renderer.heading = function (text, level, raw) {
})
return '
]*>/g
-
function _unescape(str) {
let div = document.createElement('div')
div.innerHTML = str
- return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue;
+ return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue
}
-export default ({ value = '', className, style = {} }) => {
+
+export default ({
+ value = '',
+ className,
+ style = {},
+}) => {
let str = String(value)
const html = useMemo(() => {
let rs = marked(str)
- const math_expressions = getMathExpressions()
+ const math_expressions = getMathExpressions();
if (str.match(/\[TOC\]/)) {
rs = rs.replace("[TOC]
", getTocContent())
cleanToc()
}
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
const { type, expression } = math_expressions[capture]
- return renderToString(_unescape(expression), { displayMode: type === 'block', throwOnError: false, output: 'html' })
+ return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
})
rs = rs.replace(/▁/g, "▁▁▁")
resetMathExpressions()
- return rs
+ return dompurify.sanitize(rs)
+
}, [str])
- const el = useRef()
+ const el = useRef();
function onAncherHandler(e) {
let target = e.target
if (target.tagName.toUpperCase() === 'A') {
@@ -40,7 +47,7 @@ export default ({ value = '', className, style = {} }) => {
e.preventDefault()
let viewEl = document.getElementById(ancher.replace('#', ''))
if (viewEl) {
- viewEl.parentNode.scrollTop = viewEl.offsetTop
+ viewEl.scrollIntoView(true)
}
}
}
@@ -61,6 +68,12 @@ export default ({ value = '', className, style = {} }) => {
}
}
}, [html, el.current, onAncherHandler])
-
- return ()
+ return (
+
+ )
}
diff --git a/src/forge/Order/order.js b/src/forge/Order/order.js
index 412d74900..beadca85c 100644
--- a/src/forge/Order/order.js
+++ b/src/forge/Order/order.js
@@ -212,7 +212,10 @@ class order extends Component {
this.getOption(e, id, item.name, toGet)}
+ style={{textAlign:item.color ? "left" :"center"}}
>
+ {/* 标签前面的颜色tag */}
+ {item.color && }
{item.name}
);
diff --git a/src/modules/tpm/challengesnew/tpm-md-editor.js b/src/modules/tpm/challengesnew/tpm-md-editor.js
index 0fa0e1fdf..014e19423 100644
--- a/src/modules/tpm/challengesnew/tpm-md-editor.js
+++ b/src/modules/tpm/challengesnew/tpm-md-editor.js
@@ -1,16 +1,16 @@
-import React, { Fragment, useEffect, useRef, useState } from 'react'
-import { getUploadActionUrl, getUrl } from 'educoder'
+import React, { Fragment, useEffect, useRef, useState } from 'react';
+import { getUploadActionUrl, getUrl } from 'educoder';
import ResizeObserver from 'resize-observer-polyfill';
-import '../../courses/css/Courses.css'
-import './css/TPMchallengesnew.css'
-import 'codemirror/lib/codemirror.css'
+import '../../courses/css/Courses.css';
+import './css/TPMchallengesnew.css';
+import 'codemirror/lib/codemirror.css';
const $ = window.$
-const mdIcons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "inline-latex", "latex", '|', "image", "table", '|', "line-break", "watch", "clear"]
+const mdIcons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "inline-latex", "latex", '|', "image", "table", '|', "line-break", "watch", "clear"];
-const NULL_CH = '▁'
+const NULL_CH = '▁';
function md_add_data(k, mdu, d) {
window.sessionStorage.setItem(k + mdu, d);
@@ -42,7 +42,7 @@ window.md_rec_data = md_rec_data;
function md_elocalStorage(editor, mdu, id) {
let oc = window.sessionStorage.getItem('content' + mdu)
- if (oc !== null && oc != editor.getValue()) {
+ if (oc !== null && oc !== editor.getValue()) {
$("#e_tips_" + id).data('editor', editor);
let h = '您上次有已保存的数据,是否恢复 ? / 不恢复';
$("#e_tips_" + id).html(h)
@@ -56,15 +56,15 @@ function md_elocalStorage(editor, mdu, id) {
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
- if (editor.getValue().trim() != "") {
+ if (editor.getValue().trim() !== "") {
md_add_data("content", mdu, editor.getValue());
let id2 = "#e_tips_" + id;
- let textStart = " 数据已于 "
+ let textStart = " 数据已于 ";
let text = textStart + h + ':' + m + ':' + s + " 保存 ";
// 占位符
let oldHtml = $(id2).html();
- if (oldHtml && oldHtml != ' ' && oldHtml.startsWith(textStart) == false) {
+ if (oldHtml && oldHtml !== ' ' && oldHtml.startsWith(textStart) === false) {
$(id2).html(oldHtml.split(' (')[0] + ` (${text})`);
} else {
$(id2).html(text);
@@ -77,28 +77,28 @@ function md_elocalStorage(editor, mdu, id) {
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true }) => {
- const editorEl = useRef()
- const resizeBarEl = useRef()
- const [editorInstance, setEditorInstance] = useState()
- const containerId = `mdEditor_${mdID}`
- const editorBodyId = `mdEditors_${mdID}`
- const tipId = `e_tips_mdEditor_${mdID}`
+ const editorEl = useRef();
+ const resizeBarEl = useRef();
+ const [editorInstance, setEditorInstance] = useState();
+ const containerId = `mdEditor_${mdID}`;
+ const editorBodyId = `mdEditors_${mdID}`;
+ const tipId = `e_tips_mdEditor_${mdID}`;
function onLayout() {
- let ro
+ let ro;
if (editorEl.current) {
ro = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
- editorInstance.resize()
- editorInstance.cm.refresh()
- editorInstance.cm.focus()
+ editorInstance.resize();
+ editorInstance.cm.refresh();
+ editorInstance.cm.focus();
}
}
})
- ro.observe(editorEl.current)
+ ro.observe(editorEl.current);
}
- return ro
+ return ro;
}
useEffect(() => {
@@ -211,7 +211,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla
useEffect(() => {
if (editorInstance && initValue !== undefined) {
- if (initValue != null && initValue != editorInstance.getValue()) {
+ if (initValue !== null && initValue !== editorInstance.getValue()) {
editorInstance.setValue(initValue.toString())
}
}
@@ -265,7 +265,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla
{showResizeBar ? : null}
- {noStorage == true ? null : }
+ {noStorage === true ? null : }
)