UNPKG

@cisstech/nge

Version:

NG Essentials is a collection of libraries for Angular developers.

104 lines 15.7 kB
import { HttpClient } from '@angular/common/http'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, Output, inject, } from '@angular/core'; import { ResourceLoaderService } from '@cisstech/nge/services'; import { firstValueFrom } from 'rxjs'; import { NGE_MARKDOWN_THEMES } from './nge-markdown-config'; import { NGE_MARKDOWN_CONTRIBUTION } from './nge-markdown-contribution'; import { NgeMarkdownService } from './nge-markdown.service'; import * as i0 from "@angular/core"; export class NgeMarkdownComponent { get klass() { if (!this.theme) return ''; const classeNames = [`nge-markdown-theme--${this.theme}`]; if (this.isDark) { classeNames.push(`nge-markdown-theme--${this.theme}--dark`); } return classeNames.join(' '); } constructor() { this.el = inject(ElementRef); this.http = inject(HttpClient, { optional: true }); this.markdownService = inject(NgeMarkdownService); this.resourceLoader = inject(ResourceLoaderService); this.changeDetectorRef = inject(ChangeDetectorRef); this.themes = inject(NGE_MARKDOWN_THEMES, { optional: true }); this.contributions = inject(NGE_MARKDOWN_CONTRIBUTION, { optional: true, }); this.isDark = false; /** Theme to apply to the markdown content. */ this.theme = 'github'; /** * An event that emit after each rendering pass * with the list of tokens parsed from the input markdown. */ this.render = new EventEmitter(); this.themes = this.themes || []; } ngOnInit() { this.el.nativeElement.style.opacity = '0'; } async ngOnChanges() { await this.checkTheme(); this.file ? await this.renderFromFile(this.file) : await this.renderFromString(this.data || ''); this.el.nativeElement.style.opacity = '1'; } async ngAfterViewInit() { await this.checkTheme(); if (!this.file && !this.data) { await this.renderFromString(this.el.nativeElement.innerHTML, true); } this.el.nativeElement.style.opacity = '1'; } async renderFromFile(file) { if (!this.http) { throw new Error('[nge-markdown] When using the `file` attribute you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information'); } const markdown = await firstValueFrom(this.http.get(file, { responseType: 'text' })); await this.renderFromString(markdown); } async renderFromString(markdown, isHtmlString = false) { const tokens = await this.markdownService.compile({ target: this.el.nativeElement, markdown, isHtmlString, contributions: this.contributions, }); this.render.emit(tokens); this.changeDetectorRef.markForCheck(); } async checkTheme() { if (this.theme) { const themeInfo = this.themes?.find((theme) => theme.name === this.theme); if (themeInfo) { await firstValueFrom(this.resourceLoader.loadAllSync([['style', themeInfo.styleUrl]])).catch(); } } const { darkThemeClassName } = this.markdownService.config; if (darkThemeClassName) { // TODO: support angular universal this.isDark = document.querySelector(darkThemeClassName.startsWith('.') ? darkThemeClassName : `.${darkThemeClassName}`) != null; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: NgeMarkdownComponent, selector: "nge-markdown, [nge-markdown]", inputs: { file: "file", data: "data", theme: "theme" }, outputs: { render: "render" }, host: { properties: { "class": "this.klass" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{transition:opacity .3s ease-in-out}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownComponent, decorators: [{ type: Component, args: [{ selector: 'nge-markdown, [nge-markdown]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n", styles: [":host{transition:opacity .3s ease-in-out}\n"] }] }], ctorParameters: () => [], propDecorators: { file: [{ type: Input }], data: [{ type: Input }], theme: [{ type: Input }], klass: [{ type: HostBinding, args: ['class'] }], render: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdlLW1hcmtkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nZS9tYXJrZG93bi9zcmMvbmdlLW1hcmtkb3duLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nZS9tYXJrZG93bi9zcmMvbmdlLW1hcmtkb3duLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUNqRCxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUdMLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFFOUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLE1BQU0sQ0FBQTtBQUNyQyxPQUFPLEVBQUUsbUJBQW1CLEVBQW9CLE1BQU0sdUJBQXVCLENBQUE7QUFDN0UsT0FBTyxFQUFFLHlCQUF5QixFQUEyQixNQUFNLDZCQUE2QixDQUFBO0FBQ2hHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFBOztBQVEzRCxNQUFNLE9BQU8sb0JBQW9CO0lBc0IvQixJQUNJLEtBQUs7UUFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUMxQixNQUFNLFdBQVcsR0FBRyxDQUFDLHVCQUF1QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUN6RCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixXQUFXLENBQUMsSUFBSSxDQUFDLHVCQUF1QixJQUFJLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQTtRQUM3RCxDQUFDO1FBQ0Qs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S0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0YsS0FBSztzQkFEUixXQUFXO3VCQUFDLE9BQU87Z0JBY1YsTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJ1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBSZXNvdXJjZUxvYWRlclNlcnZpY2UgfSBmcm9tICdAY2lzc3RlY2gvbmdlL3NlcnZpY2VzJ1xuaW1wb3J0IHR5cGUgeyBUb2tlbnNMaXN0IH0gZnJvbSAnbWFya2VkJ1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgTkdFX01BUktET1dOX1RIRU1FUywgTmdlTWFya2Rvd25UaGVtZSB9IGZyb20gJy4vbmdlLW1hcmtkb3duLWNvbmZpZydcbmltcG9ydCB7IE5HRV9NQVJLRE9XTl9DT05UUklCVVRJT04sIE5nZU1hcmtkb3duQ29udHJpYnV0aW9uIH0gZnJvbSAnLi9uZ2UtbWFya2Rvd24tY29udHJpYnV0aW9uJ1xuaW1wb3J0IHsgTmdlTWFya2Rvd25TZXJ2aWNlIH0gZnJvbSAnLi9uZ2UtbWFya2Rvd24uc2VydmljZSdcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmdlLW1hcmtkb3duLCBbbmdlLW1hcmtkb3duXScsXG4gIHRlbXBsYXRlVXJsOiAnbmdlLW1hcmtkb3duLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJ25nZS1tYXJrZG93bi5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTmdlTWFya2Rvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWw6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+ID0gaW5qZWN0KEVsZW1lbnRSZWYpXG4gIHByaXZhdGUgcmVhZG9ubHkgaHR0cCA9IGluamVjdChIdHRwQ2xpZW50LCB7IG9wdGlvbmFsOiB0cnVlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgbWFya2Rvd25TZXJ2aWNlID0gaW5qZWN0KE5nZU1hcmtkb3duU2VydmljZSlcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvdXJjZUxvYWRlciA9IGluamVjdChSZXNvdXJjZUxvYWRlclNlcnZpY2UpXG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhbmdlRGV0ZWN0b3JSZWYgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpXG4gIHByaXZhdGUgcmVhZG9ubHkgdGhlbWVzID0gaW5qZWN0KE5HRV9NQVJLRE9XTl9USEVNRVMsIHsgb3B0aW9uYWw6IHRydWUgfSkgYXMgdW5rbm93biBhcyBOZ2VNYXJrZG93blRoZW1lW11cbiAgcHJpdmF0ZSByZWFkb25seSBjb250cmlidXRpb25zID0gaW5qZWN0KE5HRV9NQVJLRE9XTl9DT05UUklCVVRJT04sIHtcbiAgICBvcHRpb25hbDogdHJ1ZSxcbiAgfSkgYXMgdW5rbm93biBhcyBOZ2VNYXJrZG93bkNvbnRyaWJ1dGlvbltdXG5cbiAgcHJpdmF0ZSBpc0RhcmsgPSBmYWxzZVxuXG4gIC8qKiBMaW5rIHRvIGEgbWFya2Rvd24gZmlsZSB0byByZW5kZXIuICovXG4gIEBJbnB1dCgpIGZpbGU/OiBzdHJpbmdcblxuICAvKiogTWFya2Rvd24gc3RyaW5nIHRvIHJlbmRlci4gKi9cbiAgQElucHV0KCkgZGF0YT86IHN0cmluZ1xuXG4gIC8qKiBUaGVtZSB0byBhcHBseSB0byB0aGUgbWFya2Rvd24gY29udGVudC4gKi9cbiAgQElucHV0KCkgdGhlbWU/OiBzdHJpbmcgfCBudWxsID0gJ2dpdGh1YidcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgZ2V0IGtsYXNzKCkge1xuICAgIGlmICghdGhpcy50aGVtZSkgcmV0dXJuICcnXG4gICAgY29uc3QgY2xhc3NlTmFtZXMgPSBbYG5nZS1tYXJrZG93bi10aGVtZS0tJHt0aGlzLnRoZW1lfWBdXG4gICAgaWYgKHRoaXMuaXNEYXJrKSB7XG4gICAgICBjbGFzc2VOYW1lcy5wdXNoKGBuZ2UtbWFya2Rvd24tdGhlbWUtLSR7dGhpcy50aGVtZX0tLWRhcmtgKVxuICAgIH1cbiAgICByZXR1cm4gY2xhc3NlTmFtZXMuam9pbignICcpXG4gIH1cblxuICAvKipcbiAgICogQW4gZXZlbnQgdGhhdCBlbWl0IGFmdGVyIGVhY2ggcmVuZGVyaW5nIHBhc3NcbiAgICogd2l0aCB0aGUgbGlzdCBvZiB0b2tlbnMgcGFyc2VkIGZyb20gdGhlIGlucHV0IG1hcmtkb3duLlxuICAgKi9cbiAgQE91dHB1dCgpIHJlbmRlciA9IG5ldyBFdmVudEVtaXR0ZXI8VG9rZW5zTGlzdD4oKVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudGhlbWVzID0gdGhpcy50aGVtZXMgfHwgW11cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gJzAnXG4gIH1cblxuICBhc3luYyBuZ09uQ2hhbmdlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmNoZWNrVGhlbWUoKVxuICAgIHRoaXMuZmlsZSA/IGF3YWl0IHRoaXMucmVuZGVyRnJvbUZpbGUodGhpcy5maWxlKSA6IGF3YWl0IHRoaXMucmVuZGVyRnJvbVN0cmluZyh0aGlzLmRhdGEgfHwgJycpXG4gICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAnMSdcbiAgfVxuXG4gIGFzeW5jIG5nQWZ0ZXJWaWV3SW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmNoZWNrVGhlbWUoKVxuICAgIGlmICghdGhpcy5maWxlICYmICF0aGlzLmRhdGEpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyRnJvbVN0cmluZyh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MLCB0cnVlKVxuICAgIH1cbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuc3R5bGUub3BhY2l0eSA9ICcxJ1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZW5kZXJGcm9tRmlsZShmaWxlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaHR0cCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnW25nZS1tYXJrZG93bl0gV2hlbiB1c2luZyB0aGUgYGZpbGVgIGF0dHJpYnV0ZSB5b3UgKmhhdmUgdG8qIHBhc3MgdGhlIGBIdHRwQ2xpZW50YCBhcyBhIHBhcmFtZXRlciBvZiB0aGUgYGZvclJvb3RgIG1ldGhvZC4gU2VlIFJFQURNRSBmb3IgbW9yZSBpbmZvcm1hdGlvbidcbiAgICAgIClcbiAgICB9XG4gICAgY29uc3QgbWFya2Rvd24gPSBhd2FpdCBmaXJzdFZhbHVlRnJvbSh0aGlzLmh0dHAuZ2V0KGZpbGUsIHsgcmVzcG9uc2VUeXBlOiAndGV4dCcgfSkpXG4gICAgYXdhaXQgdGhpcy5yZW5kZXJGcm9tU3RyaW5nKG1hcmtkb3duKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZW5kZXJGcm9tU3RyaW5nKG1hcmtkb3duOiBzdHJpbmcsIGlzSHRtbFN0cmluZyA9IGZhbHNlKSB7XG4gICAgY29uc3QgdG9rZW5zID0gYXdhaXQgdGhpcy5tYXJrZG93blNlcnZpY2UuY29tcGlsZSh7XG4gICAgICB0YXJnZXQ6IHRoaXMuZWwubmF0aXZlRWxlbWVudCxcbiAgICAgIG1hcmtkb3duLFxuICAgICAgaXNIdG1sU3RyaW5nLFxuICAgICAgY29udHJpYnV0aW9uczogdGhpcy5jb250cmlidXRpb25zLFxuICAgIH0pXG4gICAgdGhpcy5yZW5kZXIuZW1pdCh0b2tlbnMpXG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjaGVja1RoZW1lKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnRoZW1lKSB7XG4gICAgICBjb25zdCB0aGVtZUluZm8gPSB0aGlzLnRoZW1lcz8uZmluZCgodGhlbWUpID0+IHRoZW1lLm5hbWUgPT09IHRoaXMudGhlbWUpXG4gICAgICBpZiAodGhlbWVJbmZvKSB7XG4gICAgICAgIGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMucmVzb3VyY2VMb2FkZXIubG9hZEFsbFN5bmMoW1snc3R5bGUnLCB0aGVtZUluZm8uc3R5bGVVcmxdXSkpLmNhdGNoKClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB7IGRhcmtUaGVtZUNsYXNzTmFtZSB9ID0gdGhpcy5tYXJrZG93blNlcnZpY2UuY29uZmlnXG4gICAgaWYgKGRhcmtUaGVtZUNsYXNzTmFtZSkge1xuICAgICAgLy8gVE9ETzogc3VwcG9ydCBhbmd1bGFyIHVuaXZlcnNhbFxuICAgICAgdGhpcy5pc0RhcmsgPVxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGRhcmtUaGVtZUNsYXNzTmFtZS5zdGFydHNXaXRoKCcuJykgPyBkYXJrVGhlbWVDbGFzc05hbWUgOiBgLiR7ZGFya1RoZW1lQ2xhc3NOYW1lfWApICE9XG4gICAgICAgIG51bGxcbiAgICB9XG4gIH1cbn1cbiIsIjxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiJdfQ==