@dotcms/angular 0.0.1-beta.1 → 0.0.1-beta.11

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 (99) hide show
  1. package/dotcms-angular.d.ts.map +1 -1
  2. package/esm2022/dotcms-angular.mjs +2 -2
  3. package/esm2022/lib/deprecated/components/dot-editable-text/dot-editable-text.component.mjs +229 -0
  4. package/esm2022/lib/deprecated/components/dot-editable-text/utils.mjs +43 -0
  5. package/esm2022/lib/deprecated/components/no-component/no-component.component.mjs +32 -0
  6. package/esm2022/lib/deprecated/deprecated-api.mjs +11 -0
  7. package/esm2022/lib/{layout → deprecated/layout}/column/column.component.mjs +1 -1
  8. package/esm2022/lib/deprecated/layout/container/container.component.mjs +126 -0
  9. package/esm2022/lib/deprecated/layout/contentlet/contentlet.component.mjs +120 -0
  10. package/esm2022/lib/deprecated/layout/dotcms-layout/dotcms-layout.component.mjs +105 -0
  11. package/esm2022/lib/{layout → deprecated/layout}/row/row.component.mjs +1 -1
  12. package/esm2022/lib/deprecated/models/dotcms.model.mjs +3 -0
  13. package/esm2022/lib/deprecated/models/index.mjs +3 -0
  14. package/esm2022/lib/deprecated/services/dotcms-context/page-context.service.mjs +79 -0
  15. package/esm2022/lib/deprecated/utils/image_loader.mjs +75 -0
  16. package/esm2022/lib/deprecated/utils/index.mjs +84 -0
  17. package/esm2022/next/components/dotcms-editable-text/dotcms-editable-text.component.mjs +225 -0
  18. package/esm2022/{lib/components/dot-editable-text → next/components/dotcms-editable-text}/utils.mjs +1 -1
  19. package/esm2022/next/directives/dotcms-show-when/dotcms-show-when.directive.mjs +49 -0
  20. package/esm2022/next/dotcms-angular-next.mjs +5 -0
  21. package/esm2022/next/models/dotcms.model.mjs +3 -0
  22. package/esm2022/next/models/index.mjs +3 -0
  23. package/esm2022/next/providers/dotcms-image-loader/dotcms-image_loader.mjs +74 -0
  24. package/esm2022/next/public_api.mjs +4 -0
  25. package/esm2022/public_api.mjs +2 -0
  26. package/fesm2022/dotcms-angular-next.mjs +395 -0
  27. package/fesm2022/dotcms-angular-next.mjs.map +1 -0
  28. package/fesm2022/dotcms-angular.mjs +97 -4
  29. package/fesm2022/dotcms-angular.mjs.map +1 -1
  30. package/index.d.ts +6 -5
  31. package/lib/{components → deprecated/components}/dot-editable-text/dot-editable-text.component.d.ts +4 -0
  32. package/lib/deprecated/components/dot-editable-text/dot-editable-text.component.d.ts.map +1 -0
  33. package/lib/deprecated/components/dot-editable-text/utils.d.ts.map +1 -0
  34. package/lib/deprecated/components/no-component/no-component.component.d.ts.map +1 -0
  35. package/lib/deprecated/deprecated-api.d.ts +11 -0
  36. package/lib/deprecated/deprecated-api.d.ts.map +1 -0
  37. package/lib/deprecated/layout/column/column.component.d.ts.map +1 -0
  38. package/lib/deprecated/layout/container/container.component.d.ts.map +1 -0
  39. package/lib/deprecated/layout/contentlet/contentlet.component.d.ts.map +1 -0
  40. package/lib/{layout → deprecated/layout}/dotcms-layout/dotcms-layout.component.d.ts +5 -0
  41. package/lib/deprecated/layout/dotcms-layout/dotcms-layout.component.d.ts.map +1 -0
  42. package/lib/deprecated/layout/row/row.component.d.ts.map +1 -0
  43. package/lib/deprecated/models/dotcms.model.d.ts.map +1 -0
  44. package/lib/deprecated/models/index.d.ts.map +1 -0
  45. package/lib/{services → deprecated/services}/dotcms-context/page-context.service.d.ts +4 -0
  46. package/lib/deprecated/services/dotcms-context/page-context.service.d.ts.map +1 -0
  47. package/lib/deprecated/utils/image_loader.d.ts +21 -0
  48. package/lib/deprecated/utils/image_loader.d.ts.map +1 -0
  49. package/lib/deprecated/utils/index.d.ts.map +1 -0
  50. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts +129 -0
  51. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts.map +1 -0
  52. package/next/components/dotcms-editable-text/utils.d.ts +7 -0
  53. package/{lib/components/dot-editable-text → next/components/dotcms-editable-text}/utils.d.ts.map +1 -1
  54. package/next/directives/dotcms-show-when/dotcms-show-when.directive.d.ts +21 -0
  55. package/next/directives/dotcms-show-when/dotcms-show-when.directive.d.ts.map +1 -0
  56. package/next/dotcms-angular-next.d.ts.map +1 -0
  57. package/next/index.d.ts +6 -0
  58. package/next/models/dotcms.model.d.ts +416 -0
  59. package/next/models/dotcms.model.d.ts.map +1 -0
  60. package/next/models/index.d.ts +40 -0
  61. package/next/models/index.d.ts.map +1 -0
  62. package/next/providers/dotcms-image-loader/dotcms-image_loader.d.ts +21 -0
  63. package/next/providers/dotcms-image-loader/dotcms-image_loader.d.ts.map +1 -0
  64. package/next/public_api.d.ts +4 -0
  65. package/next/public_api.d.ts.map +1 -0
  66. package/package.json +9 -2
  67. package/public_api.d.ts +2 -0
  68. package/public_api.d.ts.map +1 -0
  69. package/esm2022/index.mjs +0 -5
  70. package/esm2022/lib/components/dot-editable-text/dot-editable-text.component.mjs +0 -225
  71. package/esm2022/lib/components/no-component/no-component.component.mjs +0 -32
  72. package/esm2022/lib/layout/container/container.component.mjs +0 -126
  73. package/esm2022/lib/layout/contentlet/contentlet.component.mjs +0 -120
  74. package/esm2022/lib/layout/dotcms-layout/dotcms-layout.component.mjs +0 -100
  75. package/esm2022/lib/models/dotcms.model.mjs +0 -3
  76. package/esm2022/lib/models/index.mjs +0 -3
  77. package/esm2022/lib/services/dotcms-context/page-context.service.mjs +0 -75
  78. package/esm2022/lib/utils/index.mjs +0 -84
  79. package/index.d.ts.map +0 -1
  80. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts.map +0 -1
  81. package/lib/components/no-component/no-component.component.d.ts.map +0 -1
  82. package/lib/layout/column/column.component.d.ts.map +0 -1
  83. package/lib/layout/container/container.component.d.ts.map +0 -1
  84. package/lib/layout/contentlet/contentlet.component.d.ts.map +0 -1
  85. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts.map +0 -1
  86. package/lib/layout/row/row.component.d.ts.map +0 -1
  87. package/lib/models/dotcms.model.d.ts.map +0 -1
  88. package/lib/models/index.d.ts.map +0 -1
  89. package/lib/services/dotcms-context/page-context.service.d.ts.map +0 -1
  90. package/lib/utils/index.d.ts.map +0 -1
  91. /package/lib/{components → deprecated/components}/dot-editable-text/utils.d.ts +0 -0
  92. /package/lib/{components → deprecated/components}/no-component/no-component.component.d.ts +0 -0
  93. /package/lib/{layout → deprecated/layout}/column/column.component.d.ts +0 -0
  94. /package/lib/{layout → deprecated/layout}/container/container.component.d.ts +0 -0
  95. /package/lib/{layout → deprecated/layout}/contentlet/contentlet.component.d.ts +0 -0
  96. /package/lib/{layout → deprecated/layout}/row/row.component.d.ts +0 -0
  97. /package/lib/{models → deprecated/models}/dotcms.model.d.ts +0 -0
  98. /package/lib/{models → deprecated/models}/index.d.ts +0 -0
  99. /package/lib/{utils → deprecated/utils}/index.d.ts +0 -0
