diff --git a/package-lock.json b/package-lock.json
index 2ebf246ce..5d485a9d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
"@types/md5": "^2.3.2",
"@walletconnect/client": "^1.8.0",
"buffer": "^6.0.3",
- "dompurify": "^2.4.0",
+ "dompurify": "^2.4.1",
"ethers": "^5.7.2",
"events": "^3.3.0",
"katex": "^0.16.3",
@@ -34,7 +34,7 @@
"@rsksmart/mock-web3-provider": "^1.0.1",
"@sveltejs/vite-plugin-svelte": "^1.1.0",
"@tsconfig/svelte": "^3.0.0",
- "@types/dompurify": "^2.3.4",
+ "@types/dompurify": "^2.4.0",
"@types/katex": "^0.14.0",
"@types/lodash": "^4.14.188",
"@typescript-eslint/eslint-plugin": "^5.42.0",
@@ -1091,9 +1091,9 @@
}
},
"node_modules/@types/dompurify": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.3.4.tgz",
- "integrity": "sha512-EXzDatIb5EspL2eb/xPGmaC8pePcTHrkDCONjeisusLFrVfl38Pjea/R0YJGu3k9ZQadSvMqW0WXPI2hEo2Ajg==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz",
+ "integrity": "sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==",
"dev": true,
"dependencies": {
"@types/trusted-types": "*"
@@ -2794,9 +2794,9 @@
}
},
"node_modules/dompurify": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz",
- "integrity": "sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA=="
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz",
+ "integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA=="
},
"node_modules/ecc-jsbn": {
"version": "0.1.2",
@@ -7937,9 +7937,9 @@
}
},
"@types/dompurify": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.3.4.tgz",
- "integrity": "sha512-EXzDatIb5EspL2eb/xPGmaC8pePcTHrkDCONjeisusLFrVfl38Pjea/R0YJGu3k9ZQadSvMqW0WXPI2hEo2Ajg==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz",
+ "integrity": "sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==",
"dev": true,
"requires": {
"@types/trusted-types": "*"
@@ -9230,9 +9230,9 @@
}
},
"dompurify": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz",
- "integrity": "sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA=="
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz",
+ "integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA=="
},
"ecc-jsbn": {
"version": "0.1.2",
diff --git a/package.json b/package.json
index 32d0078d2..34d99f1c2 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
"@rsksmart/mock-web3-provider": "^1.0.1",
"@sveltejs/vite-plugin-svelte": "^1.1.0",
"@tsconfig/svelte": "^3.0.0",
- "@types/dompurify": "^2.3.4",
+ "@types/dompurify": "^2.4.0",
"@types/katex": "^0.14.0",
"@types/lodash": "^4.14.188",
"@typescript-eslint/eslint-plugin": "^5.42.0",
@@ -45,7 +45,7 @@
"@types/md5": "^2.3.2",
"@walletconnect/client": "^1.8.0",
"buffer": "^6.0.3",
- "dompurify": "^2.4.0",
+ "dompurify": "^2.4.1",
"ethers": "^5.7.2",
"events": "^3.3.0",
"katex": "^0.16.3",
diff --git a/src/Markdown.svelte b/src/Markdown.svelte
index 895e94cca..e492040d0 100644
--- a/src/Markdown.svelte
+++ b/src/Markdown.svelte
@@ -24,7 +24,8 @@
let container: HTMLElement;
const render = (content: string): string =>
- dompurify.sanitize(marked.parse(content, { headerIds: false }));
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ dompurify.sanitize(marked.parse(content), { SANITIZE_DOM: false });
onMount(() => {
// Don't underline tags that contain images.
diff --git a/src/utils.ts b/src/utils.ts
index d556e19cd..362fbd49b 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -521,6 +521,27 @@ const katexMarkedExtension = {
}),
};
+// Converts self closing anchor tags into empty anchor tags, to avoid erratic wrapping behaviour
+// e.g. ->
+const anchorMarkedExtension = {
+ name: "sanitizedAnchor",
+ level: "block",
+ start: (src: string) => src.match(//)?.index,
+ tokenizer(src: string) {
+ const match = src.match(/^/);
+ if (match) {
+ return {
+ type: "sanitizedAnchor",
+ raw: match[0],
+ text: match[1].trim(),
+ };
+ }
+ },
+ renderer: (token: marked.Tokens.Generic) => {
+ return ``;
+ },
+};
+
// Overwrites the rendering of heading tokens.
// Since there are possible non ASCII characters in headings,
// we escape them by replacing them with dashes and,
@@ -536,8 +557,6 @@ export const renderer = {
},
};
-export const markdownExtensions = [emojisMarkedExtension, katexMarkedExtension];
-
export function twemoji(node: HTMLElement) {
twemojiModule.parse(node, {
base: process.env.hashRouting ? "./" : "/",
@@ -546,3 +565,9 @@ export function twemoji(node: HTMLElement) {
className: `txt-emoji`,
});
}
+
+export const markdownExtensions = [
+ emojisMarkedExtension,
+ katexMarkedExtension,
+ anchorMarkedExtension,
+];