@dotcms/angular 0.0.1-beta.4 → 0.0.1-beta.41

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.
Files changed (165) hide show
  1. package/README.md +646 -167
  2. package/dotcms-angular.d.ts.map +1 -1
  3. package/esm2022/dotcms-angular.mjs +2 -2
  4. package/esm2022/lib/deprecated/components/dot-editable-text/dot-editable-text.component.mjs +229 -0
  5. package/esm2022/lib/deprecated/components/dot-editable-text/utils.mjs +43 -0
  6. package/esm2022/lib/deprecated/components/no-component/no-component.component.mjs +32 -0
  7. package/esm2022/lib/deprecated/deprecated-api.mjs +11 -0
  8. package/esm2022/lib/{layout → deprecated/layout}/column/column.component.mjs +1 -1
  9. package/esm2022/lib/deprecated/layout/container/container.component.mjs +126 -0
  10. package/esm2022/lib/deprecated/layout/contentlet/contentlet.component.mjs +120 -0
  11. package/esm2022/lib/deprecated/layout/dotcms-layout/dotcms-layout.component.mjs +106 -0
  12. package/esm2022/lib/{layout → deprecated/layout}/row/row.component.mjs +1 -1
  13. package/esm2022/lib/deprecated/models/dotcms.model.mjs +3 -0
  14. package/esm2022/lib/deprecated/models/index.mjs +3 -0
  15. package/esm2022/lib/deprecated/services/dotcms-context/page-context.service.mjs +79 -0
  16. package/esm2022/lib/deprecated/utils/image_loader.mjs +74 -0
  17. package/esm2022/lib/deprecated/utils/index.mjs +84 -0
  18. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/code.component.mjs +49 -0
  19. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/dot-contentlet.component.mjs +125 -0
  20. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/image.component.mjs +25 -0
  21. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/list.component.mjs +66 -0
  22. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/table.component.mjs +97 -0
  23. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/text.component.mjs +231 -0
  24. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/unknown.component.mjs +65 -0
  25. package/esm2022/next/components/dotcms-block-editor-renderer/blocks/video.component.mjs +48 -0
  26. package/esm2022/next/components/dotcms-block-editor-renderer/dotcms-block-editor-renderer.component.mjs +50 -0
  27. package/esm2022/next/components/dotcms-block-editor-renderer/item/dotcms-block-editor-item.component.mjs +45 -0
  28. package/esm2022/next/components/dotcms-editable-text/dotcms-editable-text.component.mjs +240 -0
  29. package/esm2022/next/components/dotcms-editable-text/utils.mjs +20 -0
  30. package/esm2022/next/components/dotcms-layout-body/components/column/column.component.mjs +45 -0
  31. package/esm2022/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.mjs +52 -0
  32. package/esm2022/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.mjs +47 -0
  33. package/esm2022/next/components/dotcms-layout-body/components/container/container.component.mjs +99 -0
  34. package/esm2022/next/components/dotcms-layout-body/components/contentlet/contentlet.component.mjs +145 -0
  35. package/esm2022/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.mjs +47 -0
  36. package/esm2022/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.mjs +55 -0
  37. package/esm2022/next/components/dotcms-layout-body/components/row/row.component.mjs +46 -0
  38. package/esm2022/next/components/dotcms-layout-body/dotcms-layout-body.component.mjs +69 -0
  39. package/esm2022/next/directives/dotcms-show-when/dotcms-show-when.directive.mjs +49 -0
  40. package/esm2022/next/dotcms-angular-next.mjs +5 -0
  41. package/esm2022/next/models/index.mjs +3 -0
  42. package/esm2022/next/providers/dotcms-client/dotcms-client.provider.mjs +52 -0
  43. package/esm2022/next/providers/dotcms-image-loader/dotcms-image_loader.mjs +74 -0
  44. package/esm2022/next/public_api.mjs +8 -0
  45. package/esm2022/next/services/dotcms-editable-page.service.mjs +93 -0
  46. package/esm2022/next/store/dotcms.store.mjs +61 -0
  47. package/esm2022/public_api.mjs +2 -0
  48. package/fesm2022/dotcms-angular-next.mjs +1904 -0
  49. package/fesm2022/dotcms-angular-next.mjs.map +1 -0
  50. package/fesm2022/dotcms-angular.mjs +103 -10
  51. package/fesm2022/dotcms-angular.mjs.map +1 -1
  52. package/index.d.ts +6 -5
  53. package/lib/{components → deprecated/components}/dot-editable-text/dot-editable-text.component.d.ts +10 -6
  54. package/lib/deprecated/components/dot-editable-text/dot-editable-text.component.d.ts.map +1 -0
  55. package/lib/deprecated/components/dot-editable-text/utils.d.ts.map +1 -0
  56. package/lib/deprecated/components/no-component/no-component.component.d.ts.map +1 -0
  57. package/lib/deprecated/deprecated-api.d.ts +11 -0
  58. package/lib/deprecated/deprecated-api.d.ts.map +1 -0
  59. package/lib/deprecated/layout/column/column.component.d.ts.map +1 -0
  60. package/lib/deprecated/layout/container/container.component.d.ts.map +1 -0
  61. package/lib/deprecated/layout/contentlet/contentlet.component.d.ts.map +1 -0
  62. package/lib/{layout → deprecated/layout}/dotcms-layout/dotcms-layout.component.d.ts +5 -0
  63. package/lib/deprecated/layout/dotcms-layout/dotcms-layout.component.d.ts.map +1 -0
  64. package/lib/deprecated/layout/row/row.component.d.ts.map +1 -0
  65. package/lib/{models → deprecated/models}/dotcms.model.d.ts +2 -2
  66. package/lib/deprecated/models/dotcms.model.d.ts.map +1 -0
  67. package/lib/deprecated/models/index.d.ts.map +1 -0
  68. package/lib/{services → deprecated/services}/dotcms-context/page-context.service.d.ts +4 -0
  69. package/lib/deprecated/services/dotcms-context/page-context.service.d.ts.map +1 -0
  70. package/lib/deprecated/utils/image_loader.d.ts +21 -0
  71. package/lib/deprecated/utils/image_loader.d.ts.map +1 -0
  72. package/lib/deprecated/utils/index.d.ts.map +1 -0
  73. package/next/components/dotcms-block-editor-renderer/blocks/code.component.d.ts +10 -0
  74. package/next/components/dotcms-block-editor-renderer/blocks/code.component.d.ts.map +1 -0
  75. package/next/components/dotcms-block-editor-renderer/blocks/dot-contentlet.component.d.ts +34 -0
  76. package/next/components/dotcms-block-editor-renderer/blocks/dot-contentlet.component.d.ts.map +1 -0
  77. package/next/components/dotcms-block-editor-renderer/blocks/image.component.d.ts +9 -0
  78. package/next/components/dotcms-block-editor-renderer/blocks/image.component.d.ts.map +1 -0
  79. package/next/components/dotcms-block-editor-renderer/blocks/list.component.d.ts +14 -0
  80. package/next/components/dotcms-block-editor-renderer/blocks/list.component.d.ts.map +1 -0
  81. package/next/components/dotcms-block-editor-renderer/blocks/table.component.d.ts +10 -0
  82. package/next/components/dotcms-block-editor-renderer/blocks/table.component.d.ts.map +1 -0
  83. package/next/components/dotcms-block-editor-renderer/blocks/text.component.d.ts +27 -0
  84. package/next/components/dotcms-block-editor-renderer/blocks/text.component.d.ts.map +1 -0
  85. package/next/components/dotcms-block-editor-renderer/blocks/unknown.component.d.ts +18 -0
  86. package/next/components/dotcms-block-editor-renderer/blocks/unknown.component.d.ts.map +1 -0
  87. package/next/components/dotcms-block-editor-renderer/blocks/video.component.d.ts +10 -0
  88. package/next/components/dotcms-block-editor-renderer/blocks/video.component.d.ts.map +1 -0
  89. package/next/components/dotcms-block-editor-renderer/dotcms-block-editor-renderer.component.d.ts +39 -0
  90. package/next/components/dotcms-block-editor-renderer/dotcms-block-editor-renderer.component.d.ts.map +1 -0
  91. package/next/components/dotcms-block-editor-renderer/item/dotcms-block-editor-item.component.d.ts +12 -0
  92. package/next/components/dotcms-block-editor-renderer/item/dotcms-block-editor-item.component.d.ts.map +1 -0
  93. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts +129 -0
  94. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts.map +1 -0
  95. package/next/components/dotcms-editable-text/utils.d.ts +7 -0
  96. package/next/components/dotcms-editable-text/utils.d.ts.map +1 -0
  97. package/next/components/dotcms-layout-body/components/column/column.component.d.ts +21 -0
  98. package/next/components/dotcms-layout-body/components/column/column.component.d.ts.map +1 -0
  99. package/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.d.ts +27 -0
  100. package/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.d.ts.map +1 -0
  101. package/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.d.ts +23 -0
  102. package/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.d.ts.map +1 -0
  103. package/next/components/dotcms-layout-body/components/container/container.component.d.ts +32 -0
  104. package/next/components/dotcms-layout-body/components/container/container.component.d.ts.map +1 -0
  105. package/next/components/dotcms-layout-body/components/contentlet/contentlet.component.d.ts +48 -0
  106. package/next/components/dotcms-layout-body/components/contentlet/contentlet.component.d.ts.map +1 -0
  107. package/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.d.ts +16 -0
  108. package/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.d.ts.map +1 -0
  109. package/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.d.ts +13 -0
  110. package/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.d.ts.map +1 -0
  111. package/next/components/dotcms-layout-body/components/row/row.component.d.ts +22 -0
  112. package/next/components/dotcms-layout-body/components/row/row.component.d.ts.map +1 -0
  113. package/next/components/dotcms-layout-body/dotcms-layout-body.component.d.ts +30 -0
  114. package/next/components/dotcms-layout-body/dotcms-layout-body.component.d.ts.map +1 -0
  115. package/next/directives/dotcms-show-when/dotcms-show-when.directive.d.ts +21 -0
  116. package/next/directives/dotcms-show-when/dotcms-show-when.directive.d.ts.map +1 -0
  117. package/next/dotcms-angular-next.d.ts.map +1 -0
  118. package/next/index.d.ts +6 -0
  119. package/next/models/index.d.ts +39 -0
  120. package/next/models/index.d.ts.map +1 -0
  121. package/next/providers/dotcms-client/dotcms-client.provider.d.ts +60 -0
  122. package/next/providers/dotcms-client/dotcms-client.provider.d.ts.map +1 -0
  123. package/next/providers/dotcms-image-loader/dotcms-image_loader.d.ts +21 -0
  124. package/next/providers/dotcms-image-loader/dotcms-image_loader.d.ts.map +1 -0
  125. package/next/public_api.d.ts +8 -0
  126. package/next/public_api.d.ts.map +1 -0
  127. package/next/services/dotcms-editable-page.service.d.ts +40 -0
  128. package/next/services/dotcms-editable-page.service.d.ts.map +1 -0
  129. package/next/store/dotcms.store.d.ts +36 -0
  130. package/next/store/dotcms.store.d.ts.map +1 -0
  131. package/package.json +16 -9
  132. package/public_api.d.ts +2 -0
  133. package/public_api.d.ts.map +1 -0
  134. package/esm2022/index.mjs +0 -5
  135. package/esm2022/lib/components/dot-editable-text/dot-editable-text.component.mjs +0 -225
  136. package/esm2022/lib/components/dot-editable-text/utils.mjs +0 -43
  137. package/esm2022/lib/components/no-component/no-component.component.mjs +0 -32
  138. package/esm2022/lib/layout/container/container.component.mjs +0 -126
  139. package/esm2022/lib/layout/contentlet/contentlet.component.mjs +0 -120
  140. package/esm2022/lib/layout/dotcms-layout/dotcms-layout.component.mjs +0 -100
  141. package/esm2022/lib/models/dotcms.model.mjs +0 -3
  142. package/esm2022/lib/models/index.mjs +0 -3
  143. package/esm2022/lib/services/dotcms-context/page-context.service.mjs +0 -75
  144. package/esm2022/lib/utils/index.mjs +0 -84
  145. package/index.d.ts.map +0 -1
  146. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts.map +0 -1
  147. package/lib/components/dot-editable-text/utils.d.ts.map +0 -1
  148. package/lib/components/no-component/no-component.component.d.ts.map +0 -1
  149. package/lib/layout/column/column.component.d.ts.map +0 -1
  150. package/lib/layout/container/container.component.d.ts.map +0 -1
  151. package/lib/layout/contentlet/contentlet.component.d.ts.map +0 -1
  152. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts.map +0 -1
  153. package/lib/layout/row/row.component.d.ts.map +0 -1
  154. package/lib/models/dotcms.model.d.ts.map +0 -1
  155. package/lib/models/index.d.ts.map +0 -1
  156. package/lib/services/dotcms-context/page-context.service.d.ts.map +0 -1
  157. package/lib/utils/index.d.ts.map +0 -1
  158. /package/lib/{components → deprecated/components}/dot-editable-text/utils.d.ts +0 -0
  159. /package/lib/{components → deprecated/components}/no-component/no-component.component.d.ts +0 -0
  160. /package/lib/{layout → deprecated/layout}/column/column.component.d.ts +0 -0
  161. /package/lib/{layout → deprecated/layout}/container/container.component.d.ts +0 -0
  162. /package/lib/{layout → deprecated/layout}/contentlet/contentlet.component.d.ts +0 -0
  163. /package/lib/{layout → deprecated/layout}/row/row.component.d.ts +0 -0
  164. /package/lib/{models → deprecated/models}/index.d.ts +0 -0
  165. /package/lib/{utils → deprecated/utils}/index.d.ts +0 -0
