feat: use markdown-it instead of marked for descriptions
This commit is contained in:
		
							parent
							
								
									90667bc285
								
							
						
					
					
						commit
						da67d12b60
					
				
					 7 changed files with 89 additions and 29 deletions
				
			
		|  | @ -16,7 +16,7 @@ | |||
| 		"@sveltejs/adapter-node": "^1.2.2", | ||||
| 		"@sveltejs/kit": "^1.5.0", | ||||
| 		"@types/luxon": "^3.2.0", | ||||
| 		"@types/marked": "^4.0.8", | ||||
| 		"@types/markdown-it": "^12.2.3", | ||||
| 		"@types/node": "^18.15.3", | ||||
| 		"@types/sanitize-html": "^2.8.1", | ||||
| 		"@typescript-eslint/eslint-plugin": "^5.45.0", | ||||
|  | @ -28,10 +28,10 @@ | |||
| 		"prettier-plugin-svelte": "^2.8.1", | ||||
| 		"svelte": "^3.54.0", | ||||
| 		"svelte-check": "^3.0.1", | ||||
| 		"sveltestrap": "^5.10.0", | ||||
| 		"tslib": "^2.4.1", | ||||
| 		"typescript": "^4.9.3", | ||||
| 		"vite": "^4.0.0", | ||||
| 		"sveltestrap": "^5.10.0" | ||||
| 		"vite": "^4.0.0" | ||||
| 	}, | ||||
| 	"type": "module", | ||||
| 	"dependencies": { | ||||
|  | @ -42,7 +42,7 @@ | |||
| 		"bootstrap-icons": "^1.10.3", | ||||
| 		"jose": "^4.13.1", | ||||
| 		"luxon": "^3.3.0", | ||||
| 		"marked": "^4.2.12", | ||||
| 		"markdown-it": "^13.0.1", | ||||
| 		"sanitize-html": "^2.10.0" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										60
									
								
								frontend/pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										60
									
								
								frontend/pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							|  | @ -7,7 +7,7 @@ specifiers: | |||
|   '@sveltejs/adapter-node': ^1.2.2 | ||||
|   '@sveltejs/kit': ^1.5.0 | ||||
|   '@types/luxon': ^3.2.0 | ||||
|   '@types/marked': ^4.0.8 | ||||
|   '@types/markdown-it': ^12.2.3 | ||||
|   '@types/node': ^18.15.3 | ||||
|   '@types/sanitize-html': ^2.8.1 | ||||
|   '@typescript-eslint/eslint-plugin': ^5.45.0 | ||||
|  | @ -20,7 +20,7 @@ specifiers: | |||
|   eslint-plugin-svelte3: ^4.0.0 | ||||
|   jose: ^4.13.1 | ||||
|   luxon: ^3.3.0 | ||||
|   marked: ^4.2.12 | ||||
|   markdown-it: ^13.0.1 | ||||
|   prettier: ^2.8.0 | ||||
|   prettier-plugin-svelte: ^2.8.1 | ||||
|   sanitize-html: ^2.10.0 | ||||
|  | @ -39,16 +39,15 @@ dependencies: | |||
|   bootstrap-icons: 1.10.3 | ||||
|   jose: 4.13.1 | ||||
|   luxon: 3.3.0 | ||||
|   marked: 4.2.12 | ||||
|   markdown-it: 13.0.1 | ||||
|   sanitize-html: 2.10.0 | ||||
|   sveltestrap: 5.10.0_svelte@3.55.1 | ||||
| 
 | ||||
| devDependencies: | ||||
|   '@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.11.0 | ||||
|   '@sveltejs/adapter-node': 1.2.2_@sveltejs+kit@1.11.0 | ||||
|   '@sveltejs/kit': 1.11.0_svelte@3.55.1+vite@4.1.4 | ||||
|   '@types/luxon': 3.2.0 | ||||
|   '@types/marked': 4.0.8 | ||||
|   '@types/markdown-it': 12.2.3 | ||||
|   '@types/node': 18.15.3 | ||||
|   '@types/sanitize-html': 2.8.1 | ||||
|   '@typescript-eslint/eslint-plugin': 5.54.1_mlk7dnz565t663n4razh6a6v6i | ||||
|  | @ -60,6 +59,7 @@ devDependencies: | |||
|   prettier-plugin-svelte: 2.9.0_jrsxveqmsx2uadbqiuq74wlc4u | ||||
|   svelte: 3.55.1 | ||||
|   svelte-check: 3.1.0_svelte@3.55.1 | ||||
|   sveltestrap: 5.10.0_svelte@3.55.1 | ||||
|   tslib: 2.5.0 | ||||
|   typescript: 4.9.5 | ||||
|   vite: 4.1.4_@types+node@18.15.3 | ||||
|  | @ -349,7 +349,6 @@ packages: | |||
| 
 | ||||
|   /@popperjs/core/2.11.6: | ||||
|     resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@rollup/plugin-commonjs/24.0.1_rollup@3.18.0: | ||||
|     resolution: {integrity: sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==} | ||||
|  | @ -532,12 +531,23 @@ packages: | |||
|     resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /@types/linkify-it/3.0.2: | ||||
|     resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /@types/luxon/3.2.0: | ||||
|     resolution: {integrity: sha512-lGmaGFoaXHuOLXFvuju2bfvZRqxAqkHPx9Y9IQdQABrinJJshJwfNCKV+u7rR3kJbiqfTF/NhOkcxxAFrObyaA==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /@types/marked/4.0.8: | ||||
|     resolution: {integrity: sha512-HVNzMT5QlWCOdeuBsgXP8EZzKUf0+AXzN+sLmjvaB3ZlLqO+e4u0uXrdw9ub69wBKFs+c6/pA4r9sy6cCDvImw==} | ||||
|   /@types/markdown-it/12.2.3: | ||||
|     resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} | ||||
|     dependencies: | ||||
|       '@types/linkify-it': 3.0.2 | ||||
|       '@types/mdurl': 1.0.2 | ||||
|     dev: true | ||||
| 
 | ||||
|   /@types/mdurl/1.0.2: | ||||
|     resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /@types/node/18.15.3: | ||||
|  | @ -753,7 +763,6 @@ packages: | |||
| 
 | ||||
|   /argparse/2.0.1: | ||||
|     resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /array-union/2.1.0: | ||||
|     resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} | ||||
|  | @ -953,6 +962,11 @@ packages: | |||
|       domelementtype: 2.3.0 | ||||
|       domhandler: 5.0.3 | ||||
| 
 | ||||
