Browse Source

fix: external link indicator, highlight & reply headings

dev
Liu Jiangyi 5 years ago
parent
commit
949cd0d80c
  1. 5
      package-lock.json
  2. 1
      package.json
  3. 4
      public/static/fonts_7/icomoon.css
  4. 2
      public/static/fonts_7/icomoon.svg
  5. BIN
      public/static/fonts_7/icomoon.ttf
  6. BIN
      public/static/fonts_7/icomoon.woff
  7. 31
      src/Common.js
  8. 8
      src/Flows.js
  9. 3
      src/Markdown.css
  10. 16
      src/Markdown.js

5
package-lock.json generated

@ -6021,6 +6021,11 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" "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": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",

1
package.json

@ -6,6 +6,7 @@
"copy-to-clipboard": "^3.0.8", "copy-to-clipboard": "^3.0.8",
"fix-orientation": "^1.1.0", "fix-orientation": "^1.1.0",
"gh-pages": "^3.0.0", "gh-pages": "^3.0.0",
"highlight.js": "^10.1.1",
"html-to-react": "^1.4.3", "html-to-react": "^1.4.3",
"load-script": "^1.0.0", "load-script": "^1.0.0",
"markdown-it": "^11.0.0", "markdown-it": "^11.0.0",

4
public/static/fonts_7/icomoon.css

@ -99,3 +99,7 @@
.icon-github:before { .icon-github:before {
content: "\eab0"; content: "\eab0";
} }
.icon-new-tab:before {
content: "\ea7e";
}

2
public/static/fonts_7/icomoon.svg

@ -31,4 +31,6 @@
<glyph unicode="&#xea44;" 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="&#xea44;" 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="&#xea46;" 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="&#xea46;" 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="&#xeab0;" 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="&#xeab0;" 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="&#xea7e;" 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> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/static/fonts_7/icomoon.ttf

Binary file not shown.

BIN
public/static/fonts_7/icomoon.woff

Binary file not shown.

31
src/Common.js

@ -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) { shouldProcessNode (node) {
return node.type === 'text' // pid, nickname, search return node.type === 'text' // pid, nickname, search
@ -100,7 +111,10 @@ export class HighlightedMarkdown extends Component {
return (<span key={idx}> return (<span key={idx}>
{ {
rule==='url_pid' ? <span className="url-pid-link" title={p}>/##</span> : 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==='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==='nickname' ? <ColoredSpan colors={props.color_picker.get(p)}>{p}</ColoredSpan> :
rule==='search' ? <span className="search-query-highlight">{p}</span> : rule==='search' ? <span className="search-query-highlight">{p}</span> :
@ -116,10 +130,19 @@ export class HighlightedMarkdown extends Component {
processNode: processDefs.processDefaultNode processNode: processDefs.processDefaultNode
} }
] ]
const renderedMarkdown = renderMd(this.props.text)
const parser = new HtmlToReact.Parser() const parser = new HtmlToReact.Parser()
if (props.author && props.text.match(/^(?:#+ |>|```|\t|\s*-|\s*\d+\.)/)) {
return parser.parseWithInstructions(renderedMarkdown, node => node.type !== 'script', processInstructions) 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)
}
} }
} }

8
src/Flows.js

@ -74,6 +74,11 @@ class Reply extends PureComponent {
} }
render() { render() {
const replyContent = (this.props.info.text)
const splitIdx = replyContent.indexOf(']')
const author = replyContent.substr(0, splitIdx + 1),
replyText = replyContent.substr(splitIdx + 2)
return ( return (
<div className={'flow-reply box'} style={this.props.info._display_color ? { <div className={'flow-reply box'} style={this.props.info._display_color ? {
'--box-bgcolor-light': this.props.info._display_color[0], '--box-bgcolor-light': this.props.info._display_color[0],
@ -95,7 +100,8 @@ class Reply extends PureComponent {
<Time stamp={this.props.info.timestamp} /> <Time stamp={this.props.info.timestamp} />
</div> </div>
<div className="box-content"> <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>
</div> </div>
); );

3
src/Markdown.css

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

16
src/Markdown.js

@ -1,12 +1,26 @@
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import MarkdownItKaTeX from 'markdown-it-katex' 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' import 'katex/dist/katex.min.css'
let md = new MarkdownIt({ let md = new MarkdownIt({
html: false, html: false,
linkify: 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, { }).use(MarkdownItKaTeX, {
"throwOnError" : false, "throwOnError" : false,
"errorColor" : "#aa0000" "errorColor" : "#aa0000"

Loading…
Cancel
Save