From caf283bde45d2d2d711169e6fd6a9ce69408786c Mon Sep 17 00:00:00 2001 From: Joana Maia Date: Mon, 5 Dec 2022 13:25:00 +0000 Subject: [PATCH] Display markdown in activities --- frontend/package-lock.json | 17 +++++++++++ frontend/package.json | 1 + frontend/src/assets/scss/html.scss | 28 +++++++++++++++++++ frontend/src/assets/scss/index.scss | 1 + .../activity/devto-activity-content.vue | 7 +++-- .../activity/discord-activity-content.vue | 8 +++--- .../activity/hackerNews-activity-content.vue | 7 +++-- frontend/src/main.js | 2 ++ .../activity/components/activity-content.vue | 8 +++--- frontend/src/plugins/marked.js | 14 ++++++++++ frontend/src/plugins/sanitize.js | 6 ++-- 11 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 frontend/src/assets/scss/html.scss create mode 100644 frontend/src/plugins/marked.js diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 23a9fd6a0c..13b1072462 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -30,6 +30,7 @@ "lodash": "^4.17.21", "logrocket": "^3.0.1", "logrocket-vuex": "^0.0.3", + "marked": "^4.2.3", "md5": "2.3.0", "moment": "^2.29.4", "nprogress": "0.2.0", @@ -10352,6 +10353,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -23623,6 +23635,11 @@ "semver": "^6.0.0" } }, + "marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==" + }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 8949bfcf3c..a94c45d06b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -40,6 +40,7 @@ "lodash": "^4.17.21", "logrocket": "^3.0.1", "logrocket-vuex": "^0.0.3", + "marked": "^4.2.3", "md5": "2.3.0", "moment": "^2.29.4", "nprogress": "0.2.0", diff --git a/frontend/src/assets/scss/html.scss b/frontend/src/assets/scss/html.scss new file mode 100644 index 0000000000..867a70b57a --- /dev/null +++ b/frontend/src/assets/scss/html.scss @@ -0,0 +1,28 @@ +code { + white-space: pre-wrap; +} + +.parsed-body { + ul, + ol { + padding: 0 2rem; + } + + p { + min-height: 20px; + } + + ul { + display: flex; + flex-direction: column; + gap: 4px; + + &:not(:has(input[type='checkbox'])) { + list-style: initial; + } + } + + ol { + list-style: number; + } +} diff --git a/frontend/src/assets/scss/index.scss b/frontend/src/assets/scss/index.scss index 32e2fe86d8..5cddfc44d5 100644 --- a/frontend/src/assets/scss/index.scss +++ b/frontend/src/assets/scss/index.scss @@ -23,6 +23,7 @@ @import 'badge'; @import 'content'; @import 'popover'; +@import 'html'; @import 'form/date-picker'; @import 'form/radio'; @import 'form/form'; diff --git a/frontend/src/integrations/devto/components/activity/devto-activity-content.vue b/frontend/src/integrations/devto/components/activity/devto-activity-content.vue index f7383af007..fecaef07de 100644 --- a/frontend/src/integrations/devto/components/activity/devto-activity-content.vue +++ b/frontend/src/integrations/devto/components/activity/devto-activity-content.vue @@ -2,16 +2,17 @@
diff --git a/frontend/src/integrations/discord/components/activity/discord-activity-content.vue b/frontend/src/integrations/discord/components/activity/discord-activity-content.vue index 04efd68496..c433e3a7e4 100644 --- a/frontend/src/integrations/discord/components/activity/discord-activity-content.vue +++ b/frontend/src/integrations/discord/components/activity/discord-activity-content.vue @@ -2,15 +2,15 @@
diff --git a/frontend/src/integrations/hackernews/components/activity/hackerNews-activity-content.vue b/frontend/src/integrations/hackernews/components/activity/hackerNews-activity-content.vue index 26bbc331da..5dff44eddf 100644 --- a/frontend/src/integrations/hackernews/components/activity/hackerNews-activity-content.vue +++ b/frontend/src/integrations/hackernews/components/activity/hackerNews-activity-content.vue @@ -2,15 +2,16 @@
diff --git a/frontend/src/main.js b/frontend/src/main.js index 6db5747691..8823d7686d 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -19,6 +19,7 @@ import LogRocket from 'logrocket' import App from '@/app.vue' import { vueSanitizeOptions } from '@/plugins/sanitize' +import marked from '@/plugins/marked' i18nInit() /** @@ -40,6 +41,7 @@ i18nInit() app.use(ElementPlus, { locale: getElementUILanguage() }) app.use(VueGridLayout) app.use(Vue3Sanitize, vueSanitizeOptions) + app.use(marked) app.config.productionTip = process.env.NODE_ENV === 'production' diff --git a/frontend/src/modules/activity/components/activity-content.vue b/frontend/src/modules/activity/components/activity-content.vue index cc6de35526..ba752a9833 100644 --- a/frontend/src/modules/activity/components/activity-content.vue +++ b/frontend/src/modules/activity/components/activity-content.vue @@ -26,8 +26,8 @@
diff --git a/frontend/src/plugins/marked.js b/frontend/src/plugins/marked.js new file mode 100644 index 0000000000..ab6647456e --- /dev/null +++ b/frontend/src/plugins/marked.js @@ -0,0 +1,14 @@ +import { marked } from 'marked' + +export default { + install: (app) => { + app.config.globalProperties.$marked = ( + markdownString, + options + ) => { + marked.setOptions(options) + + return marked.parse(markdownString) + } + } +} diff --git a/frontend/src/plugins/sanitize.js b/frontend/src/plugins/sanitize.js index ac3eafeace..76cfbea0e3 100644 --- a/frontend/src/plugins/sanitize.js +++ b/frontend/src/plugins/sanitize.js @@ -70,7 +70,8 @@ export const vueSanitizeOptions = { 'th', 'thead', 'tr', - '
' + '
', + 'input' ], disallowedTagsMode: 'discard', allowedAttributes: { @@ -84,7 +85,8 @@ export const vueSanitizeOptions = { 'width', 'height', 'loading' - ] + ], + input: ['checked', 'disabled', 'type'] }, selfClosing: [ 'img',