ngx-contentful-rich-text
Version:
Angular renderer for the Contentful rich text field type
334 lines (317 loc) • 20 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Component, ChangeDetectionStrategy, Input, Directive, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import { MARKS, BLOCKS, INLINES } from '@contentful/rich-text-types';
class RendererProviderService {
constructor() {
this.nodeRenderers = {};
this.markRenderers = {};
}
async getMarkRenderer(node) {
const mark = node.marks[node.markIndex];
const resolver = this.markRenderers[mark.type];
let renderer;
try {
renderer = resolver(node);
}
catch (error) {
renderer = resolver;
}
if (!renderer) {
const { DefaultMarkRendererComponent } = await Promise.resolve().then(function () { return defaultMarkRenderer_component; });
renderer = DefaultMarkRendererComponent;
}
return renderer;
}
async getNodeRenderer(node) {
const resolver = this.nodeRenderers[node.nodeType];
let renderer;
try {
renderer = resolver(node);
}
catch (error) {
renderer = resolver;
}
if (!renderer) {
const { DefaultNodeRendererComponent } = await Promise.resolve().then(function () { return defaultNodeRenderer_component; });
renderer = DefaultNodeRendererComponent;
}
return renderer;
}
setNodeRenderers(customRenderers) {
this.nodeRenderers = Object.assign(this.nodeRenderers, customRenderers);
}
setMarkRenderers(customRenderers) {
this.markRenderers = Object.assign(this.markRenderers, customRenderers);
}
}
RendererProviderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: RendererProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
RendererProviderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: RendererProviderService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: RendererProviderService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
class RendererHost {
render(viewContainerRef, component, node) {
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(component);
componentRef.instance.node = node;
componentRef.changeDetectorRef.detectChanges();
}
}
class TextValueComponent {
}
TextValueComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: TextValueComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
TextValueComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: TextValueComponent, selector: "ng-component", inputs: { node: "node" }, ngImport: i0, template: '{{ node.value }}', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: TextValueComponent, decorators: [{
type: Component,
args: [{
template: '{{ node.value }}',
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}], propDecorators: { node: [{
type: Input
}] } });
class MarkRendererHostDirective extends RendererHost {
constructor(viewContainerRef, rendererProvider) {
super();
this.viewContainerRef = viewContainerRef;
this.rendererProvider = rendererProvider;
}
ngOnInit() {
const render = (component) => this.render(this.viewContainerRef, component, this.node);
if (isNaN(this.node.markIndex)) {
// Create new object because node object might not be extensible
this.node = {
...this.node,
markIndex: 0,
};
}
else {
this.node.markIndex += 1;
}
if (this.node.marks.length > this.node.markIndex) {
this.rendererProvider.getMarkRenderer(this.node).then(render);
}
else {
render(TextValueComponent);
}
}
}
MarkRendererHostDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MarkRendererHostDirective, deps: [{ token: i0.ViewContainerRef }, { token: RendererProviderService }], target: i0.ɵɵFactoryTarget.Directive });
MarkRendererHostDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.4", type: MarkRendererHostDirective, selector: "[ngxMarkRendererHost]", inputs: { node: "node" }, usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MarkRendererHostDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngxMarkRendererHost]',
}]
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: RendererProviderService }]; }, propDecorators: { node: [{
type: Input
}] } });
class NodeRendererHostDirective extends RendererHost {
constructor(viewContainerRef, rendererProvider) {
super();
this.viewContainerRef = viewContainerRef;
this.rendererProvider = rendererProvider;
}
ngOnInit() {
this.rendererProvider
.getNodeRenderer(this.node)
.then((component) => this.render(this.viewContainerRef, component, this.node));
}
}
NodeRendererHostDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NodeRendererHostDirective, deps: [{ token: i0.ViewContainerRef }, { token: RendererProviderService }], target: i0.ɵɵFactoryTarget.Directive });
NodeRendererHostDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.4", type: NodeRendererHostDirective, selector: "[ngxNodeRendererHost]", inputs: { node: "node" }, usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NodeRendererHostDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngxNodeRendererHost]',
}]
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: RendererProviderService }]; }, propDecorators: { node: [{
type: Input
}] } });
class NgxContentfulRichTextComponent {
constructor(rendererProvider) {
this.rendererProvider = rendererProvider;
}
ngOnInit() {
this.rendererProvider.setNodeRenderers(this.nodeRenderers);
this.rendererProvider.setMarkRenderers(this.markRenderers);
}
ngOnChanges(changes) {
if (changes.document?.currentValue) {
this.nodes = [changes.document.currentValue];
}
}
}
NgxContentfulRichTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxContentfulRichTextComponent, deps: [{ token: RendererProviderService }], target: i0.ɵɵFactoryTarget.Component });
NgxContentfulRichTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NgxContentfulRichTextComponent, selector: "ngx-contentful-rich-text", inputs: { document: "document", nodes: "nodes", nodeRenderers: "nodeRenderers", markRenderers: "markRenderers" }, usesOnChanges: true, ngImport: i0, 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>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: MarkRendererHostDirective, selector: "[ngxMarkRendererHost]", inputs: ["node"] }, { kind: "directive", type: NodeRendererHostDirective, selector: "[ngxNodeRendererHost]", inputs: ["node"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: 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,
}]
}], ctorParameters: function () { return [{ type: RendererProviderService }]; }, propDecorators: { document: [{
type: Input
}], nodes: [{
type: Input
}], nodeRenderers: [{
type: Input
}], markRenderers: [{
type: Input
}] } });
class MarkRenderer {
}
const TEXT = `<ng-container ngxMarkRendererHost [node]="node"></ng-container>`;
class DefaultMarkRendererComponent extends MarkRenderer {
constructor() {
super(...arguments);
this.MARKS = MARKS;
}
}
DefaultMarkRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: DefaultMarkRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
DefaultMarkRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: DefaultMarkRendererComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "\n <ng-container [ngSwitch]=\"node.marks[node.markIndex].type\">\n <b *ngSwitchCase=\"MARKS.BOLD\"><ng-container ngxMarkRendererHost [node]=\"node\"></ng-container></b>\n <code *ngSwitchCase=\"MARKS.CODE\"><ng-container ngxMarkRendererHost [node]=\"node\"></ng-container></code>\n <i *ngSwitchCase=\"MARKS.ITALIC\"><ng-container ngxMarkRendererHost [node]=\"node\"></ng-container></i>\n <u *ngSwitchCase=\"MARKS.UNDERLINE\"><ng-container ngxMarkRendererHost [node]=\"node\"></ng-container></u>\n </ng-container>\n ", isInline: true, dependencies: [{ kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: MarkRendererHostDirective, selector: "[ngxMarkRendererHost]", inputs: ["node"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: 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,
}]
}] });
var defaultMarkRenderer_component = /*#__PURE__*/Object.freeze({
__proto__: null,
DefaultMarkRendererComponent: DefaultMarkRendererComponent,
TEXT: TEXT
});
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.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: DefaultNodeRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
DefaultNodeRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: DefaultNodeRendererComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "\n <ng-container [ngSwitch]=\"node.nodeType\">\n <ng-container *ngSwitchCase=\"BLOCKS.DOCUMENT\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></ng-container>\n <div *ngSwitchCase=\"BLOCKS.EMBEDDED_ENTRY\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></div>\n <h1 *ngSwitchCase=\"BLOCKS.HEADING_1\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h1>\n <h2 *ngSwitchCase=\"BLOCKS.HEADING_2\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h2>\n <h3 *ngSwitchCase=\"BLOCKS.HEADING_3\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h3>\n <h4 *ngSwitchCase=\"BLOCKS.HEADING_4\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h4>\n <h5 *ngSwitchCase=\"BLOCKS.HEADING_5\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h5>\n <h6 *ngSwitchCase=\"BLOCKS.HEADING_6\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></h6>\n <hr *ngSwitchCase=\"BLOCKS.HR\" />\n <li *ngSwitchCase=\"BLOCKS.LIST_ITEM\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></li>\n <ol *ngSwitchCase=\"BLOCKS.OL_LIST\">\n <ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text>\n </ol>\n <p *ngSwitchCase=\"BLOCKS.PARAGRAPH\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></p>\n <blockquote *ngSwitchCase=\"BLOCKS.QUOTE\"><ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text></blockquote>\n <ul *ngSwitchCase=\"BLOCKS.UL_LIST\">\n <ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text>\n </ul>\n <ng-container *ngSwitchCase=\"INLINES.ASSET_HYPERLINK\">\n <span>type: {{ node.nodeType }} id: {{ node.data.target.sys.id }}</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"INLINES.EMBEDDED_ENTRY\">\n <span>type: {{ node.nodeType }} id: {{ node.data.target.sys.id }}</span>\n </ng-container>\n <ng-container *ngSwitchCase=\"INLINES.ENTRY_HYPERLINK\">\n <span>type: {{ node.nodeType }} id: {{ node.data.target.sys.id }}</span>\n </ng-container>\n <a *ngSwitchCase=\"INLINES.HYPERLINK\" [href]=\"node.data.uri\">\n <ngx-contentful-rich-text [nodes]=\"node.content\"></ngx-contentful-rich-text>\n </a>\n </ng-container>\n ", isInline: true, dependencies: [{ kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: NgxContentfulRichTextComponent, selector: "ngx-contentful-rich-text", inputs: ["document", "nodes", "nodeRenderers", "markRenderers"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: 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,
}]
}] });
var defaultNodeRenderer_component = /*#__PURE__*/Object.freeze({
__proto__: null,
CHILDREN: CHILDREN,
DefaultNodeRendererComponent: DefaultNodeRendererComponent
});
class NgxContentfulRichTextModule {
}
NgxContentfulRichTextModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxContentfulRichTextModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgxContentfulRichTextModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: NgxContentfulRichTextModule, declarations: [DefaultMarkRendererComponent,
DefaultNodeRendererComponent,
MarkRendererHostDirective,
NgxContentfulRichTextComponent,
NodeRendererHostDirective,
TextValueComponent], imports: [CommonModule], exports: [MarkRendererHostDirective, NgxContentfulRichTextComponent] });
NgxContentfulRichTextModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxContentfulRichTextModule, imports: [CommonModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: 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, RendererProviderService, TEXT };
//# sourceMappingURL=ngx-contentful-rich-text.mjs.map
//# sourceMappingURL=ngx-contentful-rich-text.mjs.map