forked from Gitlink/forgeplus-react
style
This commit is contained in:
parent
851afbc6c4
commit
e95ef11058
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -48,7 +48,7 @@ function buildToc(coll, k, level, ctx) {
|
|||
});
|
||||
ctx.push("</ul>")
|
||||
}
|
||||
ctx.push("</li>")
|
||||
ctx.push("</li>");
|
||||
k = buildToc(coll, k, level, ctx)
|
||||
return k
|
||||
}
|
||||
|
@ -157,7 +157,6 @@ renderer.heading = function (text, level, raw) {
|
|||
})
|
||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
silent: true,
|
||||
smartypants: true,
|
||||
|
|
|
@ -1,37 +1,44 @@
|
|||
import React, { useEffect, useRef, useMemo } from "react";
|
||||
import "katex/dist/katex.min.css";
|
||||
import { renderToString } from 'katex';
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from "../common/marked";
|
||||
import React, { useEffect, useRef, useMemo } from 'react'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
|
||||
import 'code-prettify'
|
||||
import dompurify from 'dompurify'
|
||||
|
||||
import { renderToString } from 'katex'
|
||||
|
||||
const preRegex = /<pre[^>]*>/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("<p>[TOC]</p>", 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 (<div ref={el} style={style} className={`${className ? className : ''} markdown-body`} dangerouslySetInnerHTML={{ __html: html }}></div>)
|
||||
return (
|
||||
<div
|
||||
ref={el}
|
||||
style={style}
|
||||
className={`${className ? className : ''} markdown-body`}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
></div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -212,7 +212,10 @@ class order extends Component {
|
|||
<Menu.Item
|
||||
key={item.id}
|
||||
onClick={(e) => this.getOption(e, id, item.name, toGet)}
|
||||
style={{textAlign:item.color ? "left" :"center"}}
|
||||
>
|
||||
{/* 标签前面的颜色tag */}
|
||||
{item.color && <span className="tagColor" style={{backgroundColor:`${item.color}`}}></span>}
|
||||
{item.name}
|
||||
</Menu.Item>
|
||||
);
|
||||
|
|
|
@ -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 = '您上次有已保存的数据,是否<a style="cursor: pointer;" class="link-color-blue" onclick="md_rec_data(\'content\',\'' + mdu + '\',\'' + id + '\')">恢复</a> ? / <a style="cursor: pointer;" class="link-color-blue" onclick="md_clear_data(\'content\',\'' + mdu + '\',\'' + id + '\')">不恢复</a>';
|
||||
$("#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
|
|||
</div>
|
||||
{showResizeBar ? <a ref={resizeBarEl} className='editor-resize'></a> : null}
|
||||
<div className={"fr rememberTip"}>
|
||||
{noStorage == true ? null : <div id={tipId} className="edu-txt-right color-grey-cd font-12"></div>}
|
||||
{noStorage === true ? null : <div id={tipId} className="edu-txt-right color-grey-cd font-12"></div>}
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue