forked from newthuhole/hole_thu_frontend
Merge branch 'master' of https://github.com/panda2134/webhole
Conflicts: src/Common.js
This commit is contained in:
5
package-lock.json
generated
5
package-lock.json
generated
@@ -5996,6 +5996,11 @@
|
||||
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
|
||||
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://r.cnpmjs.org/highlight.js/download/highlight.js-10.1.1.tgz",
|
||||
"integrity": "sha1-aRohSKjZIr8S5SopRWag2ZO5TFc="
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
"fix-orientation": "^1.1.0",
|
||||
"gh-pages": "^3.0.0",
|
||||
"highlight.js": "^10.1.1",
|
||||
"html-to-react": "^1.4.3",
|
||||
"load-script": "^1.0.0",
|
||||
"markdown-it": "^11.0.0",
|
||||
|
||||
@@ -99,3 +99,7 @@
|
||||
.icon-github:before {
|
||||
content: "\eab0";
|
||||
}
|
||||
|
||||
.icon-new-tab:before {
|
||||
content: "\ea7e";
|
||||
}
|
||||
@@ -31,4 +31,6 @@
|
||||
<glyph unicode="" glyph-name="back" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM669.256 642.744l-90.512 90.512-285.254-285.256 285.256-285.254 90.508 90.508-194.744 194.746z" />
|
||||
<glyph unicode="" glyph-name="order-rev" d="M704 448v-384h64v384h160l-192 192-192-192zM64 768h96v-64h-96v64zM192 768h96v-64h-96v64zM320 768h64v-96h-64v96zM64 544h64v-96h-64v96zM160 512h96v-64h-96v64zM288 512h96v-64h-96v64zM64 672h64v-96h-64v96zM320 640h64v-96h-64v96zM320 256v-192h-192v192h192zM384 320h-320v-320h320v320z" />
|
||||
<glyph unicode="" glyph-name="github" d="M512.008 947.358c-282.738 0-512.008-229.218-512.008-511.998 0-226.214 146.704-418.132 350.136-485.836 25.586-4.738 34.992 11.11 34.992 24.632 0 12.204-0.48 52.542-0.696 95.324-142.448-30.976-172.504 60.41-172.504 60.41-23.282 59.176-56.848 74.916-56.848 74.916-46.452 31.778 3.51 31.124 3.51 31.124 51.4-3.61 78.476-52.766 78.476-52.766 45.672-78.27 119.776-55.64 149.004-42.558 4.588 33.086 17.852 55.68 32.506 68.464-113.73 12.942-233.276 56.85-233.276 253.032 0 55.898 20.004 101.574 52.76 137.428-5.316 12.9-22.854 64.972 4.952 135.5 0 0 43.006 13.752 140.84-52.49 40.836 11.348 84.636 17.036 128.154 17.234 43.502-0.198 87.336-5.886 128.256-17.234 97.734 66.244 140.656 52.49 140.656 52.49 27.872-70.528 10.35-122.6 5.036-135.5 32.82-35.856 52.694-81.532 52.694-137.428 0-196.654-119.778-239.95-233.79-252.624 18.364-15.89 34.724-47.046 34.724-94.812 0-68.508-0.596-123.644-0.596-140.508 0-13.628 9.222-29.594 35.172-24.566 203.322 67.776 349.842 259.626 349.842 485.768 0 282.78-229.234 511.998-511.992 511.998z" />
|
||||
|
||||
<glyph unicode="" glyph-name="new-tab" d="M192 896v-768h768v768h-768zM896 192h-640v640h640v-640zM128 64v672l-64 64v-800h800l-64 64h-672zM352 704l160-160-192-192 96-96 192 192 160-160v416z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Binary file not shown.
Binary file not shown.
@@ -81,6 +81,17 @@ export class HighlightedMarkdown extends Component {
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
shouldProcessNode: (node) => node.name === 'a',
|
||||
processNode (node, children) {
|
||||
return (
|
||||
<a href={normalize_url(node.attribs.href)} target="_blank" rel="noopenner noreferrer" class="ext-link">
|
||||
{children}
|
||||
<span className="icon icon-new-tab" />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
shouldProcessNode (node) {
|
||||
return node.type === 'text' // pid, nickname, search
|
||||
@@ -100,7 +111,10 @@ export class HighlightedMarkdown extends Component {
|
||||
return (<span key={idx}>
|
||||
{
|
||||
rule==='url_pid' ? <span className="url-pid-link" title={p}>/##</span> :
|
||||
rule==='url' ? <a href={normalize_url(p)} target="_blank" rel="noopener">{p}</a> :
|
||||
rule==='url' ? <a href={normalize_url(p)} class="ext-link" target="_blank" rel="noopener noreferrer">
|
||||
{p}
|
||||
<span className="icon icon-new-tab" />
|
||||
</a> :
|
||||
rule==='pid' ? <a href={'#'+p} onClick={(e)=>{e.preventDefault(); props.show_pid(p.substring(1));}}>{p}</a> :
|
||||
rule==='nickname' ? <ColoredSpan colors={props.color_picker.get(p)}>{p}</ColoredSpan> :
|
||||
rule==='search' ? <span className="search-query-highlight">{p}</span> :
|
||||
@@ -116,13 +130,21 @@ export class HighlightedMarkdown extends Component {
|
||||
processNode: processDefs.processDefaultNode
|
||||
}
|
||||
]
|
||||
const renderedMarkdown = renderMd(this.props.text)
|
||||
const parser = new HtmlToReact.Parser()
|
||||
|
||||
let rtn = parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions)
|
||||
if(rtn === undefined)
|
||||
return null
|
||||
return rtn;
|
||||
if (props.author && props.text.match(/^(?:#+ |>|```|\t|\s*-|\s*\d+\.)/)) {
|
||||
const renderedMarkdown = renderMd(props.text)
|
||||
return (
|
||||
<>
|
||||
{props.author}
|
||||
{parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions) || ''}
|
||||
</>
|
||||
)
|
||||
} else {
|
||||
let rawMd = props.text
|
||||
if (props.author) rawMd = props.author + ' ' + rawMd
|
||||
const renderedMarkdown = renderMd(rawMd)
|
||||
return (parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions) || null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,4 +307,4 @@ export class ClickHandler extends PureComponent {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ class Reply extends PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const replyContent = (this.props.info.text)
|
||||
const splitIdx = replyContent.indexOf(']')
|
||||
|
||||
const author = replyContent.substr(0, splitIdx + 1),
|
||||
replyText = replyContent.substr(splitIdx + 2)
|
||||
return (
|
||||
<div className={'flow-reply box'} style={this.props.info._display_color ? {
|
||||
'--box-bgcolor-light': this.props.info._display_color[0],
|
||||
@@ -95,7 +100,8 @@ class Reply extends PureComponent {
|
||||
<Time stamp={this.props.info.timestamp} />
|
||||
</div>
|
||||
<div className="box-content">
|
||||
<HighlightedMarkdown text={this.props.info.text} color_picker={this.props.color_picker} show_pid={this.props.show_pid} />
|
||||
<HighlightedMarkdown author={author}
|
||||
text={replyText} color_picker={this.props.color_picker} show_pid={this.props.show_pid} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
3
src/Markdown.css
Normal file
3
src/Markdown.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.hljs {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@@ -1,12 +1,26 @@
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import MarkdownItKaTeX from 'markdown-it-katex'
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import './Markdown.css'
|
||||
|
||||
import 'katex/dist/katex.min.css'
|
||||
|
||||
let md = new MarkdownIt({
|
||||
html: false,
|
||||
linkify: false,
|
||||
breaks: true
|
||||
breaks: true,
|
||||
inline: true,
|
||||
highlight (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return '<pre class="hljs"><code>' +
|
||||
hljs.highlight(lang, str, true).value +
|
||||
'</code></pre>';
|
||||
} catch (__) {}
|
||||
}
|
||||
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
|
||||
}
|
||||
}).use(MarkdownItKaTeX, {
|
||||
"throwOnError" : false,
|
||||
"errorColor" : "#aa0000"
|
||||
|
||||
Reference in New Issue
Block a user