render markdown and plainify descriptions on previews
This commit is contained in:
parent
13fec08ba3
commit
84bced652c
|
@ -0,0 +1,26 @@
|
||||||
|
import { SANITIZE_OPTIONS, TEXT_WITH_HTML_RULES } from '@shared/core-utils'
|
||||||
|
|
||||||
|
const sanitizeHtml = require('sanitize-html')
|
||||||
|
const markdownItEmoji = require('markdown-it-emoji/light')
|
||||||
|
const MarkdownItClass = require('markdown-it')
|
||||||
|
const markdownIt = new MarkdownItClass('default', { linkify: true, breaks: true, html: true })
|
||||||
|
|
||||||
|
markdownIt.enable(TEXT_WITH_HTML_RULES)
|
||||||
|
markdownIt.use(markdownItEmoji)
|
||||||
|
|
||||||
|
const toSafeHtml = text => {
|
||||||
|
// Restore line feed
|
||||||
|
const textWithLineFeed = text.replace(/<br.?\/?>/g, '\r\n')
|
||||||
|
|
||||||
|
// Convert possible markdown (emojis, emphasis and lists) to html
|
||||||
|
const html = markdownIt.render(textWithLineFeed)
|
||||||
|
|
||||||
|
// Convert to safe Html
|
||||||
|
return sanitizeHtml(html, SANITIZE_OPTIONS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export {
|
||||||
|
toSafeHtml
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import { VideoChannelModel } from '../models/video/video-channel'
|
||||||
import { getActivityStreamDuration } from '../models/video/video-format-utils'
|
import { getActivityStreamDuration } from '../models/video/video-format-utils'
|
||||||
import { VideoPlaylistModel } from '../models/video/video-playlist'
|
import { VideoPlaylistModel } from '../models/video/video-playlist'
|
||||||
import { MAccountActor, MChannelActor } from '../types/models'
|
import { MAccountActor, MChannelActor } from '../types/models'
|
||||||
|
import { toSafeHtml } from '../helpers/markdown'
|
||||||
|
|
||||||
type Tags = {
|
type Tags = {
|
||||||
ogType: string
|
ogType: string
|
||||||
|
@ -54,6 +55,10 @@ type Tags = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toPlainText = (content: string) => {
|
||||||
|
return toSafeHtml(content).replace(/<[^>]+>/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
class ClientHtml {
|
class ClientHtml {
|
||||||
|
|
||||||
private static htmlCache: { [path: string]: string } = {}
|
private static htmlCache: { [path: string]: string } = {}
|
||||||
|
@ -94,13 +99,13 @@ class ClientHtml {
|
||||||
}
|
}
|
||||||
|
|
||||||
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(video.name))
|
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(video.name))
|
||||||
customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(video.description))
|
customHtml = ClientHtml.addDescriptionTag(customHtml, toPlainText(video.description))
|
||||||
|
|
||||||
const url = WEBSERVER.URL + video.getWatchStaticPath()
|
const url = WEBSERVER.URL + video.getWatchStaticPath()
|
||||||
const originUrl = video.url
|
const originUrl = video.url
|
||||||
const title = escapeHTML(video.name)
|
const title = escapeHTML(video.name)
|
||||||
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
||||||
const description = escapeHTML(video.description)
|
const description = toPlainText(video.description)
|
||||||
|
|
||||||
const image = {
|
const image = {
|
||||||
url: WEBSERVER.URL + video.getPreviewStaticPath()
|
url: WEBSERVER.URL + video.getPreviewStaticPath()
|
||||||
|
@ -152,13 +157,13 @@ class ClientHtml {
|
||||||
}
|
}
|
||||||
|
|
||||||
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(videoPlaylist.name))
|
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(videoPlaylist.name))
|
||||||
customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(videoPlaylist.description))
|
customHtml = ClientHtml.addDescriptionTag(customHtml, toPlainText(videoPlaylist.description))
|
||||||
|
|
||||||
const url = videoPlaylist.getWatchUrl()
|
const url = videoPlaylist.getWatchUrl()
|
||||||
const originUrl = videoPlaylist.url
|
const originUrl = videoPlaylist.url
|
||||||
const title = escapeHTML(videoPlaylist.name)
|
const title = escapeHTML(videoPlaylist.name)
|
||||||
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
||||||
const description = escapeHTML(videoPlaylist.description)
|
const description = toPlainText(videoPlaylist.description)
|
||||||
|
|
||||||
const image = {
|
const image = {
|
||||||
url: videoPlaylist.getThumbnailUrl()
|
url: videoPlaylist.getThumbnailUrl()
|
||||||
|
@ -236,13 +241,13 @@ class ClientHtml {
|
||||||
}
|
}
|
||||||
|
|
||||||
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(entity.getDisplayName()))
|
let customHtml = ClientHtml.addTitleTag(html, escapeHTML(entity.getDisplayName()))
|
||||||
customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(entity.description))
|
customHtml = ClientHtml.addDescriptionTag(customHtml, toPlainText(entity.description))
|
||||||
|
|
||||||
const url = entity.getLocalUrl()
|
const url = entity.getLocalUrl()
|
||||||
const originUrl = entity.Actor.url
|
const originUrl = entity.Actor.url
|
||||||
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
const siteName = escapeHTML(CONFIG.INSTANCE.NAME)
|
||||||
const title = escapeHTML(entity.getDisplayName())
|
const title = escapeHTML(entity.getDisplayName())
|
||||||
const description = escapeHTML(entity.description)
|
const description = toPlainText(entity.description)
|
||||||
|
|
||||||
const image = {
|
const image = {
|
||||||
url: entity.Actor.getAvatarUrl(),
|
url: entity.Actor.getAvatarUrl(),
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { join } from 'path'
|
||||||
import { VideoChannelModel } from '@server/models/video/video-channel'
|
import { VideoChannelModel } from '@server/models/video/video-channel'
|
||||||
import { MVideoBlacklistLightVideo, MVideoBlacklistVideo } from '@server/types/models/video/video-blacklist'
|
import { MVideoBlacklistLightVideo, MVideoBlacklistVideo } from '@server/types/models/video/video-blacklist'
|
||||||
import { MVideoImport, MVideoImportVideo } from '@server/types/models/video/video-import'
|
import { MVideoImport, MVideoImportVideo } from '@server/types/models/video/video-import'
|
||||||
import { SANITIZE_OPTIONS, TEXT_WITH_HTML_RULES } from '@shared/core-utils'
|
|
||||||
import { AbuseState, EmailPayload, UserAbuse } from '@shared/models'
|
import { AbuseState, EmailPayload, UserAbuse } from '@shared/models'
|
||||||
import { SendEmailDefaultOptions } from '../../shared/models/server/emailer.model'
|
import { SendEmailDefaultOptions } from '../../shared/models/server/emailer.model'
|
||||||
import { isTestInstance, root } from '../helpers/core-utils'
|
import { isTestInstance, root } from '../helpers/core-utils'
|
||||||
|
@ -15,26 +14,7 @@ import { WEBSERVER } from '../initializers/constants'
|
||||||
import { MAbuseFull, MAbuseMessage, MAccountDefault, MActorFollowActors, MActorFollowFull, MPlugin, MUser } from '../types/models'
|
import { MAbuseFull, MAbuseMessage, MAccountDefault, MActorFollowActors, MActorFollowFull, MPlugin, MUser } from '../types/models'
|
||||||
import { MCommentOwnerVideo, MVideo, MVideoAccountLight } from '../types/models/video'
|
import { MCommentOwnerVideo, MVideo, MVideoAccountLight } from '../types/models/video'
|
||||||
import { JobQueue } from './job-queue'
|
import { JobQueue } from './job-queue'
|
||||||
|
import { toSafeHtml } from '../helpers/markdown'
|
||||||
const sanitizeHtml = require('sanitize-html')
|
|
||||||
const markdownItEmoji = require('markdown-it-emoji/light')
|
|
||||||
const MarkdownItClass = require('markdown-it')
|
|
||||||
const markdownIt = new MarkdownItClass('default', { linkify: true, breaks: true, html: true })
|
|
||||||
|
|
||||||
markdownIt.enable(TEXT_WITH_HTML_RULES)
|
|
||||||
|
|
||||||
markdownIt.use(markdownItEmoji)
|
|
||||||
|
|
||||||
const toSafeHtml = text => {
|
|
||||||
// Restore line feed
|
|
||||||
const textWithLineFeed = text.replace(/<br.?\/?>/g, '\r\n')
|
|
||||||
|
|
||||||
// Convert possible markdown (emojis, emphasis and lists) to html
|
|
||||||
const html = markdownIt.render(textWithLineFeed)
|
|
||||||
|
|
||||||
// Convert to safe Html
|
|
||||||
return sanitizeHtml(html, SANITIZE_OPTIONS)
|
|
||||||
}
|
|
||||||
|
|
||||||
const Email = require('email-templates')
|
const Email = require('email-templates')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue