X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fvideos%2Fshared%2Fmarkdown.service.ts;h=14eeba77750c85acc5aa0091240dd1ee75ad7420;hb=53055a1124cbc2eaeeeeef21b19b0b46e96f23c5;hp=82745f0c68283ab2e7f7385091b4f22e1713f3c8;hpb=63c4b44961aa86ed4dabf039e495879103f9d729;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts index 82745f0c6..14eeba777 100644 --- a/client/src/app/videos/shared/markdown.service.ts +++ b/client/src/app/videos/shared/markdown.service.ts @@ -4,40 +4,73 @@ import * as MarkdownIt from 'markdown-it' @Injectable() export class MarkdownService { - private markdownIt: MarkdownIt.MarkdownIt + static TEXT_RULES = [ + 'linkify', + 'autolink', + 'emphasis', + 'link', + 'newline', + 'list' + ] + static ENHANCED_RULES = MarkdownService.TEXT_RULES.concat([ 'image' ]) + + private textMarkdownIt: MarkdownIt.MarkdownIt + private enhancedMarkdownIt: MarkdownIt.MarkdownIt constructor () { - this.markdownIt = new MarkdownIt('zero', { linkify: true }) - .enable('linkify') - .enable('autolink') - .enable('emphasis') - .enable('link') - .enable('newline') + this.textMarkdownIt = this.createMarkdownIt(MarkdownService.TEXT_RULES) + this.enhancedMarkdownIt = this.createMarkdownIt(MarkdownService.ENHANCED_RULES) + } + + textMarkdownToHTML (markdown: string) { + if (!markdown) return '' + + const html = this.textMarkdownIt.render(markdown) + return this.avoidTruncatedLinks(html) + } + + enhancedMarkdownToHTML (markdown: string) { + if (!markdown) return '' + + const html = this.enhancedMarkdownIt.render(markdown) + return this.avoidTruncatedLinks(html) + } + private createMarkdownIt (rules: string[]) { + const markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true }) + + for (let rule of rules) { + markdownIt.enable(rule) + } + + this.setTargetToLinks(markdownIt) + + return markdownIt + } + + private setTargetToLinks (markdownIt: MarkdownIt.MarkdownIt) { // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer - const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) { + const defaultRender = markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options) } - this.markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) { - // If you are sure other plugins can't add `target` - drop check below - const aIndex = tokens[idx].attrIndex('target') + markdownIt.renderer.rules.link_open = function (tokens, index, options, env, self) { + const token = tokens[index] - if (aIndex < 0) { - tokens[idx].attrPush(['target', '_blank']) // add new attribute - } else { - tokens[idx].attrs[aIndex][1] = '_blank' // replace value of existing attr - } + const targetIndex = token.attrIndex('target') + if (targetIndex < 0) token.attrPush([ 'target', '_blank' ]) + else token.attrs[targetIndex][1] = '_blank' + + const relIndex = token.attrIndex('rel') + if (relIndex < 0) token.attrPush([ 'rel', 'noopener noreferrer' ]) + else token.attrs[relIndex][1] = 'noopener noreferrer' // pass token to default renderer. - return defaultRender(tokens, idx, options, env, self) + return defaultRender(tokens, index, options, env, self) } } - markdownToHTML (markdown: string) { - const html = this.markdownIt.render(markdown) - - // Avoid linkify truncated links - return html.replace(/]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') + private avoidTruncatedLinks (html: string) { + return html.replace(/]+>([^<]+)<\/a>\s*...((<\/p>)|(<\/li>)|(<\/strong>))?$/mi, '$1...') } }