From 3c665a736d861f46d72f51b77384a2496c73be52 Mon Sep 17 00:00:00 2001 From: Andrea Barbasso <´andrea.barbasso@4science.com´> Date: Fri, 7 Jun 2024 14:58:50 +0200 Subject: [PATCH] [DURACOM-273] fix markdown rendering applying before mathjax rendering (cherry picked from commit 66e1a2488b14c84b41486fabc77350f17d722b0d) --- src/app/core/shared/client-math.service.ts | 4 +-- src/app/core/shared/math.service.spec.ts | 4 +-- src/app/core/shared/math.service.ts | 2 +- src/app/core/shared/server-math.service.ts | 2 +- src/app/shared/utils/markdown.directive.ts | 40 ++++++++++++++-------- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/app/core/shared/client-math.service.ts b/src/app/core/shared/client-math.service.ts index 2fde521ba9a..0630ec32461 100644 --- a/src/app/core/shared/client-math.service.ts +++ b/src/app/core/shared/client-math.service.ts @@ -31,7 +31,7 @@ export class ClientMathService extends MathService { protected mathJaxOptions = { tex: { - inlineMath: [['$', '$'], ['\\(', '\\)']], + inlineMath: [['$', '$'], ['$$', '$$'], ['\\(', '\\)']], }, svg: { fontCache: 'global', @@ -108,7 +108,7 @@ export class ClientMathService extends MathService { */ render(element: HTMLElement) { if (environment.markdown.mathjax) { - this._window.nativeWindow.MathJax.typesetPromise([element]); + return (window as any).MathJax.typesetPromise([element]) as Promise; } } } diff --git a/src/app/core/shared/math.service.spec.ts b/src/app/core/shared/math.service.spec.ts index cc0b2814f20..75d8bf1024c 100644 --- a/src/app/core/shared/math.service.spec.ts +++ b/src/app/core/shared/math.service.spec.ts @@ -22,8 +22,8 @@ export class MockMathService extends MathService { return of(true); } - render(element: HTMLElement): void { - return; + render(element: HTMLElement): Promise { + return Promise.resolve(); } } diff --git a/src/app/core/shared/math.service.ts b/src/app/core/shared/math.service.ts index c06ce06220b..909e0395643 100644 --- a/src/app/core/shared/math.service.ts +++ b/src/app/core/shared/math.service.ts @@ -15,5 +15,5 @@ export abstract class MathService { protected abstract registerMathJaxAsync(config: MathJaxConfig): Promise; abstract ready(): Observable; - abstract render(element: HTMLElement): void; + abstract render(element: HTMLElement): Promise; } diff --git a/src/app/core/shared/server-math.service.ts b/src/app/core/shared/server-math.service.ts index 75fa775feeb..62070dbafc0 100644 --- a/src/app/core/shared/server-math.service.ts +++ b/src/app/core/shared/server-math.service.ts @@ -47,6 +47,6 @@ export class ServerMathService extends MathService { } render(element: HTMLElement) { - return; + return Promise.resolve(); } } diff --git a/src/app/shared/utils/markdown.directive.ts b/src/app/shared/utils/markdown.directive.ts index a38b079ffd5..0540e25cc54 100644 --- a/src/app/shared/utils/markdown.directive.ts +++ b/src/app/shared/utils/markdown.directive.ts @@ -55,32 +55,42 @@ export class MarkdownDirective implements OnInit, OnDestroy { async render(value: string, forcePreview = false): Promise { if (isEmpty(value) || (!environment.markdown.enabled && !forcePreview)) { - return value; - } - const MarkdownIt = await this.markdownIt; - const md = new MarkdownIt({ - html: true, - linkify: true, - }); - - const html = this.sanitizer.sanitize(SecurityContext.HTML, md.render(value)); - this.el.innerHTML = html; - - if (environment.markdown.mathjax) { - this.renderMathjax(); + this.el.innerHTML = value; + return; + } else { + if (environment.markdown.mathjax) { + this.renderMathjaxThenMarkdown(value); + } else { + this.renderMarkdown(value); + } } } - private renderMathjax() { + private renderMathjaxThenMarkdown(value: string) { + const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, value); + this.el.innerHTML = sanitized; this.mathService.ready().pipe( filter((ready) => ready), take(1), takeUntil(this.alive$), ).subscribe(() => { - this.mathService.render(this.el); + this.mathService.render(this.el)?.then(_ => { + this.renderMarkdown(this.el.innerHTML, true); + }); }); } + private async renderMarkdown(value: string, alreadySanitized = false) { + const MarkdownIt = await this.markdownIt; + const md = new MarkdownIt({ + html: true, + linkify: true, + }); + + const html = alreadySanitized ? md.render(value) : this.sanitizer.sanitize(SecurityContext.HTML, md.render(value)); + this.el.innerHTML = html; + } + ngOnDestroy() { this.alive$.next(false); }