@designcrowd/library.brand-page 6.0.6-ast-bg-shape-2 → 6.0.6-json-prereq-2

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 (151) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-FBIOiGyB.js → CreatedOnBrandCrowd-de-de-F1Ldbx6c.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-C0UyWKLw.js → CreatedOnBrandCrowd-en-us-D8z2m0Et.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-Ob5_G51b.js → CreatedOnBrandCrowd-es-es-CLSkbkYu.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Dp7DaN9s.js → CreatedOnBrandCrowd-fr-ca-Cyc4YWYR.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-Dp7DaN9s.js → CreatedOnBrandCrowd-fr-fr-Cyc4YWYR.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-B42T278-.js → CreatedOnBrandCrowd-pt-br-DSSUcSmV.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-B42T278-.js → CreatedOnBrandCrowd-pt-pt-DSSUcSmV.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-LDOPwzR8.js → CreatedOnDcom-de-de-DF1JaJPE.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DVH4dPqF.js → CreatedOnDcom-en-us-Dek2GCu0.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-CCjDf6JK.js → CreatedOnDcom-es-es-C3JD7_bP.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-B-onUZea.js → CreatedOnDcom-fr-ca-Bllxm84y.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-CvUTso8h.js → CreatedOnDcom-fr-fr-B3cFZgRB.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-Bx2ex-72.js → CreatedOnDcom-pt-br-DHCnZdZk.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-LXHdb2Ol.js → CreatedOnDcom-pt-pt-BLooAZOd.js} +1 -1
  15. package/lib/src/brand-page/models/index.d.ts +34 -28
  16. package/lib/src/brand-page/models/index.js +0 -2
  17. package/lib/src/brand-page/utils/migration/migration-18.d.ts +2 -0
  18. package/lib/src/brand-page/utils/migration/migration-18.js +71 -0
  19. package/lib/src/brand-page/utils/migration.util.js +11 -0
  20. package/lib/src/brand-page/utils/text.util.d.ts +1 -1
  21. package/lib/src/brand-page/utils/text.util.js +32 -0
  22. package/lib/src/brand-page/utils/vcard.util.js +4 -4
  23. package/lib/src/brand-page/view-models.d.ts +3 -3
  24. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +22 -0
  25. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +22 -0
  26. package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.d.ts +18 -21
  27. package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.js +54 -3
  28. package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.d.ts +56 -0
  29. package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.js +37 -0
  30. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +1 -1
  31. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +28 -0
  32. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +66 -0
  33. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +20 -99
  34. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +0 -6
  35. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +0 -1
  36. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +0 -1
  37. package/lib/src/brand-page-maker/utils/index.d.ts +2 -0
  38. package/lib/src/brand-page-maker/utils/index.js +2 -0
  39. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +19 -5
  40. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +35 -5
  41. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +33 -0
  42. package/lib/src/brand-page-maker/utils/rte-render.util.js +50 -0
  43. package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +6 -0
  44. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +158 -0
  45. package/lib/src/brand-page-maker/utils/rte-serializer.d.ts +5 -0
  46. package/lib/src/brand-page-maker/utils/rte-serializer.js +112 -0
  47. package/lib/src/{bundled-translations-BzzINHD2.js → bundled-translations-BUyt4scr.js} +9 -9
  48. package/lib/src/{bundled-translations.de-DE-opJOfLO-.js → bundled-translations.de-DE-DEw_OVai.js} +27 -27
  49. package/lib/src/{bundled-translations.es-ES-MaidBiW6.js → bundled-translations.es-ES-CFKWmkgY.js} +21 -21
  50. package/lib/src/{bundled-translations.fr-CA-CuG0285l.js → bundled-translations.fr-CA-DCl5LJS4.js} +21 -21
  51. package/lib/src/{bundled-translations.fr-FR-DWh-DHys.js → bundled-translations.fr-FR-B5BjgllA.js} +18 -18
  52. package/lib/src/{bundled-translations.pt-BR-DG6n1YPu.js → bundled-translations.pt-BR-5PWpMPuM.js} +13 -13
  53. package/lib/src/{bundled-translations.pt-PT-J5-Lhk0H.js → bundled-translations.pt-PT-B9_wN0HR.js} +22 -22
  54. package/lib/src/bundles/bundled-translations.de-DE.json +1 -14
  55. package/lib/src/bundles/bundled-translations.es-ES.json +1 -14
  56. package/lib/src/bundles/bundled-translations.fr-CA.json +1 -14
  57. package/lib/src/bundles/bundled-translations.fr-FR.json +1 -14
  58. package/lib/src/bundles/bundled-translations.json +1 -14
  59. package/lib/src/bundles/bundled-translations.pt-BR.json +1 -14
  60. package/lib/src/bundles/bundled-translations.pt-PT.json +1 -14
  61. package/lib/src/css/library.brand-page-brandCrowd.min.css +1 -1
  62. package/lib/src/css/library.brand-page-brandPage.min.css +1 -1
  63. package/lib/src/css/library.brand-page-designCom.min.css +1 -1
  64. package/lib/src/css/library.brand-page-preview.min.css +1 -1
  65. package/lib/src/index.d.ts +1 -0
  66. package/lib/src/index.mjs +150 -145
  67. package/lib/src/{lib-wawntNBs.js → lib-BWEaceMZ.js} +45307 -45289
  68. package/lib/src/lib.js +2 -0
  69. package/lib/src/metadata-builder/builders/update-content-text-builder.js +20 -15
  70. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -3
  71. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  72. package/lib/src/metadata-builder/helpers/rte.helpers.js +6 -3
  73. package/lib/src/shared/background-settings/background-settings-models.d.ts +2 -2
  74. package/lib/src/shared/background-settings/components/background-shapes/BackgroundShapeSettings.mixin.d.ts +0 -13
  75. package/lib/src/shared/background-settings/models/background-settings-models.d.ts +1 -1
  76. package/lib/src/shared/background-settings/store/background-settings-store.d.ts +1 -24
  77. package/lib/src/shared/background-settings/store/background-settings-store.js +0 -34
  78. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +12 -3
  79. package/lib/src/shared/content-settings/components/image-field/ImageField.mixin.d.ts +0 -11
  80. package/lib/src/shared/content-settings/components/image-field/ImageField.mixin.js +0 -5
  81. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.d.ts +1 -24
  82. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.js +1 -14
  83. package/lib/src/shared/content-settings/components/radio-field/RadioField.mixin.d.ts +1 -1
  84. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +0 -12
  85. package/lib/src/utils/minify-brand-page-metadata.js +4 -1
  86. package/package.json +1 -1
  87. package/src/brand-page/components/text-wrapper/TextWrapper.vue +17 -6
  88. package/src/brand-page/models/index.ts +35 -31
  89. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -6
  90. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +0 -1
  91. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +0 -2
  92. package/src/brand-page/utils/migration/migration-18.test.ts +72 -0
  93. package/src/brand-page/utils/migration/migration-18.ts +83 -0
  94. package/src/brand-page/utils/migration.util.ts +12 -0
  95. package/src/brand-page/utils/style.util.test.ts +51 -0
  96. package/src/brand-page/utils/text.util.test.ts +47 -0
  97. package/src/brand-page/utils/text.util.ts +43 -4
  98. package/src/brand-page/utils/vcard.util.ts +6 -4
  99. package/src/brand-page/view-models.ts +3 -2
  100. package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +23 -0
  101. package/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.ts +88 -3
  102. package/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.ts +37 -0
  103. package/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.vue +8 -37
  104. package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +113 -0
  105. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +22 -106
  106. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +0 -1
  107. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +200 -0
  108. package/src/brand-page-maker/utils/index.ts +2 -0
  109. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +4 -3
  110. package/src/brand-page-maker/utils/rich-text-editor.util.ts +50 -11
  111. package/src/brand-page-maker/utils/rte-render-parity.test.ts +156 -0
  112. package/src/brand-page-maker/utils/rte-render.util.ts +77 -0
  113. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +158 -0
  114. package/src/brand-page-maker/utils/rte-sanitize.util.ts +195 -0
  115. package/src/brand-page-maker/utils/rte-serializer.ts +172 -0
  116. package/src/bundles/bundled-translations.de-DE.json +1 -14
  117. package/src/bundles/bundled-translations.es-ES.json +1 -14
  118. package/src/bundles/bundled-translations.fr-CA.json +1 -14
  119. package/src/bundles/bundled-translations.fr-FR.json +1 -14
  120. package/src/bundles/bundled-translations.json +1 -14
  121. package/src/bundles/bundled-translations.pt-BR.json +1 -14
  122. package/src/bundles/bundled-translations.pt-PT.json +1 -14
  123. package/src/lib.ts +9 -0
  124. package/src/metadata-builder/builders/update-content-text-builder.ts +32 -18
  125. package/src/metadata-builder/builders/update-content-text-style-builder.ts +6 -4
  126. package/src/metadata-builder/helpers/rte.helpers.ts +11 -7
  127. package/src/shared/background-settings/background-settings-models.ts +2 -3
  128. package/src/shared/background-settings/components/BackgroundSettings.vue +115 -133
  129. package/src/shared/background-settings/components/i18n/background-settings.de-DE.json +1 -14
  130. package/src/shared/background-settings/components/i18n/background-settings.es-ES.json +1 -14
  131. package/src/shared/background-settings/components/i18n/background-settings.fr-CA.json +1 -14
  132. package/src/shared/background-settings/components/i18n/background-settings.fr-FR.json +1 -14
  133. package/src/shared/background-settings/components/i18n/background-settings.json +1 -14
  134. package/src/shared/background-settings/components/i18n/background-settings.pt-BR.json +1 -14
  135. package/src/shared/background-settings/components/i18n/background-settings.pt-PT.json +1 -14
  136. package/src/shared/background-settings/models/background-settings-models.ts +1 -4
  137. package/src/shared/background-settings/store/background-settings-store.ts +0 -61
  138. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +16 -3
  139. package/src/shared/content-settings/components/image-field/ImageField.mixin.ts +0 -5
  140. package/src/shared/content-settings/components/image-field/ImageField.vue +1 -1
  141. package/src/shared/content-settings/components/items-field/ItemsField.mixin.ts +1 -14
  142. package/src/shared/content-settings/components/items-field/ItemsField.vue +1 -7
  143. package/src/utils/minify-brand-page-metadata.ts +4 -1
  144. package/lib/src/shared/background-settings/composables/useBackgroundShapeControls.d.ts +0 -40
  145. package/lib/src/shared/background-settings/composables/useBackgroundShapeControls.js +0 -58
  146. package/lib/src/shared/background-settings/composables/useSingleBackgroundShape.d.ts +0 -21
  147. package/lib/src/shared/background-settings/composables/useSingleBackgroundShape.js +0 -51
  148. package/src/shared/background-settings/components/MultiBackgroundShapes.vue +0 -256
  149. package/src/shared/background-settings/components/SingleBackgroundShape.vue +0 -85
  150. package/src/shared/background-settings/composables/useBackgroundShapeControls.ts +0 -124
  151. package/src/shared/background-settings/composables/useSingleBackgroundShape.ts +0 -82
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-wawntNBs.js";
2
+ import { _ as t } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-wawntNBs.js";
2
+ import { _ as e } from "./lib-BWEaceMZ.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-wawntNBs.js";
2
+ import { _ as e } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-wawntNBs.js";
2
+ import { _ as e } from "./lib-BWEaceMZ.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-wawntNBs.js";
2
+ import { _ as e } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-wawntNBs.js";
2
+ import { _ as e } from "./lib-BWEaceMZ.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-wawntNBs.js";
2
+ import { _ as M } from "./lib-BWEaceMZ.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-wawntNBs.js";
2
+ import { _ as M } from "./lib-BWEaceMZ.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -7,6 +7,14 @@ import { TextStyles } from './styles.model';
7
7
  import { LogoStyles } from './logo.model';
