From 1c200ee5bcb1532625899ca3798ad42fa43795cf Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Thu, 25 Jan 2024 23:28:42 +0530 Subject: [PATCH] perf: prevent adding multiple DOMPurify hooks Currently, everytime `removeScript()` is called, the same DOMPurify hooks are getting added again and again. Co-authored-by: Alois Klink --- .../mermaid/src/diagrams/common/common.ts | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index caf43bc682..8609a175ae 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -18,13 +18,18 @@ export const getRows = (s?: string): string[] => { return str.split('#br#'); }; -/** - * Removes script tags from a text - * - * @param txt - The text to sanitize - * @returns The safer text - */ -export const removeScript = (txt: string): string => { +const setupDompurifyHooksIfNotSetup = (() => { + let setup = false; + + return () => { + if (!setup) { + setupDompurifyHooks(); + setup = true; + } + }; +})(); + +function setupDompurifyHooks() { const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => { @@ -33,8 +38,6 @@ export const removeScript = (txt: string): string => { } }); - const sanitizedText = DOMPurify.sanitize(txt); - DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => { if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) || ''); @@ -44,6 +47,18 @@ export const removeScript = (txt: string): string => { } } }); +} + +/** + * Removes script tags from a text + * + * @param txt - The text to sanitize + * @returns The safer text + */ +export const removeScript = (txt: string): string => { + setupDompurifyHooksIfNotSetup(); + + const sanitizedText = DOMPurify.sanitize(txt); return sanitizedText; };