diff options
author | Chocobozzz <me@florianbigard.com> | 2018-02-20 11:04:21 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-02-20 11:04:21 +0100 |
commit | 3d9eaae318670986fedab257b8be344c9b43d8d5 (patch) | |
tree | 6aaa8ff8d5fd7d162e05147eb02f3175ab8c933c /client/src/app/videos | |
parent | 5de8a55abce53108bc1024f1194457c6528bd11e (diff) | |
download | PeerTube-3d9eaae318670986fedab257b8be344c9b43d8d5.tar.gz PeerTube-3d9eaae318670986fedab257b8be344c9b43d8d5.tar.zst PeerTube-3d9eaae318670986fedab257b8be344c9b43d8d5.zip |
Add links support in comments
Diffstat (limited to 'client/src/app/videos')
4 files changed, 27 insertions, 9 deletions
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts index 9e499d829..183cde000 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts | |||
@@ -2,7 +2,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } | |||
2 | import { FormBuilder, FormGroup } from '@angular/forms' | 2 | import { FormBuilder, FormGroup } from '@angular/forms' |
3 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
4 | import { Observable } from 'rxjs/Observable' | 4 | import { Observable } from 'rxjs/Observable' |
5 | import { VideoCommentCreate, VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' | 5 | import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' |
6 | import { FormReactive } from '../../../shared' | 6 | import { FormReactive } from '../../../shared' |
7 | import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment' | 7 | import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment' |
8 | import { User } from '../../../shared/users' | 8 | import { User } from '../../../shared/users' |
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.ts b/client/src/app/videos/+video-watch/comment/video-comment.component.ts index 9176de80f..0224132ac 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' | 1 | import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' |
2 | import { MarkdownService } from '@app/videos/shared' | ||
2 | import * as sanitizeHtml from 'sanitize-html' | 3 | import * as sanitizeHtml from 'sanitize-html' |
3 | import { Account as AccountInterface } from '../../../../../../shared/models/actors' | 4 | import { Account as AccountInterface } from '../../../../../../shared/models/actors' |
4 | import { UserRight } from '../../../../../../shared/models/users' | 5 | import { UserRight } from '../../../../../../shared/models/users' |
@@ -29,7 +30,10 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
29 | sanitizedCommentHTML = '' | 30 | sanitizedCommentHTML = '' |
30 | newParentComments = [] | 31 | newParentComments = [] |
31 | 32 | ||
32 | constructor (private authService: AuthService) {} | 33 | constructor ( |
34 | private authService: AuthService, | ||
35 | private markdownService: MarkdownService | ||
36 | ) {} | ||
33 | 37 | ||
34 | get user () { | 38 | get user () { |
35 | return this.authService.getUser() | 39 | return this.authService.getUser() |
@@ -90,9 +94,13 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
90 | 94 | ||
91 | private init () { | 95 | private init () { |
92 | this.sanitizedCommentHTML = sanitizeHtml(this.comment.text, { | 96 | this.sanitizedCommentHTML = sanitizeHtml(this.comment.text, { |
93 | allowedTags: [ 'p', 'span', 'br' ] | 97 | allowedTags: [ 'a', 'p', 'span', 'br' ], |
98 | allowedSchemes: [ 'http', 'https' ] | ||
94 | }) | 99 | }) |
95 | 100 | ||
101 | // Convert possible markdown to html | ||
102 | this.sanitizedCommentHTML = this.markdownService.linkify(this.comment.text) | ||
103 | |||
96 | this.newParentComments = this.parentComments.concat([ this.comment ]) | 104 | this.newParentComments = this.parentComments.concat([ this.comment ]) |
97 | } | 105 | } |
98 | } | 106 | } |
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.service.ts b/client/src/app/videos/+video-watch/comment/video-comment.service.ts index 14d32b1aa..470af1230 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.service.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.service.ts | |||
@@ -1,12 +1,14 @@ | |||
1 | import { HttpClient, HttpParams } from '@angular/common/http' | 1 | import { HttpClient, HttpParams } from '@angular/common/http' |
2 | import { Injectable } from '@angular/core' | 2 | import { Injectable } from '@angular/core' |
3 | import { lineFeedToHtml } from '@app/shared/misc/utils' | ||
4 | import { MarkdownService } from '@app/videos/shared' | ||
3 | import 'rxjs/add/operator/catch' | 5 | import 'rxjs/add/operator/catch' |
4 | import 'rxjs/add/operator/map' | 6 | import 'rxjs/add/operator/map' |
5 | import { immutableAssign, lineFeedToHtml } from '@app/shared/misc/utils' | ||
6 | import { Observable } from 'rxjs/Observable' | 7 | import { Observable } from 'rxjs/Observable' |
7 | import { ResultList } from '../../../../../../shared/models' | 8 | import { ResultList } from '../../../../../../shared/models' |
8 | import { | 9 | import { |
9 | VideoComment as VideoCommentServerModel, VideoCommentCreate, | 10 | VideoComment as VideoCommentServerModel, |
11 | VideoCommentCreate, | ||
10 | VideoCommentThreadTree | 12 | VideoCommentThreadTree |
11 | } from '../../../../../../shared/models/videos/video-comment.model' | 13 | } from '../../../../../../shared/models/videos/video-comment.model' |
12 | import { environment } from '../../../../environments/environment' | 14 | import { environment } from '../../../../environments/environment' |
diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/videos/shared/markdown.service.ts index 3f51a82ce..a275446eb 100644 --- a/client/src/app/videos/shared/markdown.service.ts +++ b/client/src/app/videos/shared/markdown.service.ts | |||
@@ -5,6 +5,7 @@ import * as MarkdownIt from 'markdown-it' | |||
5 | @Injectable() | 5 | @Injectable() |
6 | export class MarkdownService { | 6 | export class MarkdownService { |
7 | private markdownIt: MarkdownIt.MarkdownIt | 7 | private markdownIt: MarkdownIt.MarkdownIt |
8 | private linkifier: MarkdownIt.MarkdownIt | ||
8 | 9 | ||
9 | constructor () { | 10 | constructor () { |
10 | this.markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true }) | 11 | this.markdownIt = new MarkdownIt('zero', { linkify: true, breaks: true }) |
@@ -14,8 +15,11 @@ export class MarkdownService { | |||
14 | .enable('link') | 15 | .enable('link') |
15 | .enable('newline') | 16 | .enable('newline') |
16 | .enable('list') | 17 | .enable('list') |
18 | this.setTargetToLinks(this.markdownIt) | ||
17 | 19 | ||
18 | this.setTargetToLinks() | 20 | this.linkifier = new MarkdownIt('zero', { linkify: true }) |
21 | .enable('linkify') | ||
22 | this.setTargetToLinks(this.linkifier) | ||
19 | } | 23 | } |
20 | 24 | ||
21 | markdownToHTML (markdown: string) { | 25 | markdownToHTML (markdown: string) { |
@@ -25,13 +29,17 @@ export class MarkdownService { | |||
25 | return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') | 29 | return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...') |
26 | } | 30 | } |
27 | 31 | ||
28 | private setTargetToLinks () { | 32 | linkify (text: string) { |
33 | return this.linkifier.render(text) | ||
34 | } | ||
35 | |||
36 | private setTargetToLinks (markdownIt: MarkdownIt.MarkdownIt) { | ||
29 | // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer | 37 | // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer |
30 | const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) { | 38 | const defaultRender = markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) { |
31 | return self.renderToken(tokens, idx, options) | 39 | return self.renderToken(tokens, idx, options) |
32 | } | 40 | } |
33 | 41 | ||
34 | this.markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) { | 42 | markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) { |
35 | // If you are sure other plugins can't add `target` - drop check below | 43 | // If you are sure other plugins can't add `target` - drop check below |
36 | const aIndex = tokens[idx].attrIndex('target') | 44 | const aIndex = tokens[idx].attrIndex('target') |
37 | 45 | ||