8
8
  import type { LogoImageModel, LogoTemplateImageModel } from './logo.model';
9
9
  import type { BrandPagePaymentConfig } from './payment.model';
10
+ import type { JSONContent } from '@tiptap/vue-3';
11
+ /**
12
+ * BP-5787 — a rich-text field is either a legacy inline-HTML string or a
13
+ * Tiptap JSON document. Typing RTE content fields as RichTextValue (instead of
14
+ * `string`) forces every consumer to handle both forms — surfacing at compile
15
+ * time any code that assumes a plain string (e.g. `.replace`, `.length`).
16
+ */
17
+ export type RichTextValue = string | JSONContent;
10
18
  export * from './brand-page-context.model';
11
19
  export * from './payment.model';
12
20
  export * from './content.model';
@@ -26,13 +34,11 @@ export declare class BackgroundShape {
26
34
  constructor(option?: Partial<BackgroundShape>);
27
35
  }
28
36
  export type BackgroundStyle = Partial<Omit<BrandPageCssStyle, 'backgroundColor'>>;
29
- export type BackgroundShapeMode = 'single' | 'multiple';
30
37
  export declare class BackgroundStyles {
31
38
  style: BackgroundStyle;
32
39
  backgroundShapeStyle: BackgroundStyle;
33
40
  backgroundImageUrl: string;
34
41
  backgroundShapes: BackgroundShape[];
35
- shapeMode?: BackgroundShapeMode;
36
42
  personalisationRole?: PersonalisationRole;
37
43
  media?: AbstractMedia;
38
44
  mediaOverlayStyle: BrandPageCssStyle;
@@ -143,7 +149,7 @@ export interface TextContent extends Content {
143
149
  /**
144
150
  * For BrandPage/BrandContact only
145
151
  */
146
- text: string;
152
+ text: RichTextValue;
147
153
  /**
148
154
  * For BrandSite
149
155
  */
@@ -166,9 +172,9 @@ export interface TextContent extends Content {
166
172
  }
167
173
  export interface ProfileContent extends Content {
168
174
  avatarImageUrl: string;
169
- name: string;
170
- title: string;
171
- description: string;
175
+ name: RichTextValue;
176
+ title: RichTextValue;
177
+ description: RichTextValue;
172
178
  backgroundColor: BrandPageCssStyle;
173
179
  colorReplacements: ColorReplacement[];
174
180
  mediaType?: string;
@@ -186,7 +192,7 @@ export interface MapContent extends Content {
186
192
  }
187
193
  export interface MailingListContent extends Content {
188
194
  acceptedFields?: 'emailOnly' | 'nameAndEmail';
189
- title: string;
195
+ title: RichTextValue;
190
196
  buttonText: string;
191
197
  titleStyle: TextStyleDeclaration;
192
198
  buttonTextStyle: TextStyleDeclaration;
@@ -237,10 +243,10 @@ export interface FormField {
237
243
  export interface ContactFormContent extends Content {
238
244
  type: 'contact-form';
239
245
  displayStyle: string;
240
- title: string;
241
- description: string;
246
+ title: RichTextValue;
247
+ description: RichTextValue;
242
248
  buttonText: string;
243
- successMessage: string;
249
+ successMessage: RichTextValue;
244
250
  fields: FormField[];
245
251
  responseEmail: string;
246
252
  imageUrl?: string;
@@ -259,8 +265,8 @@ export interface ContactFormContent extends Content {
259
265
  export interface BannerSectionContent extends Content {
260
266
  type: 'banner-section';
261
267
  imageUrl: string;
262
- title: string;
263
- description: string;
268
+ title: RichTextValue;
269
+ description: RichTextValue;
264
270
  buttonText: string | false;
265
271
  url: string;
266
272
  email?: string;
@@ -287,8 +293,8 @@ export declare const MEDIA_TYPES: {
287
293
  };
288
294
  export type MediaType = keyof typeof MEDIA_TYPES;
289
295
  export interface TextMediaItem extends ImageItem {
290
- title: string;
291
- paragraph: string;
296
+ title: RichTextValue;
297
+ paragraph: RichTextValue;
292
298
  itemsId: number;
293
299
  buttonText?: string | false;
294
300
  buttonPageId?: string;
@@ -307,16 +313,16 @@ export interface TextShapeItem extends TextMediaItem {
307
313
  export interface ShapeItem extends ImageItem {
308
314
  colorReplacements: ColorReplacement[];
309
315
  mediaType: MediaType;
310
- title?: string;
311
- paragraph?: string;
316
+ title?: RichTextValue;
317
+ paragraph?: RichTextValue;
312
318
  titleOverride?: string;
313
319
  paragraphOverride?: string;
314
320
  }
315
321
  export interface TestimonialItems {
316
322
  imageUrl: string;
317
- name: string;
318
- position: string;
319
- testimonials: string;
323
+ name: RichTextValue;
324
+ position: RichTextValue;
325
+ testimonials: RichTextValue;
320
326
  colorReplacements: ColorReplacement[];
321
327
  mediaType: string;
322
328
  size?: string;
@@ -327,7 +333,7 @@ export interface TestimonialItems {
327
333
  positionOverride?: string;
328
334
  }
329
335
  export interface TextItem {
330
- text: string;
336
+ text: RichTextValue;
331
337
  textStyle: TextStyleDeclaration;
332
338
  textOverride?: string;
333
339
  }
@@ -344,8 +350,8 @@ export interface ImagesSectionContent extends Content, MediaSection {
344
350
  enablePopup: boolean;
345
351
  }
346
352
  export interface MediaSection extends Content {
347
- title: string;
348
- description: string;
353
+ title: RichTextValue;
354
+ description: RichTextValue;
349
355
  displayStyle: ImagesSectionContentDisplayStyle;
350
356
  items: TextShapeItem[] | TextMediaItem[];
351
357
  titleStyle: TextStyleDeclaration;
@@ -362,7 +368,7 @@ export interface ColorReplacement {
362
368
  }
363
369
  export interface TestimonialSectionContent extends Content {
364
370
  type: 'testimonial-section';
365
- title: string;
371
+ title: RichTextValue;
366
372
  displayStyle: string;
367
373
  items: TestimonialItems[];
368
374
  titleStyle: TextStyleDeclaration;
@@ -376,8 +382,8 @@ export interface TestimonialSectionContent extends Content {
376
382
  export interface AboutSectionContent extends Content {
377
383
  type: 'about-section';
378
384
  imageUrl: string;
379
- title: string;
380
- paragraph: string;
385
+ title: RichTextValue;
386
+ paragraph: RichTextValue;
381
387
  displayStyle: string;
382
388
  titleStyle: TextStyleDeclaration;
383
389
  paragraphStyle: TextStyleDeclaration;
@@ -399,7 +405,7 @@ export declare const SOCIAL_LINKS_ICON_DISPLAY_STYLES: {
399
405
  export type SocialLinksIconDisplayStyle = keyof typeof SOCIAL_LINKS_ICON_DISPLAY_STYLES;
400
406
  export interface SocialLinksContent extends Content {
401
407
  type: 'social-links';
402
- title: string;
408
+ title: RichTextValue;
403
409
  links: LinksItem[];
404
410
  iconDisplayStyle: SocialLinksIconDisplayStyle;
405
411
  iconFillStyles: BrandPageCssStyle;
@@ -422,8 +428,8 @@ export interface DividerSectionContent extends Content {
422
428
  }
423
429
  export interface BookingSectionContent extends Content {
424
430
  type: 'booking-section';
425
- title: string;
426
- description: string;
431
+ title: RichTextValue;
432
+ description: RichTextValue;
427
433
  buttonText: string;
428
434
  url: string;
429
435
  email?: string;
@@ -46,7 +46,6 @@ export class BackgroundStyles {
46
46
  backgroundShapeStyle;
47
47
  backgroundImageUrl;
48
48
  backgroundShapes;
49
- shapeMode;
50
49
  personalisationRole;
51
50
  media;
52
51
  mediaOverlayStyle;
@@ -54,7 +53,6 @@ export class BackgroundStyles {
54
53
  this.backgroundImageUrl = option.backgroundImageUrl || '';
55
54
  this.backgroundShapes = (option.backgroundShapes ||
56
55
  []);
57
- this.shapeMode = option.shapeMode;
58
56
  this.style = option.style || {
59
57
  background: '',
60
58
  };
@@ -0,0 +1,2 @@
1
+ import type { MigrationData } from '../migration.util';
2
+ export declare const migration18: (migrationResult: MigrationData) => Promise<MigrationData>;
@@ -0,0 +1,71 @@
1
+ import { hasRTEContent } from '../../../brand-page-maker/utils';
2
+ import { useExternalRichTextEditor } from '../../../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
3
+ /**
4
+ * BP-5787 — migrate existing inline-HTML RTE content to Tiptap JSON.
5
+ *
6
+ * The editor now emits, and the renderer now reads, Tiptap JSON. Existing
7
+ * published/saved sites still hold RTE fields as HTML strings. This converts
8
+ * them on load:
9
+ * - maker: the loaded model is JSON, so the next save persists JSON.
10
+ * - web-renderer: lazy migrate-on-read — old sites render from JSON without
11
+ * needing a re-save.
12
+ *
13
+ * Runs on EVERY load (runAlways) so it also normalises content the AI section
14
+ * builders still emit as HTML — there is no need to change those builders or
15
+ * widen the content model types.
16
+ *
17
+ * Scope: only HTML-RTE strings (hasRTEContent) are converted. Plain strings,
18
+ * numbers, and already-JSON docs are left untouched, so the migration is
19
+ * idempotent (re-running on JSON content is a no-op — non-string values are
20
+ * skipped). Nested RTE inside item arrays (textItems, testimonials, images…)
21
+ * is handled by recursing into arrays; style objects are intentionally not
22
+ * descended into (they never hold RTE content).
23
+ */
24
+ const convertRteStringsToJson = (value, editor) => {
25
+ if (Array.isArray(value)) {
26
+ value.forEach((item) => convertRteStringsToJson(item, editor));
27
+ return;
28
+ }
29
+ if (!value || typeof value !== 'object')
30
+ return;
31
+ const record = value;
32
+ Object.keys(record).forEach((key) => {
33
+ const field = record[key];
34
+ if (typeof field === 'string' && hasRTEContent(field)) {
35
+ editor.commands.setContent(field);
36
+ record[key] = editor.getJSON();
37
+ }
38
+ else if (Array.isArray(field)) {
39
+ convertRteStringsToJson(field, editor);
40
+ }
41
+ });
42
+ };
43
+ export const migration18 = async (migrationResult) => {
44
+ const { brandPageModel } = migrationResult;
45
+ // HTML→JSON parsing needs a DOM (Tiptap's editor). In a DOM-less context
46
+ // (pure-node SSR or unit tests) we can't parse HTML, so we leave the RTE
47
+ // fields as HTML strings — the renderer and the fraud/translation extractors
48
+ // all dual-read HTML, so this is safe. Conversion happens wherever a DOM is
49
+ // available (the browser editor, jsdom).
50
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
51
+ return migrationResult;
52
+ }
53
+ let externalEditor;
54
+ try {
55
+ externalEditor = useExternalRichTextEditor().externalEditor;
56
+ }
57
+ catch {
58
+ return migrationResult;
59
+ }
60
+ try {
61
+ for (const page of brandPageModel.pages) {
62
+ for (const content of page.contents) {
63
+ convertRteStringsToJson(content, externalEditor);
64
+ }
65
+ }
66
+ }
67
+ finally {
68
+ externalEditor.destroy();
69
+ }
70
+ return migrationResult;
71
+ };
@@ -20,6 +20,7 @@ import { migration14 } from './migration/migration-14';
20
20
  import { migration15 } from './migration/migration-15';
21
21
  import { migration16 } from './migration/migration-16';
22
22
  import { migration17 } from './migration/migration-17';
23
+ import { migration18 } from './migration/migration-18';
23
24
  const MIGRATION_TABLE = [
24
25
  {
25
26
  version: 1,
@@ -132,6 +133,16 @@ const MIGRATION_TABLE = [
132
133
  runAlways: true,
133
134
  description: 'Padding Control backfill (BP-5699 Tier 2 + BP-5700 Store): backfill existing top/bottom spacing as explicit padding for text (12px), images/social links/shapes/booking (32px), store (16px), contact form (per layout), banner and about (per display style)',
134
135
  },
136
+ {
137
+ version: 18,
138
+ migrateFn: migration18,
139
+ // runAlways: normalise RTE to JSON on every load. Idempotent (only HTML
140
+ // strings are converted; JSON is skipped), so it also catches content the
141
+ // AI section builders still emit as HTML — converting it on the next read
142
+ // without a new migration or changes to those builders.
143
+ runAlways: true,
144
+ description: 'BP-5787: convert inline-HTML RTE content to Tiptap JSON on load (lazy migrate-on-read for web-renderer; persisted on next maker save; also normalises AI-built HTML)',
145
+ },
135
146
  ];
136
147
  export const GetLatestModelVersion = () => Math.max(...MIGRATION_TABLE.map((x) => x.version));
137
148
  export const migrateBrandPageModel = async (brandPageModel, options) => {
@@ -1,5 +1,5 @@
1
1
  export declare const getRenderText: (text: string) => string;
2
- export declare const escapeContentText: (text: string | undefined) => string | undefined;
2
+ export declare const escapeContentText: (text: unknown) => string | undefined;
3
3
  export declare const decodeHtmlEntities: (text: string) => string;
4
4
  export declare const unescapeContentText: (text: string) => string;
5
5
  export declare const encodeContentText: (text: string | undefined) => string | undefined;
@@ -1,11 +1,43 @@
1
1
  import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
2
+ /**
3
+ * BP-5787 — a Tiptap JSON document is an object with `type: 'doc'`.
4
+ * Inlined here (rather than importing from brand-page-maker) to avoid a
5
+ * circular import: rich-text-editor.util imports getRenderText from this file.
6
+ */
7
+ const isTiptapDoc = (value) => typeof value === 'object' &&
8
+ value !== null &&
9
+ value.type === 'doc';
10
+ const jsonDocPlainText = (doc) => {
11
+ const parts = [];
12
+ const walk = (node) => {
13
+ if (typeof node?.text === 'string')
14
+ parts.push(node.text);
15
+ node?.content?.forEach(walk);
16
+ };
17
+ walk(doc);
18
+ return parts.join(' ').replace(/\s+/g, ' ').trim();
19
+ };
2
20
  export const getRenderText = (text) => {
21
+ // BP-5787: RTE fields may now be Tiptap JSON objects. Non-strings pass
22
+ // through untouched so the renderer (TextWrapper) handles them via its
23
+ // JSON-aware path, instead of throwing on `.replace`.
24
+ if (typeof text !== 'string') {
25
+ return text;
26
+ }
3
27
  return text.replace(new RegExp(`(${ESCAPED_NEWLINE_CHARACTER}|\\n)`, 'g'), '<br/>');
4
28
  };
29
+ // Accepts a legacy inline-HTML string or a Tiptap JSON document (BP-5787):
30
+ // for JSON it returns the concatenated visible text; for HTML it strips tags.
5
31
  export const escapeContentText = (text) => {
6
32
  if (!text) {
7
33
  return text;
8
34
  }
35
+ if (isTiptapDoc(text)) {
36
+ return jsonDocPlainText(text);
37
+ }
38
+ if (typeof text !== 'string') {
39
+ return undefined;
40
+ }
9
41
  return text
10
42
  .replace(/(<([^>]+)>)/gi, '')
11
43
  .replace(/(\r\n|\r|\n)/g, ESCAPED_NEWLINE_CHARACTER);
@@ -150,9 +150,9 @@ const processSocialLinks = (socialLinksContent, vcardLines, addedEntries) => {
150
150
  });
151
151
  };
152
152
  const addProfileInfo = (profile, vcardLines) => {
153
- const name = sanitizeForVCard(profile.name || '');
154
- const title = sanitizeForVCard(profile.title || '');
155
- const description = sanitizeForVCard(profile.description || '');
153
+ const name = sanitizeForVCard(getPlainTextFromRTE(profile.name) || '');
154
+ const title = sanitizeForVCard(getPlainTextFromRTE(profile.title) || '');
155
+ const description = sanitizeForVCard(getPlainTextFromRTE(profile.description) || '');
156
156
  if (name) {
157
157
  const nameParts = name.trim().split(/\s+/);
158
158
  const lastName = nameParts.length > 1 ? nameParts.pop() || '' : '';
@@ -205,6 +205,6 @@ const downloadVCard = (vcard, filename) => {
205
205
  export const saveContact = (brandPageData) => {
206
206
  const vcard = generateVCard(brandPageData);
207
207
  const profile = findProfileContent(brandPageData);
208
- const filename = generateVCardFilename(profile?.name);
208
+ const filename = generateVCardFilename(getPlainTextFromRTE(profile?.name));
209
209
  downloadVCard(vcard, filename);
210
210
  };
@@ -1,4 +1,4 @@
1
- import type { ButtonWithModalContent, ProfileContent, TextContent, VideoContent, ImageContent, ContentType, ButtonStyles, LogoStyles, MapContent, ImageGalleryContent, GalleryStyles, MailingListContent, RequestPaymentContent, ShopContent, SupportMeContent, ContactFormContent, BannerSectionContent, BrandPageType, SocialLinksContent, TestimonialSectionContent, AboutSectionContent, DividerSectionContent, ShapesSectionContent, ButtonLinkType, PageHeaderMobile, PageHeaderDesktop, PageFooterMobile, PageFooterDesktop, TextMediaItem, TextShapeItem, TextStyleDeclaration, AspectRatio, LogoImageModel, LogoTemplateImageModel, CookieOptions, BookingSectionContent, MediaTypes, TextStyles, BackgroundStyle, BackgroundShape, PersonalisationRole, SaveContactOptions } from './models';
1
+ import type { ButtonWithModalContent, ProfileContent, TextContent, VideoContent, ImageContent, ContentType, ButtonStyles, LogoStyles, MapContent, ImageGalleryContent, GalleryStyles, MailingListContent, RequestPaymentContent, ShopContent, SupportMeContent, ContactFormContent, BannerSectionContent, BrandPageType, SocialLinksContent, TestimonialSectionContent, AboutSectionContent, DividerSectionContent, ShapesSectionContent, ButtonLinkType, PageHeaderMobile, PageHeaderDesktop, PageFooterMobile, PageFooterDesktop, TextMediaItem, TextShapeItem, TextStyleDeclaration, AspectRatio, LogoImageModel, LogoTemplateImageModel, CookieOptions, BookingSectionContent, MediaTypes, TextStyles, BackgroundStyle, BackgroundShape, PersonalisationRole, SaveContactOptions, RichTextValue } from './models';
2
2
  import type { ImagesSectionContentDisplayStyle } from './constants';
3
3
  export type ViewModelType = 'button' | 'image' | 'image-gallery' | 'logo' | 'map' | 'mailing-list' | 'profile' | 'support-me' | 'request-payment' | 'text' | 'video' | 'contact-form' | 'banner-section' | 'images-section' | 'about-section' | 'divider-section' | 'testimonial-section' | 'social-links' | 'shapes-section' | 'shop-section' | 'booking-section';
4
4
  export interface ContentViewModel {
@@ -94,8 +94,8 @@ export interface TextImageSectionViewModel {
94
94
  id: string;
95
95
  type: 'images-section';
96
96
  role: ContentType;
97
- title: string;
98
- description: string;
97
+ title: RichTextValue;
98
+ description: RichTextValue;
99
99
  displayStyle: ImagesSectionContentDisplayStyle;
100
100
  aspectRatio: AspectRatio;
101
101
  areImagesFullWidth: boolean;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * BP-5787 — golden-master fixture for the RTE HTML→JSON migration.
3
+ *
4
+ * A single rich-text value that exercises every mark/node the editor can emit,
5
+ * so one snapshot guards the whole serialisation surface. Captured as a baseline
6
+ * on the current HTML pipeline; after the migration the JSON pipeline must
7
+ * reproduce byte-identical rendered output (see rte-render-parity.test.ts).
8
+ *
9
+ * Coverage:
10
+ * - block nodes: heading (h2), paragraph, text-align (center / right)
11
+ * - inline marks: bold, italic, underline, strike
12
+ * - textStyle attrs: fontFamily, fontSize (em), letterSpacing (em), lineHeight (unitless)
13
+ * - colour: theme TOKEN ref (var(--logo-text-color)) AND a literal hex (#FF0000)
14
+ * - highlight (background colour via <mark>)
15
+ * - links: internal (target=_self) and external (target=_blank rel=noopener)
16
+ */
17
+ export declare const COMPLEX_RTE_HTML = "<h2 style=\"text-align: center\"><span style=\"color: var(--logo-text-color)\">Themed heading</span></h2><p><strong>bold</strong> <em>italic</em> <u>underline</u> <s>strike</s> <span style=\"font-family: Montserrat; font-size: 1.5em; letter-spacing: 0.05em; line-height: 1.4\">styled span</span> <mark data-color=\"#ffe08a\" style=\"background-color: #ffe08a\">highlight</mark> <span style=\"color: #FF0000\">literal hex</span> <a target=\"_self\" href=\"/about\">internal link</a> <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://example.com\">external link</a></p><p style=\"text-align: right\">second paragraph, right-aligned</p>";
18
+ /**
19
+ * The theme-token CSS variable that MUST survive the HTML→JSON round-trip
20
+ * (BP-5787 stores token refs instead of flattening them to rgb()).
21
+ */
22
+ export declare const THEME_TOKEN_REF = "var(--logo-text-color)";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * BP-5787 — golden-master fixture for the RTE HTML→JSON migration.
3
+ *
4
+ * A single rich-text value that exercises every mark/node the editor can emit,
5
+ * so one snapshot guards the whole serialisation surface. Captured as a baseline
6
+ * on the current HTML pipeline; after the migration the JSON pipeline must
7
+ * reproduce byte-identical rendered output (see rte-render-parity.test.ts).
8
+ *
9
+ * Coverage:
10
+ * - block nodes: heading (h2), paragraph, text-align (center / right)
11
+ * - inline marks: bold, italic, underline, strike
12
+ * - textStyle attrs: fontFamily, fontSize (em), letterSpacing (em), lineHeight (unitless)
13
+ * - colour: theme TOKEN ref (var(--logo-text-color)) AND a literal hex (#FF0000)
14
+ * - highlight (background colour via <mark>)
15
+ * - links: internal (target=_self) and external (target=_blank rel=noopener)
16
+ */
17
+ export const COMPLEX_RTE_HTML = `<h2 style="text-align: center"><span style="color: var(--logo-text-color)">Themed heading</span></h2><p><strong>bold</strong> <em>italic</em> <u>underline</u> <s>strike</s> <span style="font-family: Montserrat; font-size: 1.5em; letter-spacing: 0.05em; line-height: 1.4">styled span</span> <mark data-color="#ffe08a" style="background-color: #ffe08a">highlight</mark> <span style="color: #FF0000">literal hex</span> <a target="_self" href="/about">internal link</a> <a target="_blank" rel="noopener noreferrer nofollow" href="https://example.com">external link</a></p><p style="text-align: right">second paragraph, right-aligned</p>`;
18
+ /**
19
+ * The theme-token CSS variable that MUST survive the HTML→JSON round-trip
20
+ * (BP-5787 stores token refs instead of flattening them to rgb()).
21
+ */
22
+ export const THEME_TOKEN_REF = 'var(--logo-text-color)';
@@ -1,14 +1,15 @@
1
1
  import type { BackgroundStylesConfigOption } from '@brand-page-maker/models/background-styles-config';
2
2
  import type { UserMediaItem, UserMediaItemWithDimensions } from 'src/shared/my-uploads/models';
3
+ interface BackgroundShapePosition {
4
+ name: string;
5
+ screenLeft: number;
6
+ screenTop: number;
7
+ originLeft: number;
8
+ originTop: number;
9
+ scalePercentage: number;
10
+ opacityPercentage: number;
11
+ }
3
12
  declare const _default: import("vue").DefineComponent<{}, {
4
- backgroundShapes: import("vue").ComputedRef<import("@shared/background-settings/composables/useBackgroundShapeControls").BackgroundShapePosition[]>;
5
- onShapeScreenXChange: (index: number, value: number) => void;
6
- onShapeScreenYChange: (index: number, value: number) => void;
7
- onShapeOriginXChange: (index: number, value: number) => void;
8
- onShapeOriginYChange: (index: number, value: number) => void;
9
- onShapeSizeChange: (index: number, value: number | string) => void;
10
- onShapeOpacityChange: (index: number, value: number | string) => void;
11
- onDeleteShape: (index: number) => void;
12
13
  logoTheme: import("vue").ComputedRef<{
13
14
  logoTextColor: {
14
15
  rgb: string;
@@ -179,7 +180,6 @@ declare const _default: import("vue").DefineComponent<{}, {
179
180
  wordBreak?: string | undefined;
180
181
  };
181
182
  }[];
182
- shapeMode?: import("../../../brand-page").BackgroundShapeMode | undefined;
183
183
  personalisationRole?: import("../../../brand-page").PersonalisationRole | undefined;
184
184
  media?: {
185
185
  type: import("../../../brand-page").MediaTypes;
@@ -282,9 +282,6 @@ declare const _default: import("vue").DefineComponent<{}, {
282
282
  backgroundStyle: import("../../../brand-page").BackgroundStyle;
283
283
  }): void;
284
284
  setBackgroundShapes(payload: import("../../../brand-page").BackgroundShape[]): void;
285
- setShapeMode(payload: {
286
- shapeMode: import("../../../brand-page").BackgroundShapeMode;
287
- }): void;
288
285
  setBackgroundPersonalisationRole(payload: {
289
286
  personalisationRole: import("../../../brand-page").PersonalisationRole | undefined;
290
287
  }): void;
@@ -302,13 +299,6 @@ declare const _default: import("vue").DefineComponent<{}, {
302
299
  deleteBackgroundShape({ shapeIndex }: {
303
300
  shapeIndex: number;
304
301
  }): void;
305
- replaceBackgroundShape({ shapeIndex, shapeUrl, width, height, aspectRatio, }: {
306
- shapeIndex: number;
307
- shapeUrl: string;
308
- width?: number;
309
- height?: number;
310
- aspectRatio?: number;
311
- }): void;
312
302
  setLogoColors({ logoColors }: import("../../../shared/background-settings/background-settings-models").SetLogoColorsPayload): void;
313
303
  clearUserImageBackgroundImageUrl(): void;
314
304
  setAdminBackgroundOptionDefaultValues(): void;
@@ -321,8 +311,6 @@ declare const _default: import("vue").DefineComponent<{}, {
321
311
  setBackgroundMode(payload: {
322
312
  backgroundMode: import("@brand-page-maker/stores").BrandPageSettingsMode;
323
313
  }): void;
324
- openShapePicker(intent: import("@shared/background-settings/store").ShapePickerIntent): void;
325
- closeShapePicker(): void;
326
314
  setBackgroundMedia(payload: import("src/shared/my-uploads/models").MediaBaseSelectedPayload): void;
327
315
  removeBackgroundVideo(): void;
328
316
  resetMediaOverlayStyle(): void;
@@ -344,9 +332,18 @@ declare const _default: import("vue").DefineComponent<{}, {
344
332
  readonly backgroundShapeStyle: "backgroundShapeStyle";
345
333
  };
346
334
  }, {
335
+ backgroundShapes(): BackgroundShapePosition[];
347
336
  colorPickerValue(): (key: BackgroundStylesConfigOption) => string;
348
337
  backgroundShapeUrl(): string;
349
338
  }, {
339
+ onShapeSettingChange(index: number, updatedSettings: any): void;
340
+ onShapeScreenXChange(index: number, value: any): void;
341
+ onShapeScreenYChange(index: number, value: any): void;
342
+ onShapeOriginXChange(index: number, value: any): void;
343
+ onShapeOriginYChange(index: number, value: any): void;
344
+ onShapeSizeChange(index: number, value: any): void;
345
+ onShapeOpacityChange(index: number, value: any): void;
346
+ onDeleteShape(index: number): void;
350
347
  onColorMatchToggled(option: BackgroundStylesConfigOption, value: boolean): void;
351
348
  onColorPickerInput(option: BackgroundStylesConfigOption, value: string | Event): void;
352
349
  onBackgroundShapeSelected(shape: UserMediaItemWithDimensions): void;