|   /entities/3.0.1: | ||||
|     resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} | ||||
|     engines: {node: '>=0.12'} | ||||
|     dev: false | ||||
| 
 | ||||
|   /entities/4.4.0: | ||||
|     resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} | ||||
|     engines: {node: '>=0.12'} | ||||
|  | @ -1459,6 +1473,12 @@ packages: | |||
|       type-check: 0.4.0 | ||||
|     dev: true | ||||
| 
 | ||||
|   /linkify-it/4.0.1: | ||||
|     resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} | ||||
|     dependencies: | ||||
|       uc.micro: 1.0.6 | ||||
|     dev: false | ||||
| 
 | ||||
|   /locate-path/6.0.0: | ||||
|     resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} | ||||
|     engines: {node: '>=10'} | ||||
|  | @ -1507,10 +1527,19 @@ packages: | |||
|       '@jridgewell/sourcemap-codec': 1.4.14 | ||||
|     dev: true | ||||
| 
 | ||||
|   /marked/4.2.12: | ||||
|     resolution: {integrity: sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==} | ||||
|     engines: {node: '>= 12'} | ||||
|   /markdown-it/13.0.1: | ||||
|     resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} | ||||
|     hasBin: true | ||||
|     dependencies: | ||||
|       argparse: 2.0.1 | ||||
|       entities: 3.0.1 | ||||
|       linkify-it: 4.0.1 | ||||
|       mdurl: 1.0.1 | ||||
|       uc.micro: 1.0.6 | ||||
|     dev: false | ||||
| 
 | ||||
