mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[DURACOM-240] working directive
need to change markdown pipe to markdown directive and put everything in there
This commit is contained in:

committed by
Giuseppe Digilio

parent
c6b72f6c64
commit
825308e223
8
src/app/core/shared/math.directive.spec.ts
Normal file
8
src/app/core/shared/math.directive.spec.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// import { MathDirective } from './math.directive';
|
||||||
|
|
||||||
|
describe('MathDirective', () => {
|
||||||
|
it('should create an instance', () => {
|
||||||
|
// const directive = new MathDirective();
|
||||||
|
// expect(directive).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
60
src/app/core/shared/math.directive.ts
Normal file
60
src/app/core/shared/math.directive.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import {
|
||||||
|
Directive,
|
||||||
|
ElementRef,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
SimpleChanges,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import {
|
||||||
|
take,
|
||||||
|
takeUntil,
|
||||||
|
} from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { MathService } from './math.service';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[dsMath]',
|
||||||
|
standalone: true,
|
||||||
|
})
|
||||||
|
export class MathDirective implements OnInit, OnChanges, OnDestroy {
|
||||||
|
@Input() dsMath: string;
|
||||||
|
private alive$ = new Subject<boolean>();
|
||||||
|
private readonly el: HTMLElement;
|
||||||
|
|
||||||
|
constructor(private mathService: MathService, private elementRef: ElementRef) {
|
||||||
|
this.el = elementRef.nativeElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes?.dsMath?.currentValue) {
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private render() {
|
||||||
|
this.mathService.ready().pipe(
|
||||||
|
take(1),
|
||||||
|
takeUntil(this.alive$),
|
||||||
|
).subscribe(() => {
|
||||||
|
// if this.dsMath begins with "The observation of the"
|
||||||
|
if (this.dsMath.startsWith('The observation of the')) {
|
||||||
|
console.warn('rendering math after ready');
|
||||||
|
console.warn('this.dsMath', this.dsMath);
|
||||||
|
console.warn('this.el', this.el);
|
||||||
|
}
|
||||||
|
this.mathService.render(this.el, this.dsMath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.alive$.next(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/app/core/shared/math.service.spec.ts
Normal file
16
src/app/core/shared/math.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MathService } from './math.service';
|
||||||
|
|
||||||
|
describe('MathService', () => {
|
||||||
|
let service: MathService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(MathService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
93
src/app/core/shared/math.service.ts
Normal file
93
src/app/core/shared/math.service.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
Observable,
|
||||||
|
ReplaySubject,
|
||||||
|
Subject,
|
||||||
|
} from 'rxjs';
|
||||||
|
|
||||||
|
interface MathJaxConfig {
|
||||||
|
source: string;
|
||||||
|
integrity: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
MathJax: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class MathService {
|
||||||
|
|
||||||
|
private signal: Subject<boolean>;
|
||||||
|
|
||||||
|
private mathJaxOptions = {
|
||||||
|
tex: {
|
||||||
|
inlineMath: [['$', '$'], ['\\(', '\\)']],
|
||||||
|
},
|
||||||
|
svg: {
|
||||||
|
fontCache: 'global',
|
||||||
|
},
|
||||||
|
startup: {
|
||||||
|
typeset: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
private mathJax: MathJaxConfig = {
|
||||||
|
source: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js',
|
||||||
|
integrity: 'sha256-CnzfCXjFj1REmPHgWvm/OQv8gFaxwbLKUi41yCU7N2s=',
|
||||||
|
id: 'MathJaxScript',
|
||||||
|
};
|
||||||
|
private mathJaxFallback: MathJaxConfig = {
|
||||||
|
source: 'assets/mathjax/mml-chtml.js',
|
||||||
|
integrity: 'sha256-CnzfCXjFj1REmPHgWvm/OQv8gFaxwbLKUi41yCU7N2s=',
|
||||||
|
id: 'MathJaxBackupScript',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
this.signal = new ReplaySubject<boolean>(1);
|
||||||
|
|
||||||
|
void this.registerMathJaxAsync(this.mathJax)
|
||||||
|
.then(() => this.signal.next(true))
|
||||||
|
.catch(_ => {
|
||||||
|
void this.registerMathJaxAsync(this.mathJaxFallback)
|
||||||
|
.then(() => this.signal.next(true))
|
||||||
|
.catch((error) => console.log(error));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async registerMathJaxAsync(config: MathJaxConfig): Promise<any> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
const optionsScript: HTMLScriptElement = document.createElement('script');
|
||||||
|
optionsScript.type = 'text/javascript';
|
||||||
|
optionsScript.text = `MathJax = ${JSON.stringify(this.mathJaxOptions)};`;
|
||||||
|
document.head.appendChild(optionsScript);
|
||||||
|
|
||||||
|
const script: HTMLScriptElement = document.createElement('script');
|
||||||
|
script.id = config.id;
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = config.source;
|
||||||
|
script.crossOrigin = 'anonymous';
|
||||||
|
script.async = true;
|
||||||
|
script.onload = () => resolve();
|
||||||
|
script.onerror = error => reject(error);
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(): Observable<boolean> {
|
||||||
|
return this.signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(element: HTMLElement, value: string) {
|
||||||
|
// Take initial typesetting which MathJax performs into account
|
||||||
|
// window.MathJax.startup.promise.then(() => {
|
||||||
|
element.innerHTML = value;
|
||||||
|
window.MathJax.typesetPromise([element]);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
@@ -9,6 +9,7 @@ import {
|
|||||||
DomSanitizer,
|
DomSanitizer,
|
||||||
SafeHtml,
|
SafeHtml,
|
||||||
} from '@angular/platform-browser';
|
} from '@angular/platform-browser';
|
||||||
|
import { MathService } from 'src/app/core/shared/math.service';
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
import { isEmpty } from '../empty.util';
|
import { isEmpty } from '../empty.util';
|
||||||
@@ -58,6 +59,7 @@ export class MarkdownPipe implements PipeTransform {
|
|||||||
@Inject(MARKDOWN_IT) private markdownIt: LazyMarkdownIt,
|
@Inject(MARKDOWN_IT) private markdownIt: LazyMarkdownIt,
|
||||||
// @Inject(MATHJAX) private mathjax: Mathjax,
|
// @Inject(MATHJAX) private mathjax: Mathjax,
|
||||||
@Inject(SANITIZE_HTML) private sanitizeHtml: SanitizeHtml,
|
@Inject(SANITIZE_HTML) private sanitizeHtml: SanitizeHtml,
|
||||||
|
private mathService: MathService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,9 +75,6 @@ export class MarkdownPipe implements PipeTransform {
|
|||||||
|
|
||||||
let html: string;
|
let html: string;
|
||||||
if (environment.markdown.mathjax) {
|
if (environment.markdown.mathjax) {
|
||||||
// TODO: instead of using md.use with mathjax, use ng-katex rendering from its service
|
|
||||||
md.use(await this.mathjax);
|
|
||||||
// TODO: keep this as is
|
|
||||||
const sanitizeHtml = await this.sanitizeHtml;
|
const sanitizeHtml = await this.sanitizeHtml;
|
||||||
html = sanitizeHtml(md.render(value), {
|
html = sanitizeHtml(md.render(value), {
|
||||||
// sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG
|
// sanitize-html doesn't let through SVG by default, so we extend its allowlists to cover MathJax SVG
|
||||||
|
@@ -476,8 +476,8 @@ export class DefaultAppConfig implements AppConfig {
|
|||||||
// Whether to enable Markdown (https://commonmark.org/) and MathJax (https://www.mathjax.org/)
|
// Whether to enable Markdown (https://commonmark.org/) and MathJax (https://www.mathjax.org/)
|
||||||
// display in supported metadata fields. By default, only dc.description.abstract is supported.
|
// display in supported metadata fields. By default, only dc.description.abstract is supported.
|
||||||
markdown: MarkdownConfig = {
|
markdown: MarkdownConfig = {
|
||||||
enabled: false,
|
enabled: true,
|
||||||
mathjax: false,
|
mathjax: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Which vocabularies should be used for which search filters
|
// Which vocabularies should be used for which search filters
|
||||||
|
Reference in New Issue
Block a user