Merge pull request #3112 from 4Science/task/main/DURACOM-273

[#3111] fix markdown rendering applying before mathjax rendering
This commit is contained in:
kshepherd
2024-07-25 14:42:25 +02:00
committed by GitHub
5 changed files with 32 additions and 22 deletions

View File

@@ -31,7 +31,7 @@ export class ClientMathService extends MathService {
protected mathJaxOptions = { protected mathJaxOptions = {
tex: { tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']], inlineMath: [['$', '$'], ['$$', '$$'], ['\\(', '\\)']],
}, },
svg: { svg: {
fontCache: 'global', fontCache: 'global',
@@ -108,7 +108,7 @@ export class ClientMathService extends MathService {
*/ */
render(element: HTMLElement) { render(element: HTMLElement) {
if (environment.markdown.mathjax) { if (environment.markdown.mathjax) {
this._window.nativeWindow.MathJax.typesetPromise([element]); return (window as any).MathJax.typesetPromise([element]) as Promise<any>;
} }
} }
} }

View File

@@ -22,8 +22,8 @@ export class MockMathService extends MathService {
return of(true); return of(true);
} }
render(element: HTMLElement): void { render(element: HTMLElement): Promise<any> {
return; return Promise.resolve();
} }
} }

View File

@@ -15,5 +15,5 @@ export abstract class MathService {
protected abstract registerMathJaxAsync(config: MathJaxConfig): Promise<any>; protected abstract registerMathJaxAsync(config: MathJaxConfig): Promise<any>;
abstract ready(): Observable<boolean>; abstract ready(): Observable<boolean>;
abstract render(element: HTMLElement): void; abstract render(element: HTMLElement): Promise<any>;
} }

View File

@@ -47,6 +47,6 @@ export class ServerMathService extends MathService {
} }
render(element: HTMLElement) { render(element: HTMLElement) {
return; return Promise.resolve();
} }
} }

View File

@@ -55,30 +55,40 @@ export class MarkdownDirective implements OnInit, OnDestroy {
async render(value: string, forcePreview = false): Promise<SafeHtml> { async render(value: string, forcePreview = false): Promise<SafeHtml> {
if (isEmpty(value) || (!environment.markdown.enabled && !forcePreview)) { if (isEmpty(value) || (!environment.markdown.enabled && !forcePreview)) {
return value; this.el.innerHTML = value;
return;
} else {
if (environment.markdown.mathjax) {
this.renderMathjaxThenMarkdown(value);
} else {
this.renderMarkdown(value);
}
} }
}
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)?.then(_ => {
this.renderMarkdown(this.el.innerHTML, true);
});
});
}
private async renderMarkdown(value: string, alreadySanitized = false) {
const MarkdownIt = await this.markdownIt; const MarkdownIt = await this.markdownIt;
const md = new MarkdownIt({ const md = new MarkdownIt({
html: true, html: true,
linkify: true, linkify: true,
}); });
const html = this.sanitizer.sanitize(SecurityContext.HTML, md.render(value)); const html = alreadySanitized ? md.render(value) : this.sanitizer.sanitize(SecurityContext.HTML, md.render(value));
this.el.innerHTML = html; this.el.innerHTML = html;
if (environment.markdown.mathjax) {
this.renderMathjax();
}
}
private renderMathjax() {
this.mathService.ready().pipe(
filter((ready) => ready),
take(1),
takeUntil(this.alive$),
).subscribe(() => {
this.mathService.render(this.el);
});
} }
ngOnDestroy() { ngOnDestroy() {