UNPKG

ngx-contentful-rich-text

Version:

Angular renderer for the Contentful rich text field type

294 lines (279 loc) 10.3 kB
import * as i0 from '@angular/core'; import { Component, ChangeDetectionStrategy, Injectable, Input, ComponentFactoryResolver, Directive, ViewContainerRef, NgModule } from '@angular/core'; import { MARKS, BLOCKS, INLINES } from '@contentful/rich-text-types'; import { CommonModule } from '@angular/common'; class MarkRenderer { } const TEXT = `<ng-container ngxMarkRendererHost [node]="node"></ng-container>`; class DefaultMarkRendererComponent extends MarkRenderer { constructor() { super(...arguments); this.MARKS = MARKS; } } DefaultMarkRendererComponent.decorators = [ { type: Component, args: [{ template: ` <ng-container [ngSwitch]="node.marks[node.markIndex].type"> <b *ngSwitchCase="MARKS.BOLD">${TEXT}</b> <code *ngSwitchCase="MARKS.CODE">${TEXT}</code> <i *ngSwitchCase="MARKS.ITALIC">${TEXT}</i> <u *ngSwitchCase="MARKS.UNDERLINE">${TEXT}</u> </ng-container> `, changeDetection: ChangeDetectionStrategy.OnPush },] } ]; class NodeRenderer { } const CHILDREN = '<ngx-contentful-rich-text [nodes]="node.content"></ngx-contentful-rich-text>'; const DEFAULT_INLINE = '<span>type: {{ node.nodeType }} id: {{ node.data.target.sys.id }}</span>'; class DefaultNodeRendererComponent extends NodeRenderer { constructor() { super(...arguments); this.BLOCKS = BLOCKS; this.INLINES = INLINES; } } DefaultNodeRendererComponent.decorators = [ { type: Component, args: [{ template: ` <ng-container [ngSwitch]="node.nodeType"> <ng-container *ngSwitchCase="BLOCKS.DOCUMENT">${CHILDREN}</ng-container> <div *ngSwitchCase="BLOCKS.EMBEDDED_ENTRY">${CHILDREN}</div> <h1 *ngSwitchCase="BLOCKS.HEADING_1">${CHILDREN}</h1> <h2 *ngSwitchCase="BLOCKS.HEADING_2">${CHILDREN}</h2> <h3 *ngSwitchCase="BLOCKS.HEADING_3">${CHILDREN}</h3> <h4 *ngSwitchCase="BLOCKS.HEADING_4">${CHILDREN}</h4> <h5 *ngSwitchCase="BLOCKS.HEADING_5">${CHILDREN}</h5> <h6 *ngSwitchCase="BLOCKS.HEADING_6">${CHILDREN}</h6> <hr *ngSwitchCase="BLOCKS.HR" /> <li *ngSwitchCase="BLOCKS.LIST_ITEM">${CHILDREN}</li> <ol *ngSwitchCase="BLOCKS.OL_LIST"> ${CHILDREN} </ol> <p *ngSwitchCase="BLOCKS.PARAGRAPH">${CHILDREN}</p> <blockquote *ngSwitchCase="BLOCKS.QUOTE">${CHILDREN}</blockquote> <ul *ngSwitchCase="BLOCKS.UL_LIST"> ${CHILDREN} </ul> <ng-container *ngSwitchCase="INLINES.ASSET_HYPERLINK"> ${DEFAULT_INLINE} </ng-container> <ng-container *ngSwitchCase="INLINES.EMBEDDED_ENTRY"> ${DEFAULT_INLINE} </ng-container> <ng-container *ngSwitchCase="INLINES.ENTRY_HYPERLINK"> ${DEFAULT_INLINE} </ng-container> <a *ngSwitchCase="INLINES.HYPERLINK" [href]="node.data.uri"> ${CHILDREN} </a> </ng-container> `, changeDetection: ChangeDetectionStrategy.OnPush },] } ]; class RendererProviderService { constructor() { this.nodeRenderers = {}; this.markRenderers = {}; } getMarkRenderer(node) { const mark = node.marks[node.markIndex]; const resolver = this.markRenderers[mark.type]; let renderer; try { renderer = resolver(node); } catch (error) { renderer = resolver; } return renderer || DefaultMarkRendererComponent; } getNodeRenderer(node) { const resolver = this.nodeRenderers[node.nodeType]; let renderer; try { renderer = resolver(node); } catch (error) { renderer = resolver; } return renderer || DefaultNodeRendererComponent; } setNodeRenderers(customRenderers) { this.nodeRenderers = Object.assign(this.nodeRenderers, customRenderers); } setMarkRenderers(customRenderers) { this.markRenderers = Object.assign(this.markRenderers, customRenderers); } } RendererProviderService.ɵprov = i0.ɵɵdefineInjectable({ factory: function RendererProviderService_Factory() { return new RendererProviderService(); }, token: RendererProviderService, providedIn: "root" }); RendererProviderService.decorators = [ { type: Injectable, args: [{ providedIn: 'root', },] } ]; class NgxContentfulRichTextComponent { constructor(rendererProvider) { this.rendererProvider = rendererProvider; } ngOnInit() { this.rendererProvider.setNodeRenderers(this.nodeRenderers); this.rendererProvider.setMarkRenderers(this.markRenderers); } ngOnChanges(changes) { var _a; if ((_a = changes.document) === null || _a === void 0 ? void 0 : _a.currentValue) { this.nodes = [changes.document.currentValue]; } } } NgxContentfulRichTextComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-contentful-rich-text', template: ` <ng-container *ngIf="nodes?.length"> <ng-container *ngFor="let node of nodes"> <ng-container *ngIf="node.nodeType !== 'text'; else textNode" ngxNodeRendererHost [node]="node" > </ng-container> <ng-template #textNode> <ng-container ngxMarkRendererHost [node]="node"></ng-container> </ng-template> </ng-container> </ng-container> `, changeDetection: ChangeDetectionStrategy.OnPush },] } ]; NgxContentfulRichTextComponent.ctorParameters = () => [ { type: RendererProviderService } ]; NgxContentfulRichTextComponent.propDecorators = { document: [{ type: Input }], nodes: [{ type: Input }], nodeRenderers: [{ type: Input }], markRenderers: [{ type: Input }] }; class TextValueComponent { } TextValueComponent.decorators = [ { type: Component, args: [{ template: '{{ node.value }}', changeDetection: ChangeDetectionStrategy.OnPush },] } ]; TextValueComponent.propDecorators = { node: [{ type: Input }] }; class ComponentRendererService { constructor(componentFactoryResolver) { this.componentFactoryResolver = componentFactoryResolver; } render(viewContainerRef, component, node) { const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component); viewContainerRef.clear(); const componentRef = viewContainerRef.createComponent(componentFactory); componentRef.instance.node = node; componentRef.changeDetectorRef.detectChanges(); } } ComponentRendererService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ComponentRendererService_Factory() { return new ComponentRendererService(i0.ɵɵinject(i0.ComponentFactoryResolver)); }, token: ComponentRendererService, providedIn: "root" }); ComponentRendererService.decorators = [ { type: Injectable, args: [{ providedIn: 'root', },] } ]; ComponentRendererService.ctorParameters = () => [ { type: ComponentFactoryResolver } ]; class MarkRendererHostDirective { constructor(viewContainerRef, componentRenderer, rendererProvider) { this.viewContainerRef = viewContainerRef; this.componentRenderer = componentRenderer; this.rendererProvider = rendererProvider; } ngOnInit() { let component; if (isNaN(this.node.markIndex)) { // Create new object because node object might not be extensible this.node = Object.assign(Object.assign({}, this.node), { markIndex: 0 }); } else { this.node.markIndex += 1; } if (this.node.marks.length > this.node.markIndex) { component = this.rendererProvider.getMarkRenderer(this.node); } else { component = TextValueComponent; } this.componentRenderer.render(this.viewContainerRef, component, this.node); } } MarkRendererHostDirective.decorators = [ { type: Directive, args: [{ selector: '[ngxMarkRendererHost]', },] } ]; MarkRendererHostDirective.ctorParameters = () => [ { type: ViewContainerRef }, { type: ComponentRendererService }, { type: RendererProviderService } ]; MarkRendererHostDirective.propDecorators = { node: [{ type: Input }] }; class NodeRendererHostDirective { constructor(viewContainerRef, componentRenderer, rendererProvider) { this.viewContainerRef = viewContainerRef; this.componentRenderer = componentRenderer; this.rendererProvider = rendererProvider; } ngOnInit() { const component = this.rendererProvider.getNodeRenderer(this.node); this.componentRenderer.render(this.viewContainerRef, component, this.node); } } NodeRendererHostDirective.decorators = [ { type: Directive, args: [{ selector: '[ngxNodeRendererHost]', },] } ]; NodeRendererHostDirective.ctorParameters = () => [ { type: ViewContainerRef }, { type: ComponentRendererService }, { type: RendererProviderService } ]; NodeRendererHostDirective.propDecorators = { node: [{ type: Input }] }; class NgxContentfulRichTextModule { } NgxContentfulRichTextModule.decorators = [ { type: NgModule, args: [{ declarations: [ DefaultMarkRendererComponent, DefaultNodeRendererComponent, MarkRendererHostDirective, NgxContentfulRichTextComponent, NodeRendererHostDirective, TextValueComponent, ], imports: [CommonModule], exports: [MarkRendererHostDirective, NgxContentfulRichTextComponent], },] } ]; /* * Public API Surface of ngx-contentful-rich-text */ /** * Generated bundle index. Do not edit. */ export { CHILDREN, DefaultMarkRendererComponent, DefaultNodeRendererComponent, MarkRenderer, MarkRendererHostDirective, NgxContentfulRichTextComponent, NgxContentfulRichTextModule, NodeRenderer, TEXT, RendererProviderService as ɵa, ComponentRendererService as ɵb, NodeRendererHostDirective as ɵc, TextValueComponent as ɵd }; //# sourceMappingURL=ngx-contentful-rich-text.js.map