@ethlete/contentful 3.9.0 → 4.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @ethlete/contentful
|
|
2
2
|
|
|
3
|
+
## 4.0.0-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`b71e18f`](https://github.com/ethlete-io/ethdk/commit/b71e18fba16c08be9da03a16ba9bd74239626485) Thanks [@TomTomB](https://github.com/TomTomB)! - Use router link for internal links in contentful renderer
|
|
8
|
+
|
|
9
|
+
## 4.0.0-next.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`99b3f64`](https://github.com/ethlete-io/ethdk/commit/99b3f646701cb763512e7148592457dc509f55e5), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`5503fbb`](https://github.com/ethlete-io/ethdk/commit/5503fbb21d948d4e2d59928afa4be9846eb2102d), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`58678e9`](https://github.com/ethlete-io/ethdk/commit/58678e9d57f7ff85e2a3159657bda15f06b8e5cd), [`f5ad487`](https://github.com/ethlete-io/ethdk/commit/f5ad4879061917e91bebf144889774226202308b), [`27aa7a8`](https://github.com/ethlete-io/ethdk/commit/27aa7a825573a12c3360530d1d32df7c4690e7e8), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`6816054`](https://github.com/ethlete-io/ethdk/commit/68160548e8df8cd8fbaff61afa684442f7f7a7e5), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`f4847d4`](https://github.com/ethlete-io/ethdk/commit/f4847d4eb25b70706a4ee8c81addcd58a7d99995), [`451e170`](https://github.com/ethlete-io/ethdk/commit/451e170f2df1c49fca07bde053efa75bd23ca22f), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`f5ad487`](https://github.com/ethlete-io/ethdk/commit/f5ad4879061917e91bebf144889774226202308b), [`55dc627`](https://github.com/ethlete-io/ethdk/commit/55dc627a6a49f3a8a5c8f80f63f163e443e07099), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`5d7ae57`](https://github.com/ethlete-io/ethdk/commit/5d7ae57859077357e2e8a1761286c4744e58d4b9), [`ee5014f`](https://github.com/ethlete-io/ethdk/commit/ee5014f33dc7d79b43774aaafc2fd187073871be), [`da0ef0a`](https://github.com/ethlete-io/ethdk/commit/da0ef0a6425c1ac40c42fd13906af49860418a29), [`7e0f4d9`](https://github.com/ethlete-io/ethdk/commit/7e0f4d943abe6ae61719fcb7003cc8c19496320e), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`3d7f302`](https://github.com/ethlete-io/ethdk/commit/3d7f30253502adada00825fda3653441c01071da), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`d8f381f`](https://github.com/ethlete-io/ethdk/commit/d8f381f39710db99c2f26af64dbf9e4df75c8a49), [`ca6cdfb`](https://github.com/ethlete-io/ethdk/commit/ca6cdfbaa99430a89244024a8810249bb99e3d91), [`6816054`](https://github.com/ethlete-io/ethdk/commit/68160548e8df8cd8fbaff61afa684442f7f7a7e5), [`6e41e09`](https://github.com/ethlete-io/ethdk/commit/6e41e09668d2077fba27de1e11bacc98480becfe), [`8a85984`](https://github.com/ethlete-io/ethdk/commit/8a859841acaf7c10c876c7eb921f4c7e25e41764), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb), [`d080bb2`](https://github.com/ethlete-io/ethdk/commit/d080bb2cc246d4559ffcbf88c319b9437133d377), [`e4a7c6f`](https://github.com/ethlete-io/ethdk/commit/e4a7c6ff868e6dd541d4533e509b30821f6c83b5), [`5e764b9`](https://github.com/ethlete-io/ethdk/commit/5e764b92cbcc6b6ec288a84b397d291f0b1138fb)]:
|
|
14
|
+
- @ethlete/cdk@5.0.0-next.0
|
|
15
|
+
- @ethlete/core@5.0.0-next.0
|
|
16
|
+
- @ethlete/query@6.0.0-next.0
|
|
17
|
+
|
|
3
18
|
## 3.9.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -136,7 +151,6 @@
|
|
|
136
151
|
### Major Changes
|
|
137
152
|
|
|
138
153
|
- [`ef63100`](https://github.com/ethlete-io/ethdk/commit/ef6310039b70c0321021a532b5818822518f47c6) Thanks [@TomTomB](https://github.com/TomTomB)! - The `rich-text-renderer` component was rebuild from scratch.
|
|
139
|
-
|
|
140
154
|
- The `richText` input was renamed to `content` and is required.
|
|
141
155
|
- The value of the `content` input should be a `ContentfulCollection` object. This can be directly fetched using the Contentful REST API. Do not use their GraphQL API for this purpose.
|
|
142
156
|
- A `richTextPath` input was added to allow for the customization of the path to the `richText` field in the `ContentfulCollection` object. It is required and should point to the start of the rich text object inside the `ContentfulCollection` object. The start contains a `nodeType` property with the value `document`.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { NgClass, DOCUMENT } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, InjectionToken, inject, numberAttribute, booleanAttribute, isDevMode, ViewContainerRef,
|
|
3
|
+
import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, InjectionToken, inject, numberAttribute, booleanAttribute, isDevMode, ViewContainerRef, ElementRef, reflectComponentType } from '@angular/core';
|
|
4
4
|
import { gql } from '@ethlete/query';
|
|
5
5
|
import { normalizePictureSizes, PictureComponent } from '@ethlete/cdk';
|
|
6
|
+
import { RouterLink } from '@angular/router';
|
|
6
7
|
import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
8
|
import { INLINES, BLOCKS } from '@contentful/rich-text-types';
|
|
8
|
-
import { RuntimeError, isObject, getObjectProperty } from '@ethlete/core';
|
|
9
|
+
import { RuntimeError, isObject, injectRenderer, getObjectProperty } from '@ethlete/core';
|
|
9
10
|
import { startWith, pairwise, tap } from 'rxjs';
|
|
10
11
|
|
|
11
12
|
const GQL_FRAGMENT_CONTENTFUL_ASSET = gql `
|
|
@@ -29,10 +30,10 @@ const isContentfulGqlAsset = (asset) => {
|
|
|
29
30
|
|
|
30
31
|
class ContentfulAudioComponent {
|
|
31
32
|
constructor() {
|
|
32
|
-
this.asset = input.required();
|
|
33
|
-
this.audioClass = input(null);
|
|
34
|
-
this.figureClass = input(null);
|
|
35
|
-
this.figcaptionClass = input(null);
|
|
33
|
+
this.asset = input.required(...(ngDevMode ? [{ debugName: "asset" }] : []));
|
|
34
|
+
this.audioClass = input(null, ...(ngDevMode ? [{ debugName: "audioClass" }] : []));
|
|
35
|
+
this.figureClass = input(null, ...(ngDevMode ? [{ debugName: "figureClass" }] : []));
|
|
36
|
+
this.figcaptionClass = input(null, ...(ngDevMode ? [{ debugName: "figcaptionClass" }] : []));
|
|
36
37
|
this.data = computed(() => {
|
|
37
38
|
const asset = this.asset();
|
|
38
39
|
if (!asset) {
|
|
@@ -48,10 +49,10 @@ class ContentfulAudioComponent {
|
|
|
48
49
|
url: asset.fields.file.url,
|
|
49
50
|
title: asset.fields.title,
|
|
50
51
|
};
|
|
51
|
-
});
|
|
52
|
+
}, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
52
53
|
}
|
|
53
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
54
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
54
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
55
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ContentfulAudioComponent, isStandalone: true, selector: "et-contentful-audio", inputs: { asset: { classPropertyName: "asset", publicName: "asset", isSignal: true, isRequired: true, transformFunction: null }, audioClass: { classPropertyName: "audioClass", publicName: "audioClass", isSignal: true, isRequired: false, transformFunction: null }, figureClass: { classPropertyName: "figureClass", publicName: "figureClass", isSignal: true, isRequired: false, transformFunction: null }, figcaptionClass: { classPropertyName: "figcaptionClass", publicName: "figcaptionClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
55
56
|
@if (data(); as data) {
|
|
56
57
|
<figure [ngClass]="figureClass()">
|
|
57
58
|
<figcaption [ngClass]="figcaptionClass()">{{ data.title }}</figcaption>
|
|
@@ -60,7 +61,7 @@ class ContentfulAudioComponent {
|
|
|
60
61
|
}
|
|
61
62
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
62
63
|
}
|
|
63
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
64
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulAudioComponent, decorators: [{
|
|
64
65
|
type: Component,
|
|
65
66
|
args: [{
|
|
66
67
|
selector: 'et-contentful-audio',
|
|
@@ -76,12 +77,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
|
|
|
76
77
|
encapsulation: ViewEncapsulation.None,
|
|
77
78
|
imports: [NgClass],
|
|
78
79
|
}]
|
|
79
|
-
}] });
|
|
80
|
+
}], propDecorators: { asset: [{ type: i0.Input, args: [{ isSignal: true, alias: "asset", required: true }] }], audioClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "audioClass", required: false }] }], figureClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "figureClass", required: false }] }], figcaptionClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "figcaptionClass", required: false }] }] } });
|
|
80
81
|
|
|
81
82
|
class ContentfulFileComponent {
|
|
82
83
|
constructor() {
|
|
83
|
-
this.asset = input.required();
|
|
84
|
-
this.fileClass = input(null);
|
|
84
|
+
this.asset = input.required(...(ngDevMode ? [{ debugName: "asset" }] : []));
|
|
85
|
+
this.fileClass = input(null, ...(ngDevMode ? [{ debugName: "fileClass" }] : []));
|
|
85
86
|
this.data = computed(() => {
|
|
86
87
|
const asset = this.asset();
|
|
87
88
|
if (!asset) {
|
|
@@ -101,10 +102,10 @@ class ContentfulFileComponent {
|
|
|
101
102
|
size: asset.fields.file.details.size,
|
|
102
103
|
title: asset.fields.title,
|
|
103
104
|
};
|
|
104
|
-
});
|
|
105
|
+
}, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
105
106
|
}
|
|
106
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
107
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
107
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
108
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ContentfulFileComponent, isStandalone: true, selector: "et-contentful-file", inputs: { asset: { classPropertyName: "asset", publicName: "asset", isSignal: true, isRequired: true, transformFunction: null }, fileClass: { classPropertyName: "fileClass", publicName: "fileClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
108
109
|
@if (data(); as data) {
|
|
109
110
|
<a [href]="data.url" [ngClass]="fileClass()" class="underline" target="_blank">
|
|
110
111
|
{{ data.title }} ({{ data.size }} Bytes)
|
|
@@ -112,7 +113,7 @@ class ContentfulFileComponent {
|
|
|
112
113
|
}
|
|
113
114
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
114
115
|
}
|
|
115
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulFileComponent, decorators: [{
|
|
116
117
|
type: Component,
|
|
117
118
|
args: [{
|
|
118
119
|
selector: 'et-contentful-file',
|
|
@@ -127,7 +128,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
|
|
|
127
128
|
encapsulation: ViewEncapsulation.None,
|
|
128
129
|
imports: [NgClass],
|
|
129
130
|
}]
|
|
130
|
-
}] });
|
|
131
|
+
}], propDecorators: { asset: [{ type: i0.Input, args: [{ isSignal: true, alias: "asset", required: true }] }], fileClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileClass", required: false }] }] } });
|
|
131
132
|
|
|
132
133
|
const CONTENTFUL_CONFIG = new InjectionToken('ContentfulConfig');
|
|
133
134
|
|
|
@@ -233,20 +234,18 @@ const generateContentfulImageSources = (data, srcsetSizes, backgroundColor, qual
|
|
|
233
234
|
class ContentfulImageComponent {
|
|
234
235
|
constructor() {
|
|
235
236
|
this._contentfulConfig = inject(CONTENTFUL_CONFIG);
|
|
236
|
-
this.asset = input.required();
|
|
237
|
-
this.backgroundColor = input(null);
|
|
238
|
-
this.srcsetSizes = input(this._contentfulConfig.imageOptions.srcsetSizes);
|
|
239
|
-
this.quality = input(null, { transform: numberAttribute });
|
|
240
|
-
this.focusArea = input(null);
|
|
241
|
-
this.resizeBehavior = input(null);
|
|
242
|
-
this.hasPriority = input(false, { transform: booleanAttribute });
|
|
243
|
-
this.imgClass = input(null);
|
|
244
|
-
this.figureClass = input(null);
|
|
245
|
-
this.figcaptionClass = input(null);
|
|
246
|
-
this.pictureClass = input(null);
|
|
247
|
-
this.sizes = input(normalizePictureSizes(this._contentfulConfig.imageOptions.sizes), {
|
|
248
|
-
transform: (v) => normalizePictureSizes(v),
|
|
249
|
-
});
|
|
237
|
+
this.asset = input.required(...(ngDevMode ? [{ debugName: "asset" }] : []));
|
|
238
|
+
this.backgroundColor = input(null, ...(ngDevMode ? [{ debugName: "backgroundColor" }] : []));
|
|
239
|
+
this.srcsetSizes = input(this._contentfulConfig.imageOptions.srcsetSizes, ...(ngDevMode ? [{ debugName: "srcsetSizes" }] : []));
|
|
240
|
+
this.quality = input(null, { ...(ngDevMode ? { debugName: "quality" } : {}), transform: numberAttribute });
|
|
241
|
+
this.focusArea = input(null, ...(ngDevMode ? [{ debugName: "focusArea" }] : []));
|
|
242
|
+
this.resizeBehavior = input(null, ...(ngDevMode ? [{ debugName: "resizeBehavior" }] : []));
|
|
243
|
+
this.hasPriority = input(false, { ...(ngDevMode ? { debugName: "hasPriority" } : {}), transform: booleanAttribute });
|
|
244
|
+
this.imgClass = input(null, ...(ngDevMode ? [{ debugName: "imgClass" }] : []));
|
|
245
|
+
this.figureClass = input(null, ...(ngDevMode ? [{ debugName: "figureClass" }] : []));
|
|
246
|
+
this.figcaptionClass = input(null, ...(ngDevMode ? [{ debugName: "figcaptionClass" }] : []));
|
|
247
|
+
this.pictureClass = input(null, ...(ngDevMode ? [{ debugName: "pictureClass" }] : []));
|
|
248
|
+
this.sizes = input(normalizePictureSizes(this._contentfulConfig.imageOptions.sizes), { ...(ngDevMode ? { debugName: "sizes" } : {}), transform: (v) => normalizePictureSizes(v) });
|
|
250
249
|
this.normalizedAsset = computed(() => {
|
|
251
250
|
const asset = this.asset();
|
|
252
251
|
if (isContentfulGqlAsset(asset)) {
|
|
@@ -265,7 +264,7 @@ class ContentfulImageComponent {
|
|
|
265
264
|
height: asset?.fields?.file?.details?.image?.height ?? null,
|
|
266
265
|
};
|
|
267
266
|
}
|
|
268
|
-
});
|
|
267
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedAsset" }] : []));
|
|
269
268
|
this._sources = computed(() => {
|
|
270
269
|
const asset = this.asset();
|
|
271
270
|
const backgroundColor = this.backgroundColor();
|
|
@@ -277,14 +276,14 @@ class ContentfulImageComponent {
|
|
|
277
276
|
return [];
|
|
278
277
|
}
|
|
279
278
|
return generateContentfulImageSources(asset, srcsetSizes, backgroundColor, quality, focusArea, resizeBehavior);
|
|
280
|
-
});
|
|
279
|
+
}, ...(ngDevMode ? [{ debugName: "_sources" }] : []));
|
|
281
280
|
this._defaultSrc = computed(() => {
|
|
282
281
|
const asset = this.asset();
|
|
283
282
|
return asset ? generateDefaultContentfulImageSource(asset) : null;
|
|
284
|
-
});
|
|
283
|
+
}, ...(ngDevMode ? [{ debugName: "_defaultSrc" }] : []));
|
|
285
284
|
}
|
|
286
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
287
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
285
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
286
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: ContentfulImageComponent, isStandalone: true, selector: "et-contentful-image", inputs: { asset: { classPropertyName: "asset", publicName: "asset", isSignal: true, isRequired: true, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, srcsetSizes: { classPropertyName: "srcsetSizes", publicName: "srcsetSizes", isSignal: true, isRequired: false, transformFunction: null }, quality: { classPropertyName: "quality", publicName: "quality", isSignal: true, isRequired: false, transformFunction: null }, focusArea: { classPropertyName: "focusArea", publicName: "focusArea", isSignal: true, isRequired: false, transformFunction: null }, resizeBehavior: { classPropertyName: "resizeBehavior", publicName: "resizeBehavior", isSignal: true, isRequired: false, transformFunction: null }, hasPriority: { classPropertyName: "hasPriority", publicName: "hasPriority", isSignal: true, isRequired: false, transformFunction: null }, imgClass: { classPropertyName: "imgClass", publicName: "imgClass", isSignal: true, isRequired: false, transformFunction: null }, figureClass: { classPropertyName: "figureClass", publicName: "figureClass", isSignal: true, isRequired: false, transformFunction: null }, figcaptionClass: { classPropertyName: "figcaptionClass", publicName: "figcaptionClass", isSignal: true, isRequired: false, transformFunction: null }, pictureClass: { classPropertyName: "pictureClass", publicName: "pictureClass", isSignal: true, isRequired: false, transformFunction: null }, sizes: { classPropertyName: "sizes", publicName: "sizes", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-contentful-image" }, ngImport: i0, template: `
|
|
288
287
|
<et-picture
|
|
289
288
|
[imgClass]="imgClass()"
|
|
290
289
|
[hasPriority]="hasPriority()"
|
|
@@ -301,7 +300,7 @@ class ContentfulImageComponent {
|
|
|
301
300
|
/>
|
|
302
301
|
`, isInline: true, dependencies: [{ kind: "component", type: PictureComponent, selector: "et-picture", inputs: ["sources", "hasPriority", "imgClass", "figureClass", "figcaptionClass", "pictureClass", "defaultSrc", "alt", "figcaption", "width", "height", "sizes"], outputs: ["imgLoaded", "imgError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
303
302
|
}
|
|
304
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulImageComponent, decorators: [{
|
|
305
304
|
type: Component,
|
|
306
305
|
args: [{
|
|
307
306
|
selector: 'et-contentful-image',
|
|
@@ -328,12 +327,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
|
|
|
328
327
|
class: 'et-contentful-image',
|
|
329
328
|
},
|
|
330
329
|
}]
|
|
331
|
-
}] });
|
|
330
|
+
}], propDecorators: { asset: [{ type: i0.Input, args: [{ isSignal: true, alias: "asset", required: true }] }], backgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundColor", required: false }] }], srcsetSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "srcsetSizes", required: false }] }], quality: [{ type: i0.Input, args: [{ isSignal: true, alias: "quality", required: false }] }], focusArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusArea", required: false }] }], resizeBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizeBehavior", required: false }] }], hasPriority: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPriority", required: false }] }], imgClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "imgClass", required: false }] }], figureClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "figureClass", required: false }] }], figcaptionClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "figcaptionClass", required: false }] }], pictureClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pictureClass", required: false }] }], sizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizes", required: false }] }] } });
|
|
332
331
|
|
|
333
332
|
class ContentfulVideoComponent {
|
|
334
333
|
constructor() {
|
|
335
|
-
this.asset = input.required();
|
|
336
|
-
this.videoClass = input(null);
|
|
334
|
+
this.asset = input.required(...(ngDevMode ? [{ debugName: "asset" }] : []));
|
|
335
|
+
this.videoClass = input(null, ...(ngDevMode ? [{ debugName: "videoClass" }] : []));
|
|
337
336
|
this.data = computed(() => {
|
|
338
337
|
const asset = this.asset();
|
|
339
338
|
if (!asset) {
|
|
@@ -349,10 +348,10 @@ class ContentfulVideoComponent {
|
|
|
349
348
|
url: asset.fields.file.url,
|
|
350
349
|
contentType: asset.fields.file.contentType,
|
|
351
350
|
};
|
|
352
|
-
});
|
|
351
|
+
}, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
353
352
|
}
|
|
354
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
355
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
353
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulVideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
354
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ContentfulVideoComponent, isStandalone: true, selector: "et-contentful-video", inputs: { asset: { classPropertyName: "asset", publicName: "asset", isSignal: true, isRequired: true, transformFunction: null }, videoClass: { classPropertyName: "videoClass", publicName: "videoClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
356
355
|
@if (data(); as data) {
|
|
357
356
|
<video [ngClass]="videoClass()" controls>
|
|
358
357
|
<source src="{{ data.url }}" type="{{ data.contentType }}" />
|
|
@@ -360,7 +359,7 @@ class ContentfulVideoComponent {
|
|
|
360
359
|
}
|
|
361
360
|
`, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
362
361
|
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
362
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulVideoComponent, decorators: [{
|
|
364
363
|
type: Component,
|
|
365
364
|
args: [{
|
|
366
365
|
selector: 'et-contentful-video',
|
|
@@ -375,17 +374,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
|
|
|
375
374
|
encapsulation: ViewEncapsulation.None,
|
|
376
375
|
imports: [NgClass],
|
|
377
376
|
}]
|
|
378
|
-
}] });
|
|
377
|
+
}], propDecorators: { asset: [{ type: i0.Input, args: [{ isSignal: true, alias: "asset", required: true }] }], videoClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "videoClass", required: false }] }] } });
|
|
379
378
|
|
|
380
379
|
const createContentfulConfig = (config = {}) => ({
|
|
381
380
|
// This default config must be inline and not saved inside a const for some weird webpack reason
|
|
382
381
|
...{
|
|
383
382
|
useTailwindClasses: false,
|
|
383
|
+
internalHosts: [],
|
|
384
384
|
components: {
|
|
385
385
|
audio: ContentfulAudioComponent,
|
|
386
386
|
file: ContentfulFileComponent,
|
|
387
387
|
image: ContentfulImageComponent,
|
|
388
388
|
video: ContentfulVideoComponent,
|
|
389
|
+
link: ContentfulLinkComponent,
|
|
389
390
|
},
|
|
390
391
|
customComponents: {},
|
|
391
392
|
imageOptions: {
|
|
@@ -397,6 +398,107 @@ const createContentfulConfig = (config = {}) => ({
|
|
|
397
398
|
...(config || {}),
|
|
398
399
|
});
|
|
399
400
|
|
|
401
|
+
const getPrimaryDomain = (host) => {
|
|
402
|
+
const parts = host.split('.');
|
|
403
|
+
return parts.length > 2 ? parts.slice(-2).join('.') : host;
|
|
404
|
+
};
|
|
405
|
+
class ContentfulLinkComponent {
|
|
406
|
+
constructor() {
|
|
407
|
+
this._document = inject(DOCUMENT);
|
|
408
|
+
this._config = inject(CONTENTFUL_CONFIG, { optional: true }) ?? createContentfulConfig();
|
|
409
|
+
this.href = input.required(...(ngDevMode ? [{ debugName: "href" }] : []));
|
|
410
|
+
this.text = input.required(...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
411
|
+
this.textClass = input('', ...(ngDevMode ? [{ debugName: "textClass" }] : []));
|
|
412
|
+
this.isExternal = computed(() => {
|
|
413
|
+
const href = this.href();
|
|
414
|
+
const isAbsolute = href.startsWith('http://') || href.startsWith('https://') || href.startsWith('//');
|
|
415
|
+
if (!isAbsolute)
|
|
416
|
+
return false;
|
|
417
|
+
try {
|
|
418
|
+
const parsed = new URL(href.startsWith('//') ? `https:${href}` : href);
|
|
419
|
+
const internalHosts = [this._document.location.host, ...this._config.internalHosts];
|
|
420
|
+
return !internalHosts.includes(parsed.host);
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
}, ...(ngDevMode ? [{ debugName: "isExternal" }] : []));
|
|
426
|
+
this.openInNewTab = computed(() => {
|
|
427
|
+
if (!this.isExternal())
|
|
428
|
+
return false;
|
|
429
|
+
const href = this.href();
|
|
430
|
+
try {
|
|
431
|
+
const parsed = new URL(href.startsWith('//') ? `https:${href}` : href);
|
|
432
|
+
const internalPrimaryDomains = [
|
|
433
|
+
getPrimaryDomain(this._document.location.host),
|
|
434
|
+
...this._config.internalHosts.map(getPrimaryDomain),
|
|
435
|
+
];
|
|
436
|
+
return !internalPrimaryDomains.includes(getPrimaryDomain(parsed.host));
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
}, ...(ngDevMode ? [{ debugName: "openInNewTab" }] : []));
|
|
442
|
+
this.internalPath = computed(() => {
|
|
443
|
+
const href = this.href();
|
|
444
|
+
if (!href.startsWith('http://') && !href.startsWith('https://') && !href.startsWith('//')) {
|
|
445
|
+
return href;
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
const url = new URL(href.startsWith('//') ? `https:${href}` : href);
|
|
449
|
+
return url.pathname + url.search + url.hash;
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
return href;
|
|
453
|
+
}
|
|
454
|
+
}, ...(ngDevMode ? [{ debugName: "internalPath" }] : []));
|
|
455
|
+
this.linkClass = computed(() => {
|
|
456
|
+
const base = 'et-contentful-rich-text-default-element et-contentful-rich-text-default-a';
|
|
457
|
+
const extra = this.textClass();
|
|
458
|
+
return extra ? `${base} ${extra}` : base;
|
|
459
|
+
}, ...(ngDevMode ? [{ debugName: "linkClass" }] : []));
|
|
460
|
+
}
|
|
461
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
462
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ContentfulLinkComponent, isStandalone: true, selector: "et-contentful-link", inputs: { href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: true, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: `
|
|
463
|
+
@if (isExternal()) {
|
|
464
|
+
<a
|
|
465
|
+
[class]="linkClass()"
|
|
466
|
+
[href]="href()"
|
|
467
|
+
[target]="openInNewTab() ? '_blank' : null"
|
|
468
|
+
[rel]="openInNewTab() ? 'noopener noreferrer' : null"
|
|
469
|
+
>{{ text() }}</a
|
|
470
|
+
>
|
|
471
|
+
} @else {
|
|
472
|
+
<a [class]="linkClass()" [routerLink]="internalPath()">{{ text() }}</a>
|
|
473
|
+
}
|
|
474
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
475
|
+
}
|
|
476
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulLinkComponent, decorators: [{
|
|
477
|
+
type: Component,
|
|
478
|
+
args: [{
|
|
479
|
+
selector: 'et-contentful-link',
|
|
480
|
+
template: `
|
|
481
|
+
@if (isExternal()) {
|
|
482
|
+
<a
|
|
483
|
+
[class]="linkClass()"
|
|
484
|
+
[href]="href()"
|
|
485
|
+
[target]="openInNewTab() ? '_blank' : null"
|
|
486
|
+
[rel]="openInNewTab() ? 'noopener noreferrer' : null"
|
|
487
|
+
>{{ text() }}</a
|
|
488
|
+
>
|
|
489
|
+
} @else {
|
|
490
|
+
<a [class]="linkClass()" [routerLink]="internalPath()">{{ text() }}</a>
|
|
491
|
+
}
|
|
492
|
+
`,
|
|
493
|
+
host: {
|
|
494
|
+
style: 'display: contents',
|
|
495
|
+
},
|
|
496
|
+
imports: [RouterLink],
|
|
497
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
498
|
+
encapsulation: ViewEncapsulation.None,
|
|
499
|
+
}]
|
|
500
|
+
}], propDecorators: { href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: true }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], textClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "textClass", required: false }] }] } });
|
|
501
|
+
|
|
400
502
|
const RICH_TEXT_RENDERER_ERRORS = {
|
|
401
503
|
rich_text_undefined: 'The property value given at richTextPath is undefined. Use the richTextPath input to specify the path to the rich text object.',
|
|
402
504
|
rich_text_wrong_type: 'The rich text object does not satisfy the RichTextResponse interface. It should contain a property named "nodeType" with the value "document".',
|
|
@@ -456,8 +558,6 @@ const translateContentfulNodeTypeToHtmlTag = (nodeType) => {
|
|
|
456
558
|
return 'th';
|
|
457
559
|
case BLOCKS.EMBEDDED_ASSET:
|
|
458
560
|
return 'div';
|
|
459
|
-
case INLINES.HYPERLINK:
|
|
460
|
-
return 'a';
|
|
461
561
|
case INLINES.ENTRY_HYPERLINK:
|
|
462
562
|
return 'a';
|
|
463
563
|
case INLINES.ASSET_HYPERLINK:
|
|
@@ -466,7 +566,7 @@ const translateContentfulNodeTypeToHtmlTag = (nodeType) => {
|
|
|
466
566
|
return 'span';
|
|
467
567
|
// Will be ignored by the renderer
|
|
468
568
|
case 'document':
|
|
469
|
-
return '
|
|
569
|
+
return 'div';
|
|
470
570
|
case BLOCKS.EMBEDDED_ENTRY:
|
|
471
571
|
return 'div';
|
|
472
572
|
case INLINES.EMBEDDED_ENTRY:
|
|
@@ -568,6 +668,7 @@ const DEFAULT_COMPONENT_TYPES = {
|
|
|
568
668
|
VIDEO: '$$$_et-video',
|
|
569
669
|
AUDIO: '$$$_et-audio',
|
|
570
670
|
FILE: '$$$_et-file',
|
|
671
|
+
LINK: '$$$_et-link',
|
|
571
672
|
};
|
|
572
673
|
const isExecutedComponentCommandCacheItem = (cache) => {
|
|
573
674
|
return isComponentRenderCommand(cache.command);
|
|
@@ -633,7 +734,7 @@ const createContentfulIncludeMap = (config) => {
|
|
|
633
734
|
class ContentfulRichTextRendererComponent {
|
|
634
735
|
constructor() {
|
|
635
736
|
this._viewContainerRef = inject(ViewContainerRef);
|
|
636
|
-
this._renderer =
|
|
737
|
+
this._renderer = injectRenderer();
|
|
637
738
|
this._elementRef = inject(ElementRef);
|
|
638
739
|
this._document = inject(DOCUMENT);
|
|
639
740
|
this._config = inject(CONTENTFUL_CONFIG, { optional: true }) ?? createContentfulConfig();
|
|
@@ -647,12 +748,12 @@ class ContentfulRichTextRendererComponent {
|
|
|
647
748
|
* The contentful response gotten via their REST api.
|
|
648
749
|
* @see https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/entries/entries-collection
|
|
649
750
|
*/
|
|
650
|
-
this.content = input.required();
|
|
751
|
+
this.content = input.required(...(ngDevMode ? [{ debugName: "content" }] : []));
|
|
651
752
|
/**
|
|
652
753
|
* The path to where the rich text field is inside the contentful response. Dot and array notation is allowed.
|
|
653
754
|
* @example "items[0].fields.html"
|
|
654
755
|
*/
|
|
655
|
-
this.richTextPath = input.required();
|
|
756
|
+
this.richTextPath = input.required(...(ngDevMode ? [{ debugName: "richTextPath" }] : []));
|
|
656
757
|
/**
|
|
657
758
|
* A map of all includes in the contentful response.
|
|
658
759
|
* This is useful for looking up assets and entries that are referenced in the rich text without having to use loops.
|
|
@@ -662,7 +763,7 @@ class ContentfulRichTextRendererComponent {
|
|
|
662
763
|
const assets = content?.includes.Asset;
|
|
663
764
|
const entries = content?.includes.Entry;
|
|
664
765
|
return createContentfulIncludeMap({ assets: assets ?? [], entries: entries ?? [] });
|
|
665
|
-
});
|
|
766
|
+
}, ...(ngDevMode ? [{ debugName: "contentIncludesMap" }] : []));
|
|
666
767
|
/**
|
|
667
768
|
* The rich text data that should be rendered.
|
|
668
769
|
*/
|
|
@@ -680,14 +781,14 @@ class ContentfulRichTextRendererComponent {
|
|
|
680
781
|
throw richTextRendererError('rich_text_wrong_type', false, { content, richTextPath });
|
|
681
782
|
}
|
|
682
783
|
return richText;
|
|
683
|
-
});
|
|
784
|
+
}, ...(ngDevMode ? [{ debugName: "richTextData" }] : []));
|
|
684
785
|
this.renderCommands = computed(() => {
|
|
685
786
|
const richTextData = this.richTextData();
|
|
686
787
|
if (!richTextData) {
|
|
687
788
|
return [];
|
|
688
789
|
}
|
|
689
790
|
return this._createRenderCommands(richTextData);
|
|
690
|
-
});
|
|
791
|
+
}, ...(ngDevMode ? [{ debugName: "renderCommands" }] : []));
|
|
691
792
|
this.renderCommandHistory = toSignal(toObservable(this.renderCommands).pipe(startWith([]), pairwise()), { initialValue: [[], []] });
|
|
692
793
|
this.previousRenderCommandMap = computed(() => {
|
|
693
794
|
const [prevCommands] = this.renderCommandHistory();
|
|
@@ -696,7 +797,7 @@ class ContentfulRichTextRendererComponent {
|
|
|
696
797
|
map.set(getRenderCommandId(command), command);
|
|
697
798
|
}
|
|
698
799
|
return map;
|
|
699
|
-
});
|
|
800
|
+
}, ...(ngDevMode ? [{ debugName: "previousRenderCommandMap" }] : []));
|
|
700
801
|
this.renderInstructions = computed(() => {
|
|
701
802
|
const commands = this.renderCommands();
|
|
702
803
|
const previousRenderCommandMap = new Map(this.previousRenderCommandMap());
|
|
@@ -762,7 +863,7 @@ class ContentfulRichTextRendererComponent {
|
|
|
762
863
|
}
|
|
763
864
|
}
|
|
764
865
|
return instructions;
|
|
765
|
-
});
|
|
866
|
+
}, ...(ngDevMode ? [{ debugName: "renderInstructions" }] : []));
|
|
766
867
|
toObservable(this.renderInstructions)
|
|
767
868
|
.pipe(takeUntilDestroyed(), tap((instructions) => {
|
|
768
869
|
this._execInstructions(instructions);
|
|
@@ -870,6 +971,35 @@ class ContentfulRichTextRendererComponent {
|
|
|
870
971
|
domPosition++;
|
|
871
972
|
break;
|
|
872
973
|
}
|
|
974
|
+
case INLINES.HYPERLINK: {
|
|
975
|
+
const uri = node.data['uri'] ?? '';
|
|
976
|
+
// Collect all text and marks from children (hyperlink children are text nodes)
|
|
977
|
+
let linkText = '';
|
|
978
|
+
const linkMarks = [];
|
|
979
|
+
for (const child of node.content) {
|
|
980
|
+
if (child.nodeType === 'text') {
|
|
981
|
+
linkText += child.value;
|
|
982
|
+
linkMarks.push(...child.marks);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
const textClass = linkMarks.length ? marksToClass(linkMarks) : '';
|
|
986
|
+
let linkComponentId = componentIdMap.get(DEFAULT_COMPONENT_TYPES.LINK) ?? -1;
|
|
987
|
+
const linkId = DEFAULT_COMPONENT_TYPES.LINK + ++linkComponentId;
|
|
988
|
+
componentIdMap.set(DEFAULT_COMPONENT_TYPES.LINK, linkComponentId);
|
|
989
|
+
const linkCommand = [
|
|
990
|
+
RENDER_COMMAND_TYPE.COMPONENT,
|
|
991
|
+
nestingLevel,
|
|
992
|
+
domPosition,
|
|
993
|
+
commandIndex++,
|
|
994
|
+
{},
|
|
995
|
+
this._config.components.link,
|
|
996
|
+
{ href: uri, text: linkText, textClass },
|
|
997
|
+
linkId,
|
|
998
|
+
];
|
|
999
|
+
rootCommands.push(linkCommand);
|
|
1000
|
+
domPosition++;
|
|
1001
|
+
break;
|
|
1002
|
+
}
|
|
873
1003
|
case BLOCKS.EMBEDDED_ENTRY:
|
|
874
1004
|
case INLINES.EMBEDDED_ENTRY: {
|
|
875
1005
|
// Render component
|
|
@@ -955,15 +1085,6 @@ class ContentfulRichTextRendererComponent {
|
|
|
955
1085
|
rootCommands.push(closeCommand);
|
|
956
1086
|
domPosition++;
|
|
957
1087
|
}
|
|
958
|
-
if (node.nodeType === INLINES.HYPERLINK) {
|
|
959
|
-
const uri = node.data['uri'];
|
|
960
|
-
attributes['href'] = uri;
|
|
961
|
-
const host = this._document.location.host;
|
|
962
|
-
const isExternal = !uri.includes(host);
|
|
963
|
-
if (isExternal) {
|
|
964
|
-
attributes['target'] = '_blank';
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
1088
|
break;
|
|
968
1089
|
}
|
|
969
1090
|
}
|
|
@@ -1088,7 +1209,9 @@ class ContentfulRichTextRendererComponent {
|
|
|
1088
1209
|
}
|
|
1089
1210
|
const rootNode = cached.element;
|
|
1090
1211
|
const oldParentElement = cached.element.parentElement;
|
|
1091
|
-
|
|
1212
|
+
if (oldParentElement) {
|
|
1213
|
+
this._renderer.removeChild(oldParentElement, rootNode);
|
|
1214
|
+
}
|
|
1092
1215
|
const newParentElement = this._findParent(command);
|
|
1093
1216
|
const nextElement = this._findFollowingElement(command);
|
|
1094
1217
|
this._renderInsertOrAppend(rootNode, newParentElement, nextElement);
|
|
@@ -1115,10 +1238,14 @@ class ContentfulRichTextRendererComponent {
|
|
|
1115
1238
|
cached.componentRef?.destroy();
|
|
1116
1239
|
}
|
|
1117
1240
|
else if (isTextRenderCommand(command)) {
|
|
1118
|
-
|
|
1241
|
+
if (cached.element?.parentElement) {
|
|
1242
|
+
this._renderer.removeChild(cached.element.parentElement, cached.element);
|
|
1243
|
+
}
|
|
1119
1244
|
}
|
|
1120
1245
|
else if (isHtmlOpenRenderCommand(command)) {
|
|
1121
|
-
|
|
1246
|
+
if (cached.element?.parentElement) {
|
|
1247
|
+
this._renderer.removeChild(cached.element.parentElement, cached.element);
|
|
1248
|
+
}
|
|
1122
1249
|
}
|
|
1123
1250
|
this._executedCommandsCache.delete(id);
|
|
1124
1251
|
}
|
|
@@ -1126,16 +1253,19 @@ class ContentfulRichTextRendererComponent {
|
|
|
1126
1253
|
return componentRef.hostView.rootNodes[0];
|
|
1127
1254
|
}
|
|
1128
1255
|
_updateComponentInputs(command, componentRef) {
|
|
1256
|
+
const inputMeta = reflectComponentType(command[COMPONENT_RENDER_COMMAND_POSITION.COMPONENT])?.inputs ?? [];
|
|
1257
|
+
const inputsByProp = new Map(inputMeta.map((i) => [i.propName, i.templateName]));
|
|
1129
1258
|
for (const [key, value] of Object.entries(command[COMPONENT_RENDER_COMMAND_POSITION.INPUTS])) {
|
|
1130
|
-
|
|
1259
|
+
const publicName = inputsByProp.get(key);
|
|
1260
|
+
if (publicName === undefined)
|
|
1131
1261
|
continue;
|
|
1132
|
-
componentRef.setInput(
|
|
1262
|
+
componentRef.setInput(publicName, value);
|
|
1133
1263
|
}
|
|
1134
1264
|
}
|
|
1135
1265
|
_findParent(command) {
|
|
1136
1266
|
const hostElement = this._elementRef.nativeElement;
|
|
1137
1267
|
const nestingLevel = command[RENDER_COMMAND_POSITION.NESTING_LEVEL];
|
|
1138
|
-
let parentElement
|
|
1268
|
+
let parentElement;
|
|
1139
1269
|
if (nestingLevel === 0) {
|
|
1140
1270
|
parentElement = hostElement;
|
|
1141
1271
|
}
|
|
@@ -1194,22 +1324,21 @@ class ContentfulRichTextRendererComponent {
|
|
|
1194
1324
|
this._renderer.appendChild(parentElement, nodeToRender);
|
|
1195
1325
|
}
|
|
1196
1326
|
}
|
|
1197
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1198
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
1327
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulRichTextRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1328
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: ContentfulRichTextRendererComponent, isStandalone: true, selector: "et-contentful-rich-text-renderer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, richTextPath: { classPropertyName: "richTextPath", publicName: "richTextPath", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "et-contentful-rich-text-renderer" }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1199
1329
|
}
|
|
1200
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1330
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ContentfulRichTextRendererComponent, decorators: [{
|
|
1201
1331
|
type: Component,
|
|
1202
1332
|
args: [{
|
|
1203
1333
|
selector: 'et-contentful-rich-text-renderer',
|
|
1204
1334
|
template: ``,
|
|
1205
1335
|
encapsulation: ViewEncapsulation.None,
|
|
1206
1336
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1207
|
-
standalone: true,
|
|
1208
1337
|
host: {
|
|
1209
1338
|
class: 'et-contentful-rich-text-renderer',
|
|
1210
1339
|
},
|
|
1211
1340
|
}]
|
|
1212
|
-
}], ctorParameters: () => [] });
|
|
1341
|
+
}], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: true }] }], richTextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "richTextPath", required: true }] }] } });
|
|
1213
1342
|
|
|
1214
1343
|
const ContentfulImports = [
|
|
1215
1344
|
ContentfulAudioComponent,
|
|
@@ -1230,5 +1359,5 @@ const isContentfulEntryType = (entry, type) => entry.sys.contentType.sys.id ===
|
|
|
1230
1359
|
* Generated bundle index. Do not edit.
|
|
1231
1360
|
*/
|
|
1232
1361
|
|
|
1233
|
-
export { COMPONENT_RENDER_COMMAND_POSITION, CONTENTFUL_CONFIG, ContentfulAudioComponent, ContentfulFileComponent, ContentfulImageComponent, ContentfulImports, ContentfulRichTextRendererComponent, ContentfulVideoComponent, ET_CONTENTFUL_ANY_ENTRY_CONTENT_TYPE_SYS_ID, GQL_FRAGMENT_CONTENTFUL_ASSET, HTML_CLOSE_RENDER_COMMAND_POSITION, HTML_OPEN_RENDER_COMMAND_POSITION, RENDER_COMMAND_POSITION, RENDER_COMMAND_TYPE, RENDER_INSTRUCTION_POSITION, RENDER_INSTRUCTION_TYPE, TEXT_RENDER_COMMAND_POSITION, createContentfulConfig, createContentfulIncludeMap, generateContentfulImageSources, generateDefaultContentfulImageSource, getRenderCommandId, isComponentRenderCommand, isContentfulEntryType, isContentfulGqlAsset, isExecutedComponentCommandCacheItem, isExecutedHtmlOrTextCommandCacheItem, isExecutedTextCommandCacheItem, isHtmlCloseRenderCommand, isHtmlOpenRenderCommand, isRichTextRootNode, isTextRenderCommand, marksToClass, parseContentfulImageSize, provideContentfulConfig, translateContentfulNodeTypeToHtmlTag };
|
|
1362
|
+
export { COMPONENT_RENDER_COMMAND_POSITION, CONTENTFUL_CONFIG, ContentfulAudioComponent, ContentfulFileComponent, ContentfulImageComponent, ContentfulImports, ContentfulLinkComponent, ContentfulRichTextRendererComponent, ContentfulVideoComponent, ET_CONTENTFUL_ANY_ENTRY_CONTENT_TYPE_SYS_ID, GQL_FRAGMENT_CONTENTFUL_ASSET, HTML_CLOSE_RENDER_COMMAND_POSITION, HTML_OPEN_RENDER_COMMAND_POSITION, RENDER_COMMAND_POSITION, RENDER_COMMAND_TYPE, RENDER_INSTRUCTION_POSITION, RENDER_INSTRUCTION_TYPE, TEXT_RENDER_COMMAND_POSITION, createContentfulConfig, createContentfulIncludeMap, generateContentfulImageSources, generateDefaultContentfulImageSource, getRenderCommandId, isComponentRenderCommand, isContentfulEntryType, isContentfulGqlAsset, isExecutedComponentCommandCacheItem, isExecutedHtmlOrTextCommandCacheItem, isExecutedTextCommandCacheItem, isHtmlCloseRenderCommand, isHtmlOpenRenderCommand, isRichTextRootNode, isTextRenderCommand, marksToClass, parseContentfulImageSize, provideContentfulConfig, translateContentfulNodeTypeToHtmlTag };
|
|
1234
1363
|
//# sourceMappingURL=ethlete-contentful.mjs.map
|