Add links support in comments
authorChocobozzz <me@florianbigard.com>
Tue, 20 Feb 2018 10:04:21 +0000 (11:04 +0100)
committerChocobozzz <me@florianbigard.com>
Tue, 20 Feb 2018 10:04:21 +0000 (11:04 +0100)
client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
client/src/app/videos/+video-watch/comment/video-comment.component.ts
client/src/app/videos/+video-watch/comment/video-comment.service.ts
client/src/app/videos/shared/markdown.service.ts

index 9e499d829b63d73b575f5a37173ada92d8ef9112..183cde0002e3df08a244ca6688d9a8f934cbefd7 100644 (file)
@@ -2,7 +2,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild }
 import { FormBuilder, FormGroup } from '@angular/forms'
 import { NotificationsService } from 'angular2-notifications'
 import { Observable } from 'rxjs/Observable'
-import { VideoCommentCreate, VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
+import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
 import { FormReactive } from '../../../shared'
 import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment'
 import { User } from '../../../shared/users'
index 9176de80f4a2e1e520001fbfb29c68388deeaa2f..0224132ac9b53cee3a5f449de3310aee9b3463bf 100644 (file)
@@ -1,4 +1,5 @@
 import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'
+import { MarkdownService } from '@app/videos/shared'
 import * as sanitizeHtml from 'sanitize-html'
 import { Account as AccountInterface } from '../../../../../../shared/models/actors'
 import { UserRight } from '../../../../../../shared/models/users'
@@ -29,7 +30,10 @@ export class VideoCommentComponent implements OnInit, OnChanges {
   sanitizedCommentHTML = ''
   newParentComments = []
 
-  constructor (private authService: AuthService) {}
+  constructor (
+    private authService: AuthService,
+    private markdownService: MarkdownService
+  ) {}
 
   get user () {
     return this.authService.getUser()
@@ -90,9 +94,13 @@ export class VideoCommentComponent implements OnInit, OnChanges {
 
   private init () {
     this.sanitizedCommentHTML = sanitizeHtml(this.comment.text, {
-      allowedTags: [ 'p', 'span', 'br' ]
+      allowedTags: [ 'a', 'p', 'span', 'br' ],
+      allowedSchemes: [ 'http', 'https' ]
     })
 
+    // Convert possible markdown to html
+    this.sanitizedCommentHTML = this.markdownService.linkify(this.comment.text)
+
     this.newParentComments = this.parentComments.concat([ this.comment ])
   }
 }
index 14d32b1aa6f1732e2e17a59230d385c1aab8800c..470af12305cc3604091b07e68caadf04bb589ece 100644 (file)
@@ -1,12 +1,14 @@
 import { HttpClient, HttpParams } from '@angular/common/http'
 import { Injectable } from '@angular/core'
+import { lineFeedToHtml } from '@app/shared/misc/utils'
+import { MarkdownService } from '@app/videos/shared'
 import 'rxjs/add/operator/catch'
 import 'rxjs/add/operator/map'
-import { immutableAssign, lineFeedToHtml } from '@app/shared/misc/utils'
 import { Observable } from 'rxjs/Observable'
 import { ResultList } from '../../../../../../shared/models'
 import {
-  VideoComment as VideoCommentServerModel, VideoCommentCreate,
+  VideoComment as VideoCommentServerModel,
+  VideoCommentCreate,
   VideoCommentThreadTree
 } from '../../../../../../shared/models/videos/video-comment.model'
 import { environment } from '../../../../environments/environment'
index 3f51a82ce28c3980de134f546d63b445c12ac2ef..a275446eba89aa0c2ee95b625f87f6c526d1b575 100644 (file)
@@ -5,6 +5,7 @@ import * as MarkdownIt from 'markdown-it'
 @Injectable()
 export class MarkdownService {
   private markdownIt: MarkdownIt.MarkdownIt
+  private linkifier: MarkdownIt.MarkdownIt
 
   constructor () {
     this.markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true })
@@ -14,8 +15,11 @@ export class MarkdownService {
       .enable('link')
       .enable('newline')
       .enable('list')
+    this.setTargetToLinks(this.markdownIt)
 
-    this.setTargetToLinks()
+    this.linkifier = new MarkdownIt('zero', { linkify: true })
+      .enable('linkify')
+    this.setTargetToLinks(this.linkifier)
   }
 
   markdownToHTML (markdown: string) {
@@ -25,13 +29,17 @@ export class MarkdownService {
     return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...')
   }
 
-  private setTargetToLinks () {
+  linkify (text: string) {
+    return this.linkifier.render(text)
+  }
+
+  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) {
+    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')