@@ -0,0 +1,395 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ViewContainerRef, TemplateRef, Directive, Input, Renderer2, ElementRef, SecurityContext, Component, ViewChild, HostListener } from '@angular/core';
3
+ import { getUVEState } from '@dotcms/uve';
4
+ import { UVE_MODE } from '@dotcms/uve/types';
5
+ import { IMAGE_LOADER } from '@angular/common';
6
+ import { TINYMCE_SCRIPT_SRC, EditorComponent } from '@tinymce/tinymce-angular';
7
+ import { DomSanitizer } from '@angular/platform-browser';
8
+ import { NOTIFY_CLIENT, isInsideEditor, DotCmsClient, postMessageToEditor, CLIENT_ACTIONS } from '@dotcms/client';
9
+
10
+ /**
11
+ * Directive to show a template when the UVE is in a specific mode.
12
+ *
13
+ * @example
14
+ * <div *dotCMSShowWhen="UVE_MODE.EDIT">
15
+ * This will be shown when the UVE is in edit mode.
16
+ * </div>
17
+ *
18
+ * @export
19
+ * @class DotCMSShowWhenDirective
20
+ */
21
+ class DotCMSShowWhenDirective {
22
+ #when = UVE_MODE.EDIT;
23
+ #hasView = false;
24
+ set dotCMSShowWhen(value) {
25
+ this.#when = value;
26
+ this.updateViewContainer();
27
+ }
28
+ #viewContainerRef = inject(ViewContainerRef);
29
+ #templateRef = inject(TemplateRef);
30
+ updateViewContainer() {
31
+ const state = getUVEState();
32
+ const shouldShow = state?.mode === this.#when;
33
+ if (shouldShow && !this.#hasView) {
34
+ this.#viewContainerRef.createEmbeddedView(this.#templateRef);
35
+ this.#hasView = true;
36
+ }
37
+ else if (!shouldShow && this.#hasView) {
38
+ this.#viewContainerRef.clear();
39
+ this.#hasView = false;
40
+ }
41
+ }
42
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSShowWhenDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
43
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.3", type: DotCMSShowWhenDirective, isStandalone: true, selector: "[dotCMSShowWhen]", inputs: { dotCMSShowWhen: "dotCMSShowWhen" }, ngImport: i0 }); }
44
+ }
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSShowWhenDirective, decorators: [{
46
+ type: Directive,
47
+ args: [{
48
+ selector: '[dotCMSShowWhen]',
49
+ standalone: true
50
+ }]
51
+ }], propDecorators: { dotCMSShowWhen: [{
52
+ type: Input
53
+ }] } });
54
+
55
+ /**
56
+ * Validates if a given path is a valid URL string
57
+ *
58
+ * @param path - The path to validate
59
+ * @returns boolean indicating if the path is valid
60
+ */
61
+ function isValidPath(path) {
62
+ if (typeof path !== 'string' || path.trim() === '') {
63
+ return false;
64
+ }
65
+ try {
66
+ new URL(path);
67
+ return true;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * Provides a DotCMS image loader configuration for the Angular Image directive
75
+ *
76
+ * @param path - The base URL path to the DotCMS instance, or empty to use current site
77
+ * @returns An array of providers for the IMAGE_LOADER token
78
+ * @throws Error if the provided path is invalid
79
+ * @example
80
+ * ```typescript
81
+ * // In your app.config.ts
82
+ * export const appConfig: ApplicationConfig = {
83
+ * providers: [
84
+ * provideDotCMSImageLoader('https://demo.dotcms.com')
85
+ * // Or use current site:
86
+ * // provideDotCMSImageLoader()
87
+ * ]
88
+ * };
89
+ * ```
90
+ */
91
+ function provideDotCMSImageLoader(path) {
92
+ // If path is provided, validate it
93
+ if (path && !isValidPath(path)) {
94
+ throw new Error(`Image loader has detected an invalid path (\`${path}\`). ` +
95
+ `To fix this, supply either the full URL to the dotCMS site, or leave it empty to use the current site.`);
96
+ }
97
+ return [
98
+ {
99
+ provide: IMAGE_LOADER,
100
+ useValue: (config) => createDotCMSURL(config, path)
101
+ }
102
+ ];
103
+ }
104
+ /**
105
+ * Creates a DotCMS-compatible URL for image loading
106
+ *
107
+ * @param config - The image loader configuration
108
+ * @param path - The base URL path to the DotCMS instance
109
+ * @returns A fully qualified URL for the image
110
+ * @internal
111
+ */
112
+ function createDotCMSURL(config, path) {
113
+ const { loaderParams, src, width } = config;
114
+ const params = loaderParams;
115
+ if (params?.isOutsideSRC) {
116
+ return src;
117
+ }
118
+ // Use empty string as fallback to support using current site
119
+ const dotcmsHost = path ? new URL(path).origin : '';
120
+ const imageSRC = src.includes('/dA/') ? src : `/dA/${src}`;
121
+ const languageId = params?.languageId ?? '1';
122
+ if (width) {
123
+ return `${dotcmsHost}${imageSRC}/${width}w?language_id=${languageId}`;
124
+ }
125
+ return `${dotcmsHost}${imageSRC}?language_id=${languageId}`;
126
+ }
127
+
128
+ const DEFAULT_TINYMCE_CONFIG = {
129
+ menubar: false,
130
+ inline: true,
131
+ valid_styles: {
132
+ '*': 'font-size,font-family,color,text-decoration,text-align'
133
+ },
134
+ powerpaste_word_import: 'clean',
135
+ powerpaste_html_import: 'clean',
136
+ suffix: '.min', // Suffix to use when loading resources
137
+ license_key: 'gpl'
138
+ };
139
+ const TINYMCE_CONFIG = {
140
+ minimal: {
141
+ ...DEFAULT_TINYMCE_CONFIG,
142
+ plugins: 'link autolink',
143
+ toolbar: 'bold italic underline | link',
144
+ valid_elements: 'strong,em,span[style],a[href]'
145
+ },
146
+ full: {
147
+ ...DEFAULT_TINYMCE_CONFIG,
148
+ plugins: 'link lists autolink charmap',
149
+ style_formats: [
150
+ { title: 'Paragraph', format: 'p' },
151
+ { title: 'Header 1', format: 'h1' },
152
+ { title: 'Header 2', format: 'h2' },
153
+ { title: 'Header 3', format: 'h3' },
154
+ { title: 'Header 4', format: 'h4' },
155
+ { title: 'Header 5', format: 'h5' },
156
+ { title: 'Header 6', format: 'h6' },
157
+ { title: 'Pre', format: 'pre' },
158
+ { title: 'Code', format: 'code' }
159
+ ],
160
+ toolbar: [
161
+ 'styleselect undo redo | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignfull | numlist bullist outdent indent | hr charmap removeformat | link'
162
+ ]
163
+ },
164
+ plain: {
165
+ ...DEFAULT_TINYMCE_CONFIG,
166
+ plugins: '',
167
+ toolbar: ''
168
+ }
169
+ };
170
+
171
+ /**
172
+ * Dot editable text component.
173
+ * This component is responsible to render a text field that can be edited inline.
174
+ *
175
+ * @export
176
+ * @class DotCMSEditableTextComponent
177
+ * @implements {OnInit}
178
+ * @implements {OnChanges}
179
+ */
180
+ class DotCMSEditableTextComponent {
181
+ constructor() {
182
+ /**
183
+ * Represents the mode of the editor which can be `plain`, `minimal`, or `full`
184
+ *
185
+ * @type {DOT_EDITABLE_TEXT_MODE}
186
+ * @memberof DotCMSEditableTextComponent
187
+ */
188
+ this.mode = 'plain';
189
+ /**
190
+ * Represents the format of the editor which can be `text` or `html`
191
+ *
192
+ * @type {DOT_EDITABLE_TEXT_FORMAT}
193
+ * @memberof DotCMSEditableTextComponent
194
+ */
195
+ this.format = 'text';
196
+ /**
197
+ * Represents the field name of the `contentlet` that can be edited
198
+ *
199
+ * @memberof DotCMSEditableTextComponent
200
+ */
201
+ this.fieldName = '';
202
+ /**
203
+ * Represents the content of the `contentlet` that can be edited
204
+ *
205
+ * @protected
206
+ * @memberof DotCMSEditableTextComponent
207
+ */
208
+ this.content = '';
209
+ this.#sanitizer = inject(DomSanitizer);
210
+ this.#renderer = inject(Renderer2);
211
+ this.#elementRef = inject(ElementRef);
212
+ }
213
+ #sanitizer;
214
+ #renderer;
215
+ #elementRef;
216
+ /**
217
+ * The TinyMCE editor
218
+ *
219
+ * @readonly
220
+ * @memberof DotCMSEditableTextComponent
221
+ */
222
+ get editor() {
223
+ return this.editorComponent?.editor;
224
+ }
225
+ /**
226
+ * Returns the number of pages the contentlet is on
227
+ *
228
+ * @readonly
229
+ * @memberof DotCMSEditableTextComponent
230
+ */
231
+ get onNumberOfPages() {
232
+ return this.contentlet['onNumberOfPages'] || 1;
233
+ }
234
+ /**
235
+ * Handle copy contentlet inline editing success event
236
+ *
237
+ * @param {MessageEvent} { data }
238
+ * @return {*}
239
+ * @memberof DotCMSEditableTextComponent
240
+ */
241
+ onMessage({ data }) {
242
+ const { name, payload } = data;
243
+ if (name !== NOTIFY_CLIENT.UVE_COPY_CONTENTLET_INLINE_EDITING_SUCCESS) {
244
+ return;
245
+ }
246
+ const { oldInode, inode } = payload;
247
+ const currentInode = this.contentlet.inode;
248
+ if (currentInode === oldInode || currentInode === inode) {
249
+ this.editorComponent.editor.focus();
250
+ return;
251
+ }
252
+ }
253
+ ngOnInit() {
254
+ this.isInsideEditor = isInsideEditor();
255
+ if (!this.isInsideEditor) {
256
+ this.innerHTMLToElement();
257
+ return;
258
+ }
259
+ this.init = {
260
+ ...TINYMCE_CONFIG[this.mode],
261
+ base_url: `${DotCmsClient.dotcmsUrl}/ext/tinymcev7`
262
+ };
263
+ }
264
+ ngOnChanges() {
265
+ this.content = this.contentlet[this.fieldName] || '';
266
+ if (this.editor) {
267
+ this.editor.setContent(this.content, { format: this.format });
268
+ }
269
+ }
270
+ /**
271
+ * Handle mouse down event
272
+ *
273
+ * @param {EventObj<MouseEvent>} { event }
274
+ * @return {*}
275
+ * @memberof DotCMSEditableTextComponent
276
+ */
277
+ onMouseDown({ event }) {
278
+ if (this.onNumberOfPages <= 1 || this.editorComponent.editor.hasFocus()) {
279
+ return;
280
+ }
281
+ const { inode, languageId: language } = this.contentlet;
282
+ event.stopPropagation();
283
+ event.preventDefault();
284
+ try {
285
+ postMessageToEditor({
286
+ action: CLIENT_ACTIONS.COPY_CONTENTLET_INLINE_EDITING,
287
+ payload: {
288
+ dataset: {
289
+ inode,
290
+ language,
291
+ fieldName: this.fieldName
292
+ }
293
+ }
294
+ });
295
+ }
296
+ catch (error) {
297
+ console.error('Failed to post message to editor:', error);
298
+ }
299
+ }
300
+ /**
301
+ * Handle focus out event
302
+ *
303
+ * @return {*}
304
+ * @memberof DotCMSEditableTextComponent
305
+ */
306
+ onFocusOut() {
307
+ const content = this.editor.getContent({ format: this.format });
308
+ if (!this.editor.isDirty() || !this.didContentChange(content)) {
309
+ return;
310
+ }
311
+ const { inode, languageId: langId } = this.contentlet;
312
+ try {
313
+ postMessageToEditor({
314
+ action: CLIENT_ACTIONS.UPDATE_CONTENTLET_INLINE_EDITING,
315
+ payload: {
316
+ content,
317
+ dataset: {
318
+ inode,
319
+ langId,
320
+ fieldName: this.fieldName
321
+ }
322
+ }
323
+ });
324
+ }
325
+ catch (error) {
326
+ console.error('Failed to post message to editor:', error);
327
+ }
328
+ }
329
+ /**
330
+ * inner HTML to element
331
+ *
332
+ * @private
333
+ * @param {string} editedContent
334
+ * @return {*}
335
+ * @memberof DotCMSEditableTextComponent
336
+ */
337
+ innerHTMLToElement() {
338
+ const element = this.#elementRef.nativeElement;
339
+ const safeHtml = this.#sanitizer.bypassSecurityTrustHtml(this.content);
340
+ const content = this.#sanitizer.sanitize(SecurityContext.HTML, safeHtml) || '';
341
+ this.#renderer.setProperty(element, 'innerHTML', content);
342
+ }
343
+ /**
344
+ * Check if the content has changed
345
+ *
346
+ * @private
347
+ * @param {string} editedContent
348
+ * @return {*}
349
+ * @memberof DotCMSEditableTextComponent
350
+ */
351
+ didContentChange(editedContent) {
352
+ return this.content !== editedContent;
353
+ }
354
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditableTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
355
+ 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: [
356
+ {
357
+ provide: TINYMCE_SCRIPT_SRC,
358
+ useFactory: () => {
359
+ return `${DotCmsClient.dotcmsUrl}/ext/tinymcev7/tinymce.min.js`;
360
+ }
361
+ }
362
+ ], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (isInsideEditor) {\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):hover{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"] }] }); }
363
+ }
364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSEditableTextComponent, decorators: [{
365
+ type: Component,
366
+ args: [{ selector: 'dotcms-editable-text', standalone: true, imports: [EditorComponent], providers: [
367
+ {
368
+ provide: TINYMCE_SCRIPT_SRC,
369
+ useFactory: () => {
370
+ return `${DotCmsClient.dotcmsUrl}/ext/tinymcev7/tinymce.min.js`;
371
+ }
372
+ }
373
+ ], template: "@if (isInsideEditor) {\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):hover{outline:2px solid #006ce7;border-radius:4px}\n"] }]
374
+ }], propDecorators: { editorComponent: [{
375
+ type: ViewChild,
376
+ args: [EditorComponent]
377
+ }], mode: [{
378
+ type: Input
379
+ }], format: [{
380
+ type: Input
381
+ }], contentlet: [{
382
+ type: Input
383
+ }], fieldName: [{
384
+ type: Input
385
+ }], onMessage: [{
386
+ type: HostListener,
387
+ args: ['window:message', ['$event']]
388
+ }] } });
389
+
390
+ /**
391
+ * Generated bundle index. Do not edit.
392
+ */
393
+
394
+ export { DotCMSEditableTextComponent, DotCMSShowWhenDirective, provideDotCMSImageLoader };
395
+ //# sourceMappingURL=dotcms-angular-next.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotcms-angular-next.mjs","sources":["../../../../../libs/sdk/angular/next/directives/dotcms-show-when/dotcms-show-when.directive.ts","../../../../../libs/sdk/angular/next/providers/dotcms-image-loader/dotcms-image_loader.ts","../../../../../libs/sdk/angular/next/components/dotcms-editable-text/utils.ts","../../../../../libs/sdk/angular/next/components/dotcms-editable-text/dotcms-editable-text.component.ts","../../../../../libs/sdk/angular/next/components/dotcms-editable-text/dotcms-editable-text.component.html","../../../../../libs/sdk/angular/next/dotcms-angular-next.ts"],"sourcesContent":["import { Directive, Input, ViewContainerRef, TemplateRef, inject } from '@angular/core';\n\nimport { getUVEState } from '@dotcms/uve';\nimport { UVE_MODE, UVEState } from '@dotcms/uve/types';\n\n/**\n * Directive to show a template when the UVE is in a specific mode.\n *\n * @example\n * <div *dotCMSShowWhen=\"UVE_MODE.EDIT\">\n * This will be shown when the UVE is in edit mode.\n * </div>\n *\n * @export\n * @class DotCMSShowWhenDirective\n */\n@Directive({\n selector: '[dotCMSShowWhen]',\n standalone: true\n})\nexport class DotCMSShowWhenDirective {\n #when: UVE_MODE = UVE_MODE.EDIT;\n #hasView = false;\n\n @Input() set dotCMSShowWhen(value: UVE_MODE) {\n this.#when = value;\n this.updateViewContainer();\n }\n\n #viewContainerRef = inject(ViewContainerRef);\n #templateRef = inject(TemplateRef);\n\n private updateViewContainer() {\n const state: UVEState | undefined = getUVEState();\n\n const shouldShow = state?.mode === this.#when;\n\n if (shouldShow && !this.#hasView) {\n this.#viewContainerRef.createEmbeddedView(this.#templateRef);\n this.#hasView = true;\n } else if (!shouldShow && this.#hasView) {\n this.#viewContainerRef.clear();\n this.#hasView = false;\n }\n }\n}\n","import { IMAGE_LOADER, ImageLoaderConfig } from '@angular/common';\nimport { Provider } from '@angular/core';\n\n/**\n * Type definition for the DotCMS image loader parameters\n */\ninterface DotCMSImageLoaderParams {\n isOutsideSRC?: boolean;\n languageId?: string;\n}\n\n/**\n * Validates if a given path is a valid URL string\n *\n * @param path - The path to validate\n * @returns boolean indicating if the path is valid\n */\nfunction isValidPath(path: unknown): boolean {\n if (typeof path !== 'string' || path.trim() === '') {\n return false;\n }\n\n try {\n new URL(path);\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Provides a DotCMS image loader configuration for the Angular Image directive\n *\n * @param path - The base URL path to the DotCMS instance, or empty to use current site\n * @returns An array of providers for the IMAGE_LOADER token\n * @throws Error if the provided path is invalid\n * @example\n * ```typescript\n * // In your app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideDotCMSImageLoader('https://demo.dotcms.com')\n * // Or use current site:\n * // provideDotCMSImageLoader()\n * ]\n * };\n * ```\n */\nexport function provideDotCMSImageLoader(path?: string): Provider[] {\n // If path is provided, validate it\n if (path && !isValidPath(path)) {\n throw new Error(\n `Image loader has detected an invalid path (\\`${path}\\`). ` +\n `To fix this, supply either the full URL to the dotCMS site, or leave it empty to use the current site.`\n );\n }\n\n return [\n {\n provide: IMAGE_LOADER,\n useValue: (config: ImageLoaderConfig) => createDotCMSURL(config, path)\n }\n ];\n}\n\n/**\n * Creates a DotCMS-compatible URL for image loading\n *\n * @param config - The image loader configuration\n * @param path - The base URL path to the DotCMS instance\n * @returns A fully qualified URL for the image\n * @internal\n */\nfunction createDotCMSURL(config: ImageLoaderConfig, path?: string): string {\n const { loaderParams, src, width } = config;\n const params = loaderParams as DotCMSImageLoaderParams;\n\n if (params?.isOutsideSRC) {\n return src;\n }\n\n // Use empty string as fallback to support using current site\n const dotcmsHost = path ? new URL(path).origin : '';\n const imageSRC = src.includes('/dA/') ? src : `/dA/${src}`;\n const languageId = params?.languageId ?? '1';\n\n if (width) {\n return `${dotcmsHost}${imageSRC}/${width}w?language_id=${languageId}`;\n }\n\n return `${dotcmsHost}${imageSRC}?language_id=${languageId}`;\n}\n","import { EditorComponent } from '@tinymce/tinymce-angular';\n\nexport type DOT_EDITABLE_TEXT_MODE = 'minimal' | 'full' | 'plain';\n\nexport type DOT_EDITABLE_TEXT_FORMAT = 'html' | 'text';\n\nconst DEFAULT_TINYMCE_CONFIG: EditorComponent['init'] = {\n menubar: false,\n inline: true,\n valid_styles: {\n '*': 'font-size,font-family,color,text-decoration,text-align'\n },\n powerpaste_word_import: 'clean',\n powerpaste_html_import: 'clean',\n suffix: '.min', // Suffix to use when loading resources\n license_key: 'gpl'\n};\n\nexport const TINYMCE_CONFIG: {\n [key in DOT_EDITABLE_TEXT_MODE]: EditorComponent['init'];\n} = {\n minimal: {\n ...DEFAULT_TINYMCE_CONFIG,\n plugins: 'link autolink',\n toolbar: 'bold italic underline | link',\n valid_elements: 'strong,em,span[style],a[href]'\n },\n full: {\n ...DEFAULT_TINYMCE_CONFIG,\n plugins: 'link lists autolink charmap',\n style_formats: [\n { title: 'Paragraph', format: 'p' },\n { title: 'Header 1', format: 'h1' },\n { title: 'Header 2', format: 'h2' },\n { title: 'Header 3', format: 'h3' },\n { title: 'Header 4', format: 'h4' },\n { title: 'Header 5', format: 'h5' },\n { title: 'Header 6', format: 'h6' },\n { title: 'Pre', format: 'pre' },\n { title: 'Code', format: 'code' }\n ],\n toolbar: [\n 'styleselect undo redo | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignfull | numlist bullist outdent indent | hr charmap removeformat | link'\n ]\n },\n plain: {\n ...DEFAULT_TINYMCE_CONFIG,\n plugins: '',\n toolbar: ''\n }\n};\n","import { EditorComponent, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';\nimport { EventObj } from '@tinymce/tinymce-angular/editor/Events';\n\nimport {\n Component,\n ElementRef,\n HostListener,\n inject,\n Input,\n OnChanges,\n OnInit,\n Renderer2,\n SecurityContext,\n ViewChild\n} from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\n\nimport {\n CLIENT_ACTIONS,\n DotCmsClient,\n isInsideEditor,\n NOTIFY_CLIENT,\n postMessageToEditor\n} from '@dotcms/client';\n\nimport { TINYMCE_CONFIG, DOT_EDITABLE_TEXT_FORMAT, DOT_EDITABLE_TEXT_MODE } from './utils';\n\nimport { DotCMSContentlet } from '../../models';\n\n/**\n * Dot editable text component.\n * This component is responsible to render a text field that can be edited inline.\n *\n * @export\n * @class DotCMSEditableTextComponent\n * @implements {OnInit}\n * @implements {OnChanges}\n */\n@Component({\n selector: 'dotcms-editable-text',\n standalone: true,\n templateUrl: './dotcms-editable-text.component.html',\n styleUrl: './dotcms-editable-text.component.css',\n imports: [EditorComponent],\n providers: [\n {\n provide: TINYMCE_SCRIPT_SRC,\n useFactory: () => {\n return `${DotCmsClient.dotcmsUrl}/ext/tinymcev7/tinymce.min.js`;\n }\n }\n ]\n})\nexport class DotCMSEditableTextComponent implements OnInit, OnChanges {\n @ViewChild(EditorComponent) editorComponent!: EditorComponent;\n\n /**\n * Represents the mode of the editor which can be `plain`, `minimal`, or `full`\n *\n * @type {DOT_EDITABLE_TEXT_MODE}\n * @memberof DotCMSEditableTextComponent\n */\n @Input() mode: DOT_EDITABLE_TEXT_MODE = 'plain';\n /**\n * Represents the format of the editor which can be `text` or `html`\n *\n * @type {DOT_EDITABLE_TEXT_FORMAT}\n * @memberof DotCMSEditableTextComponent\n */\n @Input() format: DOT_EDITABLE_TEXT_FORMAT = 'text';\n /**\n * Represents the `contentlet` that can be inline edited\n *\n * @type {DotCMSContentlet}\n * @memberof DotCMSEditableTextComponent\n */\n @Input() contentlet!: DotCMSContentlet;\n /**\n * Represents the field name of the `contentlet` that can be edited\n *\n * @memberof DotCMSEditableTextComponent\n */\n @Input() fieldName = '';\n\n /**\n * Represents the content of the `contentlet` that can be edited\n *\n * @protected\n * @memberof DotCMSEditableTextComponent\n */\n protected content = '';\n /**\n * Represents the configuration of the editor\n *\n * @protected\n * @type {EditorComponent['init']}\n * @memberof DotCMSEditableTextComponent\n */\n protected init!: EditorComponent['init'];\n /**\n * Represents if the component is inside the editor\n *\n * @protected\n * @type {boolean}\n * @memberof DotCMSEditableTextComponent\n */\n protected isInsideEditor!: boolean;\n\n readonly #sanitizer = inject<DomSanitizer>(DomSanitizer);\n readonly #renderer = inject<Renderer2>(Renderer2);\n readonly #elementRef = inject<ElementRef>(ElementRef);\n\n /**\n * The TinyMCE editor\n *\n * @readonly\n * @memberof DotCMSEditableTextComponent\n */\n get editor() {\n return this.editorComponent?.editor;\n }\n\n /**\n * Returns the number of pages the contentlet is on\n *\n * @readonly\n * @memberof DotCMSEditableTextComponent\n */\n get onNumberOfPages() {\n return this.contentlet['onNumberOfPages'] || 1;\n }\n\n /**\n * Handle copy contentlet inline editing success event\n *\n * @param {MessageEvent} { data }\n * @return {*}\n * @memberof DotCMSEditableTextComponent\n */\n @HostListener('window:message', ['$event'])\n onMessage({ data }: MessageEvent) {\n const { name, payload } = data;\n if (name !== NOTIFY_CLIENT.UVE_COPY_CONTENTLET_INLINE_EDITING_SUCCESS) {\n return;\n }\n\n const { oldInode, inode } = payload;\n const currentInode = this.contentlet.inode;\n\n if (currentInode === oldInode || currentInode === inode) {\n this.editorComponent.editor.focus();\n\n return;\n }\n }\n\n ngOnInit() {\n this.isInsideEditor = isInsideEditor();\n\n if (!this.isInsideEditor) {\n this.innerHTMLToElement();\n\n return;\n }\n\n this.init = {\n ...TINYMCE_CONFIG[this.mode],\n base_url: `${DotCmsClient.dotcmsUrl}/ext/tinymcev7`\n };\n }\n\n ngOnChanges() {\n this.content = this.contentlet[this.fieldName] || '';\n if (this.editor) {\n this.editor.setContent(this.content, { format: this.format });\n }\n }\n\n /**\n * Handle mouse down event\n *\n * @param {EventObj<MouseEvent>} { event }\n * @return {*}\n * @memberof DotCMSEditableTextComponent\n */\n onMouseDown({ event }: EventObj<MouseEvent>) {\n if (this.onNumberOfPages <= 1 || this.editorComponent.editor.hasFocus()) {\n return;\n }\n\n const { inode, languageId: language } = this.contentlet;\n\n event.stopPropagation();\n event.preventDefault();\n\n try {\n postMessageToEditor({\n action: CLIENT_ACTIONS.COPY_CONTENTLET_INLINE_EDITING,\n payload: {\n dataset: {\n inode,\n language,\n fieldName: this.fieldName\n }\n }\n });\n } catch (error) {\n console.error('Failed to post message to editor:', error);\n }\n }\n /**\n * Handle focus out event\n *\n * @return {*}\n * @memberof DotCMSEditableTextComponent\n */\n onFocusOut() {\n const content = this.editor.getContent({ format: this.format });\n\n if (!this.editor.isDirty() || !this.didContentChange(content)) {\n return;\n }\n\n const { inode, languageId: langId } = this.contentlet;\n\n try {\n postMessageToEditor({\n action: CLIENT_ACTIONS.UPDATE_CONTENTLET_INLINE_EDITING,\n payload: {\n content,\n dataset: {\n inode,\n langId,\n fieldName: this.fieldName\n }\n }\n });\n } catch (error) {\n console.error('Failed to post message to editor:', error);\n }\n }\n\n /**\n * inner HTML to element\n *\n * @private\n * @param {string} editedContent\n * @return {*}\n * @memberof DotCMSEditableTextComponent\n */\n private innerHTMLToElement() {\n const element = this.#elementRef.nativeElement;\n const safeHtml = this.#sanitizer.bypassSecurityTrustHtml(this.content);\n const content = this.#sanitizer.sanitize(SecurityContext.HTML, safeHtml) || '';\n\n this.#renderer.setProperty(element, 'innerHTML', content);\n }\n\n /**\n * Check if the content has changed\n *\n * @private\n * @param {string} editedContent\n * @return {*}\n * @memberof DotCMSEditableTextComponent\n */\n private didContentChange(editedContent: string) {\n return this.content !== editedContent;\n }\n}\n","@if (isInsideEditor) {\n <editor\n #tinyEditor\n [init]=\"init\"\n [initialValue]=\"content\"\n (onMouseDown)=\"onMouseDown($event)\"\n (onFocusOut)=\"onFocusOut()\" />\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -3,9 +3,10 @@ import * as i0 from '@angular/core';
3
3
  import { inject, Renderer2, ElementRef, SecurityContext, Component, ViewChild, Input, HostListener, Injectable, ChangeDetectionStrategy, HostBinding, signal, computed, DestroyRef } from '@angular/core';