|   /mdurl/1.0.1: | ||||
|     resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /merge2/1.4.1: | ||||
|  | @ -1976,6 +2005,7 @@ packages: | |||
|   /svelte/3.55.1: | ||||
|     resolution: {integrity: sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==} | ||||
|     engines: {node: '>= 8'} | ||||
|     dev: true | ||||
| 
 | ||||
|   /sveltestrap/5.10.0_svelte@3.55.1: | ||||
|     resolution: {integrity: sha512-k6Ob+6G2AMYvBidXHBKM9W28fJqFHbmosqCe/NC8pv6TV7K+v47Yw+zmnLWkjqCzzmjkSLkL48SrHZrlWc9mYQ==} | ||||
|  | @ -1984,7 +2014,7 @@ packages: | |||
|     dependencies: | ||||
|       '@popperjs/core': 2.11.6 | ||||
|       svelte: 3.55.1 | ||||
|     dev: false | ||||
|     dev: true | ||||
| 
 | ||||
|   /text-table/0.2.0: | ||||
|     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} | ||||
|  | @ -2044,6 +2074,10 @@ packages: | |||
|     hasBin: true | ||||
|     dev: true | ||||
| 
 | ||||
|   /uc.micro/1.0.6: | ||||
|     resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /undici/5.20.0: | ||||
|     resolution: {integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==} | ||||
|     engines: {node: '>=12.18'} | ||||
|  |  | |||
							
								
								
									
										11
									
								
								frontend/src/lib/api/markdown.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								frontend/src/lib/api/markdown.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| import MarkdownIt from "markdown-it"; | ||||
| import sanitize from "sanitize-html"; | ||||
| 
 | ||||
| const md = new MarkdownIt({ | ||||
|   html: false, | ||||
|   breaks: true, | ||||
| }).disable(["heading", "link", "table"]); | ||||
| 
 | ||||
| export default function renderMarkdown(src: string | null) { | ||||
|   return src ? sanitize(md.render(src)) : null; | ||||
| } | ||||
|  | @ -1,7 +1,4 @@ | |||
| <script lang="ts"> | ||||
|   import { marked } from "marked"; | ||||
|   import sanitizeHtml from "sanitize-html"; | ||||
| 
 | ||||
|   import type { PageData } from "./$types"; | ||||
| 
 | ||||
