mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +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,
|
||||
SafeHtml,
|
||||
} from '@angular/platform-browser';
|
||||
import { MathService } from 'src/app/core/shared/math.service';
|
||||
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { isEmpty } from '../empty.util';
|
||||
@@ -58,6 +59,7 @@ export class MarkdownPipe implements PipeTransform {
|
||||
@Inject(MARKDOWN_IT) private markdownIt: LazyMarkdownIt,
|
||||
// @Inject(MATHJAX) private mathjax: Mathjax,
|
||||
@Inject(SANITIZE_HTML) private sanitizeHtml: SanitizeHtml,
|
||||
private mathService: MathService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -73,9 +75,6 @@ export class MarkdownPipe implements PipeTransform {
|
||||
|
||||
let html: string;
|
||||
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;
|
||||
html = sanitizeHtml(md.render(value), {
|
||||
// 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/)
|
||||
// display in supported metadata fields. By default, only dc.description.abstract is supported.
|
||||
markdown: MarkdownConfig = {
|
||||
enabled: false,
|
||||
mathjax: false,
|
||||
enabled: true,
|
||||
mathjax: true,
|
||||
};
|
||||
|
||||
// Which vocabularies should be used for which search filters
|
||||
|
Reference in New Issue
Block a user