4
4
  import { DomSanitizer } from '@angular/platform-browser';
5
5
  import { NOTIFY_CLIENT, isInsideEditor, DotCmsClient, postMessageToEditor, CLIENT_ACTIONS, initEditor, updateNavigation } from '@dotcms/client';
6
- import { AsyncPipe, NgComponentOutlet } from '@angular/common';
6
+ import { AsyncPipe, NgComponentOutlet, IMAGE_LOADER } from '@angular/common';
7
7
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
8
  import { ActivatedRoute } from '@angular/router';
9
+ import { createUVESubscription } from '@dotcms/uve';
9
10
  import { BehaviorSubject } from 'rxjs';
10
11
  import { map } from 'rxjs/operators';
11
12
 
@@ -53,6 +54,10 @@ const TINYMCE_CONFIG = {
53
54
  };
54
55
 
55
56
  /**
57
+ * @deprecated This component is deprecated and will be removed in future versions.
58
+ * Please use the new Rich Text Editor component from the main SDK.
59
+ * For more information, refer to the migration guide in the documentation.
60
+ *
56
61
  * Dot editable text component.
57
62
  * This component is responsible to render a text field that can be edited inline.
58
63
  *
@@ -272,6 +277,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
272
277
  }] } });
273
278
 
274
279
  /**
280
+ * @deprecated This service is deprecated and will be removed in future versions.
281
+ * Please use the new Page Context service from the main SDK.
282
+ * For more information, refer to the migration guide in the documentation.
283
+ *
275
284
  * @author dotCMS
276
285
  * @description This service is responsible for managing the page context.
277
286
  * @export
@@ -760,6 +769,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
760
769
  }] } });
761
770
 
762
771
  /**
772
+ * @deprecated This component is deprecated and will be removed in future versions.
773
+ * Please use the new Page Layout component from the main SDK.
774
+ * For more information, refer to the migration guide in the documentation.
775
+ *
763
776
  * `DotcmsLayoutComponent` is a class that represents the layout for a DotCMS page.
764
777
  * It includes a `pageAsset` property that represents the DotCMS page asset and a `components` property that represents the dynamic components for the page.
765
778
  *
@@ -806,7 +819,7 @@ class DotcmsLayoutComponent {
806
819
  initEditor({ pathname });
807
820
  updateNavigation(pathname || '/');
808
821
  });
809
- this.client.editor.on('changes', (data) => {
822
+ this.uveSubscription = createUVESubscription('changes', (data) => {
810
823
  if (this.onReload) {
811
824
  this.onReload();
812
825
  return;
@@ -819,7 +832,7 @@ class DotcmsLayoutComponent {
819
832
  if (!isInsideEditor()) {
820
833
  return;
821
834
  }
822
- this.client.editor.off('changes');
835
+ this.uveSubscription?.unsubscribe();
823
836
  }
824
837
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotcmsLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
825
838
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotcmsLayoutComponent, isStandalone: true, selector: "dotcms-layout", inputs: { pageAsset: "pageAsset", components: "components", onReload: "onReload", editor: "editor" }, ngImport: i0, template: `
@@ -855,9 +868,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
855
868
 
856
869
  /* eslint-disable @typescript-eslint/no-explicit-any */