|   import { | ||||
|  | @ -33,11 +30,12 @@ | |||
|   import { apiFetchClient } from "$lib/api/fetch"; | ||||
|   import ErrorAlert from "$lib/components/ErrorAlert.svelte"; | ||||
|   import { goto } from "$app/navigation"; | ||||
|   import renderMarkdown from "$lib/api/markdown"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
| 
 | ||||
|   let bio: string | null; | ||||
|   $: bio = data.bio ? sanitizeHtml(marked.parse(data.bio, { breaks: true })) : null; | ||||
|   $: bio = renderMarkdown(data.bio); | ||||
| 
 | ||||
|   let memberPage: number = 0; | ||||
|   let memberSlice: PartialMember[] = []; | ||||
|  |  | |||
|  | @ -1,7 +1,4 @@ | |||
| <script lang="ts"> | ||||
|   import { marked } from "marked"; | ||||
|   import sanitizeHtml from "sanitize-html"; | ||||
| 
 | ||||
|   import FieldCard from "$lib/components/FieldCard.svelte"; | ||||
| 
 | ||||
|   import type { PageData } from "./$types"; | ||||
|  | @ -12,11 +9,12 @@ | |||
|   import { memberAvatars, pronounDisplay, WordStatus } from "$lib/api/entities"; | ||||
|   import { PUBLIC_BASE_URL } from "$env/static/public"; | ||||
|   import { userStore } from "$lib/store"; | ||||
|   import renderMarkdown from "$lib/api/markdown"; | ||||
| 
 | ||||
|   export let data: PageData; | ||||
| 
 | ||||
|   let bio: string | null; | ||||
|   $: bio = data.bio ? sanitizeHtml(marked.parse(data.bio, { breaks: true })) : null; | ||||
|   $: bio = renderMarkdown(data.bio); | ||||
| 
 | ||||
|   const favNames = data.names.filter((entry) => entry.status === WordStatus.Favourite); | ||||
|   const favPronouns = data.pronouns.filter((entry) => entry.status === WordStatus.Favourite); | ||||
|  |  | |||
|  | @ -335,8 +335,8 @@ | |||
|               accept="image/png, image/jpeg, image/gif, image/webp" | ||||
|             /> | ||||
|             <p class="text-muted mt-3"> | ||||
|               <Icon name="info-circle-fill" /> Only PNG, JPEG, GIF, and WebP can be used as avatars. | ||||
|               Avatars cannot be larger than 1 MB, and animated avatars will be made static. | ||||
|               <Icon name="info-circle-fill" aria-hidden /> Only PNG, JPEG, GIF, and WebP can be used | ||||
|               as avatars. Avatars cannot be larger than 1 MB, and animated avatars will be made static. | ||||
|             </p> | ||||
|             <a href="" on:click={() => (avatar = "")}>Remove avatar</a> | ||||
|           </div> | ||||
|  | @ -357,6 +357,15 @@ | |||
|           <FormGroup floating label="Bio ({bio.length}/{MAX_DESCRIPTION_LENGTH})"> | ||||
|             <textarea style="min-height: 100px;" class="form-control" bind:value={bio} /> | ||||
|           </FormGroup> | ||||
|           <p class="text-muted mt-3"> | ||||
|             <Icon name="info-circle-fill" aria-hidden /> Your bio supports limited | ||||
|             <a | ||||
|               class="text-reset" | ||||
|               href="https://commonmark.org/help/" | ||||
|               target="_blank" | ||||
|               rel="noopener noreferrer">Markdown</a | ||||
|             >. | ||||
|           </p> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -282,8 +282,9 @@ | |||
|               accept="image/png, image/jpeg, image/gif, image/webp" | ||||
|             /> | ||||
|             <p class="text-muted mt-3"> | ||||
|               <Icon name="info-circle-fill" /> Only PNG, JPEG, GIF, and WebP images can be used as avatars. | ||||
|               Avatars cannot be larger than 1 MB, and animated avatars will be made static. | ||||
|               <Icon name="info-circle-fill" aria-hidden /> Only PNG, JPEG, GIF, and WebP images can be | ||||
|               used as avatars. Avatars cannot be larger than 1 MB, and animated avatars will be made | ||||
|               static. | ||||
|             </p> | ||||
|             <p> | ||||
|               <a href="" on:click={() => (avatar = "")}>Remove avatar</a> | ||||
|  | @ -299,6 +300,15 @@ | |||
|           <FormGroup floating label="Bio ({bio.length}/{MAX_DESCRIPTION_LENGTH})"> | ||||
|             <textarea style="min-height: 100px;" class="form-control" bind:value={bio} /> | ||||
|           </FormGroup> | ||||
|           <p class="text-muted mt-3"> | ||||
|             <Icon name="info-circle-fill" aria-hidden /> Your bio supports limited | ||||
|             <a | ||||
|               class="text-reset" | ||||
|               href="https://commonmark.org/help/" | ||||
|               target="_blank" | ||||
|               rel="noopener noreferrer">Markdown</a | ||||
|             >. | ||||
|           </p> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue