diff --git a/lib/src/markdown.module.ts b/lib/src/markdown.module.ts index 82dd78d5..e03a2dd0 100644 --- a/lib/src/markdown.module.ts +++ b/lib/src/markdown.module.ts @@ -18,16 +18,19 @@ export interface MarkdownModuleConfig { sanitize?: SecurityContext; } +const sharedImports = [ + MarkdownPipe, +]; + const sharedDeclarations = [ ClipboardButtonComponent, LanguagePipe, MarkdownComponent, - MarkdownPipe, ]; @NgModule({ - imports: [CommonModule], - exports: sharedDeclarations, + imports: [CommonModule, sharedImports], + exports: [sharedDeclarations, sharedImports], declarations: sharedDeclarations, }) export class MarkdownModule { diff --git a/lib/src/markdown.pipe.spec.ts b/lib/src/markdown.pipe.spec.ts index fb380c33..d117712c 100644 --- a/lib/src/markdown.pipe.spec.ts +++ b/lib/src/markdown.pipe.spec.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ import { ElementRef, NgZone, ViewContainerRef } from '@angular/core'; -import { fakeAsync, TestBed } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { DomSanitizer } from '@angular/platform-browser'; import { MarkdownModule } from './markdown.module'; @@ -63,21 +63,19 @@ describe('MarkdownPipe', () => { }); }); - it('should render element through MarkdownService when zone is stable', fakeAsync(() => { + it('should render element through MarkdownService when zone is stable', () => { const markdown = '# Markdown'; const mockPipeOptions: MarkdownPipeOptions = { mermaid: true, mermaidOptions: { darkMode: true } }; spyOn(markdownService, 'render'); - pipe.transform(markdown, mockPipeOptions); - expect(markdownService.render).not.toHaveBeenCalled(); - zone.onStable.emit(null); + zone.run(() => pipe.transform(markdown, mockPipeOptions)); expect(markdownService.render).toHaveBeenCalledWith(elementRef.nativeElement, mockPipeOptions, viewContainerRef); - })); + }); it('should return parsed markdown', () => { diff --git a/lib/src/markdown.pipe.ts b/lib/src/markdown.pipe.ts index 52a4a84b..6bdf9fa1 100644 --- a/lib/src/markdown.pipe.ts +++ b/lib/src/markdown.pipe.ts @@ -8,6 +8,7 @@ export type MarkdownPipeOptions = ParseOptions & RenderOptions; @Pipe({ name: 'markdown', + standalone: true, }) export class MarkdownPipe implements PipeTransform { @@ -31,9 +32,20 @@ export class MarkdownPipe implements PipeTransform { const markdown = this.markdownService.parse(value, options); - this.zone.onStable - .pipe(first()) - .subscribe(() => this.markdownService.render(this.elementRef.nativeElement, options, this.viewContainerRef)); + const render = () => + this.markdownService.render( + this.elementRef.nativeElement, + options, + this.viewContainerRef + ); + + // This check is required for zoneless apps because `onStable` would never emit any value + // when the `NoopNgZone` is used over the `NgZone`. + if (NgZone.isInAngularZone()) { + this.zone.onStable.pipe(first()).subscribe(render); + } else { + Promise.resolve().then(render); + } return this.domSanitizer.bypassSecurityTrustHtml(markdown); }