fix: external link indicator, highlight & reply headings

This commit is contained in:
Liu Jiangyi
2020-06-22 22:49:38 +08:00
parent 55473e3327
commit 949cd0d80c
10 changed files with 64 additions and 6 deletions

View File

@@ -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,10 +130,19 @@ export class HighlightedMarkdown extends Component {
processNode: processDefs.processDefaultNode
}
]
const renderedMarkdown = renderMd(this.props.text)
const parser = new HtmlToReact.Parser()
return parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions)
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 {
const renderedMarkdown = renderMd((props.author || '') + props.text)
return parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions)
}
}
}

View File

@@ -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
View File

@@ -0,0 +1,3 @@
.hljs {
white-space: pre-wrap;
}

View File

@@ -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"