@@ -0,0 +1,1904 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ViewContainerRef, TemplateRef, Input, Directive, makeEnvironmentProviders, Renderer2, ElementRef, SecurityContext, HostListener, ViewChild, Component, ChangeDetectionStrategy, computed, signal, Injectable, HostBinding } from '@angular/core';
3
+ import { UVE_MODE, DotCMSUVEAction, UVEEventType } from '@dotcms/types';
4
+ import { getUVEState, sendMessageToUVE, initUVE, updateNavigation, createUVESubscription } from '@dotcms/uve';
5
+ import { IMAGE_LOADER, NgComponentOutlet, AsyncPipe, NgTemplateOutlet, NgStyle } from '@angular/common';
6
+ import { createDotCMSClient } from '@dotcms/client/next';
7
+ import { EditorComponent, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';
8
+ import { DomSanitizer } from '@angular/platform-browser';
9
+ import { __DOTCMS_UVE_EVENT__, BlockEditorDefaultBlocks } from '@dotcms/types/internal';
10
+ import { __DEFAULT_TINYMCE_CONFIG__, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__, __TINYMCE_PATH_ON_DOTCMS__, isValidBlocks, PRODUCTION_MODE, DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_ANGULAR, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getDotContainerAttributes, getContainersData, getContentletsInContainer, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
11
+ import { Subject, of } from 'rxjs';
12
+ import { finalize } from 'rxjs/operators';
13
+
14
+ /**
15
+ * Directive to show a template when the UVE is in a specific mode.
16
+ *
17
+ * @example
18
+ * <div *dotCMSShowWhen="UVE_MODE.EDIT">
19
+ * This will be shown when the UVE is in edit mode.
20
+ * </div>
21
+ *
22
+ * @export
23
+ * @class DotCMSShowWhenDirective
24
+ */
25
+ class DotCMSShowWhenDirective {
26
+ #when = UVE_MODE.EDIT;
27
+ #hasView = false;
28
+ set dotCMSShowWhen(value) {
29
+ this.#when = value;
30
+ this.updateViewContainer();
31
+ }
32
+ #viewContainerRef = inject(ViewContainerRef);
33
+ #templateRef = inject(TemplateRef);
34
+ updateViewContainer() {
35
+ const state = getUVEState();
36
+ const shouldShow = state?.mode === this.#when;
37
+ if (shouldShow && !this.#hasView) {
38
+ this.#viewContainerRef.createEmbeddedView(this.#templateRef);
39
+ this.#hasView = true;
40
+ }
41
+ else if (!shouldShow && this.#hasView) {
42
+ this.#viewContainerRef.clear();
43
+ this.#hasView = false;
44
+ }
45
+ }
46
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSShowWhenDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
47
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.3", type: DotCMSShowWhenDirective, isStandalone: true, selector: "[dotCMSShowWhen]", inputs: { dotCMSShowWhen: "dotCMSShowWhen" }, ngImport: i0 }); }
48
+ }
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSShowWhenDirective, decorators: [{
50
+ type: Directive,
51
+ args: [{
52
+ selector: '[dotCMSShowWhen]',
53
+ standalone: true
54
+ }]
55
+ }], propDecorators: { dotCMSShowWhen: [{
56
+ type: Input
57
+ }] } });
58
+
59
+ /**
60
+ * Validates if a given path is a valid URL string
61
+ *
62
+ * @param path - The path to validate
63
+ * @returns boolean indicating if the path is valid
64
+ */
65
+ function isValidPath(path) {
66
+ if (typeof path !== 'string' || path.trim() === '') {
67
+ return false;
68
+ }
69
+ try {
70
+ new URL(path);
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * Provides a DotCMS image loader configuration for the Angular Image directive
79
+ *
80
+ * @param path - The base URL path to the DotCMS instance, or empty to use current site
81
+ * @returns An array of providers for the IMAGE_LOADER token
82
+ * @throws Error if the provided path is invalid
83
+ * @example
84
+ * ```typescript
85
+ * // In your app.config.ts
86
+ * export const appConfig: ApplicationConfig = {
87
+ * providers: [
88
+ * provideDotCMSImageLoader('https://demo.dotcms.com')
89
+ * // Or use current site:
90
+ * // provideDotCMSImageLoader()
91
+ * ]
92
+ * };
93
+ * ```
94
+ */
95
+ function provideDotCMSImageLoader(path) {
96
+ // If path is provided, validate it
97
+ if (path && !isValidPath(path)) {
98
+ throw new Error(`Image loader has detected an invalid path (\`${path}\`). ` +
99
+ `To fix this, supply either the full URL to the dotCMS site, or leave it empty to use the current site.`);
100
+ }
101
+ return [
102
+ {
103
+ provide: IMAGE_LOADER,
104
+ useValue: (config) => createDotCMSURL(config, path)
105
+ }
106
+ ];
107
+ }
108
+ /**
109
+ * Creates a DotCMS-compatible URL for image loading
110
+ *
111
+ * @param config - The image loader configuration
112
+ * @param path - The base URL path to the DotCMS instance
113
+ * @returns A fully qualified URL for the image
114
+ * @internal
115
+ */
116
+ function createDotCMSURL(config, path) {
117
+ const { loaderParams, src, width } = config;
118
+ const params = loaderParams;
119
+ if (params?.isOutsideSRC) {
120
+ return src;
121
+ }
122
+ // Use empty string as fallback to support using current site
123
+ const dotcmsHost = path ? new URL(path).origin : '';
124
+ const imageSRC = src.includes('/dA/') ? src : `/dA/${src}`;
125
+ const languageId = params?.languageId ?? '1';
126
+ if (width) {
127
+ return `${dotcmsHost}${imageSRC}/${width}w?language_id=${languageId}`;
128
+ }
129
+ return `${dotcmsHost}${imageSRC}?language_id=${languageId}`;
130
+ }
131
+
132
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
133
+ class DotCMSClient {
134
+ constructor(client) {
135
+ return client;
136
+ }
137
+ }
138
+ /**
139
+ * Creates environment providers for the DotCMS client to be used in Angular applications.
140
+ * This function configures the DI container to provide a DotCMSClient instance
141
+ * throughout the application using the specified configuration.
142
+ *
143
+ * The provider should be registered at the application level (typically in main.ts)
144
+ * to ensure a single instance is shared across the entire application.
145
+ *
146
+ * @param options - Configuration object for the DotCMS client
147
+ * @param options.apiUrl - The base URL for the DotCMS API
148
+ * @param options.authToken - Authentication token for API requests (optional)
149
+ * @param options.siteId - The site identifier (optional)
150
+ * @returns Environment providers array that can be used with bootstrapApplication
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * // main.ts
155
+ * import { bootstrapApplication } from '@angular/platform-browser';
156
+ * import { AppComponent } from './app/app.component';
157
+ * import { provideDotCMSClient } from '@dotcms/angular';
158
+ *
159
+ * bootstrapApplication(AppComponent, {
160
+ * providers: [
161
+ * provideDotCMSClient({
162
+ * apiUrl: 'https://demo.dotcms.com',
163
+ * authToken: 'your-auth-token',
164
+ * siteId: 'your-site-id'
165
+ * }),
166
+ * // other providers...
167
+ * ]
168
+ * });
169
+ * ```
170
+ *
171
+ */
172
+ function provideDotCMSClient(options) {
173
+ const dotCMSClient = createDotCMSClient(options);
174
+ return makeEnvironmentProviders([
175
+ {
176
+ provide: DotCMSClient,
177
+ useFactory: () => new DotCMSClient(dotCMSClient)
178
+ }
179
+ ]);
180
+ }
181
+
182
+ const DEFAULT_TINYMCE_CONFIG = {
183
+ ...__DEFAULT_TINYMCE_CONFIG__,
184
+ license_key: 'gpl' // Using self-hosted license key
185
+ };
186
+ const TINYMCE_CONFIG = {
187
+ minimal: {
188
+ ...DEFAULT_TINYMCE_CONFIG,
189
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.minimal
190
+ },
191
+ full: {
192
+ ...DEFAULT_TINYMCE_CONFIG,
193
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.full
194
+ },
195
+ plain: {
196
+ ...DEFAULT_TINYMCE_CONFIG,
197
+ ...__BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.plain
198
+ }
199
+ };
200
+
201
+ /**
202
+ * Dot editable text component.
203
+ * This component is responsible to render a text field that can be edited inline.
204
+ *
205
+ * @export
206
+ * @class DotCMSEditableTextComponent
207
+ * @implements {OnInit}
208
+ * @implements {OnChanges}
209
+ */
210
+ class DotCMSEditableTextComponent {
211
+ constructor() {
212
+ /**
213
+ * Represents the mode of the editor which can be `plain`, `minimal`, or `full`
214
+ *
215
+ * @type {DOT_EDITABLE_TEXT_MODE}
216
+ * @memberof DotCMSEditableTextComponent
217
+ */
218
+ this.mode = 'plain';
219
+ /**
220
+ * Represents the format of the editor which can be `text` or `html`
221
+ *
222
+ * @type {DOT_EDITABLE_TEXT_FORMAT}
223
+ * @memberof DotCMSEditableTextComponent
224
+ */
225
+ this.format = 'text';
226
+ /**
227
+ * Represents the content of the `contentlet` that can be edited
228
+ *
229
+ * @protected
230
+ * @memberof DotCMSEditableTextComponent
231
+ */
232
+ this.content = '';
233
+ this.#NotDotCMSHostMessage = 'The `dotCMSHost` parameter is not defined. Check that the UVE is sending the correct parameters.';
234
+ this.#sanitizer = inject(DomSanitizer);
235
+ this.#renderer = inject(Renderer2);
236
+ this.#elementRef = inject(ElementRef);
237
+ }
238
+ #NotDotCMSHostMessage;
239
+ #sanitizer;
240
+ #renderer;
241
+ #elementRef;
242
+ /**
243
+ * The TinyMCE editor
244
+ *
245
+ * @readonly
246
+ * @memberof DotCMSEditableTextComponent
247
+ */
248
+ get editor() {
249
+ return this.editorComponent?.editor;
250
+ }
251
+ /**
252
+ * Represents if the component is inside the editor
253
+ *
254
+ * @protected
255
+ * @type {boolean}
256
+ * @memberof DotCMSEditableTextComponent
257
+ */
258
+ get isEditMode() {
259
+ const { mode, dotCMSHost } = getUVEState() || {};
260
+ return mode === UVE_MODE.EDIT && dotCMSHost;
261
+ }
262
+ /**
263
+ * Returns the number of pages the contentlet is on
264
+ *
265
+ * @readonly
266
+ * @memberof DotCMSEditableTextComponent
267
+ */
268
+ get onNumberOfPages() {
269
+ return this.contentlet['onNumberOfPages'] || 1;
270
+ }
271
+ /**
272
+ * Handle copy contentlet inline editing success event
273
+ *
274
+ * @param {MessageEvent} { data }
275
+ * @return {*}
276
+ * @memberof DotCMSEditableTextComponent
277
+ */
278
+ onMessage({ data }) {
279
+ const { name, payload } = data;
280
+ if (name !== __DOTCMS_UVE_EVENT__.UVE_COPY_CONTENTLET_INLINE_EDITING_SUCCESS) {
281
+ return;
282
+ }
283
+ const { oldInode, inode } = payload;
284
+ const currentInode = this.contentlet.inode;
285
+ if (currentInode === oldInode || currentInode === inode) {
286
+ this.editorComponent.editor.focus();
287
+ return;
288
+ }
289
+ }
290
+ ngOnInit() {
291
+ const { dotCMSHost } = getUVEState() || {};
292
+ if (!this.isEditMode) {
293
+ this.innerHTMLToElement();
294
+ if (!dotCMSHost) {
295
+ console.warn(this.#NotDotCMSHostMessage);
296
+ }
297
+ return;
298
+ }
299
+ this.init = {
300
+ ...TINYMCE_CONFIG[this.mode],
301
+ base_url: `${dotCMSHost}/ext/tinymcev7`
302
+ };
303
+ }
304
+ ngOnChanges() {
305
+ this.content = this.contentlet[this.fieldName] || '';
306
+ if (this.editor) {
307
+ this.editor.setContent(this.content, { format: this.format });
308
+ }
309
+ }
310
+ /**
311
+ * Handle mouse down event
312
+ *
313
+ * @param {EventObj<MouseEvent>} { event }
314
+ * @return {*}
315
+ * @memberof DotCMSEditableTextComponent
316
+ */
317
+ onMouseDown({ event }) {
318
+ if (Number(this.onNumberOfPages) <= 1 || this.editorComponent.editor.hasFocus()) {
319
+ return;
320
+ }
321
+ const { inode, languageId: language } = this.contentlet;
322
+ event.stopPropagation();
323
+ event.preventDefault();
324
+ try {
325
+ sendMessageToUVE({
326
+ action: DotCMSUVEAction.COPY_CONTENTLET_INLINE_EDITING,
327
+ payload: {
328
+ dataset: {
329
+ inode,
330
+ language,
331
+ fieldName: this.fieldName
332
+ }
333
+ }
334
+ });
335
+ }
336
+ catch (error) {
337
+ console.error('Failed to post message to editor:', error);
338
+ }
339
+ }
340
+ /**
341
+ * Handle focus out event
342
+ *
343
+ * @return {*}
344
+ * @memberof DotCMSEditableTextComponent
345
+ */
346
+ onFocusOut() {
347
+ const content = this.editor.getContent({ format: this.format });
348
+ if (!this.editor.isDirty() || !this.didContentChange(content)) {
349
+ return;
350
+ }
351
+ const { inode, languageId: langId } = this.contentlet;
352
+ try {
353
+ sendMessageToUVE({
354
+ action: DotCMSUVEAction.UPDATE_CONTENTLET_INLINE_EDITING,
355
+ payload: {
356
+ content,
357
+ dataset: {
358
+ inode,
359
+ langId,
360
+ fieldName: this.fieldName
361
+ }
362
+ }
363
+ });
364
+ }
365
+ catch (error) {
366
+ console.error('Failed to post message to editor:', error);
367
+ }
368
+ }
369
+ /**
370
+ * inner HTML to element
371
+ *
372
+ * @private
373
+ * @param {string} editedContent
374
+ * @return {*}
375
+ * @memberof DotCMSEditableTextComponent
376
+ */
377
+ innerHTMLToElement() {
378
+ const element = this.#elementRef.nativeElement;
379
+ const safeHtml = this.#sanitizer.bypassSecurityTrustHtml(this.content);
380
+ const content = this.#sanitizer.sanitize(SecurityContext.HTML, safeHtml) || '';
381
+ this.#renderer.setProperty(element, 'innerHTML', content);
382
+ }
383
+ /**
384
+ * Check if the content has changed
385
+ *
386
+ * @private
387
+ * @param {string} editedContent
388
+ * @return {*}
389
+ * @memberof DotCMSEditableTextComponent
390
+ */
391
+ didContentChange(editedContent) {
392
+ return this.content !== editedContent;
393
+ }
394
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditableTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
395
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotCMSEditableTextComponent, isStandalone: true, selector: "dotcms-editable-text", inputs: { mode: "mode", format: "format", contentlet: "contentlet", fieldName: "fieldName" }, host: { listeners: { "window:message": "onMessage($event)" } }, providers: [
396
+ {
397
+ provide: TINYMCE_SCRIPT_SRC,
398
+ useFactory: () => {
399
+ const { dotCMSHost } = getUVEState() || {};
400
+ return `${dotCMSHost || ''}${__TINYMCE_PATH_ON_DOTCMS__}`;
401
+ }
402
+ }
403
+ ], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isEditMode) {\n <editor\n #tinyEditor\n [init]=\"init\"\n [initialValue]=\"content\"\n (onMouseDown)=\"onMouseDown($event)\"\n (onFocusOut)=\"onFocusOut()\" />\n}\n", styles: [":host ::ng-deep .mce-content-body:not(.mce-edit-focus){outline:2px solid #006ce7;border-radius:4px}\n"], dependencies: [{ kind: "component", type: EditorComponent, selector: "editor", inputs: ["cloudChannel", "apiKey", "init", "id", "initialValue", "outputFormat", "inline", "tagName", "plugins", "toolbar", "modelEvents", "allowedEvents", "ignoreEvents", "disabled"] }] }); }
404
+ }
405
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditableTextComponent, decorators: [{
406
+ type: Component,
407
+ args: [{ selector: 'dotcms-editable-text', standalone: true, imports: [EditorComponent], providers: [
408
+ {
409
+ provide: TINYMCE_SCRIPT_SRC,
410
+ useFactory: () => {
411
+ const { dotCMSHost } = getUVEState() || {};
412
+ return `${dotCMSHost || ''}${__TINYMCE_PATH_ON_DOTCMS__}`;
413
+ }
414
+ }
415
+ ], template: "@if (isEditMode) {\n <editor\n #tinyEditor\n [init]=\"init\"\n [initialValue]=\"content\"\n (onMouseDown)=\"onMouseDown($event)\"\n (onFocusOut)=\"onFocusOut()\" />\n}\n", styles: [":host ::ng-deep .mce-content-body:not(.mce-edit-focus){outline:2px solid #006ce7;border-radius:4px}\n"] }]
416
+ }], propDecorators: { editorComponent: [{
417
+ type: ViewChild,
418
+ args: [EditorComponent]
419
+ }], mode: [{
420
+ type: Input
421
+ }], format: [{
422
+ type: Input
423
+ }], contentlet: [{
424
+ type: Input
425
+ }], fieldName: [{
426
+ type: Input
427
+ }], onMessage: [{
428
+ type: HostListener,
429
+ args: ['window:message', ['$event']]
430
+ }] } });
431
+
432
+ class DotCodeBlock {
433
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCodeBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
434
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotCodeBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-code-block", ngImport: i0, template: `
435
+ <pre>
436
+ <code>
437
+ <ng-content />
438
+ </code>
439
+ </pre>
440
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
441
+ }
442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCodeBlock, decorators: [{
443
+ type: Component,
444
+ args: [{
445
+ selector: 'dotcms-block-editor-renderer-code-block',
446
+ standalone: true,
447
+ template: `
448
+ <pre>
449
+ <code>
450
+ <ng-content />
451
+ </code>
452
+ </pre>
453
+ `,
454
+ changeDetection: ChangeDetectionStrategy.OnPush
455
+ }]
456
+ }] });
457
+ class DotBlockQuote {
458
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotBlockQuote, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
459
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotBlockQuote, isStandalone: true, selector: "dotcms-block-editor-renderer-block-quote", ngImport: i0, template: `
460
+ <blockquote>
461
+ <ng-content />
462
+ </blockquote>
463
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
464
+ }
465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotBlockQuote, decorators: [{
466
+ type: Component,
467
+ args: [{
468
+ selector: 'dotcms-block-editor-renderer-block-quote',
469
+ standalone: true,
470
+ template: `
471
+ <blockquote>
472
+ <ng-content />
473
+ </blockquote>
474
+ `,
475
+ changeDetection: ChangeDetectionStrategy.OnPush
476
+ }]
477
+ }] });
478
+
479
+ class NoComponentProvided {
480
+ constructor() {
481
+ this.style = {
482
+ backgroundColor: '#fffaf0',
483
+ color: '#333',
484
+ padding: '1rem',
485
+ borderRadius: '0.5rem',
486
+ marginBottom: '1rem',
487
+ marginTop: '1rem',
488
+ border: '1px solid #ed8936'
489
+ };
490
+ }
491
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NoComponentProvided, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
492
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: NoComponentProvided, isStandalone: true, selector: "dotcms-no-component-provided", inputs: { contentType: "contentType" }, ngImport: i0, template: `
493
+ <div data-testid="no-component-provided" [style]="style">
494
+ <strong style="color: #c05621">Dev Warning</strong>
495
+ : No component or custom renderer provided for content type
496
+ <strong style="color: #c05621">{{ contentType || 'Unknown' }}</strong>
497
+ .
498
+ <br />
499
+ Please refer to the
500
+ <a
501
+ href="https://dev.dotcms.com/docs/block-editor"
502
+ target="_blank"
503
+ rel="noopener noreferrer"
504
+ style="color: #c05621">
505
+ Block Editor Custom Renderers Documentation
506
+ </a>
507
+ for guidance.
508
+ </div>
509
+ `, isInline: true }); }
510
+ }
511
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NoComponentProvided, decorators: [{
512
+ type: Component,
513
+ args: [{
514
+ selector: 'dotcms-no-component-provided',
515
+ standalone: true,
516
+ template: `
517
+ <div data-testid="no-component-provided" [style]="style">
518
+ <strong style="color: #c05621">Dev Warning</strong>
519
+ : No component or custom renderer provided for content type
520
+ <strong style="color: #c05621">{{ contentType || 'Unknown' }}</strong>
521
+ .
522
+ <br />
523
+ Please refer to the
524
+ <a
525
+ href="https://dev.dotcms.com/docs/block-editor"
526
+ target="_blank"
527
+ rel="noopener noreferrer"
528
+ style="color: #c05621">
529
+ Block Editor Custom Renderers Documentation
530
+ </a>
531
+ for guidance.
532
+ </div>
533
+ `
534
+ }]
535
+ }], propDecorators: { contentType: [{
536
+ type: Input
537
+ }] } });
538
+ /**
539
+ * DotContent component that renders content based on content type
540
+ */
541
+ class DotContentletBlock {
542
+ constructor() {
543
+ this.$data = computed(() => this.attrs?.['data']);
544
+ this.DOT_CONTENT_NO_DATA_MESSAGE = '[DotCMSBlockEditorRenderer]: No data provided for Contentlet Block. Try to add a contentlet to the block editor. If the error persists, please contact the DotCMS support team.';
545
+ this.DOT_CONTENT_NO_MATCHING_COMPONENT_MESSAGE = (contentType) => `[DotCMSBlockEditorRenderer]: No matching component found for content type: ${contentType}. Provide a custom renderer for this content type to fix this error.`;
546
+ }
547
+ get isDevMode() {
548
+ return getUVEState()?.mode === UVE_MODE.EDIT;
549
+ }
550
+ ngOnInit() {
551
+ if (!this.$data()) {
552
+ console.error(this.DOT_CONTENT_NO_DATA_MESSAGE);
553
+ return;
554
+ }
555
+ const contentType = this.$data()?.contentType || '';
556
+ this.contentComponent = this.customRenderers?.[contentType];
557
+ if (!this.contentComponent) {
558
+ console.warn(this.DOT_CONTENT_NO_MATCHING_COMPONENT_MESSAGE(contentType));
559
+ }
560
+ }
561
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotContentletBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
562
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotContentletBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-contentlet", inputs: { customRenderers: "customRenderers", attrs: "attrs" }, ngImport: i0, template: `
563
+ @if (contentComponent) {
564
+ <ng-container
565
+ *ngComponentOutlet="
566
+ contentComponent | async;
567
+ inputs: { contentlet: $data() }
568
+ "></ng-container>
569
+ } @else if (isDevMode) {
570
+ <dotcms-no-component-provided [contentType]="$data()?.contentType" />
571
+ }
572
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: NoComponentProvided, selector: "dotcms-no-component-provided", inputs: ["contentType"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
573
+ }
574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotContentletBlock, decorators: [{
575
+ type: Component,
576
+ args: [{
577
+ selector: 'dotcms-block-editor-renderer-contentlet',
578
+ standalone: true,
579
+ imports: [NgComponentOutlet, AsyncPipe, NoComponentProvided],
580
+ changeDetection: ChangeDetectionStrategy.OnPush,
581
+ template: `
582
+ @if (contentComponent) {
583
+ <ng-container
584
+ *ngComponentOutlet="
585
+ contentComponent | async;
586
+ inputs: { contentlet: $data() }
587
+ "></ng-container>
588
+ } @else if (isDevMode) {
589
+ <dotcms-no-component-provided [contentType]="$data()?.contentType" />
590
+ }
591
+ `
592
+ }]
593
+ }], propDecorators: { customRenderers: [{
594
+ type: Input
595
+ }], attrs: [{
596
+ type: Input
597
+ }] } });
598
+
599
+ class DotImageBlock {
600
+ constructor() {
601
+ this.$srcURL = computed(() => this.attrs?.['src']);
602
+ }
603
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotImageBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
604
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotImageBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-image", inputs: { attrs: "attrs" }, ngImport: i0, template: `
605
+ <img [alt]="attrs?.['alt']" [src]="$srcURL()" />
606
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
607
+ }
608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotImageBlock, decorators: [{
609
+ type: Component,
610
+ args: [{
611
+ selector: 'dotcms-block-editor-renderer-image',
612
+ standalone: true,
613
+ template: `
614
+ <img [alt]="attrs?.['alt']" [src]="$srcURL()" />
615
+ `,
616
+ changeDetection: ChangeDetectionStrategy.OnPush
617
+ }]
618
+ }], propDecorators: { attrs: [{
619
+ type: Input
620
+ }] } });
621
+
622
+ class DotBulletList {
623
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotBulletList, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
624
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotBulletList, isStandalone: true, selector: "dotcms-block-editor-renderer-bullet-list", ngImport: i0, template: `
625
+ <ul>
626
+ <ng-content />
627
+ </ul>
628
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
629
+ }
630
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotBulletList, decorators: [{
631
+ type: Component,
632
+ args: [{
633
+ selector: 'dotcms-block-editor-renderer-bullet-list',
634
+ standalone: true,
635
+ changeDetection: ChangeDetectionStrategy.OnPush,
636
+ template: `
637
+ <ul>
638
+ <ng-content />
639
+ </ul>
640
+ `
641
+ }]
642
+ }] });
643
+ class DotOrdererList {
644
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotOrdererList, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
645
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotOrdererList, isStandalone: true, selector: "dotcms-block-editor-renderer-ordered-list", ngImport: i0, template: `
646
+ <ol>
647
+ <ng-content />
648
+ </ol>
649
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
650
+ }
651
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotOrdererList, decorators: [{
652
+ type: Component,
653
+ args: [{
654
+ selector: 'dotcms-block-editor-renderer-ordered-list',
655
+ standalone: true,
656
+ changeDetection: ChangeDetectionStrategy.OnPush,
657
+ template: `
658
+ <ol>
659
+ <ng-content />
660
+ </ol>
661
+ `
662
+ }]
663
+ }] });
664
+ class DotListItem {
665
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotListItem, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
666
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotListItem, isStandalone: true, selector: "dotcms-block-editor-renderer-list-item", ngImport: i0, template: `
667
+ <li>
668
+ <ng-content />
669
+ </li>
670
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
671
+ }
672
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotListItem, decorators: [{
673
+ type: Component,
674
+ args: [{
675
+ selector: 'dotcms-block-editor-renderer-list-item',
676
+ standalone: true,
677
+ changeDetection: ChangeDetectionStrategy.OnPush,
678
+ template: `
679
+ <li>
680
+ <ng-content />
681
+ </li>
682
+ `
683
+ }]
684
+ }] });
685
+
686
+ class DotTableBlock {
687
+ constructor() {
688
+ this.blockEditorItem = DotCMSBlockEditorItemComponent;
689
+ }
690
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotTableBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
691
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotTableBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-table", inputs: { content: "content" }, ngImport: i0, template: `
692
+ <table>
693
+ <thead>
694
+ @for (rowNode of content?.slice(0, 1); track rowNode.type) {
695
+ <tr>
696
+ @for (cellNode of rowNode.content; track cellNode.type) {
697
+ <th
698
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
699
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
700
+ <ng-container
701
+ *ngComponentOutlet="
702
+ blockEditorItem;
703
+ inputs: { content: cellNode.content }
704
+ "></ng-container>
705
+ </th>
706
+ }
707
+ </tr>
708
+ }
709
+ </thead>
710
+ <tbody>
711
+ @for (rowNode of content?.slice(1); track rowNode.type) {
712
+ <tr>
713
+ @for (cellNode of rowNode.content; track cellNode.type) {
714
+ <td
715
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
716
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
717
+ <ng-container
718
+ *ngComponentOutlet="
719
+ blockEditorItem;
720
+ inputs: { content: cellNode.content }
721
+ "></ng-container>
722
+ </td>
723
+ }
724
+ </tr>
725
+ }
726
+ </tbody>
727
+ </table>
728
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
729
+ }
730
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotTableBlock, decorators: [{
731
+ type: Component,
732
+ args: [{
733
+ selector: 'dotcms-block-editor-renderer-table',
734
+ standalone: true,
735
+ imports: [NgComponentOutlet],
736
+ template: `
737
+ <table>
738
+ <thead>
739
+ @for (rowNode of content?.slice(0, 1); track rowNode.type) {
740
+ <tr>
741
+ @for (cellNode of rowNode.content; track cellNode.type) {
742
+ <th
743
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
744
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
745
+ <ng-container
746
+ *ngComponentOutlet="
747
+ blockEditorItem;
748
+ inputs: { content: cellNode.content }
749
+ "></ng-container>
750
+ </th>
751
+ }
752
+ </tr>
753
+ }
754
+ </thead>
755
+ <tbody>
756
+ @for (rowNode of content?.slice(1); track rowNode.type) {
757
+ <tr>
758
+ @for (cellNode of rowNode.content; track cellNode.type) {
759
+ <td
760
+ [attr.colspan]="cellNode.attrs?.['colspan'] || 1"
761
+ [attr.rowspan]="cellNode.attrs?.['rowspan'] || 1">
762
+ <ng-container
763
+ *ngComponentOutlet="
764
+ blockEditorItem;
765
+ inputs: { content: cellNode.content }
766
+ "></ng-container>
767
+ </td>
768
+ }
769
+ </tr>
770
+ }
771
+ </tbody>
772
+ </table>
773
+ `
774
+ }]
775
+ }], propDecorators: { content: [{
776
+ type: Input
777
+ }] } });
778
+
779
+ class DotParagraphBlock {
780
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotParagraphBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
781
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotParagraphBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-paragraph", ngImport: i0, template: `
782
+ <p>
783
+ <ng-content />
784
+ </p>
785
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
786
+ }
787
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotParagraphBlock, decorators: [{
788
+ type: Component,
789
+ args: [{
790
+ selector: 'dotcms-block-editor-renderer-paragraph',
791
+ standalone: true,
792
+ changeDetection: ChangeDetectionStrategy.OnPush,
793
+ template: `
794
+ <p>
795
+ <ng-content />
796
+ </p>
797
+ `
798
+ }]
799
+ }] });
800
+ class DotHeadingBlock {
801
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotHeadingBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
802
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotHeadingBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-heading", inputs: { level: "level" }, ngImport: i0, template: `
803
+ @switch (level) {
804
+ @case ('1') {
805
+ <h1>
806
+ <ng-content />
807
+ </h1>
808
+ }
809
+ @case ('2') {
810
+ <h2>
811
+ <ng-content />
812
+ </h2>
813
+ }
814
+ @case ('3') {
815
+ <h3>
816
+ <ng-content />
817
+ </h3>
818
+ }
819
+ @case ('4') {
820
+ <h4>
821
+ <ng-content />
822
+ </h4>
823
+ }
824
+ @case ('5') {
825
+ <h5>
826
+ <ng-content />
827
+ </h5>
828
+ }
829
+ @case ('6') {
830
+ <h6>
831
+ <ng-content />
832
+ </h6>
833
+ }
834
+ @default {
835
+ <h1>
836
+ <ng-content />
837
+ </h1>
838
+ }
839
+ }
840
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
841
+ }
842
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotHeadingBlock, decorators: [{
843
+ type: Component,
844
+ args: [{
845
+ selector: 'dotcms-block-editor-renderer-heading',
846
+ standalone: true,
847
+ changeDetection: ChangeDetectionStrategy.OnPush,
848
+ template: `
849
+ @switch (level) {
850
+ @case ('1') {
851
+ <h1>
852
+ <ng-content />
853
+ </h1>
854
+ }
855
+ @case ('2') {
856
+ <h2>
857
+ <ng-content />
858
+ </h2>
859
+ }
860
+ @case ('3') {
861
+ <h3>
862
+ <ng-content />
863
+ </h3>
864
+ }
865
+ @case ('4') {
866
+ <h4>
867
+ <ng-content />
868
+ </h4>
869
+ }
870
+ @case ('5') {
871
+ <h5>
872
+ <ng-content />
873
+ </h5>
874
+ }
875
+ @case ('6') {
876
+ <h6>
877
+ <ng-content />
878
+ </h6>
879
+ }
880
+ @default {
881
+ <h1>
882
+ <ng-content />
883
+ </h1>
884
+ }
885
+ }
886
+ `
887
+ }]
888
+ }], propDecorators: { level: [{
889
+ type: Input
890
+ }] } });
891
+ class DotTextBlock {
892
+ constructor() {
893
+ this.marks = [];
894
+ this.text = '';
895
+ this.$remainingMarks = computed(() => this.marks?.slice(1));
896
+ this.$currentAttrs = computed(() => {
897
+ const attrs = { ...(this.marks?.[0]?.attrs || {}) };
898
+ if (attrs['class']) {
899
+ attrs['className'] = attrs['class'];
900
+ delete attrs['class'];
901
+ }
902
+ return attrs;
903
+ });
904
+ }
905
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotTextBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
906
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotTextBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-text", inputs: { marks: "marks", text: "text" }, ngImport: i0, template: `
907
+ @switch (marks?.[0]?.type) {
908
+ @case ('link') {
909
+ <a
910
+ [attr.href]="$currentAttrs()['href'] || ''"
911
+ [attr.target]="$currentAttrs()['target'] || ''">
912
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
913
+ </a>
914
+ }
915
+ @case ('bold') {
916
+ <strong>
917
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
918
+ </strong>
919
+ }
920
+ @case ('underline') {
921
+ <u>
922
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
923
+ </u>
924
+ }
925
+ @case ('italic') {
926
+ <em>
927
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
928
+ </em>
929
+ }
930
+ @case ('strike') {
931
+ <s>
932
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
933
+ </s>
934
+ }
935
+ @case ('superscript') {
936
+ <sup>
937
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
938
+ </sup>
939
+ }
940
+ @case ('subscript') {
941
+ <sub>
942
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
943
+ </sub>
944
+ }
945
+ @default {
946
+ {{ text }}
947
+ }
948
+ }
949
+ `, isInline: true, dependencies: [{ kind: "component", type: DotTextBlock, selector: "dotcms-block-editor-renderer-text", inputs: ["marks", "text"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
950
+ }
951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotTextBlock, decorators: [{
952
+ type: Component,
953
+ args: [{
954
+ selector: 'dotcms-block-editor-renderer-text',
955
+ standalone: true,
956
+ changeDetection: ChangeDetectionStrategy.OnPush,
957
+ template: `
958
+ @switch (marks?.[0]?.type) {
959
+ @case ('link') {
960
+ <a
961
+ [attr.href]="$currentAttrs()['href'] || ''"
962
+ [attr.target]="$currentAttrs()['target'] || ''">
963
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
964
+ </a>
965
+ }
966
+ @case ('bold') {
967
+ <strong>
968
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
969
+ </strong>
970
+ }
971
+ @case ('underline') {
972
+ <u>
973
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
974
+ </u>
975
+ }
976
+ @case ('italic') {
977
+ <em>
978
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
979
+ </em>
980
+ }
981
+ @case ('strike') {
982
+ <s>
983
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
984
+ </s>
985
+ }
986
+ @case ('superscript') {
987
+ <sup>
988
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
989
+ </sup>
990
+ }
991
+ @case ('subscript') {
992
+ <sub>
993
+ <dotcms-block-editor-renderer-text [marks]="$remainingMarks()" [text]="text" />
994
+ </sub>
995
+ }
996
+ @default {
997
+ {{ text }}
998
+ }
999
+ }
1000
+ `
1001
+ }]
1002
+ }], propDecorators: { marks: [{
1003
+ type: Input
1004
+ }], text: [{
1005
+ type: Input
1006
+ }] } });
1007
+
1008
+ class DotUnknownBlockComponent {
1009
+ constructor() {
1010
+ this.style = {
1011
+ backgroundColor: '#fff5f5',
1012
+ color: '#333',
1013
+ padding: '1rem',
1014
+ borderRadius: '0.5rem',
1015
+ marginBottom: '1rem',
1016
+ marginTop: '1rem',
1017
+ border: '1px solid #fc8181'
1018
+ };
1019
+ }
1020
+ get isEditMode() {
1021
+ return getUVEState()?.mode === UVE_MODE.EDIT;
1022
+ }
1023
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotUnknownBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1024
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotUnknownBlockComponent, isStandalone: true, selector: "dotcms-block-editor-renderer-unknown", inputs: { node: "node" }, ngImport: i0, template: `
1025
+ @if (isEditMode) {
1026
+ <div [style]="style" data-testid="unknown-block-type">
1027
+ <strong style="color: #c53030">Warning:</strong>
1028
+ The block type
1029
+ <strong>{{ node.type }}</strong>
1030
+ is not recognized. Please check your
1031
+ <a
1032
+ href="https://dev.dotcms.com/docs/block-editor"
1033
+ target="_blank"
1034
+ rel="noopener noreferrer">
1035
+ configuration
1036
+ </a>
1037
+ or contact support for assistance.
1038
+ </div>
1039
+ }
1040
+ `, isInline: true }); }
1041
+ }
1042
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotUnknownBlockComponent, decorators: [{
1043
+ type: Component,
1044
+ args: [{
1045
+ selector: 'dotcms-block-editor-renderer-unknown',
1046
+ standalone: true,
1047
+ template: `
1048
+ @if (isEditMode) {
1049
+ <div [style]="style" data-testid="unknown-block-type">
1050
+ <strong style="color: #c53030">Warning:</strong>
1051
+ The block type
1052
+ <strong>{{ node.type }}</strong>
1053
+ is not recognized. Please check your
1054
+ <a
1055
+ href="https://dev.dotcms.com/docs/block-editor"
1056
+ target="_blank"
1057
+ rel="noopener noreferrer">
1058
+ configuration
1059
+ </a>
1060
+ or contact support for assistance.
1061
+ </div>
1062
+ }
1063
+ `
1064
+ }]
1065
+ }], propDecorators: { node: [{
1066
+ type: Input
1067
+ }] } });
1068
+
1069
+ class DotVideoBlock {
1070
+ constructor() {
1071
+ this.$srcURL = computed(() => this.attrs?.['src']);
1072
+ this.$posterURL = computed(() => this.attrs?.['data']?.['thumbnail']);
1073
+ }
1074
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotVideoBlock, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1075
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: DotVideoBlock, isStandalone: true, selector: "dotcms-block-editor-renderer-video", inputs: { attrs: "attrs" }, ngImport: i0, template: `
1076
+ <video
1077
+ [controls]="true"
1078
+ preload="metadata"
1079
+ [poster]="this.$posterURL()"
1080
+ [width]="attrs?.['width']"
1081
+ [height]="attrs?.['height']">
1082
+ <track default kind="captions" srclang="en" />
1083
+ <source [src]="this.$srcURL()" [type]="attrs?.['mimeType']" />
1084
+ Your browser does not support the
1085
+ <code>video</code>
1086
+ element.
1087
+ </video>
1088
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1089
+ }
1090
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotVideoBlock, decorators: [{
1091
+ type: Component,
1092
+ args: [{
1093
+ selector: 'dotcms-block-editor-renderer-video',
1094
+ standalone: true,
1095
+ changeDetection: ChangeDetectionStrategy.OnPush,
1096
+ template: `
1097
+ <video
1098
+ [controls]="true"
1099
+ preload="metadata"
1100
+ [poster]="this.$posterURL()"
1101
+ [width]="attrs?.['width']"
1102
+ [height]="attrs?.['height']">
1103
+ <track default kind="captions" srclang="en" />
1104
+ <source [src]="this.$srcURL()" [type]="attrs?.['mimeType']" />
1105
+ Your browser does not support the
1106
+ <code>video</code>
1107
+ element.
1108
+ </video>
1109
+ `
1110
+ }]
1111
+ }], propDecorators: { attrs: [{
1112
+ type: Input
1113
+ }] } });
1114
+
1115
+ class DotCMSBlockEditorItemComponent {
1116
+ constructor() {
1117
+ this.BLOCKS = BlockEditorDefaultBlocks;
1118
+ }
1119
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSBlockEditorItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1120
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotCMSBlockEditorItemComponent, isStandalone: true, selector: "dotcms-block-editor-renderer-block", inputs: { content: "content", customRenderers: "customRenderers" }, ngImport: i0, template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \"></ng-container>\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [attrs]=\"node.attrs || {}\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container\n *ngComponentOutlet=\"customRender | async; inputs: { content: node }\"></ng-container>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: DotCMSBlockEditorItemComponent, selector: "dotcms-block-editor-renderer-block", inputs: ["content", "customRenderers"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: DotParagraphBlock, selector: "dotcms-block-editor-renderer-paragraph" }, { kind: "component", type: DotTextBlock, selector: "dotcms-block-editor-renderer-text", inputs: ["marks", "text"] }, { kind: "component", type: DotHeadingBlock, selector: "dotcms-block-editor-renderer-heading", inputs: ["level"] }, { kind: "component", type: DotBulletList, selector: "dotcms-block-editor-renderer-bullet-list" }, { kind: "component", type: DotOrdererList, selector: "dotcms-block-editor-renderer-ordered-list" }, { kind: "component", type: DotListItem, selector: "dotcms-block-editor-renderer-list-item" }, { kind: "component", type: DotCodeBlock, selector: "dotcms-block-editor-renderer-code-block" }, { kind: "component", type: DotBlockQuote, selector: "dotcms-block-editor-renderer-block-quote" }, { kind: "component", type: DotImageBlock, selector: "dotcms-block-editor-renderer-image", inputs: ["attrs"] }, { kind: "component", type: DotVideoBlock, selector: "dotcms-block-editor-renderer-video", inputs: ["attrs"] }, { kind: "component", type: DotTableBlock, selector: "dotcms-block-editor-renderer-table", inputs: ["content"] }, { kind: "component", type: DotContentletBlock, selector: "dotcms-block-editor-renderer-contentlet", inputs: ["customRenderers", "attrs"] }, { kind: "component", type: DotUnknownBlockComponent, selector: "dotcms-block-editor-renderer-unknown", inputs: ["node"] }] }); }
1121
+ }
1122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSBlockEditorItemComponent, decorators: [{
1123
+ type: Component,
1124
+ args: [{ selector: 'dotcms-block-editor-renderer-block', standalone: true, imports: [
1125
+ NgTemplateOutlet,
1126
+ NgComponentOutlet,
1127
+ AsyncPipe,
1128
+ DotParagraphBlock,
1129
+ DotTextBlock,
1130
+ DotHeadingBlock,
1131
+ DotBulletList,
1132
+ DotOrdererList,
1133
+ DotListItem,
1134
+ DotCodeBlock,
1135
+ DotBlockQuote,
1136
+ DotImageBlock,
1137
+ DotVideoBlock,
1138
+ DotTableBlock,
1139
+ DotContentletBlock,
1140
+ DotUnknownBlockComponent
1141
+ ], template: "@for (node of content; track node) {\n @if (customRenderers?.[node.type]) {\n <ng-container\n *ngTemplateOutlet=\"\n customRender;\n context: { customRender: customRenderers?.[node.type], node: node }\n \"></ng-container>\n } @else {\n @switch (node.type) {\n @case (BLOCKS.PARAGRAPH) {\n <dotcms-block-editor-renderer-paragraph [style]=\"node.attrs\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-paragraph>\n }\n\n @case (BLOCKS.TEXT) {\n <dotcms-block-editor-renderer-text [marks]=\"node.marks\" [text]=\"node.text || ''\" />\n }\n\n @case (BLOCKS.HEADING) {\n <dotcms-block-editor-renderer-heading\n [style]=\"node.attrs || {}\"\n [level]=\"node.attrs?.['level'] || '1'\">\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-heading>\n }\n\n @case (BLOCKS.BULLET_LIST) {\n <dotcms-block-editor-renderer-bullet-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-bullet-list>\n }\n\n @case (BLOCKS.ORDERED_LIST) {\n <dotcms-block-editor-renderer-ordered-list>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-ordered-list>\n }\n\n @case (BLOCKS.LIST_ITEM) {\n <dotcms-block-editor-renderer-list-item>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-list-item>\n }\n\n @case (BLOCKS.BLOCK_QUOTE) {\n <dotcms-block-editor-renderer-block-quote>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-block-quote>\n }\n\n @case (BLOCKS.CODE_BLOCK) {\n <dotcms-block-editor-renderer-code-block>\n <dotcms-block-editor-renderer-block\n [content]=\"node.content\"\n [customRenderers]=\"customRenderers\" />\n </dotcms-block-editor-renderer-code-block>\n }\n\n @case (BLOCKS.HARDBREAK) {\n <br />\n }\n\n @case (BLOCKS.HORIZONTAL_RULE) {\n <hr />\n }\n\n @case (BLOCKS.DOT_IMAGE) {\n <dotcms-block-editor-renderer-image [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.DOT_VIDEO) {\n <dotcms-block-editor-renderer-video [attrs]=\"node.attrs || {}\" />\n }\n\n @case (BLOCKS.TABLE) {\n <dotcms-block-editor-renderer-table [content]=\"node.content\" />\n }\n\n @case (BLOCKS.DOT_CONTENT) {\n <dotcms-block-editor-renderer-contentlet\n [attrs]=\"node.attrs || {}\"\n [customRenderers]=\"customRenderers\" />\n }\n\n @default {\n <dotcms-block-editor-renderer-unknown [node]=\"node\" />\n }\n }\n }\n}\n\n<ng-template #customRender let-customRender=\"customRender\" let-node=\"node\">\n <ng-container\n *ngComponentOutlet=\"customRender | async; inputs: { content: node }\"></ng-container>\n</ng-template>\n" }]
1142
+ }], propDecorators: { content: [{
1143
+ type: Input
1144
+ }], customRenderers: [{
1145
+ type: Input
1146
+ }] } });
1147
+
1148
+ /**
1149
+ * A component that renders content from DotCMS's Block Editor field.
1150
+ *
1151
+ * This component provides an easy way to render Block Editor content in your Angular applications.
1152
+ * It handles the rendering of standard blocks and allows customization through custom renderers.
1153
+ *
1154
+ * For more information about Block Editor, see {@link https://dev.dotcms.com/docs/block-editor}
1155
+ *
1156
+ * @example
1157
+ * ```html
1158
+ * <dotcms-block-editor-renderer
1159
+ * [blocks]="myBlockEditorContent"
1160
+ * [customRenderers]="myCustomRenderers">
1161
+ * </dotcms-block-editor-renderer>
1162
+ * ```
1163
+ */
1164
+ class DotCMSBlockEditorRendererComponent {
1165
+ constructor() {
1166
+ this.$blockEditorState = signal({ error: null });
1167
+ this.$isInEditMode = signal(getUVEState()?.mode === UVE_MODE.EDIT);
1168
+ }
1169
+ ngOnInit() {
1170
+ const state = isValidBlocks(this.blocks);
1171
+ if (state.error) {
1172
+ console.error('Error in dotcms-block-editor-renderer: ', state.error);
1173
+ }
1174
+ this.$blockEditorState.set(isValidBlocks(this.blocks));
1175
+ }
1176
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSBlockEditorRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1177
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotCMSBlockEditorRendererComponent, isStandalone: true, selector: "dotcms-block-editor-renderer", inputs: { blocks: "blocks", customRenderers: "customRenderers", class: "class", style: "style" }, ngImport: i0, template: "@if ($blockEditorState().error && $isInEditMode()) {\n <div data-testid=\"invalid-blocks-message\">\n {{ $blockEditorState().error }}\n </div>\n} @else if (!$blockEditorState().error) {\n <div [class]=\"class\" [style]=\"style\">\n <dotcms-block-editor-renderer-block\n [content]=\"blocks.content\"\n [customRenderers]=\"customRenderers\" />\n </div>\n}\n", styles: [""], dependencies: [{ kind: "component", type: DotCMSBlockEditorItemComponent, selector: "dotcms-block-editor-renderer-block", inputs: ["content", "customRenderers"] }] }); }
1178
+ }
1179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSBlockEditorRendererComponent, decorators: [{
1180
+ type: Component,
1181
+ args: [{ selector: 'dotcms-block-editor-renderer', standalone: true, imports: [DotCMSBlockEditorItemComponent], template: "@if ($blockEditorState().error && $isInEditMode()) {\n <div data-testid=\"invalid-blocks-message\">\n {{ $blockEditorState().error }}\n </div>\n} @else if (!$blockEditorState().error) {\n <div [class]=\"class\" [style]=\"style\">\n <dotcms-block-editor-renderer-block\n [content]=\"blocks.content\"\n [customRenderers]=\"customRenderers\" />\n </div>\n}\n" }]
1182
+ }], propDecorators: { blocks: [{
1183
+ type: Input
1184
+ }], customRenderers: [{
1185
+ type: Input
1186
+ }], class: [{
1187
+ type: Input
1188
+ }], style: [{
1189
+ type: Input
1190
+ }] } });
1191
+
1192
+ /**
1193
+ * @description This component is used to display a message when a page is missing the required `layout.body` property.
1194
+ * @internal
1195
+ * @class PageErrorMessageComponent
1196
+ */
1197
+ class PageErrorMessageComponent {
1198
+ ngOnInit() {
1199
+ console.warn('Missing required layout.body property in page');
1200
+ }
1201
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: PageErrorMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: PageErrorMessageComponent, isStandalone: true, selector: "dotcms-page-error-message", ngImport: i0, template: `
1203
+ <div
1204
+ data-testid="error-message"
1205
+ style="padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px;">
1206
+ <p style="margin: 0 0 0.5rem; color: #666;">
1207
+ The
1208
+ <code>page</code>
1209
+ is missing the required
1210
+ <code>layout.body</code>
1211
+ property.
1212
+ </p>
1213
+ <p style="margin: 0; color: #666;">
1214
+ Make sure the page asset is properly loaded and includes a layout configuration.
1215
+ </p>
1216
+ </div>
1217
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1218
+ }
1219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: PageErrorMessageComponent, decorators: [{
1220
+ type: Component,
1221
+ args: [{
1222
+ selector: 'dotcms-page-error-message',
1223
+ standalone: true,
1224
+ imports: [],
1225
+ template: `
1226
+ <div
1227
+ data-testid="error-message"
1228
+ style="padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px;">
1229
+ <p style="margin: 0 0 0.5rem; color: #666;">
1230
+ The
1231
+ <code>page</code>
1232
+ is missing the required
1233
+ <code>layout.body</code>
1234
+ property.
1235
+ </p>
1236
+ <p style="margin: 0; color: #666;">
1237
+ Make sure the page asset is properly loaded and includes a layout configuration.
1238
+ </p>
1239
+ </div>
1240
+ `,
1241
+ changeDetection: ChangeDetectionStrategy.OnPush
1242
+ }]
1243
+ }] });
1244
+
1245
+ const EMPTY_DOTCMS_PAGE_STORE = {
1246
+ page: {},
1247
+ components: {},
1248
+ mode: PRODUCTION_MODE
1249
+ };
1250
+ /**
1251
+ * @description This service is responsible for managing the page context.
1252
+ * @internal
1253
+ * @author dotCMS
1254
+ * @export
1255
+ * @class DotCMSStore
1256
+ */
1257
+ class DotCMSStore {
1258
+ constructor() {
1259
+ this.$store = signal(EMPTY_DOTCMS_PAGE_STORE);
1260
+ /**
1261
+ * @description Get if the current context is in development mode
1262
+ * @readonly
1263
+ * @type {boolean}
1264
+ * @memberof DotCMSStore
1265
+ */
1266
+ this.$isDevMode = computed(() => {
1267
+ const uveState = getUVEState();
1268
+ if (uveState?.mode) {
1269
+ return uveState?.mode === UVE_MODE.EDIT;
1270
+ }
1271
+ return this.$store()?.mode === DEVELOPMENT_MODE;
1272
+ });
1273
+ }
1274
+ /**
1275
+ * @description Get the store
1276
+ * @readonly
1277
+ * @type {DotCMSPageStore}
1278
+ * @memberof DotCMSStore
1279
+ */
1280
+ get store() {
1281
+ return this.$store();
1282
+ }
1283
+ /**
1284
+ * @description Set the store
1285
+ * @param {DotCMSPageStore} value
1286
+ * @memberof DotCMSStore
1287
+ */
1288
+ setStore(store) {
1289
+ this.$store.set(store);
1290
+ }
1291
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1292
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, providedIn: 'root' }); }
1293
+ }
1294
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, decorators: [{
1295
+ type: Injectable,
1296
+ args: [{
1297
+ providedIn: 'root'
1298
+ }]
1299
+ }] });
1300
+
1301
+ /**
1302
+ * @description This component is used to display a message when a container is not found.
1303
+ * @export
1304
+ * @internal
1305
+ * @class ContainerNotFoundComponent
1306
+ * @implements {OnInit}
1307
+ */
1308
+ class ContainerNotFoundComponent {
1309
+ constructor() {
1310
+ this.identifier = 'unknown';
1311
+ this.#dotcmsContextService = inject(DotCMSStore);
1312
+ this.$isDevMode = this.#dotcmsContextService.$isDevMode;
1313
+ this.emptyContainerStyle = EMPTY_CONTAINER_STYLE_ANGULAR;
1314
+ }
1315
+ #dotcmsContextService;
1316
+ ngOnInit() {
1317
+ if (this.$isDevMode()) {
1318
+ console.error(`Container with identifier ${this.identifier} not found`);
1319
+ }
1320
+ }
1321
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerNotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1322
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContainerNotFoundComponent, isStandalone: true, selector: "dotcms-container-not-found", inputs: { identifier: "identifier" }, ngImport: i0, template: `
1323
+ @if ($isDevMode()) {
1324
+ <div [attr.data-testid]="'container-not-found'" [ngStyle]="emptyContainerStyle">
1325
+ This container with identifier {{ identifier }} was not found.
1326
+ </div>
1327
+ }
1328
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
1329
+ }
1330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerNotFoundComponent, decorators: [{
1331
+ type: Component,
1332
+ args: [{
1333
+ selector: 'dotcms-container-not-found',
1334
+ standalone: true,
1335
+ imports: [NgStyle],
1336
+ template: `
1337
+ @if ($isDevMode()) {
1338
+ <div [attr.data-testid]="'container-not-found'" [ngStyle]="emptyContainerStyle">
1339
+ This container with identifier {{ identifier }} was not found.
1340
+ </div>
1341
+ }
1342
+ `
1343
+ }]
1344
+ }], propDecorators: { identifier: [{
1345
+ type: Input
1346
+ }] } });
1347
+
1348
+ /**
1349
+ * @description This component is used to display a message when a container is empty.
1350
+ * @export
1351
+ * @internal
1352
+ * @class EmptyContainerComponent
1353
+ */
1354
+ class EmptyContainerComponent {
1355
+ constructor() {
1356
+ this.emptyContainerStyle = EMPTY_CONTAINER_STYLE_ANGULAR;
1357
+ this.#dotCMSStore = inject(DotCMSStore);
1358
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
1359
+ }
1360
+ #dotCMSStore;
1361
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: EmptyContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1362
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: EmptyContainerComponent, isStandalone: true, selector: "dotcms-empty-container", ngImport: i0, template: `
1363
+ @if ($isDevMode()) {
1364
+ <div [ngStyle]="emptyContainerStyle" data-testid="empty-container">
1365
+ <span data-testid="empty-container-message" data-dot-object="empty-content">
1366
+ This container is empty.
1367
+ </span>
1368
+ </div>
1369
+ }
1370
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
1371
+ }
1372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: EmptyContainerComponent, decorators: [{
1373
+ type: Component,
1374
+ args: [{
1375
+ selector: 'dotcms-empty-container',
1376
+ standalone: true,
1377
+ imports: [NgStyle],
1378
+ template: `
1379
+ @if ($isDevMode()) {
1380
+ <div [ngStyle]="emptyContainerStyle" data-testid="empty-container">
1381
+ <span data-testid="empty-container-message" data-dot-object="empty-content">
1382
+ This container is empty.
1383
+ </span>
1384
+ </div>
1385
+ }
1386
+ `
1387
+ }]
1388
+ }] });
1389
+
1390
+ /**
1391
+ * @description Fallback component that renders when no custom component is found for a contentlet
1392
+ * @category Components
1393
+ * @internal
1394
+ * @class FallbackComponent
1395
+ */
1396
+ class FallbackComponent {
1397
+ constructor() {
1398
+ this.UserNoComponent = null;
1399
+ }
1400
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: FallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1401
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: FallbackComponent, isStandalone: true, selector: "dotcms-fallback-component", inputs: { UserNoComponent: "UserNoComponent", contentlet: "contentlet" }, ngImport: i0, template: `
1402
+ @if (UserNoComponent) {
1403
+ <ng-container *ngComponentOutlet="UserNoComponent | async; inputs: { contentlet }" />
1404
+ } @else {
1405
+ <div data-testid="dotcms-fallback-component">
1406
+ <p>No component found for content type: {{ contentlet.contentType }}</p>
1407
+ </div>
1408
+ }
1409
+ `, isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1410
+ }
1411
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: FallbackComponent, decorators: [{
1412
+ type: Component,
1413
+ args: [{
1414
+ selector: 'dotcms-fallback-component',
1415
+ standalone: true,
1416
+ imports: [AsyncPipe, NgComponentOutlet],
1417
+ template: `
1418
+ @if (UserNoComponent) {
1419
+ <ng-container *ngComponentOutlet="UserNoComponent | async; inputs: { contentlet }" />
1420
+ } @else {
1421
+ <div data-testid="dotcms-fallback-component">
1422
+ <p>No component found for content type: {{ contentlet.contentType }}</p>
1423
+ </div>
1424
+ }
1425
+ `,
1426
+ changeDetection: ChangeDetectionStrategy.OnPush
1427
+ }]
1428
+ }], propDecorators: { UserNoComponent: [{
1429
+ type: Input
1430
+ }], contentlet: [{
1431
+ type: Input
1432
+ }] } });
1433
+
1434
+ /**
1435
+ * @description Contentlet component that renders DotCMS content with development mode support
1436
+ *
1437
+ * @component
1438
+ * @param {DotCMSContentlet} contentlet - The contentlet to be rendered
1439
+ * @param {string} container - The container identifier
1440
+ * @class ContentletComponent
1441
+ */
1442
+ class ContentletComponent {
1443
+ constructor() {
1444
+ this.dotObject = 'contentlet';
1445
+ this.#dotCMSStore = inject(DotCMSStore);
1446
+ this.$contentlet = signal(null);
1447
+ this.$UserComponent = signal(null);
1448
+ this.$UserNoComponent = signal(null);
1449
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
1450
+ this.$haveContent = signal(false);
1451
+ this.$style = computed(() => this.$isDevMode() && !this.$haveContent() ? { minHeight: '4rem' } : {});
1452
+ this.$dotAttributes = computed(() => {
1453
+ const contentlet = this.$contentlet();
1454
+ if (!contentlet || !this.$isDevMode())
1455
+ return {};
1456
+ return getDotContentletAttributes(contentlet, this.containerData.identifier);
1457
+ });
1458
+ this.identifier = null;
1459
+ this.basetype = null;
1460
+ this.title = null;
1461
+ this.inode = null;
1462
+ this.type = null;
1463
+ this.containerAttribute = null;
1464
+ this.onNumberOfPages = null;
1465
+ this.styleAttribute = null;
1466
+ }
1467
+ #dotCMSStore;
1468
+ ngOnChanges() {
1469
+ this.$contentlet.set(this.contentlet);
1470
+ this.setupComponents();
1471
+ this.identifier = this.$dotAttributes()['data-dot-identifier'];
1472
+ this.basetype = this.$dotAttributes()['data-dot-basetype'];
1473
+ this.title = this.$dotAttributes()['data-dot-title'];
1474
+ this.inode = this.$dotAttributes()['data-dot-inode'];
1475
+ this.type = this.$dotAttributes()['data-dot-type'];
1476
+ this.containerAttribute = JSON.stringify(this.containerData);
1477
+ this.onNumberOfPages = this.$dotAttributes()['data-dot-on-number-of-pages'];
1478
+ this.styleAttribute = this.$style();
1479
+ }
1480
+ ngAfterViewInit() {
1481
+ this.checkContent();
1482
+ }
1483
+ setupComponents() {
1484
+ const store = this.#dotCMSStore.store;
1485
+ if (!store)
1486
+ return;
1487
+ if (!store?.components)
1488
+ return;
1489
+ this.$UserComponent.set(store.components[this.contentlet?.contentType]);
1490
+ this.$UserNoComponent.set(store.components[CUSTOM_NO_COMPONENT]);
1491
+ }
1492
+ checkContent() {
1493
+ const element = this.contentletRef?.nativeElement;
1494
+ if (element) {
1495
+ const hasContent = element.getBoundingClientRect().height > 0;
1496
+ this.$haveContent.set(hasContent);
1497
+ }
1498
+ }
1499
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContentletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1500
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContentletComponent, isStandalone: true, selector: "dotcms-contentlet", inputs: { contentlet: "contentlet", containerData: "containerData" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-identifier": "this.identifier", "attr.data-dot-basetype": "this.basetype", "attr.data-dot-title": "this.title", "attr.data-dot-inode": "this.inode", "attr.data-dot-type": "this.type", "attr.data-dot-container": "this.containerAttribute", "attr.data-dot-on-number-of-pages": "this.onNumberOfPages", "style": "this.styleAttribute" } }, viewQueries: [{ propertyName: "contentletRef", first: true, predicate: ["contentletRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
1501
+ @if ($UserComponent()) {
1502
+ <ng-container
1503
+ *ngComponentOutlet="
1504
+ $UserComponent() | async;
1505
+ inputs: { contentlet: $contentlet() ?? contentlet }
1506
+ " />
1507
+ } @else if ($isDevMode()) {
1508
+ <dotcms-fallback-component
1509
+ [UserNoComponent]="$UserNoComponent()"
1510
+ [contentlet]="$contentlet() ?? contentlet" />
1511
+ }
1512
+ `, isInline: true, dependencies: [{ kind: "component", type: FallbackComponent, selector: "dotcms-fallback-component", inputs: ["UserNoComponent", "contentlet"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1513
+ }
1514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContentletComponent, decorators: [{
1515
+ type: Component,
1516
+ args: [{
1517
+ selector: 'dotcms-contentlet',
1518
+ standalone: true,
1519
+ imports: [FallbackComponent, AsyncPipe, NgComponentOutlet],
1520
+ template: `
1521
+ @if ($UserComponent()) {
1522
+ <ng-container
1523
+ *ngComponentOutlet="
1524
+ $UserComponent() | async;
1525
+ inputs: { contentlet: $contentlet() ?? contentlet }
1526
+ " />
1527
+ } @else if ($isDevMode()) {
1528
+ <dotcms-fallback-component
1529
+ [UserNoComponent]="$UserNoComponent()"
1530
+ [contentlet]="$contentlet() ?? contentlet" />
1531
+ }
1532
+ `,
1533
+ changeDetection: ChangeDetectionStrategy.OnPush
1534
+ }]
1535
+ }], propDecorators: { contentlet: [{
1536
+ type: Input,
1537
+ args: [{ required: true }]
1538
+ }], containerData: [{
1539
+ type: Input,
1540
+ args: [{ required: true }]
1541
+ }], contentletRef: [{
1542
+ type: ViewChild,
1543
+ args: ['contentletRef']
1544
+ }], dotObject: [{
1545
+ type: HostBinding,
1546
+ args: ['attr.data-dot-object']
1547
+ }], identifier: [{
1548
+ type: HostBinding,
1549
+ args: ['attr.data-dot-identifier']
1550
+ }], basetype: [{
1551
+ type: HostBinding,
1552
+ args: ['attr.data-dot-basetype']
1553
+ }], title: [{
1554
+ type: HostBinding,
1555
+ args: ['attr.data-dot-title']
1556
+ }], inode: [{
1557
+ type: HostBinding,
1558
+ args: ['attr.data-dot-inode']
1559
+ }], type: [{
1560
+ type: HostBinding,
1561
+ args: ['attr.data-dot-type']
1562
+ }], containerAttribute: [{
1563
+ type: HostBinding,
1564
+ args: ['attr.data-dot-container']
1565
+ }], onNumberOfPages: [{
1566
+ type: HostBinding,
1567
+ args: ['attr.data-dot-on-number-of-pages']
1568
+ }], styleAttribute: [{
1569
+ type: HostBinding,
1570
+ args: ['style']
1571
+ }] } });
1572
+
1573
+ /**
1574
+ * @description This component renders a container with all its content using the layout provided by dotCMS Page API.
1575
+ *
1576
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
1577
+ * @category Components
1578
+ * @internal
1579
+ * @class ContainerComponent
1580
+ */
1581
+ class ContainerComponent {
1582
+ constructor() {
1583
+ this.#dotCMSStore = inject(DotCMSStore);
1584
+ this.$containerData = signal(null);
1585
+ this.$contentlets = signal([]);
1586
+ this.$isEmpty = computed(() => this.$contentlets().length === 0);
1587
+ this.$dotAttributes = computed(() => {
1588
+ const containerData = this.$containerData();
1589
+ if (!containerData || !this.#dotCMSStore.$isDevMode()) {
1590
+ return {};
1591
+ }
1592
+ return getDotContainerAttributes(containerData);
1593
+ });
1594
+ this.dotObject = 'container';
1595
+ this.acceptTypes = null;
1596
+ this.identifier = null;
1597
+ this.maxContentlets = null;
1598
+ this.uuid = null;
1599
+ }
1600
+ #dotCMSStore;
1601
+ ngOnChanges() {
1602
+ const { page } = this.#dotCMSStore.store ?? {};
1603
+ if (!page) {
1604
+ return;
1605
+ }
1606
+ this.$containerData.set(getContainersData(page, this.container));
1607
+ this.$contentlets.set(getContentletsInContainer(page, this.container));
1608
+ this.acceptTypes = this.$dotAttributes()['data-dot-accept-types'];
1609
+ this.identifier = this.$dotAttributes()['data-dot-identifier'];
1610
+ this.maxContentlets = this.$dotAttributes()['data-max-contentlets'];
1611
+ this.uuid = this.$dotAttributes()['data-dot-uuid'];
1612
+ }
1613
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1614
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContainerComponent, isStandalone: true, selector: "dotcms-container", inputs: { container: "container" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-accept-types": "this.acceptTypes", "attr.data-dot-identifier": "this.identifier", "attr.data-max-contentlets": "this.maxContentlets", "attr.data-dot-uuid": "this.uuid" } }, usesOnChanges: true, ngImport: i0, template: `
1615
+ @if (!$containerData()) {
1616
+ <dotcms-container-not-found [identifier]="container.identifier" />
1617
+ } @else if ($isEmpty()) {
1618
+ <dotcms-empty-container />
1619
+ } @else {
1620
+ @for (contentlet of $contentlets(); track contentlet.identifier) {
1621
+ <dotcms-contentlet [contentlet]="contentlet" [containerData]="$containerData()!" />
1622
+ }
1623
+ }
1624
+ `, isInline: true, dependencies: [{ kind: "component", type: ContainerNotFoundComponent, selector: "dotcms-container-not-found", inputs: ["identifier"] }, { kind: "component", type: EmptyContainerComponent, selector: "dotcms-empty-container" }, { kind: "component", type: ContentletComponent, selector: "dotcms-contentlet", inputs: ["contentlet", "containerData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1625
+ }
1626
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, decorators: [{
1627
+ type: Component,
1628
+ args: [{
1629
+ selector: 'dotcms-container',
1630
+ standalone: true,
1631
+ imports: [ContainerNotFoundComponent, EmptyContainerComponent, ContentletComponent],
1632
+ template: `
1633
+ @if (!$containerData()) {
1634
+ <dotcms-container-not-found [identifier]="container.identifier" />
1635
+ } @else if ($isEmpty()) {
1636
+ <dotcms-empty-container />
1637
+ } @else {
1638
+ @for (contentlet of $contentlets(); track contentlet.identifier) {
1639
+ <dotcms-contentlet [contentlet]="contentlet" [containerData]="$containerData()!" />
1640
+ }
1641
+ }
1642
+ `,
1643
+ changeDetection: ChangeDetectionStrategy.OnPush
1644
+ }]
1645
+ }], propDecorators: { container: [{
1646
+ type: Input,
1647
+ args: [{ required: true }]
1648
+ }], dotObject: [{
1649
+ type: HostBinding,
1650
+ args: ['attr.data-dot-object']
1651
+ }], acceptTypes: [{
1652
+ type: HostBinding,
1653
+ args: ['attr.data-dot-accept-types']
1654
+ }], identifier: [{
1655
+ type: HostBinding,
1656
+ args: ['attr.data-dot-identifier']
1657
+ }], maxContentlets: [{
1658
+ type: HostBinding,
1659
+ args: ['attr.data-max-contentlets']
1660
+ }], uuid: [{
1661
+ type: HostBinding,
1662
+ args: ['attr.data-dot-uuid']
1663
+ }] } });
1664
+
1665
+ /**
1666
+ * This component renders a column with all its content using the layout provided by dotCMS Page API.
1667
+ *
1668
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
1669
+ * @category Components
1670
+ * @internal
1671
+ */
1672
+ class ColumnComponent {
1673
+ constructor() {
1674
+ this.customClasses = '';
1675
+ }
1676
+ ngOnChanges() {
1677
+ const positionClasses = getColumnPositionClasses(this.column);
1678
+ this.customClasses = combineClasses([positionClasses.startClass, positionClasses.endClass]);
1679
+ }
1680
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1681
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ColumnComponent, isStandalone: true, selector: "dotcms-column", inputs: { column: "column" }, host: { properties: { "class": "this.customClasses" } }, usesOnChanges: true, ngImport: i0, template: `
1682
+ <div [class]="column.styleClass" data-testid="dotcms-column">
1683
+ @for (container of column.containers; track $index) {
1684
+ <dotcms-container [container]="container" />
1685
+ }
1686
+ </div>
1687
+ `, isInline: true, styles: [":host.col-start-1{grid-column-start:1}:host.col-start-2{grid-column-start:2}:host.col-start-3{grid-column-start:3}:host.col-start-4{grid-column-start:4}:host.col-start-5{grid-column-start:5}:host.col-start-6{grid-column-start:6}:host.col-start-7{grid-column-start:7}:host.col-start-8{grid-column-start:8}:host.col-start-9{grid-column-start:9}:host.col-start-10{grid-column-start:10}:host.col-start-11{grid-column-start:11}:host.col-start-12{grid-column-start:12}:host.col-end-1{grid-column-end:1}:host.col-end-2{grid-column-end:2}:host.col-end-3{grid-column-end:3}:host.col-end-4{grid-column-end:4}:host.col-end-5{grid-column-end:5}:host.col-end-6{grid-column-end:6}:host.col-end-7{grid-column-end:7}:host.col-end-8{grid-column-end:8}:host.col-end-9{grid-column-end:9}:host.col-end-10{grid-column-end:10}:host.col-end-11{grid-column-end:11}:host.col-end-12{grid-column-end:12}:host.col-end-13{grid-column-end:13}\n"], dependencies: [{ kind: "component", type: ContainerComponent, selector: "dotcms-container", inputs: ["container"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1688
+ }
1689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ColumnComponent, decorators: [{
1690
+ type: Component,
1691
+ args: [{ selector: 'dotcms-column', standalone: true, imports: [ContainerComponent], template: `
1692
+ <div [class]="column.styleClass" data-testid="dotcms-column">
1693
+ @for (container of column.containers; track $index) {
1694
+ <dotcms-container [container]="container" />
1695
+ }
1696
+ </div>
1697
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host.col-start-1{grid-column-start:1}:host.col-start-2{grid-column-start:2}:host.col-start-3{grid-column-start:3}:host.col-start-4{grid-column-start:4}:host.col-start-5{grid-column-start:5}:host.col-start-6{grid-column-start:6}:host.col-start-7{grid-column-start:7}:host.col-start-8{grid-column-start:8}:host.col-start-9{grid-column-start:9}:host.col-start-10{grid-column-start:10}:host.col-start-11{grid-column-start:11}:host.col-start-12{grid-column-start:12}:host.col-end-1{grid-column-end:1}:host.col-end-2{grid-column-end:2}:host.col-end-3{grid-column-end:3}:host.col-end-4{grid-column-end:4}:host.col-end-5{grid-column-end:5}:host.col-end-6{grid-column-end:6}:host.col-end-7{grid-column-end:7}:host.col-end-8{grid-column-end:8}:host.col-end-9{grid-column-end:9}:host.col-end-10{grid-column-end:10}:host.col-end-11{grid-column-end:11}:host.col-end-12{grid-column-end:12}:host.col-end-13{grid-column-end:13}\n"] }]
1698
+ }], propDecorators: { column: [{
1699
+ type: Input,
1700
+ args: [{ required: true }]
1701
+ }], customClasses: [{
1702
+ type: HostBinding,
1703
+ args: ['class']
1704
+ }] } });
1705
+
1706
+ /**
1707
+ * @description This component renders a row with all its content using the layout provided by dotCMS Page API.
1708
+ *
1709
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
1710
+ * @category Components
1711
+ * @internal
1712
+ * @class RowComponent
1713
+ */
1714
+ class RowComponent {
1715
+ constructor() {
1716
+ this.customClasses = signal('');
1717
+ }
1718
+ ngOnChanges() {
1719
+ this.customClasses.set(combineClasses([this.row.styleClass || 'dot-row']));
1720
+ }
1721
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: RowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1722
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: RowComponent, isStandalone: true, selector: "dotcms-row", inputs: { row: "row" }, usesOnChanges: true, ngImport: i0, template: `
1723
+ <div class="dot-row-container">
1724
+ <div [class]="customClasses()" data-dot-object="row" data-testid="dotcms-row">
1725
+ @for (column of row.columns; track $index) {
1726
+ <dotcms-column [column]="column" />
1727
+ }
1728
+ </div>
1729
+ </div>
1730
+ `, isInline: true, styles: [".dot-row{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}\n"], dependencies: [{ kind: "component", type: ColumnComponent, selector: "dotcms-column", inputs: ["column"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1731
+ }
1732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: RowComponent, decorators: [{
1733
+ type: Component,
1734
+ args: [{ selector: 'dotcms-row', standalone: true, imports: [ColumnComponent], template: `
1735
+ <div class="dot-row-container">
1736
+ <div [class]="customClasses()" data-dot-object="row" data-testid="dotcms-row">
1737
+ @for (column of row.columns; track $index) {
1738
+ <dotcms-column [column]="column" />
1739
+ }
1740
+ </div>
1741
+ </div>
1742
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".dot-row{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}\n"] }]
1743
+ }], propDecorators: { row: [{
1744
+ type: Input,
1745
+ args: [{ required: true }]
1746
+ }] } });
1747
+
1748
+ /**
1749
+ * @description This component is used to render the layout for a DotCMS page.
1750
+ * @param {DotCMSPageAsset} page - The page to render the layout for
1751
+ * @param {DotCMSPageComponent} components - The components to render the layout for
1752
+ * @param {DotCMSPageRendererMode} mode - The mode to render the layout for
1753
+ *
1754
+ * @example
1755
+ * <dotcms-layout-body [page]="page" [components]="components" [mode]="'development'" />
1756
+ *
1757
+ * @export
1758
+ * @implements {OnChanges}
1759
+ * @class DotCMSLayoutBodyComponent
1760
+ */
1761
+ class DotCMSLayoutBodyComponent {
1762
+ constructor() {
1763
+ this.components = {};
1764
+ this.mode = 'production';
1765
+ this.#dotCMSStore = inject(DotCMSStore);
1766
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
1767
+ this.$rows = signal([]);
1768
+ this.$isEmpty = signal(false);
1769
+ }
1770
+ #dotCMSStore;
1771
+ ngOnChanges() {
1772
+ this.#dotCMSStore.setStore({
1773
+ page: this.page,
1774
+ components: this.components,
1775
+ mode: this.mode
1776
+ });
1777
+ this.$isEmpty.set(!this.page?.layout?.body);
1778
+ this.$rows.set(this.page?.layout?.body?.rows ?? []);
1779
+ }
1780
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSLayoutBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1781
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotCMSLayoutBodyComponent, isStandalone: true, selector: "dotcms-layout-body", inputs: { page: "page", components: "components", mode: "mode" }, providers: [DotCMSStore], usesOnChanges: true, ngImport: i0, template: `
1782
+ @if ($isEmpty() && $isDevMode()) {
1783
+ <dotcms-page-error-message />
1784
+ } @else {
1785
+ @for (row of $rows(); track row.identifier) {
1786
+ <dotcms-row [row]="row" />
1787
+ }
1788
+ }
1789
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: PageErrorMessageComponent, selector: "dotcms-page-error-message" }, { kind: "component", type: RowComponent, selector: "dotcms-row", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1790
+ }
1791
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSLayoutBodyComponent, decorators: [{
1792
+ type: Component,
1793
+ args: [{ selector: 'dotcms-layout-body', standalone: true, imports: [PageErrorMessageComponent, RowComponent], providers: [DotCMSStore], template: `
1794
+ @if ($isEmpty() && $isDevMode()) {
1795
+ <dotcms-page-error-message />
1796
+ } @else {
1797
+ @for (row of $rows(); track row.identifier) {
1798
+ <dotcms-row [row]="row" />
1799
+ }
1800
+ }
1801
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
1802
+ }], propDecorators: { page: [{
1803
+ type: Input,
1804
+ args: [{ required: true }]
1805
+ }], components: [{
1806
+ type: Input,
1807
+ args: [{ required: true }]
1808
+ }], mode: [{
1809
+ type: Input
1810
+ }] } });
1811
+
1812
+ class DotCMSEditablePageService {
1813
+ /**
1814
+ * Subject that emits the current editable page asset or null.
1815
+ * Used internally to track changes to the page data.
1816
+ *
1817
+ * @private
1818
+ * @type {Subject<DotCMSPageResponse | undefined>}
1819
+ */
1820
+ #responseSubject = new Subject();
1821
+ /**
1822
+ * Observable stream of the page asset changes.
1823
+ * Exposes the pageAssetSubject as an Observable for subscribers.
1824
+ *
1825
+ * @private
1826
+ * @type {Observable<DotCMSPageResponse | undefined>}
1827
+ */
1828
+ #response$ = this.#responseSubject.asObservable();
1829
+ /**
1830
+ * Listens for changes to an editable page and returns an Observable that emits the updated page data.
1831
+ * This method initializes the UVE (Universal Visual Editor) and sets up subscriptions to track content changes.
1832
+ *
1833
+ * @example
1834
+ * ```ts
1835
+ * // Import the service
1836
+ * import { DotCMSEditablePageService } from '@dotcms/angular';
1837
+ *
1838
+ * // Inject the service
1839
+ * constructor(private editablePageService: DotCMSEditablePageService) {}
1840
+ *
1841
+ * // Get the page data from your API call
1842
+ * const page = await client.page.get('/');
1843
+ *
1844
+ * // Listen for changes
1845
+ * const subscription = this.editablePageService.listen(page).subscribe(updatedPage => {
1846
+ * if (updatedPage) {
1847
+ * // Handle updated page data
1848
+ * console.log('Page updated:', updatedPage);
1849
+ * }
1850
+ * });
1851
+ *
1852
+ * // When done listening, unsubscribe
1853
+ * subscription.unsubscribe();
1854
+ * ```
1855
+ *
1856
+ * @param response Optional initial page data
1857
+ * @returns Observable that emits the updated page data or undefined
1858
+ */
1859
+ listen(response) {
1860
+ if (!getUVEState()) {
1861
+ return of(response);
1862
+ }
1863
+ const pageURI = response?.pageAsset?.page?.pageURI;
1864
+ initUVE(response);
1865
+ // Update the navigation to the pageURI, when we have a pageURI
1866
+ // Sometimes the page is null due to permissions, so we don't want to update the navigation
1867
+ // And wait for the UVE to resolve the page
1868
+ if (pageURI) {
1869
+ updateNavigation(pageURI);
1870
+ }
1871
+ const unsubscribeUVEChanges = this.#listenUVEChanges();
1872
+ return this.#response$.pipe(finalize(() => {
1873
+ unsubscribeUVEChanges();
1874
+ }));
1875
+ }
1876
+ /**
1877
+ * Sets up a subscription to listen for UVE content changes and updates the page asset subject.
1878
+ * This is an internal method used by listenEditablePage() to handle UVE events.
1879
+ *
1880
+ * @returns {UVEUnsubscribeFunction} Function to unsubscribe from the UVE content changes
1881
+ * @private
1882
+ */
1883
+ #listenUVEChanges() {
1884
+ const { unsubscribe } = createUVESubscription(UVEEventType.CONTENT_CHANGES, (payload) => {
1885
+ this.#responseSubject.next(payload);
1886
+ });
1887
+ return unsubscribe;
1888
+ }
1889
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1890
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, providedIn: 'root' }); }
1891
+ }
1892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditablePageService, decorators: [{
1893
+ type: Injectable,
1894
+ args: [{
1895
+ providedIn: 'root'
1896
+ }]
1897
+ }] });
1898
+
1899
+ /**
1900
+ * Generated bundle index. Do not edit.
1901
+ */
1902
+
1903
+ export { DotCMSBlockEditorRendererComponent, DotCMSClient, DotCMSEditablePageService, DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSClient, provideDotCMSImageLoader };
1904
+ //# sourceMappingURL=dotcms-angular-next.mjs.map