857
870
 
871
+ /**
872
+ * Validates if a given path is a valid URL string
873
+ *
874
+ * @param path - The path to validate
875
+ * @returns boolean indicating if the path is valid
876
+ */
877
+ function isValidPath(path) {
878
+ if (typeof path !== 'string' || path.trim() === '') {
879
+ return false;
880
+ }
881
+ try {
882
+ new URL(path);
883
+ return true;
884
+ }
885
+ catch {
886
+ return false;
887
+ }
888
+ }
889
+ /**
890
+ * Provides a DotCMS image loader configuration for the Angular Image directive
891
+ *
892
+ * @param path - The base URL path to the DotCMS instance, or empty to use current site
893
+ * @returns An array of providers for the IMAGE_LOADER token
894
+ * @throws Error if the provided path is invalid
895
+ * @example
896
+ * ```typescript
897
+ * // In your app.config.ts
898
+ * export const appConfig: ApplicationConfig = {
899
+ * providers: [
900
+ * provideDotCMSImageLoader('https://demo.dotcms.com')
901
+ * // Or use current site:
902
+ * // provideDotCMSImageLoader()
903
+ * ]
904
+ * };
905
+ * ```
906
+ */
907
+ function provideDotCMSImageLoader(path) {
908
+ // If path is provided, validate it
909
+ if (path && !isValidPath(path)) {
910
+ throw new Error(`Image loader has detected an invalid path (\`${path}\`). ` +
911
+ `To fix this, supply either the full URL to the dotCMS site, or leave it empty to use the current site.`);
912
+ }
913
+ return [
914
+ {
915
+ provide: IMAGE_LOADER,
916
+ useValue: (config) => createDotCMSUrl(config, path)
917
+ }
918
+ ];
919
+ }
920
+ /**
921
+ * Creates a DotCMS-compatible URL for image loading
922
+ *
923
+ * @param config - The image loader configuration
924
+ * @param path - The base URL path to the DotCMS instance
925
+ * @returns A fully qualified URL for the image
926
+ * @internal
927
+ */
928
+ function createDotCMSUrl(config, path) {
929
+ // console.log('createDotCMSUrl', config, path);
930
+ const { loaderParams, src, width } = config;
931
+ const params = loaderParams;
932
+ if (params?.isOutsideSRC) {
933
+ return src;
934
+ }
935
+ // Use empty string as fallback to support using current site
936
+ const dotcmsHost = path ? new URL(path).origin : '';
937
+ const imageSRC = src.includes('/dA/') ? src : `/dA/${src}`;
938
+ const languageId = params?.languageId ?? '1';
939
+ if (width) {
940
+ return `${dotcmsHost}${imageSRC}/${width}w?language_id=${languageId}`;
941
+ }
942
+ return `${dotcmsHost}${imageSRC}?language_id=${languageId}`;
943
+ }
944
+
945
+ /**
946
+ * @deprecated This API is deprecated and will be removed in future versions.
947
+ * Please migrate to the new components and services in the main SDK.
948
+ * For more information, refer to the migration guide in the documentation.
949
+ */
950
+
858
951
  /**
859
952
  * Generated bundle index. Do not edit.
860
953
  */
861
954
 
862
- export { DotEditableTextComponent, DotcmsLayoutComponent, PageContextService };
955
+ export { DotEditableTextComponent, DotcmsLayoutComponent, PageContextService, provideDotCMSImageLoader };
863
956
  //# sourceMappingURL=dotcms-angular.mjs.map